Resolves #204 Alarm panel card support
This commit is contained in:
parent
24c7675fa4
commit
5e814e8109
@ -5,6 +5,8 @@ class AlarmControlPanelEntity extends Entity {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget _buildAdditionalControlsForPage(BuildContext context) {
|
Widget _buildAdditionalControlsForPage(BuildContext context) {
|
||||||
return AlarmControlPanelControlsWidget();
|
return AlarmControlPanelControlsWidget(
|
||||||
|
extended: false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,11 @@ part of '../../main.dart';
|
|||||||
|
|
||||||
class AlarmControlPanelControlsWidget extends StatefulWidget {
|
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
|
@override
|
||||||
_AlarmControlPanelControlsWidgetWidgetState createState() => _AlarmControlPanelControlsWidgetWidgetState();
|
_AlarmControlPanelControlsWidgetWidgetState createState() => _AlarmControlPanelControlsWidgetWidgetState();
|
||||||
|
|
||||||
@ -20,23 +25,59 @@ class _AlarmControlPanelControlsWidgetWidgetState extends State<AlarmControlPane
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _pinPadHandler(value) {
|
||||||
|
setState(() {
|
||||||
|
code += "$value";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _pinPadClear() {
|
||||||
|
setState(() {
|
||||||
|
code = "";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final entityModel = EntityModel.of(context);
|
final entityModel = EntityModel.of(context);
|
||||||
final AlarmControlPanelEntity entity = entityModel.entityWrapper.entity;
|
final AlarmControlPanelEntity entity = entityModel.entityWrapper.entity;
|
||||||
List<Widget> buttons = [];
|
List<Widget> buttons = [];
|
||||||
if (entity.state == EntityState.alarm_disarmed) {
|
if (entity.state == EntityState.alarm_disarmed) {
|
||||||
buttons.addAll(<Widget>[
|
if (widget.states.contains("arm_home")) {
|
||||||
|
buttons.add(
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
onPressed: () => _callService(entity, "alarm_arm_home"),
|
onPressed: () => _callService(entity, "alarm_arm_home"),
|
||||||
child: Text("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 {
|
} else {
|
||||||
buttons.add(
|
buttons.add(
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
@ -45,33 +86,119 @@ class _AlarmControlPanelControlsWidgetWidgetState extends State<AlarmControlPane
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Widget pinPad;
|
||||||
|
if (widget.extended) {
|
||||||
|
pinPad = Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: Sizes.rowPadding),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
Wrap(
|
||||||
|
spacing: 5.0,
|
||||||
|
children: <Widget>[
|
||||||
|
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: <Widget>[
|
||||||
|
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: <Widget>[
|
||||||
|
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: <Widget>[
|
||||||
|
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(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
widget.extended ? buttonsWrapper : inputWrapper,
|
||||||
width: 150.0,
|
widget.extended ? inputWrapper : buttonsWrapper,
|
||||||
child: TextField(
|
pinPad
|
||||||
//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
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
);
|
);
|
||||||
|
@ -23,6 +23,15 @@ class EntityColor {
|
|||||||
"cool": Colors.lightBlue,
|
"cool": Colors.lightBlue,
|
||||||
EntityState.unavailable: Colors.black26,
|
EntityState.unavailable: Colors.black26,
|
||||||
EntityState.unknown: 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) {
|
static Color stateColor(String state) {
|
||||||
|
@ -457,6 +457,7 @@ class HomeAssistant {
|
|||||||
: rawCard['show_state'] ?? true,
|
: rawCard['show_state'] ?? true,
|
||||||
showEmpty: rawCard['show_empty'] ?? true,
|
showEmpty: rawCard['show_empty'] ?? true,
|
||||||
stateFilter: rawCard['state_filter'] ?? [],
|
stateFilter: rawCard['state_filter'] ?? [],
|
||||||
|
states: rawCard['states'],
|
||||||
content: rawCard['content']
|
content: rawCard['content']
|
||||||
);
|
);
|
||||||
if (rawCard["cards"] != null) {
|
if (rawCard["cards"] != null) {
|
||||||
|
@ -29,7 +29,7 @@ class MaterialDesignIcons {
|
|||||||
"alarm_control_panel.armed_home" : "mdi:bell-plus",
|
"alarm_control_panel.armed_home" : "mdi:bell-plus",
|
||||||
"alarm_control_panel.armed_away" : "mdi:bell",
|
"alarm_control_panel.armed_away" : "mdi:bell",
|
||||||
"alarm_control_panel.armed_night" : "mdi:bell-sleep",
|
"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.triggered" : "mdi:bell-ring",
|
||||||
"alarm_control_panel" : "mdi:bell"
|
"alarm_control_panel" : "mdi:bell"
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,7 @@ class HACard {
|
|||||||
bool showEmpty;
|
bool showEmpty;
|
||||||
int columnsCount;
|
int columnsCount;
|
||||||
List stateFilter;
|
List stateFilter;
|
||||||
|
List states;
|
||||||
String content;
|
String content;
|
||||||
|
|
||||||
HACard({
|
HACard({
|
||||||
@ -24,6 +25,7 @@ class HACard {
|
|||||||
this.stateFilter: const [],
|
this.stateFilter: const [],
|
||||||
this.showEmpty: true,
|
this.showEmpty: true,
|
||||||
this.content,
|
this.content,
|
||||||
|
this.states,
|
||||||
@required this.type
|
@required this.type
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -3,14 +3,18 @@ part of '../main.dart';
|
|||||||
class CardHeaderWidget extends StatelessWidget {
|
class CardHeaderWidget extends StatelessWidget {
|
||||||
|
|
||||||
final String name;
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var result;
|
var result;
|
||||||
if ((name != null) && (name.trim().length > 0)) {
|
if ((name != null) && (name.trim().length > 0)) {
|
||||||
result = new ListTile(
|
result = new ListTile(
|
||||||
|
trailing: trailing,
|
||||||
|
subtitle: subtitle,
|
||||||
title: Text("$name",
|
title: Text("$name",
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
@ -37,6 +37,10 @@ class CardWidget extends StatelessWidget {
|
|||||||
return _buildMarkdownCard(context);
|
return _buildMarkdownCard(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case CardType.alarmPanel: {
|
||||||
|
return _buildAlarmPanelCard(context);
|
||||||
|
}
|
||||||
|
|
||||||
case CardType.horizontalStack: {
|
case CardType.horizontalStack: {
|
||||||
if (card.childCards.isNotEmpty) {
|
if (card.childCards.isNotEmpty) {
|
||||||
List<Widget> children = [];
|
List<Widget> 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<Widget> 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) {
|
Widget _buildGlanceCard(BuildContext context) {
|
||||||
List<EntityWrapper> entitiesToShow = card.getEntitiesToShow();
|
List<EntityWrapper> entitiesToShow = card.getEntitiesToShow();
|
||||||
if (entitiesToShow.isEmpty && !card.showEmpty) {
|
if (entitiesToShow.isEmpty && !card.showEmpty) {
|
||||||
|
Reference in New Issue
Block a user