diff --git a/lib/entity_class/alarm_control_panel.class.dart b/lib/entity_class/alarm_control_panel.class.dart index 7366d75..42cde19 100644 --- a/lib/entity_class/alarm_control_panel.class.dart +++ b/lib/entity_class/alarm_control_panel.class.dart @@ -5,6 +5,8 @@ class AlarmControlPanelEntity extends Entity { @override Widget _buildAdditionalControlsForPage(BuildContext context) { - return AlarmControlPanelControlsWidget(); + return AlarmControlPanelControlsWidget( + extended: false, + ); } } \ No newline at end of file diff --git a/lib/entity_widgets/controls/alarm_control_panel_controls.dart b/lib/entity_widgets/controls/alarm_control_panel_controls.dart index e09f82e..1021976 100644 --- a/lib/entity_widgets/controls/alarm_control_panel_controls.dart +++ b/lib/entity_widgets/controls/alarm_control_panel_controls.dart @@ -2,6 +2,11 @@ part of '../../main.dart'; class AlarmControlPanelControlsWidget extends StatefulWidget { + final bool extended; + final List states; + + const AlarmControlPanelControlsWidget({Key key, @required this.extended, this.states: const ["arm_home", "arm_away"]}) : super(key: key); + @override _AlarmControlPanelControlsWidgetWidgetState createState() => _AlarmControlPanelControlsWidgetWidgetState(); @@ -20,23 +25,59 @@ class _AlarmControlPanelControlsWidgetWidgetState extends State buttons = []; if (entity.state == EntityState.alarm_disarmed) { - buttons.addAll([ + if (widget.states.contains("arm_home")) { + buttons.add( RaisedButton( onPressed: () => _callService(entity, "alarm_arm_home"), child: Text("ARM HOME"), - ), - RaisedButton( - onPressed: () => _callService(entity, "alarm_arm_away"), - child: Text("ARM AWAY"), ) - ] - ); + ); + } + if (widget.states.contains("arm_away")) { + buttons.add( + RaisedButton( + onPressed: () => _callService(entity, "alarm_arm_away"), + child: Text("ARM AWAY"), + ) + ); + } + if (widget.extended) { + if (widget.states.contains("arm_night")) { + buttons.add( + RaisedButton( + onPressed: () => _callService(entity, "alarm_arm_night"), + child: Text("ARM NIGHT"), + ) + ); + } + if (widget.states.contains("arm_custom_bypass")) { + buttons.add( + RaisedButton( + onPressed: () => + _callService(entity, "alarm_arm_custom_bypass"), + child: Text("ARM CUSTOM BYPASS"), + ) + ); + } + } } else { buttons.add( RaisedButton( @@ -45,33 +86,119 @@ class _AlarmControlPanelControlsWidgetWidgetState extends State[ + Wrap( + spacing: 5.0, + children: [ + RaisedButton( + onPressed: () => _pinPadHandler("1"), + child: Text("1"), + ), + RaisedButton( + onPressed: () => _pinPadHandler("2"), + child: Text("2"), + ), + RaisedButton( + onPressed: () => _pinPadHandler("3"), + child: Text("3"), + ) + ], + ), + Wrap( + spacing: 5.0, + children: [ + RaisedButton( + onPressed: () => _pinPadHandler("4"), + child: Text("4"), + ), + RaisedButton( + onPressed: () => _pinPadHandler("5"), + child: Text("5"), + ), + RaisedButton( + onPressed: () => _pinPadHandler("6"), + child: Text("6"), + ) + ], + ), + Wrap( + spacing: 5.0, + children: [ + RaisedButton( + onPressed: () => _pinPadHandler("7"), + child: Text("7"), + ), + RaisedButton( + onPressed: () => _pinPadHandler("8"), + child: Text("8"), + ), + RaisedButton( + onPressed: () => _pinPadHandler("9"), + child: Text("9"), + ) + ], + ), + Wrap( + spacing: 5.0, + alignment: WrapAlignment.end, + children: [ + RaisedButton( + onPressed: () => _pinPadHandler("0"), + child: Text("0"), + ), + RaisedButton( + onPressed: () => _pinPadClear(), + child: Text("CLEAR"), + ) + ], + ) + ], + ) + ); + } else { + pinPad = Container(); + } + Widget inputWrapper = Container( + width: 150.0, + child: TextField( + decoration: InputDecoration( + labelText: "Alarm Code" + ), + //focusNode: _focusNode, + obscureText: true, + controller: new TextEditingController.fromValue( + new TextEditingValue( + text: code, + selection: + new TextSelection.collapsed(offset: code.length) + ) + ), + onChanged: (value) { + code = value; + } + ) + ); + Widget buttonsWrapper = Padding( + padding: EdgeInsets.symmetric(vertical: Sizes.rowPadding), + child: Wrap( + alignment: WrapAlignment.center, + spacing: 15.0, + runSpacing: Sizes.rowPadding, + children: buttons + ) + ); return Column( crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Container( - width: 150.0, - child: TextField( - //focusNode: _focusNode, - obscureText: true, - controller: new TextEditingController.fromValue( - new TextEditingValue( - text: code, - selection: - new TextSelection.collapsed(offset: code.length) - ) - ), - onChanged: (value) { - code = value; - } - ) - ), - Wrap( - alignment: WrapAlignment.center, - spacing: 10.0, - runSpacing: 1.0, - children: buttons - ) + widget.extended ? buttonsWrapper : inputWrapper, + widget.extended ? inputWrapper : buttonsWrapper, + pinPad ] ); diff --git a/lib/entity_widgets/entity_colors.class.dart b/lib/entity_widgets/entity_colors.class.dart index ce085af..5be413b 100644 --- a/lib/entity_widgets/entity_colors.class.dart +++ b/lib/entity_widgets/entity_colors.class.dart @@ -23,6 +23,15 @@ class EntityColor { "cool": Colors.lightBlue, EntityState.unavailable: Colors.black26, EntityState.unknown: Colors.black26, + EntityState.alarm_disarmed: Colors.green, + EntityState.alarm_armed_away: Colors.redAccent, + EntityState.alarm_armed_custom_bypass: Colors.redAccent, + EntityState.alarm_armed_home: Colors.redAccent, + EntityState.alarm_armed_night: Colors.redAccent, + EntityState.alarm_triggered: Colors.redAccent, + EntityState.alarm_arming: Colors.amber, + EntityState.alarm_disarming: Colors.amber, + EntityState.alarm_pending: Colors.amber, }; static Color stateColor(String state) { diff --git a/lib/home_assistant.class.dart b/lib/home_assistant.class.dart index 540ebca..eaebabe 100644 --- a/lib/home_assistant.class.dart +++ b/lib/home_assistant.class.dart @@ -457,6 +457,7 @@ class HomeAssistant { : rawCard['show_state'] ?? true, showEmpty: rawCard['show_empty'] ?? true, stateFilter: rawCard['state_filter'] ?? [], + states: rawCard['states'], content: rawCard['content'] ); if (rawCard["cards"] != null) { diff --git a/lib/mdi.class.dart b/lib/mdi.class.dart index 27ab61f..0fdaf3e 100644 --- a/lib/mdi.class.dart +++ b/lib/mdi.class.dart @@ -29,7 +29,7 @@ class MaterialDesignIcons { "alarm_control_panel.armed_home" : "mdi:bell-plus", "alarm_control_panel.armed_away" : "mdi:bell", "alarm_control_panel.armed_night" : "mdi:bell-sleep", - "alarm_control_panel.armed_custom_bypass" : "mdi:bell-sleep", + "alarm_control_panel.armed_custom_bypass" : "mdi:bell", "alarm_control_panel.triggered" : "mdi:bell-ring", "alarm_control_panel" : "mdi:bell" }; diff --git a/lib/ui_class/card.class.dart b/lib/ui_class/card.class.dart index c28073a..ea85224 100644 --- a/lib/ui_class/card.class.dart +++ b/lib/ui_class/card.class.dart @@ -12,6 +12,7 @@ class HACard { bool showEmpty; int columnsCount; List stateFilter; + List states; String content; HACard({ @@ -24,6 +25,7 @@ class HACard { this.stateFilter: const [], this.showEmpty: true, this.content, + this.states, @required this.type }); diff --git a/lib/ui_widgets/card_header_widget.dart b/lib/ui_widgets/card_header_widget.dart index 3f51f23..96f6aec 100644 --- a/lib/ui_widgets/card_header_widget.dart +++ b/lib/ui_widgets/card_header_widget.dart @@ -3,14 +3,18 @@ part of '../main.dart'; class CardHeaderWidget extends StatelessWidget { final String name; + final Widget trailing; + final Widget subtitle; - const CardHeaderWidget({Key key, this.name}) : super(key: key); + const CardHeaderWidget({Key key, this.name, this.trailing, this.subtitle}) : super(key: key); @override Widget build(BuildContext context) { var result; if ((name != null) && (name.trim().length > 0)) { result = new ListTile( + trailing: trailing, + subtitle: subtitle, title: Text("$name", textAlign: TextAlign.left, overflow: TextOverflow.ellipsis, diff --git a/lib/ui_widgets/card_widget.dart b/lib/ui_widgets/card_widget.dart index d79094a..a46dfd8 100644 --- a/lib/ui_widgets/card_widget.dart +++ b/lib/ui_widgets/card_widget.dart @@ -37,6 +37,10 @@ class CardWidget extends StatelessWidget { return _buildMarkdownCard(context); } + case CardType.alarmPanel: { + return _buildAlarmPanelCard(context); + } + case CardType.horizontalStack: { if (card.childCards.isNotEmpty) { List children = []; @@ -128,6 +132,42 @@ class CardWidget extends StatelessWidget { ); } + Widget _buildAlarmPanelCard(BuildContext context) { + if (card.linkedEntityWrapper == null || card.linkedEntityWrapper.entity == null) { + return Container(width: 0, height: 0,); + } else { + List body = []; + body.add(CardHeaderWidget( + name: card.name ?? "", + subtitle: Text("${card.linkedEntityWrapper.entity.displayState}", + style: TextStyle( + color: Colors.grey + ), + ), + trailing: EntityIcon( + iconSize: 50.0, + ), + )); + body.add( + AlarmControlPanelControlsWidget( + extended: true, + states: card.states, + ) + ); + return Card( + child: EntityModel( + entityWrapper: card.linkedEntityWrapper, + handleTap: null, + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: body + ) + ) + ); + } + } + Widget _buildGlanceCard(BuildContext context) { List entitiesToShow = card.getEntitiesToShow(); if (entitiesToShow.isEmpty && !card.showEmpty) {