From 0b7bba8491c3c15d6a8da5cc009c65ccd3656dce Mon Sep 17 00:00:00 2001 From: Kenny Mochizuki Escalona Date: Mon, 11 May 2026 05:40:50 -0600 Subject: [PATCH 1/2] feat: Add support for Zigbee and new render widgets - Added `ZIGBEE` to `OperationMode` - Created `RenderWidget` enum with various UI components - Updated model structure to include icon and widget properties --- lib/src/inbound/inbound.g.dart | 1 + lib/src/inbound/src/enums.dart | 7 +- lib/src/models/models.dart | 2 + lib/src/models/models.freezed.dart | 50 ++++++++------ lib/src/models/models.g.dart | 36 ++++++++++ lib/src/models/src/model.dart | 6 ++ lib/src/models/src/widget.dart | 106 +++++++++++++++++++++++++++++ 7 files changed, 187 insertions(+), 21 deletions(-) create mode 100644 lib/src/models/src/widget.dart diff --git a/lib/src/inbound/inbound.g.dart b/lib/src/inbound/inbound.g.dart index 73d6b270..42b35cef 100644 --- a/lib/src/inbound/inbound.g.dart +++ b/lib/src/inbound/inbound.g.dart @@ -132,6 +132,7 @@ const _$OperationModeEnumMap = { OperationMode.simulation: 'SIMULATION', OperationMode.mqtt: 'MQTT', OperationMode.peripheral: 'PERIPHERAL', + OperationMode.zigbee: 'ZIGBEE', OperationMode.unknown: 'UNKNOWN', }; diff --git a/lib/src/inbound/src/enums.dart b/lib/src/inbound/src/enums.dart index b59e3bc1..3a8adaef 100644 --- a/lib/src/inbound/src/enums.dart +++ b/lib/src/inbound/src/enums.dart @@ -81,7 +81,8 @@ enum ConfigSource { /// [unknown] refers that the command definition is unknown. /// Layrz API Definition: `UNKNOWN` @JsonValue('UNKNOWN') - unknown; + unknown + ; @override String toString() => toJson(); @@ -181,6 +182,10 @@ enum OperationMode { @JsonValue('PERIPHERAL') peripheral, + /// Zigbee operation mode + @JsonValue('ZIGBEE') + zigbee, + /// [unknown] is the default value for the operation mode. @JsonValue('UNKNOWN') unknown, diff --git a/lib/src/models/models.dart b/lib/src/models/models.dart index b3caddf6..f9935b33 100644 --- a/lib/src/models/models.dart +++ b/lib/src/models/models.dart @@ -2,6 +2,7 @@ library; import 'package:collection/collection.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:layrz_icons/layrz_icons.dart'; import 'package:layrz_models/layrz_models.dart'; part 'models.freezed.dart'; @@ -11,3 +12,4 @@ part 'src/model.dart'; part 'src/hw_model.dart'; part 'src/firmware_build.dart'; part 'src/firmware_branch.dart'; +part 'src/widget.dart'; diff --git a/lib/src/models/models.freezed.dart b/lib/src/models/models.freezed.dart index a15d41c5..61b56a95 100644 --- a/lib/src/models/models.freezed.dart +++ b/lib/src/models/models.freezed.dart @@ -30,7 +30,9 @@ mixin _$Model { String? get confiotName;/// [peripheralIdentifier] is the identifier of the peripheral device. String? get peripheralIdentifier;/// [peripheralParserSpec] is the parser specification for the peripheral device. Map? get peripheralParserSpec;/// [firmwares] is the list of firmwares for the model. - List get firmwares; + List get firmwares;/// The icon of the model, if not exists, you must render the protocol icon +@IconOrNullConverter() LayrzIcon? get icon;/// Indicates the rendering widget, useful to render visually the kind of device +@JsonKey(unknownEnumValue: RenderWidget.unknown) RenderWidget get widget; /// Create a copy of Model /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @@ -43,16 +45,16 @@ $ModelCopyWith get copyWith => _$ModelCopyWithImpl(this as Model, @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is Model&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.flespiId, flespiId) || other.flespiId == flespiId)&&(identical(other.protocol, protocol) || other.protocol == protocol)&&(identical(other.protocolId, protocolId) || other.protocolId == protocolId)&&(identical(other.isGeneric, isGeneric) || other.isGeneric == isGeneric)&&const DeepCollectionEquality().equals(other.commandsStructure, commandsStructure)&&const DeepCollectionEquality().equals(other.configStructure, configStructure)&&(identical(other.confiotCapable, confiotCapable) || other.confiotCapable == confiotCapable)&&(identical(other.confiotLayout, confiotLayout) || other.confiotLayout == confiotLayout)&&(identical(other.confiotName, confiotName) || other.confiotName == confiotName)&&(identical(other.peripheralIdentifier, peripheralIdentifier) || other.peripheralIdentifier == peripheralIdentifier)&&const DeepCollectionEquality().equals(other.peripheralParserSpec, peripheralParserSpec)&&const DeepCollectionEquality().equals(other.firmwares, firmwares)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is Model&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.flespiId, flespiId) || other.flespiId == flespiId)&&(identical(other.protocol, protocol) || other.protocol == protocol)&&(identical(other.protocolId, protocolId) || other.protocolId == protocolId)&&(identical(other.isGeneric, isGeneric) || other.isGeneric == isGeneric)&&const DeepCollectionEquality().equals(other.commandsStructure, commandsStructure)&&const DeepCollectionEquality().equals(other.configStructure, configStructure)&&(identical(other.confiotCapable, confiotCapable) || other.confiotCapable == confiotCapable)&&(identical(other.confiotLayout, confiotLayout) || other.confiotLayout == confiotLayout)&&(identical(other.confiotName, confiotName) || other.confiotName == confiotName)&&(identical(other.peripheralIdentifier, peripheralIdentifier) || other.peripheralIdentifier == peripheralIdentifier)&&const DeepCollectionEquality().equals(other.peripheralParserSpec, peripheralParserSpec)&&const DeepCollectionEquality().equals(other.firmwares, firmwares)&&(identical(other.icon, icon) || other.icon == icon)&&(identical(other.widget, widget) || other.widget == widget)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,id,name,flespiId,protocol,protocolId,isGeneric,const DeepCollectionEquality().hash(commandsStructure),const DeepCollectionEquality().hash(configStructure),confiotCapable,confiotLayout,confiotName,peripheralIdentifier,const DeepCollectionEquality().hash(peripheralParserSpec),const DeepCollectionEquality().hash(firmwares)); +int get hashCode => Object.hash(runtimeType,id,name,flespiId,protocol,protocolId,isGeneric,const DeepCollectionEquality().hash(commandsStructure),const DeepCollectionEquality().hash(configStructure),confiotCapable,confiotLayout,confiotName,peripheralIdentifier,const DeepCollectionEquality().hash(peripheralParserSpec),const DeepCollectionEquality().hash(firmwares),icon,widget); @override String toString() { - return 'Model(id: $id, name: $name, flespiId: $flespiId, protocol: $protocol, protocolId: $protocolId, isGeneric: $isGeneric, commandsStructure: $commandsStructure, configStructure: $configStructure, confiotCapable: $confiotCapable, confiotLayout: $confiotLayout, confiotName: $confiotName, peripheralIdentifier: $peripheralIdentifier, peripheralParserSpec: $peripheralParserSpec, firmwares: $firmwares)'; + return 'Model(id: $id, name: $name, flespiId: $flespiId, protocol: $protocol, protocolId: $protocolId, isGeneric: $isGeneric, commandsStructure: $commandsStructure, configStructure: $configStructure, confiotCapable: $confiotCapable, confiotLayout: $confiotLayout, confiotName: $confiotName, peripheralIdentifier: $peripheralIdentifier, peripheralParserSpec: $peripheralParserSpec, firmwares: $firmwares, icon: $icon, widget: $widget)'; } @@ -63,7 +65,7 @@ abstract mixin class $ModelCopyWith<$Res> { factory $ModelCopyWith(Model value, $Res Function(Model) _then) = _$ModelCopyWithImpl; @useResult $Res call({ - String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable,@JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares + String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable,@JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares,@IconOrNullConverter() LayrzIcon? icon,@JsonKey(unknownEnumValue: RenderWidget.unknown) RenderWidget widget }); @@ -80,7 +82,7 @@ class _$ModelCopyWithImpl<$Res> /// Create a copy of Model /// with the given fields replaced by the non-null parameter values. -@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? flespiId = freezed,Object? protocol = freezed,Object? protocolId = freezed,Object? isGeneric = freezed,Object? commandsStructure = null,Object? configStructure = null,Object? confiotCapable = null,Object? confiotLayout = null,Object? confiotName = freezed,Object? peripheralIdentifier = freezed,Object? peripheralParserSpec = freezed,Object? firmwares = null,}) { +@pragma('vm:prefer-inline') @override $Res call({Object? id = null,Object? name = null,Object? flespiId = freezed,Object? protocol = freezed,Object? protocolId = freezed,Object? isGeneric = freezed,Object? commandsStructure = null,Object? configStructure = null,Object? confiotCapable = null,Object? confiotLayout = null,Object? confiotName = freezed,Object? peripheralIdentifier = freezed,Object? peripheralParserSpec = freezed,Object? firmwares = null,Object? icon = freezed,Object? widget = null,}) { return _then(_self.copyWith( id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable @@ -96,7 +98,9 @@ as ConfIoTLayout,confiotName: freezed == confiotName ? _self.confiotName : confi as String?,peripheralIdentifier: freezed == peripheralIdentifier ? _self.peripheralIdentifier : peripheralIdentifier // ignore: cast_nullable_to_non_nullable as String?,peripheralParserSpec: freezed == peripheralParserSpec ? _self.peripheralParserSpec : peripheralParserSpec // ignore: cast_nullable_to_non_nullable as Map?,firmwares: null == firmwares ? _self.firmwares : firmwares // ignore: cast_nullable_to_non_nullable -as List, +as List,icon: freezed == icon ? _self.icon : icon // ignore: cast_nullable_to_non_nullable +as LayrzIcon?,widget: null == widget ? _self.widget : widget // ignore: cast_nullable_to_non_nullable +as RenderWidget, )); } /// Create a copy of Model @@ -193,10 +197,10 @@ return $default(_that);case _: /// } /// ``` -@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable, @JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares)? $default,{required TResult orElse(),}) {final _that = this; +@optionalTypeArgs TResult maybeWhen(TResult Function( String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable, @JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares, @IconOrNullConverter() LayrzIcon? icon, @JsonKey(unknownEnumValue: RenderWidget.unknown) RenderWidget widget)? $default,{required TResult orElse(),}) {final _that = this; switch (_that) { case _Model() when $default != null: -return $default(_that.id,_that.name,_that.flespiId,_that.protocol,_that.protocolId,_that.isGeneric,_that.commandsStructure,_that.configStructure,_that.confiotCapable,_that.confiotLayout,_that.confiotName,_that.peripheralIdentifier,_that.peripheralParserSpec,_that.firmwares);case _: +return $default(_that.id,_that.name,_that.flespiId,_that.protocol,_that.protocolId,_that.isGeneric,_that.commandsStructure,_that.configStructure,_that.confiotCapable,_that.confiotLayout,_that.confiotName,_that.peripheralIdentifier,_that.peripheralParserSpec,_that.firmwares,_that.icon,_that.widget);case _: return orElse(); } @@ -214,10 +218,10 @@ return $default(_that.id,_that.name,_that.flespiId,_that.protocol,_that.protocol /// } /// ``` -@optionalTypeArgs TResult when(TResult Function( String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable, @JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares) $default,) {final _that = this; +@optionalTypeArgs TResult when(TResult Function( String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable, @JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares, @IconOrNullConverter() LayrzIcon? icon, @JsonKey(unknownEnumValue: RenderWidget.unknown) RenderWidget widget) $default,) {final _that = this; switch (_that) { case _Model(): -return $default(_that.id,_that.name,_that.flespiId,_that.protocol,_that.protocolId,_that.isGeneric,_that.commandsStructure,_that.configStructure,_that.confiotCapable,_that.confiotLayout,_that.confiotName,_that.peripheralIdentifier,_that.peripheralParserSpec,_that.firmwares);case _: +return $default(_that.id,_that.name,_that.flespiId,_that.protocol,_that.protocolId,_that.isGeneric,_that.commandsStructure,_that.configStructure,_that.confiotCapable,_that.confiotLayout,_that.confiotName,_that.peripheralIdentifier,_that.peripheralParserSpec,_that.firmwares,_that.icon,_that.widget);case _: throw StateError('Unexpected subclass'); } @@ -234,10 +238,10 @@ return $default(_that.id,_that.name,_that.flespiId,_that.protocol,_that.protocol /// } /// ``` -@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable, @JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares)? $default,) {final _that = this; +@optionalTypeArgs TResult? whenOrNull(TResult? Function( String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable, @JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares, @IconOrNullConverter() LayrzIcon? icon, @JsonKey(unknownEnumValue: RenderWidget.unknown) RenderWidget widget)? $default,) {final _that = this; switch (_that) { case _Model() when $default != null: -return $default(_that.id,_that.name,_that.flespiId,_that.protocol,_that.protocolId,_that.isGeneric,_that.commandsStructure,_that.configStructure,_that.confiotCapable,_that.confiotLayout,_that.confiotName,_that.peripheralIdentifier,_that.peripheralParserSpec,_that.firmwares);case _: +return $default(_that.id,_that.name,_that.flespiId,_that.protocol,_that.protocolId,_that.isGeneric,_that.commandsStructure,_that.configStructure,_that.confiotCapable,_that.confiotLayout,_that.confiotName,_that.peripheralIdentifier,_that.peripheralParserSpec,_that.firmwares,_that.icon,_that.widget);case _: return null; } @@ -249,7 +253,7 @@ return $default(_that.id,_that.name,_that.flespiId,_that.protocol,_that.protocol @JsonSerializable() class _Model implements Model { - const _Model({required this.id, required this.name, this.flespiId, this.protocol, this.protocolId, this.isGeneric, final List commandsStructure = const [], final List configStructure = const [], this.confiotCapable = false, @JsonKey(unknownEnumValue: ConfIoTLayout.standard) this.confiotLayout = ConfIoTLayout.standard, this.confiotName, this.peripheralIdentifier, final Map? peripheralParserSpec, final List firmwares = const []}): _commandsStructure = commandsStructure,_configStructure = configStructure,_peripheralParserSpec = peripheralParserSpec,_firmwares = firmwares; + const _Model({required this.id, required this.name, this.flespiId, this.protocol, this.protocolId, this.isGeneric, final List commandsStructure = const [], final List configStructure = const [], this.confiotCapable = false, @JsonKey(unknownEnumValue: ConfIoTLayout.standard) this.confiotLayout = ConfIoTLayout.standard, this.confiotName, this.peripheralIdentifier, final Map? peripheralParserSpec, final List firmwares = const [], @IconOrNullConverter() this.icon, @JsonKey(unknownEnumValue: RenderWidget.unknown) this.widget = RenderWidget.unknown}): _commandsStructure = commandsStructure,_configStructure = configStructure,_peripheralParserSpec = peripheralParserSpec,_firmwares = firmwares; factory _Model.fromJson(Map json) => _$ModelFromJson(json); /// [id] is the unique identifier of the model. @@ -311,6 +315,10 @@ class _Model implements Model { return EqualUnmodifiableListView(_firmwares); } +/// The icon of the model, if not exists, you must render the protocol icon +@override@IconOrNullConverter() final LayrzIcon? icon; +/// Indicates the rendering widget, useful to render visually the kind of device +@override@JsonKey(unknownEnumValue: RenderWidget.unknown) final RenderWidget widget; /// Create a copy of Model /// with the given fields replaced by the non-null parameter values. @@ -325,16 +333,16 @@ Map toJson() { @override bool operator ==(Object other) { - return identical(this, other) || (other.runtimeType == runtimeType&&other is _Model&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.flespiId, flespiId) || other.flespiId == flespiId)&&(identical(other.protocol, protocol) || other.protocol == protocol)&&(identical(other.protocolId, protocolId) || other.protocolId == protocolId)&&(identical(other.isGeneric, isGeneric) || other.isGeneric == isGeneric)&&const DeepCollectionEquality().equals(other._commandsStructure, _commandsStructure)&&const DeepCollectionEquality().equals(other._configStructure, _configStructure)&&(identical(other.confiotCapable, confiotCapable) || other.confiotCapable == confiotCapable)&&(identical(other.confiotLayout, confiotLayout) || other.confiotLayout == confiotLayout)&&(identical(other.confiotName, confiotName) || other.confiotName == confiotName)&&(identical(other.peripheralIdentifier, peripheralIdentifier) || other.peripheralIdentifier == peripheralIdentifier)&&const DeepCollectionEquality().equals(other._peripheralParserSpec, _peripheralParserSpec)&&const DeepCollectionEquality().equals(other._firmwares, _firmwares)); + return identical(this, other) || (other.runtimeType == runtimeType&&other is _Model&&(identical(other.id, id) || other.id == id)&&(identical(other.name, name) || other.name == name)&&(identical(other.flespiId, flespiId) || other.flespiId == flespiId)&&(identical(other.protocol, protocol) || other.protocol == protocol)&&(identical(other.protocolId, protocolId) || other.protocolId == protocolId)&&(identical(other.isGeneric, isGeneric) || other.isGeneric == isGeneric)&&const DeepCollectionEquality().equals(other._commandsStructure, _commandsStructure)&&const DeepCollectionEquality().equals(other._configStructure, _configStructure)&&(identical(other.confiotCapable, confiotCapable) || other.confiotCapable == confiotCapable)&&(identical(other.confiotLayout, confiotLayout) || other.confiotLayout == confiotLayout)&&(identical(other.confiotName, confiotName) || other.confiotName == confiotName)&&(identical(other.peripheralIdentifier, peripheralIdentifier) || other.peripheralIdentifier == peripheralIdentifier)&&const DeepCollectionEquality().equals(other._peripheralParserSpec, _peripheralParserSpec)&&const DeepCollectionEquality().equals(other._firmwares, _firmwares)&&(identical(other.icon, icon) || other.icon == icon)&&(identical(other.widget, widget) || other.widget == widget)); } @JsonKey(includeFromJson: false, includeToJson: false) @override -int get hashCode => Object.hash(runtimeType,id,name,flespiId,protocol,protocolId,isGeneric,const DeepCollectionEquality().hash(_commandsStructure),const DeepCollectionEquality().hash(_configStructure),confiotCapable,confiotLayout,confiotName,peripheralIdentifier,const DeepCollectionEquality().hash(_peripheralParserSpec),const DeepCollectionEquality().hash(_firmwares)); +int get hashCode => Object.hash(runtimeType,id,name,flespiId,protocol,protocolId,isGeneric,const DeepCollectionEquality().hash(_commandsStructure),const DeepCollectionEquality().hash(_configStructure),confiotCapable,confiotLayout,confiotName,peripheralIdentifier,const DeepCollectionEquality().hash(_peripheralParserSpec),const DeepCollectionEquality().hash(_firmwares),icon,widget); @override String toString() { - return 'Model(id: $id, name: $name, flespiId: $flespiId, protocol: $protocol, protocolId: $protocolId, isGeneric: $isGeneric, commandsStructure: $commandsStructure, configStructure: $configStructure, confiotCapable: $confiotCapable, confiotLayout: $confiotLayout, confiotName: $confiotName, peripheralIdentifier: $peripheralIdentifier, peripheralParserSpec: $peripheralParserSpec, firmwares: $firmwares)'; + return 'Model(id: $id, name: $name, flespiId: $flespiId, protocol: $protocol, protocolId: $protocolId, isGeneric: $isGeneric, commandsStructure: $commandsStructure, configStructure: $configStructure, confiotCapable: $confiotCapable, confiotLayout: $confiotLayout, confiotName: $confiotName, peripheralIdentifier: $peripheralIdentifier, peripheralParserSpec: $peripheralParserSpec, firmwares: $firmwares, icon: $icon, widget: $widget)'; } @@ -345,7 +353,7 @@ abstract mixin class _$ModelCopyWith<$Res> implements $ModelCopyWith<$Res> { factory _$ModelCopyWith(_Model value, $Res Function(_Model) _then) = __$ModelCopyWithImpl; @override @useResult $Res call({ - String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable,@JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares + String id, String name, String? flespiId, InboundProtocol? protocol, String? protocolId, bool? isGeneric, List commandsStructure, List configStructure, bool confiotCapable,@JsonKey(unknownEnumValue: ConfIoTLayout.standard) ConfIoTLayout confiotLayout, String? confiotName, String? peripheralIdentifier, Map? peripheralParserSpec, List firmwares,@IconOrNullConverter() LayrzIcon? icon,@JsonKey(unknownEnumValue: RenderWidget.unknown) RenderWidget widget }); @@ -362,7 +370,7 @@ class __$ModelCopyWithImpl<$Res> /// Create a copy of Model /// with the given fields replaced by the non-null parameter values. -@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? flespiId = freezed,Object? protocol = freezed,Object? protocolId = freezed,Object? isGeneric = freezed,Object? commandsStructure = null,Object? configStructure = null,Object? confiotCapable = null,Object? confiotLayout = null,Object? confiotName = freezed,Object? peripheralIdentifier = freezed,Object? peripheralParserSpec = freezed,Object? firmwares = null,}) { +@override @pragma('vm:prefer-inline') $Res call({Object? id = null,Object? name = null,Object? flespiId = freezed,Object? protocol = freezed,Object? protocolId = freezed,Object? isGeneric = freezed,Object? commandsStructure = null,Object? configStructure = null,Object? confiotCapable = null,Object? confiotLayout = null,Object? confiotName = freezed,Object? peripheralIdentifier = freezed,Object? peripheralParserSpec = freezed,Object? firmwares = null,Object? icon = freezed,Object? widget = null,}) { return _then(_Model( id: null == id ? _self.id : id // ignore: cast_nullable_to_non_nullable as String,name: null == name ? _self.name : name // ignore: cast_nullable_to_non_nullable @@ -378,7 +386,9 @@ as ConfIoTLayout,confiotName: freezed == confiotName ? _self.confiotName : confi as String?,peripheralIdentifier: freezed == peripheralIdentifier ? _self.peripheralIdentifier : peripheralIdentifier // ignore: cast_nullable_to_non_nullable as String?,peripheralParserSpec: freezed == peripheralParserSpec ? _self._peripheralParserSpec : peripheralParserSpec // ignore: cast_nullable_to_non_nullable as Map?,firmwares: null == firmwares ? _self._firmwares : firmwares // ignore: cast_nullable_to_non_nullable -as List, +as List,icon: freezed == icon ? _self.icon : icon // ignore: cast_nullable_to_non_nullable +as LayrzIcon?,widget: null == widget ? _self.widget : widget // ignore: cast_nullable_to_non_nullable +as RenderWidget, )); } diff --git a/lib/src/models/models.g.dart b/lib/src/models/models.g.dart index a28abd2f..1e933699 100644 --- a/lib/src/models/models.g.dart +++ b/lib/src/models/models.g.dart @@ -41,6 +41,14 @@ _Model _$ModelFromJson(Map json) => _Model( ?.map((e) => FirmwareBuild.fromJson(e as Map)) .toList() ?? const [], + icon: const IconOrNullConverter().fromJson(json['icon'] as String?), + widget: + $enumDecodeNullable( + _$RenderWidgetEnumMap, + json['widget'], + unknownValue: RenderWidget.unknown, + ) ?? + RenderWidget.unknown, ); Map _$ModelToJson(_Model instance) => { @@ -60,6 +68,8 @@ Map _$ModelToJson(_Model instance) => { 'peripheralIdentifier': instance.peripheralIdentifier, 'peripheralParserSpec': instance.peripheralParserSpec, 'firmwares': instance.firmwares.map((e) => e.toJson()).toList(), + 'icon': const IconOrNullConverter().toJson(instance.icon), + 'widget': instance.widget.toJson(), }; const _$ConfIoTLayoutEnumMap = { @@ -67,6 +77,32 @@ const _$ConfIoTLayoutEnumMap = { ConfIoTLayout.sdmMonitor: 'SDM_MONITOR', }; +const _$RenderWidgetEnumMap = { + RenderWidget.thermometer: 'THERMOMETER', + RenderWidget.humidity: 'HUMIDITY', + RenderWidget.pressure: 'PRESSURE', + RenderWidget.illuminance: 'ILLUMINANCE', + RenderWidget.airQuality: 'AIR_QUALITY', + RenderWidget.battery: 'BATTERY', + RenderWidget.linkQuality: 'LINK_QUALITY', + RenderWidget.binarySensor: 'BINARY_SENSOR', + RenderWidget.switch_: 'SWITCH', + RenderWidget.dimmer: 'DIMMER', + RenderWidget.colorTemperature: 'COLOR_TEMPERATURE', + RenderWidget.setpoint: 'SETPOINT', + RenderWidget.fanSpeed: 'FAN_SPEED', + RenderWidget.colorPicker: 'COLOR_PICKER', + RenderWidget.modeSelector: 'MODE_SELECTOR', + RenderWidget.sceneSelector: 'SCENE_SELECTOR', + RenderWidget.cover: 'COVER', + RenderWidget.lock: 'LOCK', + RenderWidget.powerMeter: 'POWER_METER', + RenderWidget.energyMeter: 'ENERGY_METER', + RenderWidget.voltage: 'VOLTAGE', + RenderWidget.current: 'CURRENT', + RenderWidget.unknown: 'UNKNOWN', +}; + _ModelInput _$ModelInputFromJson(Map json) => _ModelInput( id: json['id'] as String?, name: json['name'] as String? ?? '', diff --git a/lib/src/models/src/model.dart b/lib/src/models/src/model.dart index d1f1cb46..ae2f503e 100644 --- a/lib/src/models/src/model.dart +++ b/lib/src/models/src/model.dart @@ -48,6 +48,12 @@ abstract class Model with _$Model { /// [firmwares] is the list of firmwares for the model. @Default([]) List firmwares, + + /// The icon of the model, if not exists, you must render the protocol icon + @IconOrNullConverter() LayrzIcon? icon, + + /// Indicates the rendering widget, useful to render visually the kind of device + @JsonKey(unknownEnumValue: RenderWidget.unknown) @Default(RenderWidget.unknown) RenderWidget widget, }) = _Model; factory Model.fromJson(Map json) => _$ModelFromJson(json); diff --git a/lib/src/models/src/widget.dart b/lib/src/models/src/widget.dart new file mode 100644 index 00000000..aa8c10a9 --- /dev/null +++ b/lib/src/models/src/widget.dart @@ -0,0 +1,106 @@ +part of '../models.dart'; + +@JsonEnum(alwaysCreate: true) +enum RenderWidget { + /// Renders a Thermometer + @JsonValue('THERMOMETER') + thermometer, + + /// Renders a Humidity display + @JsonValue('HUMIDITY') + humidity, + + /// Renders a Pressure display + @JsonValue('PRESSURE') + pressure, + + /// Renders an Illuminance display + @JsonValue('ILLUMINANCE') + illuminance, + + /// Renders an Air Quality / CO2 display + @JsonValue('AIR_QUALITY') + airQuality, + + /// Renders a Battery level display + @JsonValue('BATTERY') + battery, + + /// Renders a Link Quality (LQI) display + @JsonValue('LINK_QUALITY') + linkQuality, + + /// Renders a read-only binary state indicator + @JsonValue('BINARY_SENSOR') + binarySensor, + + /// Renders a Switch + @JsonValue('SWITCH') + switch_, + + /// Renders a Dimmer slider + @JsonValue('DIMMER') + dimmer, + + /// Renders a Color Temperature slider + @JsonValue('COLOR_TEMPERATURE') + colorTemperature, + + /// Renders a Thermostat Setpoint slider + @JsonValue('SETPOINT') + setpoint, + + /// Renders a Fan Speed slider + @JsonValue('FAN_SPEED') + fanSpeed, + + /// Renders an RGB/RGBW Color Picker + @JsonValue('COLOR_PICKER') + colorPicker, + + /// Renders a Mode Selector (e.g. heat/cool/auto) + @JsonValue('MODE_SELECTOR') + modeSelector, + + /// Renders a Scene Selector + @JsonValue('SCENE_SELECTOR') + sceneSelector, + + /// Renders a Cover/Blind control (open, close, stop, position) + @JsonValue('COVER') + cover, + + /// Renders a Lock/Unlock control + @JsonValue('LOCK') + lock, + + /// Renders a Power display (Watts) + @JsonValue('POWER_METER') + powerMeter, + + /// Renders an Energy display (kWh) + @JsonValue('ENERGY_METER') + energyMeter, + + /// Renders a Voltage display (V) + @JsonValue('VOLTAGE') + voltage, + + /// Renders a Current display (A) + @JsonValue('CURRENT') + current, + + /// Unknown render widget + @JsonValue('UNKNOWN') + unknown, + ; + + @override + String toString() => toJson(); + String toJson() => _$RenderWidgetEnumMap[this] ?? 'UNKNOWN'; + + static RenderWidget fromJson(String json) { + final found = _$RenderWidgetEnumMap.entries.firstWhereOrNull((e) => e.value == json); + return found?.key ?? RenderWidget.unknown; + } +} From 36ec1e5b7722060ff181cc3aea6df9b640f40bab Mon Sep 17 00:00:00 2001 From: Kenny Mochizuki Escalona Date: Mon, 11 May 2026 05:41:45 -0600 Subject: [PATCH 2/2] chore: bump version to 3.8.9 --- CHANGELOG.md | 4 ++++ pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42319888..79031cb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.8.9 + +- Added new fields on `InboundProtocol` and `Model` to support Zigbee and ConfIoT related configurations + ## 3.8.8 - Fixed `casesMonitorConfig` type in `Workspace` model to be a list of nullable `CaseMonitorCard?` instead of non-nullable `CaseMonitorCard`. diff --git a/pubspec.yaml b/pubspec.yaml index a0b1c0d0..999339c2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ description: Layrz API models for Dart/Flutter. This package contains the models used by the Layrz API. name: layrz_models -version: "3.8.8" +version: "3.8.9" repository: https://github.com/goldenm-software/layrz_models environment: