Resolves #145 Fan support
This commit is contained in:
parent
a36c7a9ca3
commit
5f3c77f4b9
32
lib/entity_class/fan_entity.class.dart
Normal file
32
lib/entity_class/fan_entity.class.dart
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
part of '../main.dart';
|
||||||
|
|
||||||
|
class FanEntity extends Entity {
|
||||||
|
|
||||||
|
static const SUPPORT_SET_SPEED = 1;
|
||||||
|
static const SUPPORT_OSCILLATE = 2;
|
||||||
|
static const SUPPORT_DIRECTION = 4;
|
||||||
|
|
||||||
|
FanEntity(Map rawData) : super(rawData);
|
||||||
|
|
||||||
|
bool get supportSetSpeed => ((attributes["supported_features"] &
|
||||||
|
FanEntity.SUPPORT_SET_SPEED) ==
|
||||||
|
FanEntity.SUPPORT_SET_SPEED);
|
||||||
|
bool get supportOscillate => ((attributes["supported_features"] &
|
||||||
|
FanEntity.SUPPORT_OSCILLATE) ==
|
||||||
|
FanEntity.SUPPORT_OSCILLATE);
|
||||||
|
bool get supportDirection => ((attributes["supported_features"] &
|
||||||
|
FanEntity.SUPPORT_DIRECTION) ==
|
||||||
|
FanEntity.SUPPORT_DIRECTION);
|
||||||
|
|
||||||
|
List<String> get speedList => getStringListAttributeValue("speed_list");
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget _buildStatePart(BuildContext context) {
|
||||||
|
return SwitchStateWidget();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget _buildAdditionalControlsForPage(BuildContext context) {
|
||||||
|
return FanControlsWidget();
|
||||||
|
}
|
||||||
|
}
|
@ -80,6 +80,9 @@ class EntityCollection {
|
|||||||
case "cover": {
|
case "cover": {
|
||||||
return CoverEntity(rawEntityData);
|
return CoverEntity(rawEntityData);
|
||||||
}
|
}
|
||||||
|
case "fan": {
|
||||||
|
return FanEntity(rawEntityData);
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return Entity(rawEntityData);
|
return Entity(rawEntityData);
|
||||||
}
|
}
|
||||||
|
@ -6,27 +6,22 @@ class ModeSwitchWidget extends StatelessWidget {
|
|||||||
final onChange;
|
final onChange;
|
||||||
final double captionFontSize;
|
final double captionFontSize;
|
||||||
final bool value;
|
final bool value;
|
||||||
|
final bool expanded;
|
||||||
|
|
||||||
ModeSwitchWidget({
|
ModeSwitchWidget({
|
||||||
Key key,
|
Key key,
|
||||||
@required this.caption,
|
@required this.caption,
|
||||||
@required this.onChange,
|
@required this.onChange,
|
||||||
this.captionFontSize,
|
this.captionFontSize,
|
||||||
this.value
|
this.value,
|
||||||
|
this.expanded: true
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
return Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
_buildCaption(),
|
||||||
child: Text(
|
|
||||||
"$caption",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: captionFontSize ?? Sizes.stateFontSize
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Switch(
|
Switch(
|
||||||
onChanged: (value) => onChange(value),
|
onChanged: (value) => onChange(value),
|
||||||
value: value ?? false,
|
value: value ?? false,
|
||||||
@ -35,4 +30,19 @@ class ModeSwitchWidget extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildCaption() {
|
||||||
|
Widget captionWidget = Text(
|
||||||
|
"$caption",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: captionFontSize ?? Sizes.stateFontSize
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (expanded) {
|
||||||
|
return Expanded(
|
||||||
|
child: captionWidget,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return captionWidget;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
123
lib/entity_widgets/controls/fan_controls.dart
Normal file
123
lib/entity_widgets/controls/fan_controls.dart
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
part of '../../main.dart';
|
||||||
|
|
||||||
|
class FanControlsWidget extends StatefulWidget {
|
||||||
|
|
||||||
|
@override
|
||||||
|
_FanControlsWidgetState createState() => _FanControlsWidgetState();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FanControlsWidgetState extends State<FanControlsWidget> {
|
||||||
|
|
||||||
|
bool _tmpOscillate;
|
||||||
|
bool _tmpDirectionForward;
|
||||||
|
bool _changedHere = false;
|
||||||
|
String _tmpSpeed;
|
||||||
|
|
||||||
|
void _resetState(FanEntity entity) {
|
||||||
|
_tmpOscillate = entity.attributes["oscillating"] ?? false;
|
||||||
|
_tmpDirectionForward = entity.attributes["direction"] == "forward";
|
||||||
|
_tmpSpeed = entity.attributes["speed"];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setOscillate(FanEntity entity, bool oscillate) {
|
||||||
|
setState(() {
|
||||||
|
_tmpOscillate = oscillate;
|
||||||
|
_changedHere = true;
|
||||||
|
eventBus.fire(new ServiceCallEvent(
|
||||||
|
"fan", "oscillate", entity.entityId,
|
||||||
|
{"oscillating": oscillate}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setDirection(FanEntity entity, bool forward) {
|
||||||
|
setState(() {
|
||||||
|
_tmpDirectionForward = forward;
|
||||||
|
_changedHere = true;
|
||||||
|
eventBus.fire(new ServiceCallEvent(
|
||||||
|
"fan", "set_direction", entity.entityId,
|
||||||
|
{"direction": forward ? "forward" : "reverse"}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setSpeed(FanEntity entity, String value) {
|
||||||
|
setState(() {
|
||||||
|
_tmpSpeed = value;
|
||||||
|
_changedHere = true;
|
||||||
|
eventBus.fire(new ServiceCallEvent(
|
||||||
|
"fan", "set_speed", entity.entityId,
|
||||||
|
{"speed": value}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final entityModel = EntityModel.of(context);
|
||||||
|
final FanEntity entity = entityModel.entityWrapper.entity;
|
||||||
|
if (!_changedHere) {
|
||||||
|
_resetState(entity);
|
||||||
|
} else {
|
||||||
|
_changedHere = false;
|
||||||
|
}
|
||||||
|
return Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
_buildSpeedControl(entity),
|
||||||
|
_buildOscillateControl(entity),
|
||||||
|
_buildDirectionControl(entity)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSpeedControl(FanEntity entity) {
|
||||||
|
if (entity.supportSetSpeed && entity.speedList != null && entity.speedList.isNotEmpty) {
|
||||||
|
return ModeSelectorWidget(
|
||||||
|
onChange: (effect) => _setSpeed(entity, effect),
|
||||||
|
caption: "Speed",
|
||||||
|
options: entity.speedList,
|
||||||
|
value: _tmpSpeed
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Container(width: 0.0, height: 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildOscillateControl(FanEntity entity) {
|
||||||
|
if (entity.supportOscillate) {
|
||||||
|
return ModeSwitchWidget(
|
||||||
|
onChange: (value) => _setOscillate(entity, value),
|
||||||
|
caption: "Oscillate",
|
||||||
|
value: _tmpOscillate,
|
||||||
|
expanded: false,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Container(width: 0.0, height: 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildDirectionControl(FanEntity entity) {
|
||||||
|
if (entity.supportDirection) {
|
||||||
|
return Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
IconButton(
|
||||||
|
onPressed: _tmpDirectionForward ?
|
||||||
|
() => _setDirection(entity, false) :
|
||||||
|
null,
|
||||||
|
icon: Icon(Icons.rotate_left),
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: !_tmpDirectionForward ?
|
||||||
|
() => _setDirection(entity, true) :
|
||||||
|
null,
|
||||||
|
icon: Icon(Icons.rotate_right),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Container(width: 0.0, height: 0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -31,6 +31,7 @@ part 'entity_class/slider_entity.dart';
|
|||||||
part 'entity_class/media_player_entity.class.dart';
|
part 'entity_class/media_player_entity.class.dart';
|
||||||
part 'entity_class/lock_entity.class.dart';
|
part 'entity_class/lock_entity.class.dart';
|
||||||
part 'entity_class/group_entity.class.dart';
|
part 'entity_class/group_entity.class.dart';
|
||||||
|
part 'entity_class/fan_entity.class.dart';
|
||||||
part 'entity_widgets/common/badge.dart';
|
part 'entity_widgets/common/badge.dart';
|
||||||
part 'entity_widgets/model_widgets.dart';
|
part 'entity_widgets/model_widgets.dart';
|
||||||
part 'entity_widgets/default_entity_container.dart';
|
part 'entity_widgets/default_entity_container.dart';
|
||||||
@ -64,6 +65,7 @@ part 'entity_widgets/controls/climate_controls.dart';
|
|||||||
part 'entity_widgets/controls/cover_controls.dart';
|
part 'entity_widgets/controls/cover_controls.dart';
|
||||||
part 'entity_widgets/controls/light_controls.dart';
|
part 'entity_widgets/controls/light_controls.dart';
|
||||||
part 'entity_widgets/controls/media_player_widgets.dart';
|
part 'entity_widgets/controls/media_player_widgets.dart';
|
||||||
|
part 'entity_widgets/controls/fan_controls.dart';
|
||||||
part 'settings.page.dart';
|
part 'settings.page.dart';
|
||||||
part 'home_assistant.class.dart';
|
part 'home_assistant.class.dart';
|
||||||
part 'log.page.dart';
|
part 'log.page.dart';
|
||||||
|
@ -24,6 +24,7 @@ class MaterialDesignIcons {
|
|||||||
"cover.opening": "mdi:window-open",
|
"cover.opening": "mdi:window-open",
|
||||||
"lock.locked": "mdi:lock",
|
"lock.locked": "mdi:lock",
|
||||||
"lock.unlocked": "mdi:lock-open",
|
"lock.unlocked": "mdi:lock-open",
|
||||||
|
"fan": "mdi:fan"
|
||||||
};
|
};
|
||||||
|
|
||||||
static Map _defaultIconsByDeviceClass = {
|
static Map _defaultIconsByDeviceClass = {
|
||||||
|
Reference in New Issue
Block a user