@@ -2,21 +2,6 @@ class AlarmControlPanelCard extends HTMLElement {
2
2
constructor ( ) {
3
3
super ( ) ;
4
4
this . attachShadow ( { mode : 'open' } ) ;
5
- this . _stateStrings = {
6
- 'arm_away' : 'Arm away' ,
7
- 'arm_custom_bypass' : 'Custom' ,
8
- 'arm_home' : 'Arm home' ,
9
- 'arming' : 'Arming' ,
10
- 'arm_night' : 'Arm night' ,
11
- 'armed_away' : 'Armed away' ,
12
- 'armed_custom_bypass' : 'Armed custom' ,
13
- 'armed_home' : 'Armed home' ,
14
- 'armed_night' : 'Armed night' ,
15
- 'disarm' : 'Disarm' ,
16
- 'disarmed' : 'Disarmed' ,
17
- 'pending' : 'Pending' ,
18
- 'triggered' : 'Triggered' ,
19
- }
20
5
this . _icons = {
21
6
'armed_away' : 'mdi:security-lock' ,
22
7
'armed_custom_bypass' : 'mdi:security' ,
@@ -29,14 +14,47 @@ class AlarmControlPanelCard extends HTMLElement {
29
14
}
30
15
31
16
set hass ( hass ) {
32
- this . myhass = hass ;
33
17
const entity = hass . states [ this . _config . entity ] ;
34
- if ( entity && entity . state != this . _state ) {
35
- this . _state = entity . state ;
36
- this . _updateCardContent ( entity ) ;
18
+
19
+ if ( entity ) {
20
+ this . myhass = hass ;
21
+ if ( ! this . shadowRoot . lastChild ) {
22
+ this . _createCard ( entity ) ;
23
+ }
24
+ if ( entity . state != this . _state ) {
25
+ this . _state = entity . state ;
26
+ this . _updateCardContent ( entity ) ;
27
+ }
37
28
}
38
29
}
39
30
31
+ _createCard ( entity ) {
32
+ const config = this . _config ;
33
+
34
+ const card = document . createElement ( 'ha-card' ) ;
35
+ const content = document . createElement ( 'div' ) ;
36
+ content . id = "content" ;
37
+ content . innerHTML = `
38
+ ${ config . title ? '<div id="state-text"></div>' : '' }
39
+ <ha-icon id="state-icon"></ha-icon>
40
+ ${ this . _actionButtons ( ) }
41
+ ${ entity . attributes . code_format ?
42
+ `<paper-input label='${ this . _label ( "ui.card.alarm_control_panel.code" ) } '
43
+ type="password"></paper-input>` : '' }
44
+ ${ this . _keypad ( entity ) }
45
+ ` ;
46
+ card . appendChild ( this . _style ( config . style ) ) ;
47
+ card . appendChild ( content ) ;
48
+ this . shadowRoot . appendChild ( card ) ;
49
+
50
+ this . _setupInput ( ) ;
51
+ this . _setupKeypad ( ) ;
52
+ this . _setupActions ( ) ;
53
+ }
54
+
55
+ connectedCallback ( ) {
56
+ }
57
+
40
58
setConfig ( config ) {
41
59
if ( ! config . entity || config . entity . split ( "." ) [ 0 ] !== "alarm_control_panel" ) {
42
60
throw new Error ( 'Please specify an entity from alarm_control_panel domain.' ) ;
@@ -48,70 +66,54 @@ class AlarmControlPanelCard extends HTMLElement {
48
66
}
49
67
this . _arm_action = config . auto_enter . arm_action ;
50
68
}
69
+ if ( ! config . states ) config . states = [ 'arm_away' , 'arm_home' ] ;
70
+ if ( ! config . scale ) config . scale = '15px' ;
71
+ this . _config = Object . assign ( { } , config ) ;
51
72
52
73
const root = this . shadowRoot ;
53
74
if ( root . lastChild ) root . removeChild ( root . lastChild ) ;
54
- if ( ! config . states ) config . states = [ 'arm_home' , 'arm_away' ] ;
55
- if ( ! config . scale ) config . scale = '15px' ;
56
-
57
- this . _card = document . createElement ( 'ha-card' ) ;
58
- const content = document . createElement ( 'div' ) ;
59
- content . id = "content" ;
60
- this . _config = Object . assign ( { } , config ) ;
61
- this . _card . appendChild ( this . _style ( config . style ) ) ;
62
- this . _card . appendChild ( content ) ;
63
- root . appendChild ( this . _card ) ;
64
- this . _config = Object . assign ( { } , config ) ;
65
75
}
66
76
67
77
_updateCardContent ( entity ) {
68
78
const root = this . shadowRoot ;
69
79
const card = root . lastChild ;
70
80
const config = this . _config ;
71
81
72
- if ( ! config . title ) {
73
- card . header = this . _stateToText ( this . _state ) ;
74
- } else {
82
+ const state_str = "state.alarm_control_panel." + this . _state ;
83
+ if ( config . title ) {
75
84
card . header = config . title ;
85
+ root . getElementById ( "state-text" ) . innerHTML = this . _label ( state_str ) ;
86
+ root . getElementById ( "state-text" ) . className = `state ${ this . _state } ` ;
87
+ } else {
88
+ card . header = this . _label ( state_str ) ;
76
89
}
77
90
78
- root . getElementById ( "content" ) . innerHTML = `
79
- ${ this . _icon ( ) }
80
- ${ config . title ? `<div class='state ${ this . _state } '>
81
- ${ this . _stateToText ( this . _state ) } </div>` : '' }
82
- ${ this . _actionButtons ( ) }
83
- ${ entity . attributes . code_format ? '<paper-input label="Alarm code" type="password"></paper-input>' : '' }
84
- ${ this . _keypad ( entity ) }
85
- ` ;
86
-
87
- this . _setupActions ( ) ;
88
- this . _setupInput ( ) ;
89
- this . _setupKeypad ( ) ;
90
- }
91
+ root . getElementById ( "state-icon" ) . setAttribute ( "icon" ,
92
+ this . _icons [ this . _state ] || 'mdi:shield-outline' ) ;
93
+ root . getElementById ( "state-icon" ) . className = this . _state ;
91
94
92
- _icon ( ) {
93
- return `<ha-icon icon=' ${ this . _stateToIcon ( this . _state ) } '
94
- class=' ${ this . _state } '></ha-icon>`
95
+ const armVisible = ( this . _state === 'disarmed' ) ;
96
+ root . getElementById ( "arm-actions" ) . style . display = armVisible ? "" : "none" ;
97
+ root . getElementById ( "disarm-actions" ) . style . display = armVisible ? "none" : "" ;
95
98
}
96
99
97
100
_actionButtons ( ) {
98
101
const armVisible = ( this . _state === 'disarmed' ) ;
99
102
return `
100
- <div class="actions">
101
- ${ armVisible
102
- ? `${ this . _config . states . map ( el => `${ this . _actionButton ( el ) } ` ) . join ( '' ) } `
103
- : `${ this . _actionButton ( 'disarm' ) } ` }
104
- </div>`
103
+ <div id="arm-actions" class="actions">
104
+ ${ this . _config . states . map ( el => `${ this . _actionButton ( el ) } ` ) . join ( '' ) }
105
+ </div>
106
+ <div id="disarm-actions" class="actions">
107
+ ${ this . _actionButton ( 'disarm' ) }
108
+ </div>` ;
105
109
}
106
110
107
111
_actionButton ( state ) {
108
- return `<paper-button noink raised id="${ state } ">${ this . _stateToText ( state ) }
109
- </paper-button>` ;
112
+ return `<paper-button noink raised id="${ state } ">
113
+ ${ this . _label ( "ui.card.alarm_control_panel." + state ) } </paper-button>` ;
110
114
}
111
115
112
116
_setupActions ( ) {
113
- // TODO: fix memory leak for reattaching handlers every time
114
- // Need a way to avoid doing innerHTML, at least without detaching handlers first
115
117
const card = this . shadowRoot . lastChild ;
116
118
const config = this . _config ;
117
119
@@ -161,7 +163,8 @@ class AlarmControlPanelCard extends HTMLElement {
161
163
162
164
const input = root . lastChild . querySelector ( 'paper-input' ) ;
163
165
root . querySelectorAll ( ".pad paper-button" ) . forEach ( element => {
164
- if ( element . getAttribute ( 'value' ) === 'Clear' ) {
166
+ if ( element . getAttribute ( 'value' ) ===
167
+ this . _label ( "ui.card.alarm_control_panel.clear_code" ) ) {
165
168
element . addEventListener ( 'click' , event => {
166
169
input . value = '' ;
167
170
} )
@@ -207,7 +210,7 @@ class AlarmControlPanelCard extends HTMLElement {
207
210
${ this . _keypadButton ( "3" , "DEF" ) }
208
211
${ this . _keypadButton ( "6" , "MNO" ) }
209
212
${ this . _keypadButton ( "9" , "WXYZ" ) }
210
- ${ this . _keypadButton ( "Clear" , "" ) }
213
+ ${ this . _keypadButton ( this . _label ( "ui.card.alarm_control_panel.clear_code" ) , "" ) }
211
214
</div>
212
215
</div>`
213
216
}
@@ -324,17 +327,28 @@ class AlarmControlPanelCard extends HTMLElement {
324
327
return style ;
325
328
}
326
329
327
- _stateToIcon ( state ) {
328
- return this . _icons [ state ] || 'mdi:shield-outline'
329
- }
330
+ _label ( label , default_label = undefined ) {
331
+ // Just show "raw" label; useful when want to see underlying const
332
+ // so you can define your own label.
333
+ if ( this . _config . show_label_ids ) return label ;
334
+
335
+ if ( this . _config . labels && this . _config . labels [ label ] )
336
+ return this . _config . labels [ label ] ;
337
+
338
+ const lang = this . myhass . selectedLanguage || this . myhass . language ;
339
+ const translations = this . myhass . resources [ lang ] ;
340
+ if ( translations && translations [ label ] ) return translations [ label ] ;
341
+
342
+ if ( default_label ) return default_label ;
330
343
331
- _stateToText ( state ) {
332
- return this . _stateStrings [ state ] || 'Unknown'
344
+ // If all else fails then pretify the passed in label const
345
+ const last_bit = label . split ( '.' ) . pop ( ) ;
346
+ return last_bit . split ( '_' ) . join ( ' ' ) . replace ( / ^ \w / , c => c . toUpperCase ( ) ) ;
333
347
}
334
348
335
349
getCardSize ( ) {
336
350
return 1 ;
337
351
}
338
352
}
339
353
340
- customElements . define ( 'alarm_control_panel-card' , AlarmControlPanelCard ) ;
354
+ customElements . define ( 'alarm_control_panel-card' , AlarmControlPanelCard ) ;
0 commit comments