2018-10-01 21:57:54 +03:00
|
|
|
part of '../main.dart';
|
|
|
|
|
|
|
|
class Entity {
|
|
|
|
static const STATE_ICONS_COLORS = {
|
|
|
|
"on": Colors.amber,
|
|
|
|
"off": Color.fromRGBO(68, 115, 158, 1.0),
|
2018-10-08 23:30:09 +03:00
|
|
|
"default": Color.fromRGBO(68, 115, 158, 1.0),
|
2018-10-01 21:57:54 +03:00
|
|
|
"unavailable": Colors.black12,
|
|
|
|
"unknown": Colors.black12,
|
|
|
|
"playing": Colors.amber
|
|
|
|
};
|
2018-10-07 02:17:14 +03:00
|
|
|
static const badgeColors = {
|
|
|
|
"default": Color.fromRGBO(223, 76, 30, 1.0),
|
|
|
|
"binary_sensor": Color.fromRGBO(3, 155, 229, 1.0)
|
|
|
|
};
|
|
|
|
static List badgeDomains = ["alarm_control_panel", "binary_sensor", "device_tracker", "updater", "sun", "timer", "sensor"];
|
2018-10-01 21:57:54 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
double rightWidgetPadding = 14.0;
|
|
|
|
double leftWidgetPadding = 8.0;
|
|
|
|
double extendedWidgetHeight = 50.0;
|
|
|
|
double widgetHeight = 34.0;
|
|
|
|
double iconSize = 28.0;
|
|
|
|
double stateFontSize = 16.0;
|
|
|
|
double nameFontSize = 16.0;
|
|
|
|
double smallFontSize = 14.0;
|
|
|
|
double largeFontSize = 24.0;
|
|
|
|
double inputWidth = 160.0;
|
|
|
|
double rowPadding = 10.0;
|
|
|
|
|
2018-10-07 15:03:51 +03:00
|
|
|
Map attributes;
|
2018-10-11 23:02:05 +03:00
|
|
|
String domain;
|
|
|
|
String entityId;
|
|
|
|
String state;
|
2018-10-02 23:10:40 +03:00
|
|
|
String assumedState;
|
2018-10-01 21:57:54 +03:00
|
|
|
DateTime _lastUpdated;
|
|
|
|
|
2018-10-07 02:17:14 +03:00
|
|
|
List<Entity> childEntities = [];
|
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
List<String> attributesToShow = ["all"];
|
|
|
|
|
2018-10-01 21:57:54 +03:00
|
|
|
String get displayName =>
|
2018-10-07 15:03:51 +03:00
|
|
|
attributes["friendly_name"] ?? (attributes["name"] ?? "_");
|
2018-10-11 23:02:05 +03:00
|
|
|
|
2018-10-07 15:03:51 +03:00
|
|
|
String get deviceClass => attributes["device_class"] ?? null;
|
2018-10-01 21:57:54 +03:00
|
|
|
bool get isView =>
|
2018-10-11 23:02:05 +03:00
|
|
|
(domain == "group") &&
|
2018-10-07 15:03:51 +03:00
|
|
|
(attributes != null ? attributes["view"] ?? false : false);
|
2018-10-11 23:02:05 +03:00
|
|
|
bool get isGroup => domain == "group";
|
|
|
|
bool get isBadge => Entity.badgeDomains.contains(domain);
|
2018-10-07 15:03:51 +03:00
|
|
|
String get icon => attributes["icon"] ?? "";
|
2018-10-01 21:57:54 +03:00
|
|
|
bool get isOn => state == "on";
|
2018-10-07 15:03:51 +03:00
|
|
|
String get entityPicture => attributes["entity_picture"];
|
|
|
|
String get unitOfMeasurement => attributes["unit_of_measurement"] ?? "";
|
|
|
|
List get childEntityIds => attributes["entity_id"] ?? [];
|
2018-10-01 21:57:54 +03:00
|
|
|
String get lastUpdated => _getLastUpdatedFormatted();
|
|
|
|
|
|
|
|
Entity(Map rawData) {
|
|
|
|
update(rawData);
|
|
|
|
}
|
|
|
|
|
|
|
|
void update(Map rawData) {
|
2018-10-07 15:03:51 +03:00
|
|
|
attributes = rawData["attributes"] ?? {};
|
2018-10-11 23:02:05 +03:00
|
|
|
domain = rawData["entity_id"].split(".")[0];
|
|
|
|
entityId = rawData["entity_id"];
|
|
|
|
state = rawData["state"];
|
|
|
|
assumedState = state;
|
2018-10-01 21:57:54 +03:00
|
|
|
_lastUpdated = DateTime.tryParse(rawData["last_updated"]);
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
Widget buildDefaultWidget(BuildContext context) {
|
|
|
|
return EntityModel(
|
|
|
|
entity: this,
|
|
|
|
child: DefaultEntityContainer(
|
|
|
|
state: _buildStatePart(context)
|
|
|
|
),
|
|
|
|
handleTap: true,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildStatePart(BuildContext context) {
|
|
|
|
return SimpleEntityState();
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildStatePartForPage(BuildContext context) {
|
|
|
|
return _buildStatePart(context);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget _buildAdditionalControlsForPage(BuildContext context) {
|
|
|
|
return Container(width: 0.0, height: 0.0,);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget buildEntityPageWidget(BuildContext context) {
|
|
|
|
return EntityModel(
|
|
|
|
entity: this,
|
|
|
|
child: EntityPageContainer(
|
|
|
|
children: <Widget> [
|
|
|
|
DefaultEntityContainer(
|
|
|
|
state: _buildStatePartForPage(context)
|
|
|
|
),
|
|
|
|
LastUpdatedWidget(),
|
|
|
|
Divider(),
|
|
|
|
_buildAdditionalControlsForPage(context),
|
|
|
|
Divider(),
|
|
|
|
EntityAttributesList()
|
|
|
|
]
|
|
|
|
),
|
|
|
|
handleTap: false,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget buildBadgeWidget(BuildContext context) {
|
|
|
|
return EntityModel(
|
2018-10-02 00:41:40 +03:00
|
|
|
entity: this,
|
2018-10-15 00:15:09 +03:00
|
|
|
child: Badge(),
|
|
|
|
handleTap: true,
|
2018-10-02 00:41:40 +03:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-10-07 15:03:51 +03:00
|
|
|
String getAttribute(String attributeName) {
|
|
|
|
if (attributes != null) {
|
|
|
|
return attributes["$attributeName"];
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2018-10-01 21:57:54 +03:00
|
|
|
String _getLastUpdatedFormatted() {
|
|
|
|
if (_lastUpdated == null) {
|
|
|
|
return "-";
|
|
|
|
} else {
|
|
|
|
DateTime now = DateTime.now();
|
|
|
|
Duration d = now.difference(_lastUpdated);
|
|
|
|
String text;
|
|
|
|
int v;
|
|
|
|
if (d.inDays == 0) {
|
|
|
|
if (d.inHours == 0) {
|
|
|
|
if (d.inMinutes == 0) {
|
|
|
|
text = "seconds ago";
|
|
|
|
v = d.inSeconds;
|
|
|
|
} else {
|
|
|
|
text = "minutes ago";
|
|
|
|
v = d.inMinutes;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
text = "hours ago";
|
|
|
|
v = d.inHours;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
text = "days ago";
|
|
|
|
v = d.inDays;
|
|
|
|
}
|
|
|
|
return "$v $text";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 16:44:11 +03:00
|
|
|
}
|
2018-10-02 00:41:40 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
class SwitchEntity extends Entity {
|
|
|
|
SwitchEntity(Map rawData) : super(rawData);
|
2018-10-02 00:41:40 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
@override
|
|
|
|
Widget _buildStatePart(BuildContext context) {
|
|
|
|
return SwitchControlWidget();
|
|
|
|
}
|
2018-10-03 16:44:11 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
}
|
2018-10-02 00:41:40 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
class ButtonEntity extends Entity {
|
|
|
|
ButtonEntity(Map rawData) : super(rawData);
|
2018-10-02 00:41:40 +03:00
|
|
|
|
|
|
|
@override
|
2018-10-15 00:15:09 +03:00
|
|
|
Widget _buildStatePart(BuildContext context) {
|
|
|
|
return ButtonControlWidget();
|
2018-10-01 21:57:54 +03:00
|
|
|
}
|
2018-10-15 00:15:09 +03:00
|
|
|
|
2018-10-02 00:41:40 +03:00
|
|
|
}
|
2018-10-01 21:57:54 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
class TextEntity extends Entity {
|
|
|
|
TextEntity(Map rawData) : super(rawData);
|
2018-10-02 00:41:40 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
int get valueMinLength => attributes["min"] ?? -1;
|
|
|
|
int get valueMaxLength => attributes["max"] ?? -1;
|
|
|
|
String get valuePattern => attributes["pattern"] ?? null;
|
|
|
|
bool get isTextField => attributes["mode"] == "text";
|
|
|
|
bool get isPasswordField => attributes["mode"] == "password";
|
2018-10-07 15:03:51 +03:00
|
|
|
|
2018-10-02 00:41:40 +03:00
|
|
|
@override
|
2018-10-15 00:15:09 +03:00
|
|
|
Widget _buildStatePart(BuildContext context) {
|
|
|
|
return TextControlWidget();
|
2018-10-01 21:57:54 +03:00
|
|
|
}
|
2018-10-15 00:15:09 +03:00
|
|
|
}
|
2018-10-01 21:57:54 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
class SunEntity extends Entity {
|
|
|
|
SunEntity(Map rawData) : super(rawData);
|
|
|
|
}
|
2018-10-07 12:40:45 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
class SliderEntity extends Entity {
|
|
|
|
SliderEntity(Map rawData) : super(rawData);
|
|
|
|
|
|
|
|
double get minValue => attributes["min"] ?? 0.0;
|
|
|
|
double get maxValue => attributes["max"] ?? 100.0;
|
|
|
|
double get valueStep => attributes["step"] ?? 1.0;
|
|
|
|
double get doubleState => double.tryParse(state) ?? 0.0;
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget _buildStatePart(BuildContext context) {
|
|
|
|
return Expanded(
|
|
|
|
//width: 200.0,
|
2018-10-01 21:57:54 +03:00
|
|
|
child: Row(
|
|
|
|
children: <Widget>[
|
2018-10-15 00:15:09 +03:00
|
|
|
SliderControlWidget(expanded: true,),
|
|
|
|
SimpleEntityState(),
|
2018-10-01 21:57:54 +03:00
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
@override
|
|
|
|
Widget _buildStatePartForPage(BuildContext context) {
|
|
|
|
return SimpleEntityState();
|
2018-10-07 15:03:51 +03:00
|
|
|
}
|
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
@override
|
|
|
|
Widget _buildAdditionalControlsForPage(BuildContext context) {
|
|
|
|
return SliderControlWidget(expanded: false,);
|
2018-10-07 15:03:51 +03:00
|
|
|
}
|
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
class ClimateEntity extends Entity {
|
|
|
|
|
|
|
|
@override
|
|
|
|
double widgetHeight = 38.0;
|
|
|
|
|
|
|
|
List<String> get operationList => (attributes["operation_list"] as List).cast<String>();
|
|
|
|
double get temperature => _getTemperature();
|
|
|
|
String get operationMode => attributes['operation_mode'] ?? "";
|
|
|
|
bool get awayMode => attributes['away_mode'] == "on";
|
|
|
|
|
|
|
|
ClimateEntity(Map rawData) : super(rawData);
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget _buildStatePart(BuildContext context) {
|
|
|
|
return ClimateStateWidget();
|
2018-10-02 00:41:40 +03:00
|
|
|
}
|
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
@override
|
|
|
|
Widget _buildAdditionalControlsForPage(BuildContext context) {
|
|
|
|
return ClimateControlWidget();
|
2018-10-02 00:41:40 +03:00
|
|
|
}
|
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
double _getTemperature() {
|
|
|
|
var temp1 = attributes['temperature'] ?? attributes['target_temp_low'];
|
|
|
|
if (temp1 is int) {
|
|
|
|
return temp1.toDouble();
|
|
|
|
} else if (temp1 is double) {
|
|
|
|
return temp1;
|
|
|
|
} else {
|
|
|
|
return 0.0;
|
|
|
|
}
|
2018-10-01 21:57:54 +03:00
|
|
|
}
|
2018-10-15 00:15:09 +03:00
|
|
|
}
|
2018-10-01 21:57:54 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
class SelectEntity extends Entity {
|
|
|
|
|
|
|
|
List<String> get listOptions => attributes["options"]!= null ? (attributes["options"] as List).cast<String>() : [];
|
|
|
|
|
|
|
|
SelectEntity(Map rawData) : super(rawData);
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget _buildStatePart(BuildContext context) {
|
|
|
|
return SelectControlWidget();
|
2018-10-01 21:57:54 +03:00
|
|
|
}
|
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
class DateTimeEntity extends Entity {
|
|
|
|
|
|
|
|
bool get hasDate => attributes["has_date"] ?? false;
|
|
|
|
bool get hasTime => attributes["has_time"] ?? false;
|
|
|
|
int get year => attributes["year"] ?? 1970;
|
|
|
|
int get month => attributes["month"] ?? 1;
|
|
|
|
int get day => attributes["day"] ?? 1;
|
|
|
|
int get hour => attributes["hour"] ?? 0;
|
|
|
|
int get minute => attributes["minute"] ?? 0;
|
|
|
|
int get second => attributes["second"] ?? 0;
|
|
|
|
String get formattedState => _getFormattedState();
|
|
|
|
DateTime get dateTimeState => _getDateTimeState();
|
|
|
|
|
|
|
|
DateTimeEntity(Map rawData) : super(rawData);
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget _buildStatePart(BuildContext context) {
|
|
|
|
return DateTimeStateWidget();
|
2018-10-01 21:57:54 +03:00
|
|
|
}
|
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
DateTime _getDateTimeState() {
|
|
|
|
return DateTime(this.year, this.month, this.day, this.hour, this.minute, this.second);
|
2018-10-01 21:57:54 +03:00
|
|
|
}
|
2018-10-07 02:17:14 +03:00
|
|
|
|
2018-10-15 00:15:09 +03:00
|
|
|
String _getFormattedState() {
|
|
|
|
String formattedState = "";
|
|
|
|
if (this.hasDate) {
|
|
|
|
formattedState += formatDate(dateTimeState, [M, ' ', d, ', ', yyyy]);
|
2018-10-07 02:17:14 +03:00
|
|
|
}
|
2018-10-15 00:15:09 +03:00
|
|
|
if (this.hasTime) {
|
|
|
|
formattedState += " "+formatDate(dateTimeState, [HH, ':', nn]);
|
2018-10-07 02:17:14 +03:00
|
|
|
}
|
2018-10-15 00:15:09 +03:00
|
|
|
return formattedState;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setNewState(newValue) {
|
|
|
|
eventBus.fire(new ServiceCallEvent(domain, "set_datetime",entityId,
|
|
|
|
newValue));
|
2018-10-07 02:17:14 +03:00
|
|
|
}
|
2018-10-15 00:15:09 +03:00
|
|
|
|
2018-10-01 21:57:54 +03:00
|
|
|
}
|
2018-10-15 00:15:09 +03:00
|
|
|
|
|
|
|
|