From d351dfb947e10a07fb344649c3818d0185cde8a3 Mon Sep 17 00:00:00 2001 From: Guy Luz Date: Thu, 11 Jan 2024 00:17:31 +0200 Subject: [PATCH 1/9] Made vendor login generic --- lib/domain/connections_service.dart | 4 + .../app_connection_service.dart | 8 ++ .../demo_connection_service.dart | 6 + .../none_connection_service.dart | 6 + lib/presentation/atoms/switch_atom.dart | 4 + lib/presentation/core/entities_utils.dart | 40 +----- lib/presentation/core/routes/app_router.dart | 4 +- .../molecules/device_by_type_molecule.dart | 11 +- .../molecules/devices/ac_molecule.dart | 87 ++++++++++++ lib/presentation/molecules/molecules.dart | 3 +- .../organisms/devices_list_view.dart | 4 - .../widgets/vendor_widget.dart | 41 ++---- .../widgets/vendors_list.dart | 27 ++-- .../pages/add_routine/add_routine_page.dart | 7 +- .../add_esphome_vendor_page.dart | 22 --- .../widgets/esphome_sign_in_form.dart | 104 -------------- .../add_ewelink_vendor_page.dart | 23 ---- .../widgets/ewelink_sign_in_form.dart | 127 ------------------ .../add_lifx_vendor/add_lifx_vendor_page.dart | 23 ---- .../widgets/lifx_sign_in_form.dart | 119 ---------------- .../choose_automation_type_to_add_page.dart | 7 - .../entities_by_area_tab.dart | 1 + lib/presentation/pages/login_vendor_page.dart | 125 +++++++++++++++++ lib/presentation/pages/pages.dart | 3 - 24 files changed, 286 insertions(+), 520 deletions(-) create mode 100644 lib/presentation/molecules/devices/ac_molecule.dart delete mode 100644 lib/presentation/pages/add_vendors_pages/add_esphome_vendor/add_esphome_vendor_page.dart delete mode 100644 lib/presentation/pages/add_vendors_pages/add_esphome_vendor/widgets/esphome_sign_in_form.dart delete mode 100644 lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/add_ewelink_vendor_page.dart delete mode 100644 lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/widgets/ewelink_sign_in_form.dart delete mode 100644 lib/presentation/pages/add_vendors_pages/add_lifx_vendor/add_lifx_vendor_page.dart delete mode 100644 lib/presentation/pages/add_vendors_pages/add_lifx_vendor/widgets/lifx_sign_in_form.dart create mode 100644 lib/presentation/pages/login_vendor_page.dart diff --git a/lib/domain/connections_service.dart b/lib/domain/connections_service.dart index c00f4767..0c4a1e42 100644 --- a/lib/domain/connections_service.dart +++ b/lib/domain/connections_service.dart @@ -73,4 +73,8 @@ abstract interface class ConnectionsService { Future activateScene(String id); Future addScene(SceneCbjEntity scene); + + Future loginVendor(VendorLoginEntity value); + + Future> getVendors(); } diff --git a/lib/infrastructure/connection_service/app_connection_service.dart b/lib/infrastructure/connection_service/app_connection_service.dart index a1b7a82f..620e997a 100644 --- a/lib/infrastructure/connection_service/app_connection_service.dart +++ b/lib/infrastructure/connection_service/app_connection_service.dart @@ -53,4 +53,12 @@ class _AppConnectionService implements ConnectionsService { @override Future addScene(SceneCbjEntity scene) => IcSynchronizer().addScene(scene); + + @override + Future loginVendor(VendorLoginEntity value) async => + IcSynchronizer().loginVendor(value); + + @override + Future> getVendors() async => + IcSynchronizer().getVendors(); } diff --git a/lib/infrastructure/connection_service/demo_connection_service.dart b/lib/infrastructure/connection_service/demo_connection_service.dart index 555dfcb0..eb4c8165 100644 --- a/lib/infrastructure/connection_service/demo_connection_service.dart +++ b/lib/infrastructure/connection_service/demo_connection_service.dart @@ -52,4 +52,10 @@ class _DemoConnectionService implements ConnectionsService { @override Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => []; } diff --git a/lib/infrastructure/connection_service/none_connection_service.dart b/lib/infrastructure/connection_service/none_connection_service.dart index dabda1bd..d3a8f8d1 100644 --- a/lib/infrastructure/connection_service/none_connection_service.dart +++ b/lib/infrastructure/connection_service/none_connection_service.dart @@ -52,4 +52,10 @@ class _NoneConnectionService implements ConnectionsService { @override Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => []; } diff --git a/lib/presentation/atoms/switch_atom.dart b/lib/presentation/atoms/switch_atom.dart index 95b9d296..f75cd69e 100644 --- a/lib/presentation/atoms/switch_atom.dart +++ b/lib/presentation/atoms/switch_atom.dart @@ -75,6 +75,9 @@ class _SwitchAtomState extends State { case SwitchVariant.switchVariant: activeIcon = MdiIcons.lightSwitch; inactiveIcon = MdiIcons.lightSwitch; + case SwitchVariant.ac: + activeIcon = MdiIcons.airConditioner; + inactiveIcon = MdiIcons.airConditioner; } return SizedBox( @@ -115,5 +118,6 @@ enum SwitchVariant { boiler, smartPlug, switchVariant, + ac, ; } diff --git a/lib/presentation/core/entities_utils.dart b/lib/presentation/core/entities_utils.dart index 9ecb5a5b..912d3b0a 100644 --- a/lib/presentation/core/entities_utils.dart +++ b/lib/presentation/core/entities_utils.dart @@ -10,40 +10,12 @@ class EntitiesUtils { return FontAwesomeIcons.alignJustify; case EntityTypes.boiler: return FontAwesomeIcons.temperatureThreeQuarters; - case EntityTypes.browserApp: - // TODO: Handle this case. - break; - case EntityTypes.button: - return Icons.smart_button; - case EntityTypes.computerApp: - return Icons.computer; - case EntityTypes.emptyEntity: - // TODO: Handle this case. - break; - case EntityTypes.hub: - // TODO: Handle this case. - break; case EntityTypes.light: case EntityTypes.dimmableLight: - case EntityTypes.rgbLights: - case EntityTypes.rgbcctLights: case EntityTypes.rgbwLights: - case EntityTypes.cctLight: return FontAwesomeIcons.lightbulb; - case EntityTypes.phoneApp: - return Icons.phone; - case EntityTypes.pingEntity: - // TODO: Handle this case. - break; - case EntityTypes.playerEntity: - // TODO: Handle this case. - break; case EntityTypes.printer: - case EntityTypes.scanner: - case EntityTypes.printerWithScanner: return Icons.print; - case EntityTypes.routerEntity: - return Icons.router; case EntityTypes.securityCamera: return Icons.camera; case EntityTypes.smartComputer: @@ -52,14 +24,14 @@ class EntitiesUtils { return MdiIcons.powerSocketAu; case EntityTypes.smartTV: return Icons.tv; - case EntityTypes.smartTypeNotSupported: - // TODO: Handle this case. - break; case EntityTypes.switch_: return MdiIcons.lightSwitch; - case EntityTypes.voiceAssistant: - return MdiIcons.voicemail; + case EntityTypes.ac: + return MdiIcons.airConditioner; + case EntityTypes.emptyEntity: + case EntityTypes.pingEntity: + case EntityTypes.smartTypeNotSupported: + return Icons.question_mark; } - return Icons.question_mark; } } diff --git a/lib/presentation/core/routes/app_router.dart b/lib/presentation/core/routes/app_router.dart index cda391ab..903ba0d9 100644 --- a/lib/presentation/core/routes/app_router.dart +++ b/lib/presentation/core/routes/app_router.dart @@ -24,9 +24,6 @@ class AppRouter extends $AppRouter { AutoRoute(page: AddActionRoute.page), AutoRoute(page: ChooseAutomationTypeToAddRoute.page), AutoRoute(page: ChooseDeviceVendorToAddRoute.page), - AutoRoute(page: AddLifxVendorRoute.page), - AutoRoute(page: AddEspHomeVendorRoute.page), - AutoRoute(page: AddEwelinkVendorRoute.page), AutoRoute(page: ConnectToHomeWifiRoute.page), AutoRoute(page: OpenAccessPointRoute.page), AutoRoute(page: ScanForNewCBJCompsRoute.page), @@ -34,6 +31,7 @@ class AppRouter extends $AppRouter { AutoRoute(page: ComputerConnectionCheckRoute.page), AutoRoute(page: EntitiesInNetworkRoute.page), AutoRoute(page: EntitiesInAreaRoute.page), + AutoRoute(page: LoginVendorRoute.page), // Pages from packages AutoRoute(page: SmartCameraContainerRoute.page), diff --git a/lib/presentation/molecules/device_by_type_molecule.dart b/lib/presentation/molecules/device_by_type_molecule.dart index a9560ecb..de7fec35 100644 --- a/lib/presentation/molecules/device_by_type_molecule.dart +++ b/lib/presentation/molecules/device_by_type_molecule.dart @@ -1,5 +1,4 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; import 'package:flutter/material.dart'; @@ -36,9 +35,13 @@ class DeviceByTypeMolecule extends StatelessWidget { return DimmableLightMolecule(entity as GenericDimmableLightDE); case EntityTypes.securityCamera: return SecurityCameraMolecule(entity as GenericSecurityCameraDE); - - default: - return TextAtom('Entity type is unsupported ${type?.name ?? 'null'}'); + case EntityTypes.ac: + return AcMolecule(entity as GenericAcDE); + case EntityTypes.smartTypeNotSupported: + case EntityTypes.emptyEntity: + case EntityTypes.pingEntity: + case null: + return const SizedBox(); } } } diff --git a/lib/presentation/molecules/devices/ac_molecule.dart b/lib/presentation/molecules/devices/ac_molecule.dart new file mode 100644 index 00000000..fdef8ed9 --- /dev/null +++ b/lib/presentation/molecules/devices/ac_molecule.dart @@ -0,0 +1,87 @@ +import 'dart:collection'; + +import 'package:another_flushbar/flushbar_helper.dart'; +import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; +import 'package:cybearjinni/presentation/molecules/molecules.dart'; +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; + +class AcMolecule extends StatefulWidget { + const AcMolecule(this.entity); + + final GenericAcDE entity; + + @override + State createState() => _AcMoleculeState(); +} + +class _AcMoleculeState extends State { + Future _turnOnAllAcs() async { + FlushbarHelper.createLoading( + message: 'Turning_On_ac'.tr(), + linearProgressIndicator: const LinearProgressIndicator(), + ).show(context); + + setEntityState(EntityActions.on); + // IDeviceRepository.instance.moveUpStateDevices(devicesId: blindsIdToTurnUp); + } + + void setEntityState(EntityActions action) { + final VendorsAndServices? vendor = + widget.entity.cbjDeviceVendor.vendorsAndServices; + if (vendor == null) { + return; + } + final HashMap> uniqueIdByVendor = + HashMap(); + uniqueIdByVendor.addEntries( + [ + MapEntry( + vendor, + HashSet() + ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), + ), + ], + ); + + ConnectionsService.instance.setEntityState( + ActionObject( + uniqueIdByVendor: uniqueIdByVendor, + property: EntityProperties.acSwitchState, + actionType: action, + ), + ); + } + + Future _turnOffAllAcs() async { + FlushbarHelper.createLoading( + message: 'Turning_Off_ac'.tr(), + linearProgressIndicator: const LinearProgressIndicator(), + ).show(context); + + setEntityState(EntityActions.off); + } + + void _onChange(bool value) { + if (value) { + _turnOnAllAcs(); + } else { + _turnOffAllAcs(); + } + } + + @override + Widget build(BuildContext context) { + return DeviceNameRow( + widget.entity.cbjEntityName.getOrCrash()!, + SwitchAtom( + variant: SwitchVariant.ac, + onToggle: _onChange, + action: widget.entity.acSwitchState.action!, + state: widget.entity.entityStateGRPC.state, + ), + ); + } +} diff --git a/lib/presentation/molecules/molecules.dart b/lib/presentation/molecules/molecules.dart index 7343aac4..f90f49b3 100644 --- a/lib/presentation/molecules/molecules.dart +++ b/lib/presentation/molecules/molecules.dart @@ -1,6 +1,7 @@ export 'bottom_navigation_bar_molecule.dart'; export 'device_by_type_molecule.dart'; export 'device_name_row.dart'; +export 'devices/ac_molecule.dart'; export 'devices/blind_molecule.dart'; export 'devices/blinds_card_molecule.dart'; export 'devices/boiler_molecule.dart'; @@ -17,5 +18,5 @@ export 'devices/switch_molecule.dart'; export 'list_tile_molecule.dart'; export 'list_view_molecule.dart'; export 'loading_page_molecule.dart'; -export 'top_bar_molecule.dart'; export 'scenes_grid.dart'; +export 'top_bar_molecule.dart'; diff --git a/lib/presentation/organisms/devices_list_view.dart b/lib/presentation/organisms/devices_list_view.dart index 98811f2c..600f4891 100644 --- a/lib/presentation/organisms/devices_list_view.dart +++ b/lib/presentation/organisms/devices_list_view.dart @@ -14,15 +14,11 @@ class DevicesListView extends StatelessWidget { HashSet getReleatedTypes(EntityTypes type) { if (type == EntityTypes.light || - type == EntityTypes.rgbLights || type == EntityTypes.rgbwLights || - type == EntityTypes.cctLight || type == EntityTypes.dimmableLight) { return HashSet.from({ EntityTypes.light, - EntityTypes.rgbLights, EntityTypes.rgbwLights, - EntityTypes.cctLight, EntityTypes.dimmableLight, }); } diff --git a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart index b28c48f1..cc5ce96b 100644 --- a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart @@ -1,5 +1,5 @@ import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/routes/app_router.gr.dart'; import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; @@ -7,41 +7,25 @@ import 'package:flutter/material.dart'; import 'package:hexcolor/hexcolor.dart'; class VendorWidget extends StatelessWidget { - const VendorWidget(this.vendor); + const VendorWidget(this.vendorInformation); - final VendorData vendor; + final VendorEntityInformation vendorInformation; @override Widget build(BuildContext context) { return GestureDetector( onTap: () { - final String vendorName = vendor.name - .getOrCrash() - .toLowerCase() - .replaceAll(' ', '') - .replaceAll('_', ''); - - if (vendorName == VendorsAndServices.lifx.name.toLowerCase()) { - context.router.push(AddLifxVendorRoute(vendor: vendor)); - } else if (vendorName == - VendorsAndServices.espHome.name.toLowerCase()) { - context.router.push(AddEspHomeVendorRoute(vendor: vendor)); - } else if (vendorName == - VendorsAndServices.sonoffEweLink.name.toLowerCase()) { - context.router.push(AddEwelinkVendorRoute(vendor: vendor)); - } else if (vendorName == - VendorsAndServices.philipsHue.name.toLowerCase()) { + if (vendorInformation.loginType == VendorLoginTypes.notNeeded) { SnackBarService().show( context, - 'Please press the button on top of the Philips Hue Hub for and wait 20s', - ); - } else { - SnackBarService().show( - context, - '${vendor.name.getOrCrash()} devices will be add automatically' + '${vendorInformation.displayName} devices will be add automatically' ' for you', ); + return; } + + context.router + .push(LoginVendorRoute(vendorInformation: vendorInformation)); }, child: Container( height: 100, @@ -54,10 +38,7 @@ class VendorWidget extends StatelessWidget { height: 180, decoration: BoxDecoration( image: DecorationImage( - image: NetworkImage( - vendor.image ?? - 'http://www.clker.com/cliparts/f/Z/G/4/h/Q/no-image-available-th.png', - ), + image: NetworkImage(vendorInformation.imageUrl), fit: BoxFit.fitHeight, ), ), @@ -66,7 +47,7 @@ class VendorWidget extends StatelessWidget { width: 10, ), TextAtom( - vendor.name.getOrCrash(), + vendorInformation.displayName, style: const TextStyle( color: Colors.black, fontSize: 22, diff --git a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart index f14efa69..000a7f61 100644 --- a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart +++ b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart @@ -1,7 +1,8 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendor_widget.dart'; import 'package:flutter/material.dart'; -import 'package:kt_dart/kt.dart'; class VendorsList extends StatefulWidget { @override @@ -9,7 +10,7 @@ class VendorsList extends StatefulWidget { } class _VendorsListState extends State { - KtList vendorsList = [].toImmutableList(); + List? vendorsList; @override void initState() { @@ -18,10 +19,12 @@ class _VendorsListState extends State { } Future initializeVendors() async { - final KtList temp = - (await IVendorsRepository.instance.getVendors()).fold( - (f) => [].toImmutableList(), - (vendorsListSuccess) => vendorsListSuccess, + final List temp = + await ConnectionsService.instance.getVendors(); + temp.removeWhere( + (element) => + element.vendorsAndServices == + VendorsAndServices.vendorsAndServicesNotSupported, ); setState(() { vendorsList = temp; @@ -30,6 +33,10 @@ class _VendorsListState extends State { @override Widget build(BuildContext context) { + if (vendorsList == null) { + return const CircularProgressIndicatorAtom(); + } + return ListView.separated( separatorBuilder: (_, __) => const SizedBox( height: 16, @@ -37,12 +44,10 @@ class _VendorsListState extends State { reverse: true, padding: EdgeInsets.zero, itemBuilder: (context, index) { - final vendor = vendorsList[index]; - return VendorWidget( - vendor, - ); + final vendor = vendorsList![index]; + return VendorWidget(vendor); }, - itemCount: vendorsList.size, + itemCount: vendorsList!.length, ); } } diff --git a/lib/presentation/pages/add_routine/add_routine_page.dart b/lib/presentation/pages/add_routine/add_routine_page.dart index 222aeca6..36aba05f 100644 --- a/lib/presentation/pages/add_routine/add_routine_page.dart +++ b/lib/presentation/pages/add_routine/add_routine_page.dart @@ -10,7 +10,6 @@ import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; import 'package:cybearjinni/presentation/pages/add_action_page.dart'; import 'package:cybearjinni/presentation/pages/add_routine/widgets/routine_action_widget.dart'; -import 'package:dartz/dartz.dart' as dartz; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hexcolor/hexcolor.dart'; @@ -51,9 +50,6 @@ class _AddRoutinePageState extends State { Set> allEntityActions = {}; bool showErrorMessages = false; bool isSubmitting = false; - dartz.Option> - authFailureOrSuccessOption = dartz.none(); - HashMap? entities; Future initialzeEntities() async { @@ -170,7 +166,8 @@ class _AddRoutinePageState extends State { ), onPressed: (_) async { final EntityActionObject? actionList = - await context.router.push( + await context.router + .push( AddActionRoute(entities: entities!), ); if (actionList != null) { diff --git a/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/add_esphome_vendor_page.dart b/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/add_esphome_vendor_page.dart deleted file mode 100644 index b2d2d58c..00000000 --- a/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/add_esphome_vendor_page.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/pages/add_vendors_pages/add_esphome_vendor/widgets/esphome_sign_in_form.dart'; -import 'package:flutter/material.dart'; - -@RoutePage() -class AddEspHomeVendorPage extends StatelessWidget { - const AddEspHomeVendorPage(this.vendor); - - final VendorData vendor; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: const TextAtom('EspHome Sign In'), - ), - body: EspHomeSignInForm(vendor), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/widgets/esphome_sign_in_form.dart b/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/widgets/esphome_sign_in_form.dart deleted file mode 100644 index 31d43e77..00000000 --- a/lib/presentation/pages/add_vendors_pages/add_esphome_vendor/widgets/esphome_sign_in_form.dart +++ /dev/null @@ -1,104 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; -import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; - -class EspHomeSignInForm extends StatefulWidget { - const EspHomeSignInForm(this.vendor); - - final VendorData vendor; - - @override - State createState() => _EspHomeSignInFormState(); -} - -class _EspHomeSignInFormState extends State { - String? password; - - void _login() { - if (password == null) { - return; - } - - context.router.pop(); - - IVendorsRepository.instance.loginWithEspHome( - GenericEspHomeLoginDE( - espHomeDevicePass: GenericEspHomeDeviceLoginApiPass(password), - senderUniqueId: CoreLoginSenderId.fromUniqueString('Me'), - ), - ); - } - - @override - Widget build(BuildContext context) { - final Size screenSize = MediaQuery.of(context).size; - - return Form( - autovalidateMode: AutovalidateMode.onUserInteraction, - child: ListView( - padding: const EdgeInsets.all(8), - children: [ - Hero( - tag: 'Logo', - child: CircleAvatar( - backgroundColor: Colors.transparent, - radius: screenSize.height * 0.1, - child: Container( - width: 180, - height: 180, - decoration: BoxDecoration( - image: DecorationImage( - image: NetworkImage( - widget.vendor.image ?? '', - ), - fit: BoxFit.fitHeight, - ), - ), - ), - ), - ), - const SizedBox( - height: 8, - ), - TextFormField( - decoration: const InputDecoration( - prefixIcon: FaIcon( - FontAwesomeIcons.key, - ), - labelText: 'ESPHome device password', - ), - autocorrect: false, - onChanged: (value) { - password = value; - }, - ), - const SizedBox( - height: 8, - ), - Row( - children: [ - Expanded( - child: TextButton( - onPressed: () { - _login(); - - SnackBarService().show( - context, - 'Sign in to ESPHome, devices will appear in the ' - 'app after getting discovered', - ); - context.router.pop(); - }, - child: const TextAtom('SIGN IN'), - ), - ), - ], - ), - ], - ), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/add_ewelink_vendor_page.dart b/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/add_ewelink_vendor_page.dart deleted file mode 100644 index b6f5a048..00000000 --- a/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/add_ewelink_vendor_page.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/pages/add_vendors_pages/add_ewelink_vendor/widgets/ewelink_sign_in_form.dart'; -import 'package:flutter/material.dart'; - -@RoutePage() -class AddEwelinkVendorPage extends StatelessWidget { - const AddEwelinkVendorPage(this.vendor); - - final VendorData vendor; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.blueAccent, - title: const TextAtom('eWeLink Sign In'), - ), - body: EwelinkSignInForm(vendor), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/widgets/ewelink_sign_in_form.dart b/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/widgets/ewelink_sign_in_form.dart deleted file mode 100644 index c6a00314..00000000 --- a/lib/presentation/pages/add_vendors_pages/add_ewelink_vendor/widgets/ewelink_sign_in_form.dart +++ /dev/null @@ -1,127 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; -import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; - -class EwelinkSignInForm extends StatefulWidget { - const EwelinkSignInForm(this.vendor); - - final VendorData vendor; - - @override - State createState() => _EwelinkSignInFormState(); -} - -class _EwelinkSignInFormState extends State { - String? email; - String? password; - - Future _signInWithEwelink() async { - if (email == null || password == null) { - SnackBarService().show( - context, - 'Please enter Email and Password', - ); - return; - } - - SnackBarService().show( - context, - 'Sign in to eWeLink, devices will appear in the ' - 'app after getting discovered', - ); - context.router.pop(); - - final GenericEwelinkLoginDE genericEwelinkDE = GenericEwelinkLoginDE( - senderUniqueId: CoreLoginSenderId.fromUniqueString('Me'), - ewelinkAccountEmail: GenericEwelinkAccountEmail(email), - ewelinkAccountPass: GenericEwelinkAccountPass(password), - ); - IVendorsRepository.instance.loginWithEwelink(genericEwelinkDE); - } - - @override - Widget build(BuildContext context) { - final Size screenSize = MediaQuery.of(context).size; - - return Form( - autovalidateMode: AutovalidateMode.onUserInteraction, - child: ListView( - padding: const EdgeInsets.all(8), - children: [ - Hero( - tag: 'Logo', - child: CircleAvatar( - backgroundColor: Colors.transparent, - radius: screenSize.height * 0.1, - child: Container( - width: 180, - height: 180, - decoration: BoxDecoration( - image: DecorationImage( - image: NetworkImage(widget.vendor.image ?? ''), - fit: BoxFit.fitHeight, - ), - ), - ), - // ImageAtom('assets/cbj_logo.png'), - ), - ), - const SizedBox( - height: 8, - ), - TextFormField( - decoration: const InputDecoration( - prefixIcon: FaIcon( - FontAwesomeIcons.at, - ), - labelText: 'eWeLink device email', - ), - autocorrect: false, - onChanged: (value) { - email = value; - }, - validator: (_) { - return null; - }, - ), - const SizedBox( - height: 8, - ), - TextFormField( - decoration: const InputDecoration( - prefixIcon: FaIcon( - FontAwesomeIcons.key, - ), - labelText: 'eWeLink device password', - ), - autocorrect: false, - onChanged: (value) { - password = value; - }, - validator: (_) { - return null; - }, - ), - const SizedBox( - height: 8, - ), - Row( - children: [ - Expanded( - child: TextButton( - onPressed: () { - _signInWithEwelink(); - }, - child: const TextAtom('SIGN IN'), - ), - ), - ], - ), - ], - ), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/add_lifx_vendor_page.dart b/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/add_lifx_vendor_page.dart deleted file mode 100644 index 0eea2c53..00000000 --- a/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/add_lifx_vendor_page.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/pages/add_vendors_pages/add_lifx_vendor/widgets/lifx_sign_in_form.dart'; -import 'package:flutter/material.dart'; - -@RoutePage() -class AddLifxVendorPage extends StatelessWidget { - const AddLifxVendorPage(this.vendor); - - final VendorData vendor; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - backgroundColor: Colors.deepPurple, - title: const TextAtom('Lifx Sign In'), - ), - body: LifxSignInForm(vendor), - ); - } -} diff --git a/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/widgets/lifx_sign_in_form.dart b/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/widgets/lifx_sign_in_form.dart deleted file mode 100644 index 659d38c3..00000000 --- a/lib/presentation/pages/add_vendors_pages/add_lifx_vendor/widgets/lifx_sign_in_form.dart +++ /dev/null @@ -1,119 +0,0 @@ -import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/presentation/atoms/atoms.dart'; -import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; -import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:url_launcher/url_launcher.dart'; - -class LifxSignInForm extends StatefulWidget { - const LifxSignInForm(this.vendor); - - final VendorData vendor; - - @override - State createState() => _LifxSignInFormState(); -} - -class _LifxSignInFormState extends State { - String? api; - - Future _signInWithApiKey() async { - SnackBarService().show( - context, - 'Sign in to Lifx, devices will appear in the shortly', - ); - final GenericLifxLoginDE genericLifxDE = GenericLifxLoginDE( - senderUniqueId: CoreLoginSenderId.fromUniqueString('Me'), - lifxApiKey: GenericLifxLoginApiKey(api), - ); - IVendorsRepository.instance.loginWithLifx(genericLifxDE); - context.router.pop(); - } - - @override - Widget build(BuildContext context) { - final Size screenSize = MediaQuery.of(context).size; - - return Column( - children: [ - Expanded( - child: Form( - autovalidateMode: AutovalidateMode.onUserInteraction, - child: ListView( - padding: const EdgeInsets.all(8), - children: [ - Hero( - tag: 'Logo', - child: CircleAvatar( - backgroundColor: Colors.transparent, - radius: screenSize.height * 0.1, - child: Container( - width: 180, - height: 180, - decoration: BoxDecoration( - image: DecorationImage( - image: NetworkImage( - widget.vendor.image ?? '', - ), - fit: BoxFit.fitHeight, - ), - ), - ), - ), - ), - const SizedBox( - height: 8, - ), - TextFormField( - decoration: const InputDecoration( - prefixIcon: FaIcon( - FontAwesomeIcons.key, - ), - labelText: 'Lifx API Key', - ), - autocorrect: false, - onChanged: (value) { - api = value; - }, - ), - const SizedBox( - height: 8, - ), - Row( - children: [ - Expanded( - child: TextButton( - onPressed: () { - _signInWithApiKey(); - }, - child: const TextAtom('SIGN IN'), - ), - ), - ], - ), - ], - ), - ), - ), - Container( - alignment: Alignment.bottomRight, - child: TextButton( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all(Colors.pink), - ), - onPressed: () { - launchUrl(Uri.parse('https://cloud.lifx.com/')); - }, - child: TextAtom( - 'Get Lifx API key from Lifx website', - style: TextStyle( - color: Theme.of(context).textTheme.bodyLarge!.color, - ), - ), - ), - ), - ], - ); - } -} diff --git a/lib/presentation/pages/choose_automation_type_to_add_page.dart b/lib/presentation/pages/choose_automation_type_to_add_page.dart index f93c6564..9f301304 100644 --- a/lib/presentation/pages/choose_automation_type_to_add_page.dart +++ b/lib/presentation/pages/choose_automation_type_to_add_page.dart @@ -26,19 +26,12 @@ class ChooseAutomationTypeToAddPage extends StatelessWidget { const TextAtom( 'Do several things at once or start actions' ' automatically by adding a trigger.', - style: TextStyle( - color: Colors.black, - ), ), const SizedBox( height: 13, ), const TextAtom( 'Please choose your automation trigger', - style: TextStyle( - color: Colors.black, - fontSize: 18, - ), ), const SizedBox( height: 30, diff --git a/lib/presentation/pages/home_page/tabs/smart_devices_tab/entities_by_area_tab.dart b/lib/presentation/pages/home_page/tabs/smart_devices_tab/entities_by_area_tab.dart index 964a62ac..557509dc 100644 --- a/lib/presentation/pages/home_page/tabs/smart_devices_tab/entities_by_area_tab.dart +++ b/lib/presentation/pages/home_page/tabs/smart_devices_tab/entities_by_area_tab.dart @@ -46,6 +46,7 @@ class EntitiesByAreaTab extends StatelessWidget { areas: areas, ), ), + const SeparatorAtom(), ], ), ), diff --git a/lib/presentation/pages/login_vendor_page.dart b/lib/presentation/pages/login_vendor_page.dart new file mode 100644 index 00000000..6d89125a --- /dev/null +++ b/lib/presentation/pages/login_vendor_page.dart @@ -0,0 +1,125 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; +import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:url_launcher/url_launcher.dart'; + +@RoutePage() +class LoginVendorPage extends StatefulWidget { + const LoginVendorPage(this.vendorInformation); + + final VendorEntityInformation vendorInformation; + + @override + State createState() => _LoginVendorPageState(); +} + +class _LoginVendorPageState extends State { + String? apiKey; + + Future _signInWithApiKey() async { + SnackBarService().show( + context, + 'Sign in to ${widget.vendorInformation.displayName}, devices will appear in the shortly', + ); + + ConnectionsService.instance.loginVendor( + VendorLoginEntity( + widget.vendorInformation.vendorsAndServices, + apiKey: apiKey, + ), + ); + context.router.pop(); + } + + @override + Widget build(BuildContext context) { + final Size screenSize = MediaQuery.of(context).size; + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.deepPurple, + title: TextAtom('${widget.vendorInformation.displayName} Sign In'), + ), + body: Column( + children: [ + Expanded( + child: Form( + autovalidateMode: AutovalidateMode.onUserInteraction, + child: ListView( + padding: const EdgeInsets.all(8), + children: [ + Hero( + tag: 'Logo', + child: CircleAvatar( + backgroundColor: Colors.transparent, + radius: screenSize.height * 0.1, + child: Container( + width: 180, + height: 180, + decoration: BoxDecoration( + image: DecorationImage( + image: + NetworkImage(widget.vendorInformation.imageUrl), + fit: BoxFit.fitHeight, + ), + ), + ), + ), + ), + const SizedBox( + height: 8, + ), + TextFormField( + decoration: const InputDecoration( + prefixIcon: FaIcon(FontAwesomeIcons.key), + labelText: 'value', + ), + autocorrect: false, + onChanged: (value) { + apiKey = value; + }, + ), + const SizedBox( + height: 8, + ), + Row( + children: [ + Expanded( + child: TextButton( + onPressed: _signInWithApiKey, + child: const TextAtom('SIGN IN'), + ), + ), + ], + ), + ], + ), + ), + ), + if (widget.vendorInformation.urlToLoginCredantials != null) + Container( + alignment: Alignment.bottomRight, + child: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Colors.pink), + ), + onPressed: () { + launchUrl(Uri.parse( + widget.vendorInformation.urlToLoginCredantials!)); + }, + child: TextAtom( + widget.vendorInformation.loginType.name, + style: TextStyle( + color: Theme.of(context).textTheme.bodyLarge!.color, + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/pages.dart b/lib/presentation/pages/pages.dart index ceb5e18f..5c3cb02a 100644 --- a/lib/presentation/pages/pages.dart +++ b/lib/presentation/pages/pages.dart @@ -9,9 +9,6 @@ export 'package:cybearjinni/presentation/pages/add_new_devices_process/open_acce export 'package:cybearjinni/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/scan_for_new_cbj_comps_page.dart'; export 'package:cybearjinni/presentation/pages/add_routine/add_routine_page.dart'; export 'package:cybearjinni/presentation/pages/add_scene/add_scene_page.dart'; -export 'package:cybearjinni/presentation/pages/add_vendors_pages/add_esphome_vendor/add_esphome_vendor_page.dart'; -export 'package:cybearjinni/presentation/pages/add_vendors_pages/add_ewelink_vendor/add_ewelink_vendor_page.dart'; -export 'package:cybearjinni/presentation/pages/add_vendors_pages/add_lifx_vendor/add_lifx_vendor_page.dart'; export 'package:cybearjinni/presentation/pages/change_area_for_devices_page.dart'; export 'package:cybearjinni/presentation/pages/choose_automation_type_to_add_page.dart'; export 'package:cybearjinni/presentation/pages/connect_to_hub/connect_to_hub_page.dart'; From 8bbb82f3d816f6dd53990046ffb31523b760d5fb Mon Sep 17 00:00:00 2001 From: Guy Luz Date: Thu, 11 Jan 2024 00:59:12 +0200 Subject: [PATCH 2/9] Increasing flutter version in github actions --- .github/workflows/dart.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 4f6986bd..f3bf9a07 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -9,7 +9,7 @@ on: env: flutter_channel: 'stable' # or: 'dev' or 'beta' - flutter_version: '3.13.6' + flutter_version: '3.16.5' jobs: build: From 0b5af4bf56e752007682a39b3a548976b09758eb Mon Sep 17 00:00:00 2001 From: Guy Luz Date: Fri, 12 Jan 2024 20:32:53 +0200 Subject: [PATCH 3/9] Added support for more login types --- .../demo_connection_service.dart | 3 +- lib/presentation/atoms/atoms.dart | 1 + .../atoms/text_form_field_atom.dart | 26 +++++ ...row.dart => device_name_row_molecule.dart} | 4 +- .../molecules/devices/ac_molecule.dart | 2 +- .../molecules/devices/blind_molecule.dart | 2 +- .../molecules/devices/boiler_molecule.dart | 2 +- .../devices/dimmable_light_molecule.dart | 29 ++++- .../molecules/devices/light_molecule.dart | 2 +- .../molecules/devices/printer_molecule.dart | 2 +- .../molecules/devices/rgb_light_molecule.dart | 2 +- .../devices/security_camera_molecule.dart | 2 +- .../devices/smart_computer_molecule.dart | 2 +- .../devices/smart_plug_molecule.dart | 2 +- .../molecules/devices/smart_tv_molecule.dart | 2 +- .../molecules/devices/switch_molecule.dart | 2 +- .../molecules/insert_login_molecule.dart | 104 ++++++++++++++++++ lib/presentation/molecules/molecules.dart | 5 +- ...es_grid.dart => scenes_grid_molecule.dart} | 8 +- .../scenes_in_folders_tab.dart | 2 +- lib/presentation/pages/login_vendor_page.dart | 55 +++++---- .../pages/scenes/scenes_page.dart | 2 +- 22 files changed, 215 insertions(+), 46 deletions(-) create mode 100644 lib/presentation/atoms/text_form_field_atom.dart rename lib/presentation/molecules/{device_name_row.dart => device_name_row_molecule.dart} (81%) create mode 100644 lib/presentation/molecules/insert_login_molecule.dart rename lib/presentation/molecules/{scenes_grid.dart => scenes_grid_molecule.dart} (82%) diff --git a/lib/infrastructure/connection_service/demo_connection_service.dart b/lib/infrastructure/connection_service/demo_connection_service.dart index eb4c8165..f23916c0 100644 --- a/lib/infrastructure/connection_service/demo_connection_service.dart +++ b/lib/infrastructure/connection_service/demo_connection_service.dart @@ -57,5 +57,6 @@ class _DemoConnectionService implements ConnectionsService { Future loginVendor(VendorLoginEntity value) async {} @override - Future> getVendors() async => []; + Future> getVendors() async => + IcSynchronizer().getVendors(); } diff --git a/lib/presentation/atoms/atoms.dart b/lib/presentation/atoms/atoms.dart index 862f071d..35d15099 100644 --- a/lib/presentation/atoms/atoms.dart +++ b/lib/presentation/atoms/atoms.dart @@ -9,3 +9,4 @@ export 'scene_atom.dart'; export 'separator_atom.dart'; export 'switch_atom.dart'; export 'text_atom.dart'; +export 'text_form_field_atom.dart'; diff --git a/lib/presentation/atoms/text_form_field_atom.dart b/lib/presentation/atoms/text_form_field_atom.dart new file mode 100644 index 00000000..98124560 --- /dev/null +++ b/lib/presentation/atoms/text_form_field_atom.dart @@ -0,0 +1,26 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; + +class TextFormFieldAtom extends StatelessWidget { + const TextFormFieldAtom({ + required this.onChanged, + this.labelText, + this.prefixIcon, + }); + + final Function(String) onChanged; + final String? labelText; + final Widget? prefixIcon; + + @override + Widget build(BuildContext context) { + return TextFormField( + decoration: InputDecoration( + prefixIcon: prefixIcon, + labelText: labelText?.tr(), + ), + autocorrect: false, + onChanged: onChanged, + ); + } +} diff --git a/lib/presentation/molecules/device_name_row.dart b/lib/presentation/molecules/device_name_row_molecule.dart similarity index 81% rename from lib/presentation/molecules/device_name_row.dart rename to lib/presentation/molecules/device_name_row_molecule.dart index bf383ef4..8c28ee58 100644 --- a/lib/presentation/molecules/device_name_row.dart +++ b/lib/presentation/molecules/device_name_row_molecule.dart @@ -2,8 +2,8 @@ import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; -class DeviceNameRow extends StatelessWidget { - const DeviceNameRow(this.name, this.second); +class DeviceNameRowMolecule extends StatelessWidget { + const DeviceNameRowMolecule(this.name, this.second); final String name; final Widget second; diff --git a/lib/presentation/molecules/devices/ac_molecule.dart b/lib/presentation/molecules/devices/ac_molecule.dart index fdef8ed9..53d4c71c 100644 --- a/lib/presentation/molecules/devices/ac_molecule.dart +++ b/lib/presentation/molecules/devices/ac_molecule.dart @@ -74,7 +74,7 @@ class _AcMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.ac, diff --git a/lib/presentation/molecules/devices/blind_molecule.dart b/lib/presentation/molecules/devices/blind_molecule.dart index 3e2aa0f9..4795a196 100644 --- a/lib/presentation/molecules/devices/blind_molecule.dart +++ b/lib/presentation/molecules/devices/blind_molecule.dart @@ -100,7 +100,7 @@ class _BlindMoleculeState extends State { } } - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, Row( children: [ diff --git a/lib/presentation/molecules/devices/boiler_molecule.dart b/lib/presentation/molecules/devices/boiler_molecule.dart index cdd8583c..2987f8cd 100644 --- a/lib/presentation/molecules/devices/boiler_molecule.dart +++ b/lib/presentation/molecules/devices/boiler_molecule.dart @@ -74,7 +74,7 @@ class _BoilerMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.boiler, diff --git a/lib/presentation/molecules/devices/dimmable_light_molecule.dart b/lib/presentation/molecules/devices/dimmable_light_molecule.dart index e410d97f..e7a5e3da 100644 --- a/lib/presentation/molecules/devices/dimmable_light_molecule.dart +++ b/lib/presentation/molecules/devices/dimmable_light_molecule.dart @@ -21,15 +21,36 @@ class DimmableLightMolecule extends StatefulWidget { class _DimmableLightMoleculeState extends State { double brightness = 100; + @override + void initState() { + super.initState(); + _initialized(); + } + + Future _initialized() async { + final GenericDimmableLightDE rgbwLightDe = widget.entity; + + double lightBrightness = + double.parse(rgbwLightDe.lightBrightness.getOrCrash()); + + if (lightBrightness > 100) { + lightBrightness = 100; + } + + setState(() { + brightness = lightBrightness; + }); + } + Future _changeBrightness(double value) async { setState(() { brightness = value; }); - final HashMap hashValue = - HashMap() + final HashMap hashValue = + HashMap() ..addEntries([ - MapEntry(ActionValues.brightness, value.round().toString()), + MapEntry(ActionValues.brightness, value.round()), ]); setEntityState( @@ -86,7 +107,7 @@ class _DimmableLightMoleculeState extends State { return Column( children: [ - DeviceNameRow( + DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.light, diff --git a/lib/presentation/molecules/devices/light_molecule.dart b/lib/presentation/molecules/devices/light_molecule.dart index 5ed44e2d..62539a5e 100644 --- a/lib/presentation/molecules/devices/light_molecule.dart +++ b/lib/presentation/molecules/devices/light_molecule.dart @@ -45,7 +45,7 @@ class LightMolecule extends StatelessWidget { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.light, diff --git a/lib/presentation/molecules/devices/printer_molecule.dart b/lib/presentation/molecules/devices/printer_molecule.dart index a6e4efcb..49637125 100644 --- a/lib/presentation/molecules/devices/printer_molecule.dart +++ b/lib/presentation/molecules/devices/printer_molecule.dart @@ -33,7 +33,7 @@ class _PrinterMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, TextButton( style: ButtonStyle( diff --git a/lib/presentation/molecules/devices/rgb_light_molecule.dart b/lib/presentation/molecules/devices/rgb_light_molecule.dart index b06e2c2e..bff49486 100644 --- a/lib/presentation/molecules/devices/rgb_light_molecule.dart +++ b/lib/presentation/molecules/devices/rgb_light_molecule.dart @@ -111,7 +111,7 @@ class _RgbwLightMoleculeState extends State { return Column( children: [ - DeviceNameRow( + DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.light, diff --git a/lib/presentation/molecules/devices/security_camera_molecule.dart b/lib/presentation/molecules/devices/security_camera_molecule.dart index a0d481b8..f530314a 100644 --- a/lib/presentation/molecules/devices/security_camera_molecule.dart +++ b/lib/presentation/molecules/devices/security_camera_molecule.dart @@ -33,7 +33,7 @@ class _SecurityCameraMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, TextButton( style: ButtonStyle( diff --git a/lib/presentation/molecules/devices/smart_computer_molecule.dart b/lib/presentation/molecules/devices/smart_computer_molecule.dart index d1059909..f30f7c3a 100644 --- a/lib/presentation/molecules/devices/smart_computer_molecule.dart +++ b/lib/presentation/molecules/devices/smart_computer_molecule.dart @@ -48,7 +48,7 @@ class _SmartComputerMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/presentation/molecules/devices/smart_plug_molecule.dart b/lib/presentation/molecules/devices/smart_plug_molecule.dart index 2e648141..a215944c 100644 --- a/lib/presentation/molecules/devices/smart_plug_molecule.dart +++ b/lib/presentation/molecules/devices/smart_plug_molecule.dart @@ -55,7 +55,7 @@ class _SmartPlugsMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.smartPlug, diff --git a/lib/presentation/molecules/devices/smart_tv_molecule.dart b/lib/presentation/molecules/devices/smart_tv_molecule.dart index 52429214..750c5d80 100644 --- a/lib/presentation/molecules/devices/smart_tv_molecule.dart +++ b/lib/presentation/molecules/devices/smart_tv_molecule.dart @@ -280,7 +280,7 @@ class _SmartTvMoleculeState extends State { Widget build(BuildContext context) { return Column( children: [ - DeviceNameRow( + DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, const SizedBox(), ), diff --git a/lib/presentation/molecules/devices/switch_molecule.dart b/lib/presentation/molecules/devices/switch_molecule.dart index 77bee751..af5f09ed 100644 --- a/lib/presentation/molecules/devices/switch_molecule.dart +++ b/lib/presentation/molecules/devices/switch_molecule.dart @@ -55,7 +55,7 @@ class _SwitchMoleculeState extends State { @override Widget build(BuildContext context) { - return DeviceNameRow( + return DeviceNameRowMolecule( widget.entity.cbjEntityName.getOrCrash()!, SwitchAtom( variant: SwitchVariant.switchVariant, diff --git a/lib/presentation/molecules/insert_login_molecule.dart b/lib/presentation/molecules/insert_login_molecule.dart new file mode 100644 index 00000000..bf48c770 --- /dev/null +++ b/lib/presentation/molecules/insert_login_molecule.dart @@ -0,0 +1,104 @@ +import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; +import 'package:flutter/material.dart'; + +class InsertLoginMolecule extends StatefulWidget { + const InsertLoginMolecule({ + required this.type, + required this.vendorsAndServices, + required this.onChange, + }); + + final InsertloginMoleculeType type; + final VendorsAndServices vendorsAndServices; + final Function(VendorLoginEntity) onChange; + + @override + State createState() => _InsertLoginMoleculeState(); +} + +class _InsertLoginMoleculeState extends State { + late VendorLoginEntity loginEntity; + + @override + void initState() { + super.initState(); + loginEntity = VendorLoginEntity(widget.vendorsAndServices); + } + + void onEmailChange(String value) { + loginEntity = loginEntityCopyWith(loginEntity: loginEntity, email: value); + + widget.onChange(loginEntity); + } + + void onPasswordChange(String value) { + loginEntity = + loginEntityCopyWith(loginEntity: loginEntity, password: value); + + widget.onChange(loginEntity); + } + + void onApiKeyChange(String value) { + loginEntity = loginEntityCopyWith(loginEntity: loginEntity, apiKey: value); + + widget.onChange(loginEntity); + } + + void onAuthTokenChange(String value) { + loginEntity = + loginEntityCopyWith(loginEntity: loginEntity, authToken: value); + + widget.onChange(loginEntity); + } + + VendorLoginEntity loginEntityCopyWith({ + required VendorLoginEntity loginEntity, + String? apiKey, + String? authToken, + String? email, + String? password, + }) => + VendorLoginEntity( + loginEntity.vendor, + apiKey: apiKey ?? loginEntity.apiKey, + authToken: authToken ?? loginEntity.authToken, + email: email ?? loginEntity.email, + password: password ?? loginEntity.password, + ); + + @override + Widget build(BuildContext context) { + switch (widget.type) { + case InsertloginMoleculeType.authToken: + return TextFormFieldAtom( + onChanged: onAuthTokenChange, + labelText: 'Auth Token', + ); + case InsertloginMoleculeType.apiKey: + return TextFormFieldAtom( + onChanged: onApiKeyChange, + labelText: 'Api Key', + ); + case InsertloginMoleculeType.emailAndPassword: + return Column( + children: [ + TextFormFieldAtom( + onChanged: onEmailChange, + labelText: 'Email', + ), + TextFormFieldAtom( + onChanged: onPasswordChange, + labelText: 'Password', + ), + ], + ); + } + } +} + +enum InsertloginMoleculeType { + authToken, + apiKey, + emailAndPassword, +} diff --git a/lib/presentation/molecules/molecules.dart b/lib/presentation/molecules/molecules.dart index f90f49b3..fedd80a8 100644 --- a/lib/presentation/molecules/molecules.dart +++ b/lib/presentation/molecules/molecules.dart @@ -1,6 +1,6 @@ export 'bottom_navigation_bar_molecule.dart'; export 'device_by_type_molecule.dart'; -export 'device_name_row.dart'; +export 'device_name_row_molecule.dart'; export 'devices/ac_molecule.dart'; export 'devices/blind_molecule.dart'; export 'devices/blinds_card_molecule.dart'; @@ -15,8 +15,9 @@ export 'devices/smart_computer_molecule.dart'; export 'devices/smart_plug_molecule.dart'; export 'devices/smart_tv_molecule.dart'; export 'devices/switch_molecule.dart'; +export 'insert_login_molecule.dart'; export 'list_tile_molecule.dart'; export 'list_view_molecule.dart'; export 'loading_page_molecule.dart'; -export 'scenes_grid.dart'; +export 'scenes_grid_molecule.dart'; export 'top_bar_molecule.dart'; diff --git a/lib/presentation/molecules/scenes_grid.dart b/lib/presentation/molecules/scenes_grid_molecule.dart similarity index 82% rename from lib/presentation/molecules/scenes_grid.dart rename to lib/presentation/molecules/scenes_grid_molecule.dart index 131fbb10..3fcb78b1 100644 --- a/lib/presentation/molecules/scenes_grid.dart +++ b/lib/presentation/molecules/scenes_grid_molecule.dart @@ -2,16 +2,16 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:flutter/material.dart'; -class ScenesGrid extends StatefulWidget { - const ScenesGrid({required this.scenes}); +class ScenesGridMolecule extends StatefulWidget { + const ScenesGridMolecule({required this.scenes}); final List scenes; @override - State createState() => _ScenesGridState(); + State createState() => _ScenesGridMoleculeState(); } -class _ScenesGridState extends State { +class _ScenesGridMoleculeState extends State { late AreaEntity folderOfScenes; @override diff --git a/lib/presentation/pages/home_page/tabs/scenes_in_folders_tab/scenes_in_folders_tab.dart b/lib/presentation/pages/home_page/tabs/scenes_in_folders_tab/scenes_in_folders_tab.dart index 577f77a2..dce8ec8f 100644 --- a/lib/presentation/pages/home_page/tabs/scenes_in_folders_tab/scenes_in_folders_tab.dart +++ b/lib/presentation/pages/home_page/tabs/scenes_in_folders_tab/scenes_in_folders_tab.dart @@ -97,7 +97,7 @@ class ScenesInFoldersTab extends StatelessWidget { leftIconFunction: (BuildContext context) {}, ), Expanded( - child: ScenesGrid( + child: ScenesGridMolecule( scenes: scenes!.values.toList(), ), ), diff --git a/lib/presentation/pages/login_vendor_page.dart b/lib/presentation/pages/login_vendor_page.dart index 6d89125a..beffa50d 100644 --- a/lib/presentation/pages/login_vendor_page.dart +++ b/lib/presentation/pages/login_vendor_page.dart @@ -3,8 +3,8 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/domain/connections_service.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; +import 'package:cybearjinni/presentation/molecules/molecules.dart'; import 'package:flutter/material.dart'; -import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:url_launcher/url_launcher.dart'; @RoutePage() @@ -18,23 +18,44 @@ class LoginVendorPage extends StatefulWidget { } class _LoginVendorPageState extends State { - String? apiKey; + VendorLoginEntity? loginEntity; Future _signInWithApiKey() async { + if (loginEntity == null) { + return; + } + SnackBarService().show( context, 'Sign in to ${widget.vendorInformation.displayName}, devices will appear in the shortly', ); - ConnectionsService.instance.loginVendor( - VendorLoginEntity( - widget.vendorInformation.vendorsAndServices, - apiKey: apiKey, - ), - ); + ConnectionsService.instance.loginVendor(loginEntity!); context.router.pop(); } + Widget authTypeWidget() { + InsertloginMoleculeType type; + switch (widget.vendorInformation.loginType) { + case VendorLoginTypes.notNeeded: + return const TextAtom('Not needed'); + case VendorLoginTypes.authToken: + type = InsertloginMoleculeType.authToken; + case VendorLoginTypes.apiKey: + type = InsertloginMoleculeType.apiKey; + + case VendorLoginTypes.emailAndPassword: + type = InsertloginMoleculeType.emailAndPassword; + } + return InsertLoginMolecule( + type: type, + vendorsAndServices: widget.vendorInformation.vendorsAndServices, + onChange: (VendorLoginEntity value) { + loginEntity = value; + }, + ); + } + @override Widget build(BuildContext context) { final Size screenSize = MediaQuery.of(context).size; @@ -72,16 +93,7 @@ class _LoginVendorPageState extends State { const SizedBox( height: 8, ), - TextFormField( - decoration: const InputDecoration( - prefixIcon: FaIcon(FontAwesomeIcons.key), - labelText: 'value', - ), - autocorrect: false, - onChanged: (value) { - apiKey = value; - }, - ), + authTypeWidget(), const SizedBox( height: 8, ), @@ -107,8 +119,11 @@ class _LoginVendorPageState extends State { backgroundColor: MaterialStateProperty.all(Colors.pink), ), onPressed: () { - launchUrl(Uri.parse( - widget.vendorInformation.urlToLoginCredantials!)); + launchUrl( + Uri.parse( + widget.vendorInformation.urlToLoginCredantials!, + ), + ); }, child: TextAtom( widget.vendorInformation.loginType.name, diff --git a/lib/presentation/pages/scenes/scenes_page.dart b/lib/presentation/pages/scenes/scenes_page.dart index 12ab9dcf..6e77c17a 100644 --- a/lib/presentation/pages/scenes/scenes_page.dart +++ b/lib/presentation/pages/scenes/scenes_page.dart @@ -107,7 +107,7 @@ class _ScenesPageState extends State { // rightSecondIcon: FontAwesomeIcons.magnifyingGlass, ), Expanded( - child: ScenesGrid( + child: ScenesGridMolecule( scenes: scenes!.values.toList(), ), ), From ca02e275c4adf8d131ed0a598d0e8ba6ebd281d1 Mon Sep 17 00:00:00 2001 From: Guy Luz Date: Sat, 13 Jan 2024 17:06:22 +0200 Subject: [PATCH 4/9] wip Hub support --- lib/domain/connections_service.dart | 24 +- lib/domain/i_hub_connection_repository.dart | 1 + .../app_connection_service.dart | 3 + .../demo_connection_service.dart | 3 + .../hub_connection_service.dart | 287 ++++++++++++++++++ .../none_connection_service.dart | 3 + .../hub_client/hub_connection_repository.dart | 54 ++-- lib/presentation/core/routes/app_router.dart | 1 + .../computer_connection_check_widget.dart | 5 +- .../configure_new_cbj_comp_widget.dart | 3 +- .../pages/comunication_method_page.dart | 61 ++++ .../pages/home_page/home_page.dart | 4 + lib/presentation/pages/plus_button.dart | 48 ++- 13 files changed, 437 insertions(+), 60 deletions(-) create mode 100644 lib/infrastructure/connection_service/hub_connection_service.dart create mode 100644 lib/presentation/pages/comunication_method_page.dart diff --git a/lib/domain/connections_service.dart b/lib/domain/connections_service.dart index 0c4a1e42..b3b31239 100644 --- a/lib/domain/connections_service.dart +++ b/lib/domain/connections_service.dart @@ -1,10 +1,24 @@ import 'dart:async'; import 'dart:collection'; +import 'dart:io'; import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:cybearjinni/infrastructure/core/injection.dart'; +import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:cybearjinni/infrastructure/network_utilities_flutter.dart'; +import 'package:dartz/dartz.dart'; +import 'package:flutter/foundation.dart'; +import 'package:grpc/grpc.dart'; +import 'package:location/location.dart'; +import 'package:network_info_plus/network_info_plus.dart'; +import 'package:network_tools_flutter/network_tools_flutter.dart'; +import 'package:permission_handler/permission_handler.dart' + as permission_handler; +import 'package:rxdart/rxdart.dart'; part 'package:cybearjinni/infrastructure/connection_service/app_connection_service.dart'; +part 'package:cybearjinni/infrastructure/connection_service/hub_connection_service.dart'; part 'package:cybearjinni/infrastructure/connection_service/demo_connection_service.dart'; part 'package:cybearjinni/infrastructure/connection_service/none_connection_service.dart'; @@ -30,13 +44,16 @@ abstract interface class ConnectionsService { if (connectionType == _currentConnectionType) { return; } - final ConnectionsService? oldInstance = _instance; + _instance?.dispose(); + switch (connectionType) { case ConnectionType.appAsHub: _instance = _AppConnectionService(); _currentConnectionType = ConnectionType.appAsHub; - case ConnectionType.demo: case ConnectionType.hub: + _currentConnectionType = ConnectionType.hub; + _instance = _HubConnectionService(); + case ConnectionType.demo: case ConnectionType.remotePipes: _instance = _DemoConnectionService(); _currentConnectionType = ConnectionType.demo; @@ -45,11 +62,12 @@ abstract interface class ConnectionsService { _instance = _NoneConnectionService(); _currentConnectionType = ConnectionType.none; } - oldInstance?.dispose(); } static ConnectionType getCurrentConnectionType() => _currentConnectionType; + Future connect(); + Future searchDevices(); void setEntityState(ActionObject action); diff --git a/lib/domain/i_hub_connection_repository.dart b/lib/domain/i_hub_connection_repository.dart index 40cd72a8..a61938f9 100644 --- a/lib/domain/i_hub_connection_repository.dart +++ b/lib/domain/i_hub_connection_repository.dart @@ -5,6 +5,7 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:cybearjinni/domain/i_local_db_repository.dart'; import 'package:cybearjinni/infrastructure/core/injection.dart'; +import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:dartz/dartz.dart'; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:location/location.dart'; diff --git a/lib/infrastructure/connection_service/app_connection_service.dart b/lib/infrastructure/connection_service/app_connection_service.dart index 620e997a..67e6f712 100644 --- a/lib/infrastructure/connection_service/app_connection_service.dart +++ b/lib/infrastructure/connection_service/app_connection_service.dart @@ -61,4 +61,7 @@ class _AppConnectionService implements ConnectionsService { @override Future> getVendors() async => IcSynchronizer().getVendors(); + + @override + Future connect() async => true; } diff --git a/lib/infrastructure/connection_service/demo_connection_service.dart b/lib/infrastructure/connection_service/demo_connection_service.dart index f23916c0..72c6522c 100644 --- a/lib/infrastructure/connection_service/demo_connection_service.dart +++ b/lib/infrastructure/connection_service/demo_connection_service.dart @@ -59,4 +59,7 @@ class _DemoConnectionService implements ConnectionsService { @override Future> getVendors() async => IcSynchronizer().getVendors(); + + @override + Future connect() async => true; } diff --git a/lib/infrastructure/connection_service/hub_connection_service.dart b/lib/infrastructure/connection_service/hub_connection_service.dart new file mode 100644 index 00000000..78a6d603 --- /dev/null +++ b/lib/infrastructure/connection_service/hub_connection_service.dart @@ -0,0 +1,287 @@ +part of 'package:cybearjinni/domain/connections_service.dart'; + +class _HubConnectionService implements ConnectionsService { + _HubConnectionService() { + if (currentEnvApp == EnvApp.prod) { + hubPort = 50055; + } else { + hubPort = 60055; + } + } + + /// Port to connect to the cbj hub, will change according to the current + /// running environment + late int hubPort; + + String? hubIp; + String? networkBssid; + String? networkName; + + ClientChannel? channel; + CbjHubClient? stub; + + StreamController>? entitiesStream; + StreamController>? areasStream; + + BehaviorSubject hubMessagesToApp = + BehaviorSubject(); + + // StreamController appMessagesToHub = + // StreamController(); + + BehaviorSubject appMessagesToHub = BehaviorSubject(); + + @override + Future dispose() async { + entitiesStream?.close(); + } + + @override + Future> get getAllEntities async { + appMessagesToHub.sink + .add(ClientStatusRequests(sendingType: SendingType.firstConnection)); + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + logger.i('message from hub is $message'); + } + return HashMap(); + } + + @override + Future> get getAllAreas async => HashMap(); + + @override + Future searchDevices() async { + try { + final Either locationRequest = + await askLocationPermissionAndLocationOn(); + + if (locationRequest.isLeft()) { + return locationRequest; + } + + logger.i('searchForHub'); + String? appDeviceIp; + if (await Connectivity().checkConnectivity() == ConnectivityResult.wifi && + !kIsWeb) { + final NetworkInfo networkInfo = NetworkInfo(); + networkName = await networkInfo.getWifiName(); + appDeviceIp = await networkInfo.getWifiIP(); + networkBssid = await networkInfo.getWifiBSSID(); + } else { + return false; + // if (deviceIpOnTheNetwork == null) { + // // Issue https://github.com/CyBear-Jinni/cbj_app/issues/256 + // return left( + // const HubFailures + // .findingHubWhenConnectedToEthernetCableIsNotSupported(), + // ); + // } + + // currentDeviceIP = deviceIpOnTheNetwork; + // networkBSSID = 'no:Network:Bssid:Found'; + // networkName = 'noNetworkNameFound'; + // if (isThatTheIpOfTheHub != null && isThatTheIpOfTheHub) { + // return insertHubInfo( + // networkIp: currentDeviceIP, + // networkBSSID: networkBSSID, + // networkName: networkName, + // ); + // } + } + if (appDeviceIp == null) { + return false; + } + final String subnet = + appDeviceIp.substring(0, appDeviceIp.lastIndexOf('.')); + + logger.i('Hub Search subnet IP $subnet'); + + // TODO: Search for hub + final Stream devicesWithPort = + HostScanner.scanDevicesForSinglePort( + subnet, + hubPort, + + /// TODO: return this settings when can use with the await for loop + // resultsInIpAscendingOrder: false, + timeout: const Duration(milliseconds: 600), + ); + + await for (final ActiveHost activeHost in devicesWithPort) { + logger.i('Found Cbj Hub device: ${activeHost.address}'); + hubIp = activeHost.address; + return true; + // if (networkBSSID != null && networkName != null) { + // return insertHubInfo( + // networkIp: activeHost.address, + // networkBSSID: networkBSSID, + // networkName: networkName, + // ); + // } + } + } catch (e) { + logger.w('Exception searchForHub\n$e'); + } + } + + @override + void setEntityState(ActionObject action) {} + + @override + Stream> watchEntities() { + entitiesStream?.close(); + + entitiesStream = StreamController.broadcast(); + return entitiesStream!.stream; + } + + @override + Stream> watchAreas() { + areasStream?.close(); + + areasStream = StreamController.broadcast(); + return areasStream!.stream; + } + + @override + Future setNewArea(AreaEntity area) async {} + + @override + Future setEtitiesToArea(String areaId, HashSet entities) async {} + + @override + Future addScene(SceneCbjEntity scene) async {} + + @override + Future> getScenes() async => HashMap(); + + @override + Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => + IcSynchronizer().getVendors(); + + @override + Future connect() async { + searchDevices(); + if (hubIp == null) { + return false; + } + + connectDirectlyToHub(); + + return true; + } + + Future> askLocationPermissionAndLocationOn() async { + final Location location = Location(); + + bool serviceEnabled; + PermissionStatus permissionGranted; + + int permissionCounter = 0; + int disabledCounter = 0; + + // Get location permission is not supported on Linux + if (Platform.isLinux || Platform.isWindows) { + return right(unit); + } + + while (true) { + permissionGranted = await location.hasPermission(); + if (permissionGranted == PermissionStatus.denied) { + permissionGranted = await location.requestPermission(); + if (permissionGranted != PermissionStatus.granted) { + logger.e('Permission to use location is denied'); + await Future.delayed(const Duration(seconds: 10)); + + permissionCounter++; + if (permissionCounter > 5) { + permission_handler.openAppSettings(); + } else if (permissionCounter > 7) { + return const Left(HubFailures.unexpected()); + } + continue; + } + } + + serviceEnabled = await location.serviceEnabled(); + if (!serviceEnabled) { + serviceEnabled = await location.requestService(); + if (!serviceEnabled) { + disabledCounter++; + if (disabledCounter > 2) { + return const Left(HubFailures.unexpected()); + } + logger.w('Location is disabled'); + await Future.delayed(const Duration(seconds: 5)); + continue; + } + } + break; + } + return right(unit); + } + + /// Connect directly to the Hub if possible + Future connectDirectlyToHub() async { + if (hubIp == null) { + return; + } + + // Socket? testHubConnection; + // try { + // testHubConnection = await Socket.connect( + // hubIP, + // hubPort, + // timeout: const Duration(milliseconds: 500), + // ); + // await testHubConnection.close(); + // testHubConnection.destroy(); + // testHubConnection = null; + // } catch (e) { + // await testHubConnection?.close(); + // testHubConnection?.destroy(); + // } + + try { + // // TODO: DELTE + // await HubClient.createStreamWithHub( + // hubIp!, + // hubPort, + // ); + + channel = ClientChannel( + hubIp!, + port: hubPort, + options: + const ChannelOptions(credentials: ChannelCredentials.insecure()), + ); + + channel!.onConnectionStateChanged.listen((event) { + logger.i('gRPC connection state $event'); + }); + + stub = CbjHubClient(channel!); + + final ResponseStream response = + stub!.clientTransferEntities( + appMessagesToHub.stream, + ); + + // appMessagesToHub.sink + // .add(ClientStatusRequests(sendingType: SendingType.firstConnection)); + + hubMessagesToApp.addStream(response); + await Future.delayed(const Duration(seconds: 3)); + } catch (e) { + logger.e('Caught error while stream with hub\n$e'); + await channel?.shutdown(); + } + } +} diff --git a/lib/infrastructure/connection_service/none_connection_service.dart b/lib/infrastructure/connection_service/none_connection_service.dart index d3a8f8d1..8e8555db 100644 --- a/lib/infrastructure/connection_service/none_connection_service.dart +++ b/lib/infrastructure/connection_service/none_connection_service.dart @@ -58,4 +58,7 @@ class _NoneConnectionService implements ConnectionsService { @override Future> getVendors() async => []; + + @override + Future connect() async => true; } diff --git a/lib/infrastructure/hub_client/hub_connection_repository.dart b/lib/infrastructure/hub_client/hub_connection_repository.dart index 2c2b24a4..629ca963 100644 --- a/lib/infrastructure/hub_client/hub_connection_repository.dart +++ b/lib/infrastructure/hub_client/hub_connection_repository.dart @@ -43,7 +43,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { try { connectivityResult = await Connectivity().checkConnectivity(); } catch (e) { - icLogger.w('Cant check connectivity this is probably PC, error\n$e'); + logger.w('Cant check connectivity this is probably PC, error\n$e'); } // Last Number of bssid can change fix?, need to check if more numbers @@ -59,7 +59,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { wifiBSSIDWithoutLastNumber = wifiBSSID?.substring(0, wifiBSSID.lastIndexOf(':')); } catch (e) { - icLogger.w("Can't get WiFi BSSID"); + logger.w("Can't get WiFi BSSID"); } final Either remotePipesInformation = await ILocalDbRepository.instance.getRemotePipesDnsName(); @@ -81,14 +81,14 @@ class _HubConnectionRepository implements IHubConnectionRepository { (kIsWeb && savedWifiBssidWithoutLastNumber == 'no:Network:Bssid')) { (await openAndroidWifiSettingIfPossible()).fold( (l) { - icLogger + logger .w('No way to establish connection with the Hub, WiFi or location' ' permission is closed for here'); return; }, (r) async {}, ); - icLogger.i('Connect using direct connection to Hub'); + logger.i('Connect using direct connection to Hub'); await connectDirectlyToHub(); return; @@ -126,7 +126,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { networkName: hubNetworkName!, ).toDomain(); } catch (e) { - icLogger.e('Crashed while setting Hub info from local db\n$e'); + logger.e('Crashed while setting Hub info from local db\n$e'); } } @@ -134,7 +134,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { try { connectivityResult = await Connectivity().checkConnectivity(); } catch (e) { - icLogger.w('Cant check connectivity this is probably PC, error\n$e'); + logger.w('Cant check connectivity this is probably PC, error\n$e'); } // Last Number of bssid can change fix?, need to check if more numbers @@ -158,7 +158,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { savedWifiBssidWithoutLastNumber != null && wifiBSSIDWithoutLastNumber != null && savedWifiBssidWithoutLastNumber == wifiBSSIDWithoutLastNumber) { - icLogger.i('Connect using direct connection to Hub'); + logger.i('Connect using direct connection to Hub'); if (IHubConnectionRepository.hubEntity?.lastKnownIp.getOrCrash() != null) { @@ -191,16 +191,16 @@ class _HubConnectionRepository implements IHubConnectionRepository { } return right(compHubInfo); } catch (e) { - icLogger.e('Error getting hubInfo\n$e'); + logger.e('Error getting hubInfo\n$e'); return left(const HubFailures.unexpected()); } // return; } else { - icLogger.i('Connect using Remote Pipes'); + logger.i('Connect using Remote Pipes'); return (await ILocalDbRepository.instance.getRemotePipesDnsName()).fold( (l) { - icLogger.e('Cant find local Remote Pipes Dns name'); + logger.e('Cant find local Remote Pipes Dns name'); return left(const HubFailures.unexpected()); }, (r) async { try { @@ -212,7 +212,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { } return right(compHubInfo); } catch (e) { - icLogger.e('Error getting hubInfo\n$e'); + logger.e('Error getting hubInfo\n$e'); return left(const HubFailures.unexpected()); } }); @@ -250,7 +250,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { ResourceRecordQuery.addressIPv4(mDnsName), )) { deviceIp = record.address.address; - icLogger.i('Found address (${record.address}).'); + logger.i('Found address (${record.address}).'); } // await for (final IPAddressResourceRecord record @@ -261,7 +261,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { client.stop(); - icLogger.t('Done.'); + logger.t('Done.'); return deviceIp; } @@ -279,7 +279,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { return locationRequest; } - icLogger.i('searchForHub'); + logger.i('searchForHub'); String? currentDeviceIP; String? networkBSSID; @@ -314,7 +314,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { final String subnet = currentDeviceIP!.substring(0, currentDeviceIP.lastIndexOf('.')); - icLogger.i('Hub Search subnet IP $subnet'); + logger.i('Hub Search subnet IP $subnet'); // TODO: Search for hub // final Stream devicesWithPort = @@ -328,7 +328,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { // ); // await for (final ActiveHost activeHost in devicesWithPort) { - // icLogger.i('Found Cbj Hub device: ${activeHost.address}'); + // logger.i('Found Cbj Hub device: ${activeHost.address}'); // if (networkBSSID != null && networkName != null) { // return insertHubInfo( // networkIp: activeHost.address, @@ -338,7 +338,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { // } // } } catch (e) { - icLogger.w('Exception searchForHub\n$e'); + logger.w('Exception searchForHub\n$e'); } await Future.delayed(const Duration(seconds: 5)); return left(const HubFailures.cantFindHubInNetwork()); @@ -346,7 +346,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { @override Future saveHubIP(String hubIP) async { - icLogger.w('saveHubIP'); + logger.w('saveHubIP'); } Future> askLocationPermissionAndLocationOn() async { @@ -368,7 +368,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { if (permissionGranted == PermissionStatus.denied) { permissionGranted = await location.requestPermission(); if (permissionGranted != PermissionStatus.granted) { - icLogger.e('Permission to use location is denied'); + logger.e('Permission to use location is denied'); await Future.delayed(const Duration(seconds: 10)); permissionCounter++; @@ -389,7 +389,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { if (disabledCounter > 2) { return const Left(HubFailures.unexpected()); } - icLogger.w('Location is disabled'); + logger.w('Location is disabled'); await Future.delayed(const Duration(seconds: 5)); continue; } @@ -420,8 +420,8 @@ class _HubConnectionRepository implements IHubConnectionRepository { lastKnownIp: hubDtos.lastKnownIp, )) .fold( - (l) => icLogger.e('Cant find local Remote Pipes Dns name'), - (r) => icLogger.i('Found CyBear Jinni Hub'), + (l) => logger.e('Cant find local Remote Pipes Dns name'), + (r) => logger.i('Found CyBear Jinni Hub'), ); return right(unit); } @@ -457,7 +457,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { networkName: hubNetworkName!, ).toDomain(); } catch (e) { - icLogger.e('Crashed while setting Hub info from local db\n$e'); + logger.e('Crashed while setting Hub info from local db\n$e'); } } @@ -508,7 +508,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { (l) async { (await openAndroidWifiSettingIfPossible()).fold( (l) { - icLogger.w( + logger.w( 'No way to establish connection with the Hub, WiFi or location' ' permission is closed'); }, @@ -518,7 +518,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { ); }, (r) { - icLogger.i('Connect using Remote Pipes'); + logger.i('Connect using Remote Pipes'); HubClient.createStreamWithHub(r, 50056); tryAgainConnectToTheHubOnceMore = 0; }, @@ -556,7 +556,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { // } // } } else { - icLogger.w( + logger.w( 'Will ask the user to open WiFi and gps to try local connection', ); final bool wifiEnabled = await WiFiForIoTPlugin.isEnabled(); @@ -568,7 +568,7 @@ class _HubConnectionRepository implements IHubConnectionRepository { } (await askLocationPermissionAndLocationOn()).fold((l) { - icLogger.e( + logger.e( 'User does not allow opening location and does not have remote pipes info', ); }, (r) async { diff --git a/lib/presentation/core/routes/app_router.dart b/lib/presentation/core/routes/app_router.dart index 903ba0d9..beda6cc6 100644 --- a/lib/presentation/core/routes/app_router.dart +++ b/lib/presentation/core/routes/app_router.dart @@ -32,6 +32,7 @@ class AppRouter extends $AppRouter { AutoRoute(page: EntitiesInNetworkRoute.page), AutoRoute(page: EntitiesInAreaRoute.page), AutoRoute(page: LoginVendorRoute.page), + AutoRoute(page: ComunicationMethodRoute.page), // Pages from packages AutoRoute(page: SmartCameraContainerRoute.page), diff --git a/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart b/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart index c5de27c4..8e734e0f 100644 --- a/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart @@ -7,6 +7,7 @@ import 'package:cybearjinni/domain/cbj_comp/i_cbj_comp_repository.dart'; import 'package:cybearjinni/domain/manage_network/i_manage_network_repository.dart'; import 'package:cybearjinni/domain/manage_network/manage_network_entity.dart'; import 'package:cybearjinni/domain/security_bear/i_security_bear_connection_repository.dart'; +import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart'; import 'package:dartz/dartz.dart' as dartz; @@ -61,7 +62,7 @@ class _ComputerConnectionCheckWidgetState } bool isConnectedToWifi = false; - icLogger.i('Waiting for user to get connected to WiFi'); + logger.i('Waiting for user to get connected to WiFi'); while (true) { isConnectedToWifi = await WiFiForIoTPlugin.isConnected(); @@ -124,7 +125,7 @@ class _ComputerConnectionCheckWidgetState deviceE..cbjEntityName = CbjEntityName(deviceName), ); } catch (e) { - icLogger.w("Can't add unsupported device"); + logger.w("Can't add unsupported device"); } }); final CbjCompEntity compUpdatedData = cbjCompEntity.copyWith( diff --git a/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart b/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart index d892863e..ee1affc7 100644 --- a/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart @@ -8,6 +8,7 @@ import 'package:cybearjinni/domain/manage_network/i_manage_network_repository.da import 'package:cybearjinni/domain/manage_network/manage_network_entity.dart'; import 'package:cybearjinni/domain/security_bear/i_security_bear_connection_repository.dart'; import 'package:cybearjinni/domain/security_bear/security_bear_failures.dart'; +import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/routes/app_router.gr.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; @@ -112,7 +113,7 @@ class _ConfigureNewCbjCompWidgetsState deviceE..cbjEntityName = CbjEntityName(deviceName), ); } catch (e) { - icLogger.w("Can't add unsupported device"); + logger.w("Can't add unsupported device"); } }); final CbjCompEntity compUpdatedData = cbjCompEntity.copyWith( diff --git a/lib/presentation/pages/comunication_method_page.dart b/lib/presentation/pages/comunication_method_page.dart new file mode 100644 index 00000000..63c8ba6c --- /dev/null +++ b/lib/presentation/pages/comunication_method_page.dart @@ -0,0 +1,61 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; +import 'package:cybearjinni/presentation/atoms/atoms.dart'; +import 'package:cybearjinni/presentation/core/routes/app_router.gr.dart'; +import 'package:cybearjinni/presentation/organisms/organisms.dart'; +import 'package:flutter/material.dart'; + +@RoutePage() +class ComunicationMethodPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return PageOrganism( + pageName: 'Comunication type', + child: Column( + children: [ + const TextAtom('Chose comunication Method'), + TextAtom( + 'Current comunication: ${ConnectionsService.getCurrentConnectionType()}', + ), + Expanded( + child: Column( + children: [ + ButtonWidgetAtom( + variant: ButtonVariant.primary, + text: 'App as a Hub', + onPressed: () => ConnectionsService.setCurrentConnectionType( + ConnectionType.appAsHub, + ), + ), + ButtonWidgetAtom( + variant: ButtonVariant.primary, + text: 'Hub', + onPressed: () { + ConnectionsService.setCurrentConnectionType( + ConnectionType.hub, + ); + ConnectionsService.instance.connect(); + }, + ), + ButtonWidgetAtom( + variant: ButtonVariant.primary, + text: 'Demo', + onPressed: () => ConnectionsService.setCurrentConnectionType( + ConnectionType.demo, + ), + ), + ], + ), + ), + ButtonWidgetAtom( + variant: ButtonVariant.primary, + text: 'Insert Remote Pipes', + onPressed: () { + context.router.push(const RemotePipesRoute()); + }, + ), + ], + ), + ); + } +} diff --git a/lib/presentation/pages/home_page/home_page.dart b/lib/presentation/pages/home_page/home_page.dart index de48cccd..13b50c09 100644 --- a/lib/presentation/pages/home_page/home_page.dart +++ b/lib/presentation/pages/home_page/home_page.dart @@ -210,7 +210,11 @@ class _HomePageState extends State { GestureDetector( onTap: () async { await context.router.push(const PlusButtonRoute()); + areas = null; + entities = null; _initialzeAreas(); + _initialzeEntities(); + initializedScenes(); }, child: CircleAvatar( diff --git a/lib/presentation/pages/plus_button.dart b/lib/presentation/pages/plus_button.dart index cc95ceb5..0d8d0369 100644 --- a/lib/presentation/pages/plus_button.dart +++ b/lib/presentation/pages/plus_button.dart @@ -94,31 +94,6 @@ class PlusButtonPage extends StatelessWidget { }, ), ), - if (ConnectionsService.getCurrentConnectionType() == - ConnectionType.hub) ...[ - const SizedBox(height: 1), - ColoredBox( - color: Colors.blue, - child: ListTile( - leading: FaIcon( - FontAwesomeIcons.globe, - color: colorScheme.background, - ), - title: TextAtom( - 'Add Remote Control Support', - style: TextStyle( - color: Theme.of(context) - .textTheme - .bodyLarge! - .color, - ), - ), - onTap: () { - context.router.push(const RemotePipesRoute()); - }, - ), - ), - ], const SizedBox(height: 1), ColoredBox( color: Colors.purple.withOpacity(0.7), @@ -185,9 +160,28 @@ class PlusButtonPage extends StatelessWidget { color: Colors.white, child: Column( children: [ - const SizedBox( - height: 1, + const SizedBox(height: 1), + ColoredBox( + color: Colors.blue, + child: ListTile( + leading: FaIcon( + FontAwesomeIcons.globe, + color: colorScheme.background, + ), + title: TextAtom( + 'Comunication Method', + style: TextStyle( + color: + Theme.of(context).textTheme.bodyLarge!.color, + ), + ), + onTap: () { + context.router + .push(const ComunicationMethodRoute()); + }, + ), ), + const SizedBox(height: 1), ColoredBox( color: Colors.pink.withOpacity(0.9), child: ListTile( From 2ba7b1d8486a1902ae6801a6b6dba71ffdd8c12b Mon Sep 17 00:00:00 2001 From: Guy Luz Date: Sun, 14 Jan 2024 23:48:49 +0200 Subject: [PATCH 5/9] Adding Hub support --- lib/domain/connections_service.dart | 11 +- lib/domain/device/devices_errors.dart | 14 - lib/domain/device/devices_failures.dart | 35 - lib/domain/device/devices_validators.dart | 88 -- lib/domain/device/i_device_repository.dart | 145 --- lib/domain/i_hub_connection_repository.dart | 46 - lib/domain/i_local_db_repository.dart | 2 +- .../i_software_info_repository.dart | 1 - lib/infrastructure/cbj_app_server_d.dart | 6 +- .../app_connection_service.dart | 8 +- .../demo_connection_service.dart | 10 +- .../hub_connection_service.dart | 127 +- .../none_connection_service.dart | 11 +- lib/infrastructure/device_repository.dart | 1160 ----------------- .../hub_client/hub_connection_repository.dart | 582 --------- .../hub_client/hub_requests_routing.dart | 221 ---- .../isar_local_db/isar_repository.dart | 2 +- lib/infrastructure/mqtt.dart | 46 +- .../security_bear_connection_repository.dart | 2 +- .../software_info_repository.dart | 20 +- lib/presentation/atoms/scene_atom.dart | 2 +- .../molecules/devices/ac_molecule.dart | 6 +- .../molecules/devices/blind_molecule.dart | 8 +- .../molecules/devices/boiler_molecule.dart | 6 +- .../devices/dimmable_light_molecule.dart | 6 +- .../devices/light_card_molecule.dart | 21 +- .../molecules/devices/light_molecule.dart | 2 +- .../molecules/devices/printer_molecule.dart | 2 +- .../molecules/devices/rgb_light_molecule.dart | 18 +- .../devices/security_camera_molecule.dart | 2 +- .../devices/smart_computer_molecule.dart | 9 +- .../devices/smart_plug_molecule.dart | 4 +- .../molecules/devices/smart_tv_molecule.dart | 2 +- .../molecules/devices/switch_molecule.dart | 4 +- lib/presentation/pages/add_action_page.dart | 4 +- .../pages/add_bindings/add_binding_page.dart | 11 +- lib/presentation/pages/add_new_area_page.dart | 14 +- .../widgets/vendors_list.dart | 2 +- .../computer_connection_check_widget.dart | 4 +- .../configure_new_cbj_comp_widget.dart | 2 +- .../widgets/connect_to_home_wifi_widget.dart | 4 +- .../widgets/open_access_point_widget.dart | 4 +- .../scan_for_new_cbj_comps_widget.dart | 8 +- .../pages/add_routine/add_routine_page.dart | 11 +- .../pages/add_scene/add_scene_page.dart | 14 +- .../pages/change_area_for_devices_page.dart | 6 +- .../connect_to_hub/connect_to_hub_page.dart | 3 +- .../widgets/cbj_hub_in_network_widget.dart | 2 +- .../pages/connect_to_hub_more_page.dart | 16 +- .../pages/entities_in_area_page.dart | 2 +- .../pages/entities_in_network_page.dart | 2 +- .../pages/home_page/home_page.dart | 8 +- .../introduction_screen_body.dart | 2 +- lib/presentation/pages/plus_button.dart | 2 +- lib/presentation/pages/remote_pipes_page.dart | 4 +- .../pages/scenes/scenes_page.dart | 4 +- .../pages/software_info_page.dart | 2 +- 57 files changed, 276 insertions(+), 2484 deletions(-) delete mode 100644 lib/domain/device/devices_errors.dart delete mode 100644 lib/domain/device/devices_failures.dart delete mode 100644 lib/domain/device/devices_validators.dart delete mode 100644 lib/domain/device/i_device_repository.dart delete mode 100644 lib/domain/i_hub_connection_repository.dart delete mode 100644 lib/infrastructure/device_repository.dart delete mode 100644 lib/infrastructure/hub_client/hub_connection_repository.dart delete mode 100644 lib/infrastructure/hub_client/hub_requests_routing.dart diff --git a/lib/domain/connections_service.dart b/lib/domain/connections_service.dart index b3b31239..d1f50712 100644 --- a/lib/domain/connections_service.dart +++ b/lib/domain/connections_service.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:collection'; +import 'dart:convert'; import 'dart:io'; import 'package:cbj_integrations_controller/integrations_controller.dart'; @@ -70,13 +71,13 @@ abstract interface class ConnectionsService { Future searchDevices(); - void setEntityState(ActionObject action); + void setEntityState(RequestActionObject action); Future setEtitiesToArea(String areaId, HashSet entities); - Future> get getAllEntities; + Future> get getEntities; - Future> get getAllAreas; + Future> get getAreas; Stream> watchEntities(); @@ -86,13 +87,13 @@ abstract interface class ConnectionsService { Future setNewArea(AreaEntity area); - Future> getScenes(); + Future> get getScenes; Future activateScene(String id); Future addScene(SceneCbjEntity scene); - Future loginVendor(VendorLoginEntity value); + Future loginVendor(VendorLoginEntity value); Future> getVendors(); } diff --git a/lib/domain/device/devices_errors.dart b/lib/domain/device/devices_errors.dart deleted file mode 100644 index 8a3a820d..00000000 --- a/lib/domain/device/devices_errors.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:cybearjinni/domain/device/devices_failures.dart'; - -class DevicesUnexpectedValueError extends Error { - DevicesUnexpectedValueError(this.deviceValueFailure); - - final DevicesFailure deviceValueFailure; - - @override - String toString() { - const explanation = - 'Encountered a ValueFailure at an unrecoverable point. Terminating.'; - return Error.safeToString('$explanation Failure was: $deviceValueFailure'); - } -} diff --git a/lib/domain/device/devices_failures.dart b/lib/domain/device/devices_failures.dart deleted file mode 100644 index 08bf7b7e..00000000 --- a/lib/domain/device/devices_failures.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'devices_failures.freezed.dart'; - -@freezed -class DevicesFailure { - const factory DevicesFailure.empty({ - required T failedValue, - }) = _Empty; - - const factory DevicesFailure.actionExcecuter({ - required T failedValue, - }) = _ActionExcecuter; - - const factory DevicesFailure.exceedingLength({ - required T failedValue, - required int max, - }) = _ExceedingLength; - - const factory DevicesFailure.unexpected() = _Unexpected; - - const factory DevicesFailure.insufficientPermission() = - _InsufficientPermission; - - const factory DevicesFailure.unableToUpdate() = _UnableToUpdate; - - const factory DevicesFailure.powerConsumptionIsNotNumber() = - _PowerConsumptionIsNotNumber; - - const factory DevicesFailure.deviceActionDoesNotExist() = - _DeviceActionDoesNotExist; - - const factory DevicesFailure.deviceTypeDoesNotExist() = - _DeviceTypeDoesNotExist; -} diff --git a/lib/domain/device/devices_validators.dart b/lib/domain/device/devices_validators.dart deleted file mode 100644 index 07018491..00000000 --- a/lib/domain/device/devices_validators.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/device/devices_failures.dart'; -import 'package:dartz/dartz.dart'; - -Either, String> validateDeviceNotEmpty(String input) { - if (input.isNotEmpty) { - return right(input); - } else { - return left( - DevicesFailure.empty( - failedValue: input, - ), - ); - } -} - -Either, String> validateLastKnownIpNotEmpty( - String input, -) { - if (input.isNotEmpty) { - return right(input); - } else { - return left( - DevicesFailure.empty( - failedValue: input, - ), - ); - } -} - -Either, String> validatePowerConsumptionNotEmpty( - String input, -) { - if (double.tryParse(input) != null) { - return right(input); - } else { - return left(const DevicesFailure.powerConsumptionIsNotNumber()); - } -} - -Either, String> validateAreaNameNotEmpty(String input) { - return right(input); -} - -Either, String> validateMdnsNameNotEmpty(String input) { - return right(input); -} - -Either, String> validateWiFiNameNotEmpty(String input) { - return right(input); -} - -Either, String> validateDeviceMaxNameLength( - String input, - int maxLength, -) { - if (input.length <= maxLength) { - return right(input); - } else { - return left( - DevicesFailure.exceedingLength( - failedValue: input, - max: maxLength, - ), - ); - } -} - -Either, String> validateDeviceStateExist(String input) { - if (EntityUtils.stringToDeviceState(input) != null) { - return right(input); - } - return left(const DevicesFailure.deviceActionDoesNotExist()); -} - -Either, String> validateDeviceActionExist(String input) { - if (EntityUtils.stringToDeviceAction(input) != null) { - return right(input); - } - return left(const DevicesFailure.deviceActionDoesNotExist()); -} - -Either, String> validateDeviceTypeExist(String input) { - if (EntityUtils.stringToDt(input) != null) { - return right(input); - } - return left(const DevicesFailure.deviceTypeDoesNotExist()); -} diff --git a/lib/domain/device/i_device_repository.dart b/lib/domain/device/i_device_repository.dart deleted file mode 100644 index 537a9357..00000000 --- a/lib/domain/device/i_device_repository.dart +++ /dev/null @@ -1,145 +0,0 @@ -import 'dart:async'; -import 'dart:collection'; -import 'dart:io'; - -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/device/devices_failures.dart'; -import 'package:cybearjinni/infrastructure/core/logger.dart'; -import 'package:cybearjinni/infrastructure/hub_client/hub_requests_routing.dart'; -import 'package:dartz/dartz.dart'; -import 'package:device_info_plus/device_info_plus.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; -import 'package:kt_dart/kt.dart'; -import 'package:multicast_dns/multicast_dns.dart'; -import 'package:network_info_plus/network_info_plus.dart'; -import 'package:permission_handler/permission_handler.dart'; -import 'package:rxdart/rxdart.dart'; - -part 'package:cybearjinni/infrastructure/device_repository.dart'; - -@Deprecated('Old architecture. Replaced by EntitiesService') -abstract interface class IDeviceRepository { - static IDeviceRepository? _instance; - - static IDeviceRepository get instance { - return _instance ??= _DeviceRepository(); - } - - void addOrUpdateDevice(DeviceEntityBase deviceEntity); - - void addOrUpdateDeviceAndStateToWaiting(DeviceEntityBase deviceEntity); - - Future initiateHubConnection(); - - Future>> getAllEntites(); - - Stream>> watchAll(); - - Stream>> watchAllDevices(); - - Stream>> watchLights(); - - Stream>> watchBlinds(); - - Stream>> watchBoilers(); - - Stream>> watchSmartTv(); - - Stream>> watchSwitches(); - - Stream>> watchSmartPlugs(); - - Stream>> - watchSmartComputers(); - - Stream>> watchPrinters(); - - Stream>> watchUncompleted(); - - Future> create( - DeviceEntityBase deviceEntity, - ); - - Future> updateWithDeviceEntity({ - required DeviceEntityBase deviceEntity, - }); - - Future> turnOnDevices({ - required List? devicesId, - }); - - Future> turnOffDevices({ - required List? devicesId, - }); - - Future> changeColorTemperatureDevices({ - required List? devicesId, - required int colorTemperatureToChange, - }); - - Future> changeHsvColorDevices({ - required List? devicesId, - required HSVColor hsvColorToChange, - }); - - Future> changeBrightnessDevices({ - required List? devicesId, - required int brightnessToChange, - }); - - Future> moveUpStateDevices({ - required List? devicesId, - }); - - Future> stopStateDevices({ - required List? devicesId, - }); - - Future> moveDownStateDevices({ - required List? devicesId, - }); - - Future> suspendDevices({ - required List? devicesId, - }); - - Future> shutdownDevices({ - required List? devicesId, - }); - - Future> closeStateDevices({ - required List? devicesId, - }); - - Future> pauseStateDevices({ - required List? devicesId, - }); - - Future> playStateDevices({ - required List? devicesId, - }); - - Future> changeVolumeDevices({ - required List? devicesId, - }); - - Future> queuePrevStateDevices({ - required List? devicesId, - }); - - Future> queueNextStateDevices({ - required List? devicesId, - }); - - BehaviorSubject> allResponseFromTheHubStreamController = - BehaviorSubject>(); - - BehaviorSubject> areasResponseFromTheHubStreamController = - BehaviorSubject>(); - - BehaviorSubject> - devicesResponseFromTheHubStreamController = - BehaviorSubject>(); -} diff --git a/lib/domain/i_hub_connection_repository.dart b/lib/domain/i_hub_connection_repository.dart deleted file mode 100644 index a61938f9..00000000 --- a/lib/domain/i_hub_connection_repository.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'dart:async'; -import 'dart:io'; - -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:cybearjinni/domain/i_local_db_repository.dart'; -import 'package:cybearjinni/infrastructure/core/injection.dart'; -import 'package:cybearjinni/infrastructure/core/logger.dart'; -import 'package:dartz/dartz.dart'; -import 'package:flutter/foundation.dart' show kIsWeb; -import 'package:location/location.dart'; -import 'package:multicast_dns/multicast_dns.dart'; -import 'package:network_info_plus/network_info_plus.dart'; -import 'package:permission_handler/permission_handler.dart' - as permission_handler; -import 'package:wifi_iot/wifi_iot.dart'; - -part 'package:cybearjinni/infrastructure/hub_client/hub_connection_repository.dart'; - -@Deprecated( - 'Old architecture. Replaced with ConnectionsService. Delete after Re adding Hub comunication', -) -abstract class IHubConnectionRepository { - static IHubConnectionRepository? _instance; - - static IHubConnectionRepository get instance { - return _instance ??= _HubConnectionRepository(); - } - - static HubEntity? hubEntity; - - Future connectWithHub({bool demoMod = false}); - - Future> getHubCompInfo( - CompHubInfo appInfoForHub, - ); - - Future closeConnection(); - - Future> searchForHub({ - String? deviceIpOnTheNetwork, - bool? isThatTheIpOfTheHub, - }); - - Future saveHubIP(String hubIP); -} diff --git a/lib/domain/i_local_db_repository.dart b/lib/domain/i_local_db_repository.dart index 92e4c29d..af328350 100644 --- a/lib/domain/i_local_db_repository.dart +++ b/lib/domain/i_local_db_repository.dart @@ -16,7 +16,7 @@ abstract interface class ILocalDbRepository { return _instance ??= _IsarRepository(); } - Future asyncConstructor(); + Future asyncConstructor(); Future> saveHubEntity({ required String hubNetworkBssid, diff --git a/lib/domain/software_info/i_software_info_repository.dart b/lib/domain/software_info/i_software_info_repository.dart index 75792e1a..bbe487ad 100644 --- a/lib/domain/software_info/i_software_info_repository.dart +++ b/lib/domain/software_info/i_software_info_repository.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/i_hub_connection_repository.dart'; import 'package:cybearjinni/domain/security_bear/i_security_bear_connection_repository.dart'; import 'package:cybearjinni/domain/security_bear/security_bear_failures.dart'; import 'package:cybearjinni/domain/software_info/software_info_entity.dart'; diff --git a/lib/infrastructure/cbj_app_server_d.dart b/lib/infrastructure/cbj_app_server_d.dart index 32c440b1..4ff328c9 100644 --- a/lib/infrastructure/cbj_app_server_d.dart +++ b/lib/infrastructure/cbj_app_server_d.dart @@ -25,7 +25,7 @@ class _CBJAppServerD extends CyBearJinniAppServiceBase { return Future.value(CompAppInfo()); } -// Future cBJAppGetSmartDeviceInformationAsync( +// Future cBJAppGetSmartDeviceInformationAsync( // SmartDeviceInfo smartDevice) async { // final String smartDeviceIp = smartDevice.smartDeviceIP; // @@ -54,14 +54,14 @@ class CreateTheCBJAppServer { Server? server; /// This function will create the server - Future createServer(StreamController compInfoStream) async { + Future createServer(StreamController compInfoStream) async { await server?.shutdown(); server = Server.create(services: [_CBJAppServerD(compInfoStream)]); await server!.serve(port: 30055); logger.i('App server listening on port ${server!.port}...'); } - Future shutdownServer() async { + Future shutdownServer() async { await server?.shutdown(); return; } diff --git a/lib/infrastructure/connection_service/app_connection_service.dart b/lib/infrastructure/connection_service/app_connection_service.dart index 67e6f712..af0dca37 100644 --- a/lib/infrastructure/connection_service/app_connection_service.dart +++ b/lib/infrastructure/connection_service/app_connection_service.dart @@ -9,11 +9,11 @@ class _AppConnectionService implements ConnectionsService { late SearchDevices searchDevicesInstance; @override - Future> get getAllEntities async => + Future> get getEntities async => IcSynchronizer().getEntities(); @override - Future> get getAllAreas async => + Future> get getAreas async => IcSynchronizer().getAreas(); @override @@ -29,7 +29,7 @@ class _AppConnectionService implements ConnectionsService { IcSynchronizer().areasChangesStream.stream; @override - void setEntityState(ActionObject action) => + void setEntityState(RequestActionObject action) => IcSynchronizer().setEntitiesState(action); @override @@ -45,7 +45,7 @@ class _AppConnectionService implements ConnectionsService { IcSynchronizer().setEtitiesToArea(areaId, entities); @override - Future> getScenes() async => + Future> get getScenes async => IcSynchronizer().getScenes(); @override diff --git a/lib/infrastructure/connection_service/demo_connection_service.dart b/lib/infrastructure/connection_service/demo_connection_service.dart index 72c6522c..1dd06616 100644 --- a/lib/infrastructure/connection_service/demo_connection_service.dart +++ b/lib/infrastructure/connection_service/demo_connection_service.dart @@ -10,17 +10,17 @@ class _DemoConnectionService implements ConnectionsService { } @override - Future> get getAllEntities async => + Future> get getEntities async => DemoConnectionController.getAllEntities(); @override - Future> get getAllAreas async => HashMap(); + Future> get getAreas async => HashMap(); @override Future searchDevices() async {} @override - void setEntityState(ActionObject action) {} + void setEntityState(RequestActionObject action) {} @override Stream> watchEntities() { @@ -48,13 +48,13 @@ class _DemoConnectionService implements ConnectionsService { Future addScene(SceneCbjEntity scene) async {} @override - Future> getScenes() async => HashMap(); + Future> get getScenes async => HashMap(); @override Future activateScene(String id) async {} @override - Future loginVendor(VendorLoginEntity value) async {} + Future loginVendor(VendorLoginEntity value) async {} @override Future> getVendors() async => diff --git a/lib/infrastructure/connection_service/hub_connection_service.dart b/lib/infrastructure/connection_service/hub_connection_service.dart index 78a6d603..6fde9032 100644 --- a/lib/infrastructure/connection_service/hub_connection_service.dart +++ b/lib/infrastructure/connection_service/hub_connection_service.dart @@ -37,18 +37,117 @@ class _HubConnectionService implements ConnectionsService { } @override - Future> get getAllEntities async { - appMessagesToHub.sink - .add(ClientStatusRequests(sendingType: SendingType.firstConnection)); + Future> get getEntities async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allEntities.name), + ); + final HashMap entities = HashMap(); + await for (final RequestsAndStatusFromHub message in hubMessagesToApp.stream) { - logger.i('message from hub is $message'); + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allEntities) { + continue; + } + + try { + final Map entitiesMap = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + entities.addEntries( + entitiesMap.entries.map( + (e) => MapEntry( + e.key, + DeviceHelper.convertJsonStringToDomain(e.value), + ), + ), + ); + } catch (e) { + logger.e('Error converting entities\n$e'); + } + break; } - return HashMap(); + + return entities; } @override - Future> get getAllAreas async => HashMap(); + Future> get getAreas async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allAreas.name), + ); + + final HashMap areas = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allAreas) { + continue; + } + + try { + final Map entitiesMap = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + areas.addEntries( + entitiesMap.entries.map( + (e) => MapEntry( + e.key, + AreaEntityDtos.fromJson( + jsonDecode(e.value) as Map, + ).toDomain(), + ), + ), + ); + } catch (e) { + logger.e('Error converting areas\n$e'); + } + break; + } + + return areas; + } + + @override + Future> get getScenes async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allScenes.name), + ); + + final HashMap scenesMap = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allScenes) { + continue; + } + + try { + final Map entities = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + scenesMap.addEntries( + entities.entries.map( + (e) => MapEntry( + e.key, + SceneCbjDtos.fromJson(jsonDecode(e.value) as Map) + .toDomain(), + ), + ), + ); + } catch (e) { + logger.e('Error converting scenes\n$e'); + } + break; + } + + return scenesMap; + } @override Future searchDevices() async { @@ -126,7 +225,14 @@ class _HubConnectionService implements ConnectionsService { } @override - void setEntityState(ActionObject action) {} + void setEntityState(RequestActionObject action) { + appMessagesToHub.sink.add( + ClientStatusRequests( + sendingType: SendingType.setEntitiesAction.name, + allRemoteCommands: action.toInfrastructure().toJsonString(), + ), + ); + } @override Stream> watchEntities() { @@ -153,14 +259,11 @@ class _HubConnectionService implements ConnectionsService { @override Future addScene(SceneCbjEntity scene) async {} - @override - Future> getScenes() async => HashMap(); - @override Future activateScene(String id) async {} @override - Future loginVendor(VendorLoginEntity value) async {} + Future loginVendor(VendorLoginEntity value) async {} @override Future> getVendors() async => @@ -229,7 +332,7 @@ class _HubConnectionService implements ConnectionsService { } /// Connect directly to the Hub if possible - Future connectDirectlyToHub() async { + Future connectDirectlyToHub() async { if (hubIp == null) { return; } diff --git a/lib/infrastructure/connection_service/none_connection_service.dart b/lib/infrastructure/connection_service/none_connection_service.dart index 8e8555db..fb1049d2 100644 --- a/lib/infrastructure/connection_service/none_connection_service.dart +++ b/lib/infrastructure/connection_service/none_connection_service.dart @@ -10,17 +10,16 @@ class _NoneConnectionService implements ConnectionsService { } @override - Future> get getAllEntities async => - HashMap(); + Future> get getEntities async => HashMap(); @override - Future> get getAllAreas async => HashMap(); + Future> get getAreas async => HashMap(); @override Future searchDevices() async {} @override - void setEntityState(ActionObject action) {} + void setEntityState(RequestActionObject action) {} @override Stream> watchEntities() { @@ -45,7 +44,7 @@ class _NoneConnectionService implements ConnectionsService { Future setEtitiesToArea(String areaId, HashSet entities) async {} @override - Future> getScenes() async => HashMap(); + Future> get getScenes async => HashMap(); @override Future addScene(SceneCbjEntity scene) async {} @@ -54,7 +53,7 @@ class _NoneConnectionService implements ConnectionsService { Future activateScene(String id) async {} @override - Future loginVendor(VendorLoginEntity value) async {} + Future loginVendor(VendorLoginEntity value) async {} @override Future> getVendors() async => []; diff --git a/lib/infrastructure/device_repository.dart b/lib/infrastructure/device_repository.dart deleted file mode 100644 index f2da2154..00000000 --- a/lib/infrastructure/device_repository.dart +++ /dev/null @@ -1,1160 +0,0 @@ -part of 'package:cybearjinni/domain/device/i_device_repository.dart'; - -class _DeviceRepository implements IDeviceRepository { - // final DeviceRemoteService _deviceRemoteService; - // final DeviceLocalService _deviceLocalService; - HashMap allDevices = - HashMap(); - - // @override - // void addOrUpdateFromApp(dynamic entity) { - // if (entity is AreaEntity) { - // _addOrUpdateArea(entity); - // } else if (entity is DeviceEntityBase) { - // _addOrUpdateDevice(entity); - // } else { - // logger.w('Entity type to update ${entity.runtimeType} is not supported'); - // } - // allResponseFromTheHubStreamController.sink - // .add(entity); - // } - - @override - void addOrUpdateDevice(DeviceEntityBase deviceEntity) { - allDevices[deviceEntity.cbjDeviceVendor.getOrCrash()] = deviceEntity; - devicesResponseFromTheHubStreamController.sink - .add(allDevices.values.toImmutableList()); - } - - @override - void addOrUpdateDeviceAndStateToWaiting(DeviceEntityBase deviceEntity) { - addOrUpdateDevice( - deviceEntity.copyWithDeviceState( - EntityStateGRPC.waitingInComp, - ), - ); - } - - @override - Future initiateHubConnection() async { - AppRequestsToHub.listenToApp(); - - HubRequestRouting.navigateRequest(); - } - - @override - Future>> - getAllEntites() async { - try { - return right(allDevices.values.toImmutableList()); - } catch (e) { - if (e is PlatformException && e.message!.contains('PERMISSION_DENIED')) { - logger.w('Insufficient permission while getting all devices'); - return left(const DevicesFailure.insufficientPermission()); - } else { - logger.e('Unexpected error while getting all devices'); - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - } - - @override - Stream> watchAll() async* { - yield* allResponseFromTheHubStreamController.map((event) => right(event)); - } - - @override - Stream>> - watchAllDevices() async* { - yield* devicesResponseFromTheHubStreamController.stream - .map((event) => right(event)); - } - - @override - Stream>> - watchLights() async* { - // Using watchAll devices from server function and filtering out only the - // Light device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.light.toString() || - element.entityTypes.getOrCrash() == - EntityTypes.dimmableLight.toString() || - element.entityTypes.getOrCrash() == - EntityTypes.rgbwLights.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchSwitches() async* { - // Using watchAll devices from server function and filtering out only the - // Switches device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.switch_.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchSmartPlugs() async* { - // Using watchAll devices from server function and filtering out only the - // Smart Plugs device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.smartPlug.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchSmartComputers() async* { - // Using watchAll devices from server function and filtering out only the - // Smart Computers device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.smartComputer.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchBlinds() async* { - // Using watchAll devices from server function and filtering out only the - // Blinds device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.blinds.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchBoilers() async* { - // Using watchAll devices from server function and filtering out only the - // Boilers device type - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.boiler.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchSmartTv() async* { - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.smartTV.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> - watchPrinters() async* { - yield* watchAllDevices().map( - (event) => event.fold((l) => left(l), (r) { - return right( - r.toList().asList().where((element) { - return element!.entityTypes.getOrCrash() == - EntityTypes.printer.toString(); - }).toImmutableList(), - ); - }), - ); - } - - @override - Stream>> watchUncompleted() { - // TODO: implement watchUncompleted - throw UnimplementedError(); - } - - @override - Future> create( - DeviceEntityBase deviceEntity, - ) async { - try { - String deviceModelString = 'No Model found'; - final DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); - if (Platform.isAndroid) { - final AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; - logger.i(androidInfo.model); - deviceModelString = androidInfo.model; - } else if (Platform.isIOS) { - final IosDeviceInfo iosInfo = await deviceInfo.iosInfo; - logger.i(iosInfo.utsname.machine); - deviceModelString = iosInfo.model; - } - - const String currentUserId = 'user id'; - - deviceEntity - .copyWithStateMassage('Setting up device') - .copyWithSenderDeviceOs(Platform.operatingSystem) - .copyWithDeviceSenderDeviceModel(deviceModelString) - .copyWithSenderId(currentUserId); - - DeviceEntityDtoBase.fromDomain(); - - return right(unit); - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - } - - @override - Future> updateWithDeviceEntity({ - required DeviceEntityBase deviceEntity, - }) async { - return left(const DevicesFailure.unexpected()); - } - - @override - Future> turnOnDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericLightDE) { - deviceEntity.lightSwitchState = - GenericLightSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericDimmableLightDE) { - deviceEntity.lightSwitchState = - GenericDimmableLightSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericRgbwLightDE) { - deviceEntity.lightSwitchState = - GenericRgbwLightSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericSwitchDE) { - deviceEntity.switchState = - GenericSwitchSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericBoilerDE) { - deviceEntity.boilerSwitchState = - GenericBoilerSwitchState(EntityActions.on.toString()); - } else if (deviceEntity is GenericSmartPlugDE) { - deviceEntity.smartPlugState = - GenericSmartPlugState(EntityActions.on.toString()); - } else { - logger.w( - 'On action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> turnOffDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericLightDE) { - deviceEntity.lightSwitchState = - GenericLightSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericDimmableLightDE) { - deviceEntity.lightSwitchState = - GenericDimmableLightSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericRgbwLightDE) { - deviceEntity.lightSwitchState = - GenericRgbwLightSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericSwitchDE) { - deviceEntity.switchState = - GenericSwitchSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericBoilerDE) { - deviceEntity.boilerSwitchState = - GenericBoilerSwitchState(EntityActions.off.toString()); - } else if (deviceEntity is GenericSmartPlugDE) { - deviceEntity.smartPlugState = - GenericSmartPlugState(EntityActions.off.toString()); - } else { - logger.w( - 'Off action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> changeColorTemperatureDevices({ - required List? devicesId, - required int colorTemperatureToChange, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericRgbwLightDE) { - deviceEntity.lightColorTemperature = GenericRgbwLightColorTemperature( - colorTemperatureToChange.toString(), - ); - } else { - logger.w( - 'Off action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - try { - if (!deviceEntity.doesWaitingToSendTemperatureColorRequest) { - deviceEntity.doesWaitingToSendTemperatureColorRequest = true; - - final Future> updateEntityResponse = - updateWithDeviceEntity(deviceEntity: deviceEntity); - - await Future.delayed( - Duration( - milliseconds: - deviceEntity.sendNewTemperatureColorEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendTemperatureColorRequest = false; - - return updateEntityResponse; - } - } catch (e) { - await Future.delayed( - Duration( - milliseconds: - deviceEntity.sendNewTemperatureColorEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendTemperatureColorRequest = false; - return left(const DevicesFailure.unexpected()); - } - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> changeHsvColorDevices({ - required List? devicesId, - required HSVColor hsvColorToChange, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericRgbwLightDE) { - deviceEntity - ..lightColorAlpha = - GenericRgbwLightColorAlpha(hsvColorToChange.alpha.toString()) - ..lightColorHue = - GenericRgbwLightColorHue(hsvColorToChange.hue.toString()) - ..lightColorSaturation = GenericRgbwLightColorSaturation( - hsvColorToChange.saturation.toString(), - ) - ..lightColorValue = - GenericRgbwLightColorValue(hsvColorToChange.value.toString()); - } else { - logger.w( - 'Off action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - try { - if (!deviceEntity.doesWaitingToSendHsvColorRequest) { - deviceEntity.doesWaitingToSendHsvColorRequest = true; - - final Future> updateEntityResponse = - updateWithDeviceEntity(deviceEntity: deviceEntity); - - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewHsvColorEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendHsvColorRequest = false; - - return updateEntityResponse; - } - } catch (e) { - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewHsvColorEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendHsvColorRequest = false; - return left(const DevicesFailure.unexpected()); - } - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> changeBrightnessDevices({ - required List? devicesId, - required int brightnessToChange, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - Either totalActionResult = right(unit); - - try { - Either actionResult; - - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } else if (deviceEntity is GenericDimmableLightDE) { - deviceEntity.lightBrightness = - GenericDimmableLightBrightness(brightnessToChange.toString()); - actionResult = await dimDimmableLight(deviceEntity); - } else if (deviceEntity is GenericRgbwLightDE) { - deviceEntity.lightBrightness = - GenericRgbwLightBrightness(brightnessToChange.toString()); - actionResult = await dimRgbwLight(deviceEntity); - } else { - logger.w( - 'Brightness action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - if (actionResult.isLeft()) { - totalActionResult = actionResult; - } - } - return totalActionResult; - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - } - - Future> dimDimmableLight( - GenericDimmableLightDE deviceEntity, - ) async { - try { - if (!deviceEntity.doesWaitingToSendBrightnessRequest) { - deviceEntity.doesWaitingToSendBrightnessRequest = true; - - final Future> updateEntityResponse = - updateWithDeviceEntity(deviceEntity: deviceEntity); - - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewBrightnessEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendBrightnessRequest = false; - return updateEntityResponse; - } - } catch (e) { - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewBrightnessEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendBrightnessRequest = false; - return left(const DevicesFailure.unexpected()); - } - return right(unit); - } - - Future> dimRgbwLight( - GenericRgbwLightDE deviceEntity, - ) async { - try { - if (!deviceEntity.doesWaitingToSendBrightnessRequest) { - deviceEntity.doesWaitingToSendBrightnessRequest = true; - - final Future> updateEntityResponse = - updateWithDeviceEntity(deviceEntity: deviceEntity); - - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewBrightnessEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendBrightnessRequest = false; - return updateEntityResponse; - } - } catch (e) { - await Future.delayed( - Duration( - milliseconds: deviceEntity.sendNewBrightnessEachMilliseconds, - ), - ); - deviceEntity.doesWaitingToSendBrightnessRequest = false; - return left(const DevicesFailure.unexpected()); - } - return right(unit); - } - - @override - Future> moveUpStateDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericBlindsDE) { - deviceEntity.blindsSwitchState = - GenericBlindsSwitchState(EntityActions.moveUp.toString()); - } else { - logger.w( - 'Off action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> stopStateDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericBlindsDE) { - deviceEntity.blindsSwitchState = - GenericBlindsSwitchState(EntityActions.stop.toString()); - } else if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.stop.toString(), - ); - } else { - logger.w( - 'Stop action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> moveDownStateDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericBlindsDE) { - deviceEntity.blindsSwitchState = - GenericBlindsSwitchState(EntityActions.moveDown.toString()); - } else { - logger.w( - 'Move down action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> suspendDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartComputerDE) { - deviceEntity.smartComputerSuspendState = - GenericSmartComputerSuspendState( - EntityActions.suspend.toString(), - ); - } else { - logger.w( - 'Suspend action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> shutdownDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartComputerDE) { - deviceEntity.smartComputerShutDownState = - GenericSmartComputerShutdownState( - EntityActions.shutdown.toString(), - ); - } else { - logger.w( - 'Shutdown action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> changeVolumeDevices({ - required List? devicesId, - }) async { - // TODO: implement changeVolumeDevices - throw UnimplementedError(); - } - - @override - Future> closeStateDevices({ - List? devicesId, - String? forceUpdateLocation, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericBlindsDE) { - deviceEntity.blindsSwitchState = - GenericBlindsSwitchState(EntityActions.close.toString()); - } else { - logger.w( - 'Close action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> pauseStateDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.pause.toString(), - ); - } else { - logger.w( - 'Pause action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> playStateDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.play.toString(), - ); - } else { - logger.w( - 'Play action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> queuePrevStateDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.skipPreviousVid.toString(), - ); - } else { - logger.w( - 'Skip prev vid action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - @override - Future> queueNextStateDevices({ - required List? devicesId, - }) async { - final List deviceEntityListToUpdate = - await getDeviceEntityListFromId(devicesId!); - - try { - for (final DeviceEntityBase? deviceEntity in deviceEntityListToUpdate) { - if (deviceEntity == null) { - continue; - } - if (deviceEntity is GenericSmartTvDE) { - deviceEntity.pausePlayState = GenericSmartTvPausePlayState( - EntityActions.skipNextVid.toString(), - ); - } else { - logger.w( - 'Skip next vid action not supported for' - ' ${deviceEntity.entityTypes.getOrCrash()} type', - ); - continue; - } - - updateWithDeviceEntity(deviceEntity: deviceEntity); - } - } on PlatformException catch (e) { - if (e.message!.contains('PERMISSION_DENIED')) { - return left(const DevicesFailure.insufficientPermission()); - } else if (e.message!.contains('NOT_FOUND')) { - return left(const DevicesFailure.unableToUpdate()); - } else { - // log.error(e.toString()); - return left(const DevicesFailure.unexpected()); - } - } - return right(unit); - } - - Future> updateComputer( - DeviceEntityBase deviceEntity, - ) async { - try { - addOrUpdateDeviceAndStateToWaiting(deviceEntity); - - try { - deviceEntity.copyWithDeviceState(EntityStateGRPC.waitingInCloud); - - final String deviceDtoAsString = - DeviceHelper.convertDomainToJsonString(deviceEntity); - final ClientStatusRequests clientStatusRequests = ClientStatusRequests( - allRemoteCommands: deviceDtoAsString, - sendingType: SendingType.entityType, - ); - AppRequestsToHub.appRequestsToHubStreamController - .add(clientStatusRequests); - } catch (e) { - logger.e('This is the error\n$e'); - - // final DocumentReference homeDoc = - // await _firestore.currentHomeDocument(); - // final CollectionReference devicesCollection = - // homeDoc.devicesCollecttion; - // final DocumentReference deviceDocumentReference = - // devicesCollection.doc(deviceEntity.id!.getOrCrash()); - // updateDatabase(documentPath: deviceDocumentReference, fieldsToUpdate: { - // 'lastKnownIp': lastKnownIp, - // }); - } - - return right(unit); - } catch (e) { - logger.w('Probably ip of device was not inserted into the device object'); - return left(const DevicesFailure.unexpected()); - } - } - - Future> getDeviceEntityListFromId( - List deviceIdList, - ) async { - final List deviceEntityList = []; - - if (allDevices.isEmpty) { - return []; - } - - for (final deviceId in deviceIdList) { - final DeviceEntityBase? device = allDevices[deviceId]; - if (device == null) { - continue; - } - deviceEntityList.add(device); - } - return deviceEntityList; - } - - /// Search device IP by computer Avahi (mdns) name - Future getDeviceIpByDeviceAvahiName(String mDnsName) async { - String deviceIp = ''; - final String fullMdnsName = '$mDnsName.local'; - - final MDnsClient client = MDnsClient( - rawDatagramSocketFactory: ( - dynamic host, - int port, { - bool? reuseAddress, - bool? reusePort, - int? ttl, - }) { - return RawDatagramSocket.bind(host, port, ttl: ttl!); - }, - ); - // Start the client with default options. - - await client.start(); - await for (final IPAddressResourceRecord record - in client.lookup( - ResourceRecordQuery.addressIPv4(fullMdnsName), - )) { - deviceIp = record.address.address; - logger.t('Found address (${record.address}).'); - } - - // await for (final IPAddressResourceRecord record - // in client.lookup( - // ResourceRecordQuery.addressIPv6(fullMdnsName))) { - // logger.t('Found address (${record.address}).'); - // } - - client.stop(); - - logger.t('Done.'); - - return deviceIp; - } - - /// How to send the data, in the local network or the remote server/cloud - Future whereToUpdateDevicesData( - String? forceUpdateLocation, - String? deviceSecondWifiName, - ) async { - String updateLocation; - - try { - if (forceUpdateLocation == null) { - final status = await Permission.location.status; - if (status.isDenied) { - Permission.location.request(); - } - - final String? wifiName = await NetworkInfo().getWifiName(); - - if (deviceSecondWifiName != null && - deviceSecondWifiName.isNotEmpty && - deviceSecondWifiName == wifiName) { - updateLocation = 'L'; // L for local network - } else { - updateLocation = 'R'; // R for remote - } - } else { - updateLocation = forceUpdateLocation; - } - } catch (exception) { - updateLocation = 'L'; - } - - return updateLocation; - } - - /// Stream controller of the app request for the hub - @override - BehaviorSubject allResponseFromTheHubStreamController = - BehaviorSubject(); - - @override - BehaviorSubject> - devicesResponseFromTheHubStreamController = - BehaviorSubject>(); - - @override - BehaviorSubject> areasResponseFromTheHubStreamController = - BehaviorSubject>(); -} diff --git a/lib/infrastructure/hub_client/hub_connection_repository.dart b/lib/infrastructure/hub_client/hub_connection_repository.dart deleted file mode 100644 index 629ca963..00000000 --- a/lib/infrastructure/hub_client/hub_connection_repository.dart +++ /dev/null @@ -1,582 +0,0 @@ -part of 'package:cybearjinni/domain/i_hub_connection_repository.dart'; - -@Deprecated( - 'Old architecture. Replaced with ConnectionsService. Delete after Re adding Hub comunication', -) -class _HubConnectionRepository implements IHubConnectionRepository { - _HubConnectionRepository() { - if (currentEnvApp == EnvApp.prod) { - hubPort = 50055; - } else { - hubPort = 60055; - } - } - - /// Port to connect to the cbj hub, will change according to the current - /// running environment - late int hubPort; - - int tryAgainConnectToTheHubOnceMore = 0; - - bool cancelConnectionWithHub = false; - - bool appInDemoMod = false; - - @override - Future connectWithHub({bool demoMod = false}) async { - if (cancelConnectionWithHub && !demoMod) { - return; - } - appInDemoMod = demoMod; - - if (appInDemoMod) { - cancelConnectionWithHub = true; - return streamFromDemoMode(); - } - - /// Load network information from local db - if (IHubConnectionRepository.hubEntity == null) { - await loadNetworkInformationFromDb(); - } - - ConnectivityResult? connectivityResult; - try { - connectivityResult = await Connectivity().checkConnectivity(); - } catch (e) { - logger.w('Cant check connectivity this is probably PC, error\n$e'); - } - - // Last Number of bssid can change fix?, need to check if more numbers - // can do that - final String? savedWifiBssid = - IHubConnectionRepository.hubEntity?.hubNetworkBssid.getOrCrash(); - final String? savedWifiBssidWithoutLastNumber = - savedWifiBssid?.substring(0, savedWifiBssid.lastIndexOf(':')); - String? wifiBSSID; - String? wifiBSSIDWithoutLastNumber; - try { - wifiBSSID = await NetworkInfo().getWifiBSSID(); - wifiBSSIDWithoutLastNumber = - wifiBSSID?.substring(0, wifiBSSID.lastIndexOf(':')); - } catch (e) { - logger.w("Can't get WiFi BSSID"); - } - final Either remotePipesInformation = - await ILocalDbRepository.instance.getRemotePipesDnsName(); - - // Check if you are connected to the home local network for direct - // communication with the Hub. - // This block can be false also if user does not approve some permissions - // or #256 if the app run on the computer and connected with ethernet cable - // (not effecting connection with WiFi) - if (remotePipesInformation.isLeft() || - (connectivityResult != null && - connectivityResult == ConnectivityResult.wifi && - savedWifiBssidWithoutLastNumber != null && - wifiBSSIDWithoutLastNumber != null && - savedWifiBssidWithoutLastNumber == wifiBSSIDWithoutLastNumber) || - (connectivityResult != null && - connectivityResult == ConnectivityResult.ethernet && - savedWifiBssidWithoutLastNumber == 'no:Network:Bssid') || - (kIsWeb && savedWifiBssidWithoutLastNumber == 'no:Network:Bssid')) { - (await openAndroidWifiSettingIfPossible()).fold( - (l) { - logger - .w('No way to establish connection with the Hub, WiFi or location' - ' permission is closed for here'); - return; - }, - (r) async {}, - ); - logger.i('Connect using direct connection to Hub'); - - await connectDirectlyToHub(); - return; - } else { - await connectionUsingRemotePipes(); - } - } - - @override - Future> getHubCompInfo( - CompHubInfo appInfoForHub, - ) async { - if (IHubConnectionRepository.hubEntity == null) { - try { - String? hubNetworkBssid; - (await ILocalDbRepository.instance.getHubEntityNetworkBssid()).fold( - (l) => throw 'Error getting Hub network Bssid', - (r) => hubNetworkBssid = r, - ); - - String? hubNetworkName; - (await ILocalDbRepository.instance.getHubEntityNetworkName()).fold( - (l) => throw 'Error getting Hub network name', - (r) => hubNetworkName = r, - ); - - String? hubNetworkIp; - (await ILocalDbRepository.instance.getHubEntityLastKnownIp()).fold( - (l) => throw 'Error getting Hub network IP', - (r) => hubNetworkIp = r, - ); - IHubConnectionRepository.hubEntity = HubDtos( - hubNetworkBssid: hubNetworkBssid!, - lastKnownIp: hubNetworkIp!, - networkName: hubNetworkName!, - ).toDomain(); - } catch (e) { - logger.e('Crashed while setting Hub info from local db\n$e'); - } - } - - ConnectivityResult? connectivityResult; - try { - connectivityResult = await Connectivity().checkConnectivity(); - } catch (e) { - logger.w('Cant check connectivity this is probably PC, error\n$e'); - } - - // Last Number of bssid can change fix?, need to check if more numbers - // can do that - final String? savedWifiBssid = - IHubConnectionRepository.hubEntity?.hubNetworkBssid.getOrCrash(); - final String? savedWifiBssidWithoutLastNumber = - savedWifiBssid?.substring(0, savedWifiBssid.lastIndexOf(':')); - - final String? wifiBSSID = await NetworkInfo().getWifiBSSID(); - final String? wifiBSSIDWithoutLastNumber = - wifiBSSID?.substring(0, wifiBSSID.lastIndexOf(':')); - - // Check if you are connected to the home local network for direct - // communication with the Hub. - // This block can be false also if user does not improve some permissions - // or #256 if the app run on the computer and connected with ethernet cable - // (not effecting connection with WiFi) - if (connectivityResult != null && - connectivityResult == ConnectivityResult.wifi && - savedWifiBssidWithoutLastNumber != null && - wifiBSSIDWithoutLastNumber != null && - savedWifiBssidWithoutLastNumber == wifiBSSIDWithoutLastNumber) { - logger.i('Connect using direct connection to Hub'); - - if (IHubConnectionRepository.hubEntity?.lastKnownIp.getOrCrash() != - null) { - Socket? testHubConnection; - try { - testHubConnection = await Socket.connect( - IHubConnectionRepository.hubEntity!.lastKnownIp.getOrCrash(), - hubPort, - timeout: const Duration(milliseconds: 500), - ); - testHubConnection.destroy(); - } catch (e) { - testHubConnection?.destroy(); - - await searchForHub(); - } - } else { - await searchForHub(); - } - - try { - final CompHubInfo? compHubInfo = await HubClient.getHubCompInfo( - IHubConnectionRepository.hubEntity!.lastKnownIp.getOrCrash(), - hubPort, - appInfoForHub, - ); - - if (compHubInfo == null) { - return left(const HubFailures.unexpected()); - } - return right(compHubInfo); - } catch (e) { - logger.e('Error getting hubInfo\n$e'); - return left(const HubFailures.unexpected()); - } - - // return; - } else { - logger.i('Connect using Remote Pipes'); - return (await ILocalDbRepository.instance.getRemotePipesDnsName()).fold( - (l) { - logger.e('Cant find local Remote Pipes Dns name'); - return left(const HubFailures.unexpected()); - }, (r) async { - try { - final CompHubInfo? compHubInfo = - await HubClient.getHubCompInfo(r, 50056, appInfoForHub); - - if (compHubInfo == null) { - return left(const HubFailures.unexpected()); - } - return right(compHubInfo); - } catch (e) { - logger.e('Error getting hubInfo\n$e'); - return left(const HubFailures.unexpected()); - } - }); - // Here for easy find and local testing - // HubClient.createStreamWithHub('127.0.0.1', 50056); - } - } - - @override - Future closeConnection() async { - cancelConnectionWithHub = true; - } - - /// Search device IP by computer Avahi (mdns) name - Future getDeviceIpByDeviceAvahiName(String mDnsName) async { - String deviceIp = ''; - // final String fullMdnsName = '$mDnsName.local'; - - final MDnsClient client = MDnsClient( - rawDatagramSocketFactory: ( - dynamic host, - int port, { - bool? reuseAddress, - bool? reusePort, - int? ttl, - }) { - return RawDatagramSocket.bind(host, port, ttl: ttl!); - }, - ); - - // Start the client with default options. - await client.start(); - await for (final IPAddressResourceRecord record - in client.lookup( - ResourceRecordQuery.addressIPv4(mDnsName), - )) { - deviceIp = record.address.address; - logger.i('Found address (${record.address}).'); - } - - // await for (final IPAddressResourceRecord record - // in client.lookup( - // ResourceRecordQuery.addressIPv6(fullMdnsName))) { - // logger.t('Found address (${record.address}).'); - // } - - client.stop(); - - logger.t('Done.'); - - return deviceIp; - } - - @override - Future> searchForHub({ - String? deviceIpOnTheNetwork, - bool? isThatTheIpOfTheHub, - }) async { - try { - final Either locationRequest = - await askLocationPermissionAndLocationOn(); - - if (locationRequest.isLeft()) { - return locationRequest; - } - - logger.i('searchForHub'); - - String? currentDeviceIP; - String? networkBSSID; - String? networkName; - if (await Connectivity().checkConnectivity() == ConnectivityResult.wifi && - !kIsWeb) { - final NetworkInfo networkInfo = NetworkInfo(); - networkName = await networkInfo.getWifiName(); - currentDeviceIP = await networkInfo.getWifiIP(); - networkBSSID = await networkInfo.getWifiBSSID(); - } else { - if (deviceIpOnTheNetwork == null) { - // Issue https://github.com/CyBear-Jinni/cbj_app/issues/256 - return left( - const HubFailures - .findingHubWhenConnectedToEthernetCableIsNotSupported(), - ); - } - - currentDeviceIP = deviceIpOnTheNetwork; - networkBSSID = 'no:Network:Bssid:Found'; - networkName = 'noNetworkNameFound'; - if (isThatTheIpOfTheHub != null && isThatTheIpOfTheHub) { - return insertHubInfo( - networkIp: currentDeviceIP, - networkBSSID: networkBSSID, - networkName: networkName, - ); - } - } - - final String subnet = - currentDeviceIP!.substring(0, currentDeviceIP.lastIndexOf('.')); - - logger.i('Hub Search subnet IP $subnet'); - - // TODO: Search for hub - // final Stream devicesWithPort = - // HostScanner.scanDevicesForSinglePort( - // subnet, - // hubPort, - - // /// TODO: return this settings when can use with the await for loop - // // resultsInIpAscendingOrder: false, - // timeout: const Duration(milliseconds: 600), - // ); - - // await for (final ActiveHost activeHost in devicesWithPort) { - // logger.i('Found Cbj Hub device: ${activeHost.address}'); - // if (networkBSSID != null && networkName != null) { - // return insertHubInfo( - // networkIp: activeHost.address, - // networkBSSID: networkBSSID, - // networkName: networkName, - // ); - // } - // } - } catch (e) { - logger.w('Exception searchForHub\n$e'); - } - await Future.delayed(const Duration(seconds: 5)); - return left(const HubFailures.cantFindHubInNetwork()); - } - - @override - Future saveHubIP(String hubIP) async { - logger.w('saveHubIP'); - } - - Future> askLocationPermissionAndLocationOn() async { - final Location location = Location(); - - bool serviceEnabled; - PermissionStatus permissionGranted; - - int permissionCounter = 0; - int disabledCounter = 0; - - // Get location permission is not supported on Linux - if (Platform.isLinux || Platform.isWindows) { - return right(unit); - } - - while (true) { - permissionGranted = await location.hasPermission(); - if (permissionGranted == PermissionStatus.denied) { - permissionGranted = await location.requestPermission(); - if (permissionGranted != PermissionStatus.granted) { - logger.e('Permission to use location is denied'); - await Future.delayed(const Duration(seconds: 10)); - - permissionCounter++; - if (permissionCounter > 5) { - permission_handler.openAppSettings(); - } else if (permissionCounter > 7) { - return const Left(HubFailures.unexpected()); - } - continue; - } - } - - serviceEnabled = await location.serviceEnabled(); - if (!serviceEnabled) { - serviceEnabled = await location.requestService(); - if (!serviceEnabled) { - disabledCounter++; - if (disabledCounter > 2) { - return const Left(HubFailures.unexpected()); - } - logger.w('Location is disabled'); - await Future.delayed(const Duration(seconds: 5)); - continue; - } - } - break; - } - return right(unit); - } - - /// Will save hub info both on ram and to the local database - Future> insertHubInfo({ - required String networkIp, - required String networkName, - required String networkBSSID, - }) async { - IHubConnectionRepository.hubEntity = HubEntity( - hubNetworkBssid: HubNetworkBssid(networkBSSID), - networkName: HubNetworkName(networkName), - lastKnownIp: HubNetworkIp(networkIp), - ); - - final HubDtos hubDtos = - IHubConnectionRepository.hubEntity!.toInfrastructure(); - - (await ILocalDbRepository.instance.saveHubEntity( - hubNetworkBssid: hubDtos.hubNetworkBssid, - networkName: hubDtos.networkName, - lastKnownIp: hubDtos.lastKnownIp, - )) - .fold( - (l) => logger.e('Cant find local Remote Pipes Dns name'), - (r) => logger.i('Found CyBear Jinni Hub'), - ); - return right(unit); - } - - Future streamFromDemoMode() async { - await HubClientDemo.createStreamWithHub(); - } - - /// Load saved Hub network information and load it to - /// IHubConnectionRepository.hubEntity - Future loadNetworkInformationFromDb() async { - try { - String? hubNetworkBssid; - (await ILocalDbRepository.instance.getHubEntityNetworkBssid()).fold( - (l) => throw 'Error getting Hub network Bssid', - (r) => hubNetworkBssid = r, - ); - - String? hubNetworkName; - (await ILocalDbRepository.instance.getHubEntityNetworkName()).fold( - (l) => throw 'Error getting Hub network name', - (r) => hubNetworkName = r, - ); - - String? hubNetworkIp; - (await ILocalDbRepository.instance.getHubEntityLastKnownIp()).fold( - (l) => throw 'Error getting Hub network IP', - (r) => hubNetworkIp = r, - ); - IHubConnectionRepository.hubEntity = HubDtos( - hubNetworkBssid: hubNetworkBssid!, - lastKnownIp: hubNetworkIp!, - networkName: hubNetworkName!, - ).toDomain(); - } catch (e) { - logger.e('Crashed while setting Hub info from local db\n$e'); - } - } - - /// Connect directly to the Hub if possible - Future connectDirectlyToHub() async { - Socket? testHubConnection; - try { - testHubConnection = await Socket.connect( - IHubConnectionRepository.hubEntity!.lastKnownIp.getOrCrash(), - hubPort, - timeout: const Duration(milliseconds: 500), - ); - await testHubConnection.close(); - testHubConnection.destroy(); - testHubConnection = null; - } catch (e) { - await testHubConnection?.close(); - testHubConnection?.destroy(); - - Either foundAHub = await searchForHub(); - // If can't find hub in local network - if (foundAHub.isLeft()) { - // Connect using Remote pipes if connection information exists - if ((await ILocalDbRepository.instance.getRemotePipesDnsName()) - .isRight()) { - await connectionUsingRemotePipes(); - return; - } - while (true) { - foundAHub = await searchForHub(); - if (foundAHub.isRight()) { - break; - } - } - } - } - - tryAgainConnectToTheHubOnceMore = 0; - await HubClient.createStreamWithHub( - IHubConnectionRepository.hubEntity!.lastKnownIp.getOrCrash(), - hubPort, - ); - } - - /// Connect to the Hub using the Remote Pipes - Future connectionUsingRemotePipes() async { - (await ILocalDbRepository.instance.getRemotePipesDnsName()).fold( - (l) async { - (await openAndroidWifiSettingIfPossible()).fold( - (l) { - logger.w( - 'No way to establish connection with the Hub, WiFi or location' - ' permission is closed'); - }, - (r) async { - await connectWithHub(); - }, - ); - }, - (r) { - logger.i('Connect using Remote Pipes'); - HubClient.createStreamWithHub(r, 50056); - tryAgainConnectToTheHubOnceMore = 0; - }, - ); - } - - Future> openAndroidWifiSettingIfPossible() async { - final bool wifiEnabled = await WiFiForIoTPlugin.isEnabled(); - final Location location = Location(); - - if (wifiEnabled && await location.serviceEnabled()) { - final bool wifiEnabled = await WiFiForIoTPlugin.isConnected(); - if (wifiEnabled) { - return right(unit); - } - // while (true) { - // if (wifiEnabled) { - // if (tryAgainConnectToTheHubOnceMore <= 10) { - // // Even if WiFi got enabled it still takes time for the - // // device to complete the automatic connection to previous - // // WiFi network, so we give it a little time before stop trying - // tryAgainConnectToTheHubOnceMore += 1; - // await Future.delayed(const Duration(seconds: 5)); - // } else { - // logger.w( - // "User cannot connect to home as he is A. Not in his home B. Didn't set Remote Pipes", - // ); - // } - // } else { - // logger.t('User not connected to any WiFi, Will try again.'); - // tryAgainConnectToTheHubOnceMore = 0; - // await Future.delayed(const Duration(milliseconds: 500)); - // - // return right(unit); - // } - // } - } else { - logger.w( - 'Will ask the user to open WiFi and gps to try local connection', - ); - final bool wifiEnabled = await WiFiForIoTPlugin.isEnabled(); - if (!wifiEnabled) { - WiFiForIoTPlugin.setEnabled(true, shouldOpenSettings: true); - tryAgainConnectToTheHubOnceMore = 0; - await Future.delayed(const Duration(milliseconds: 500)); - return right(unit); - } - - (await askLocationPermissionAndLocationOn()).fold((l) { - logger.e( - 'User does not allow opening location and does not have remote pipes info', - ); - }, (r) async { - // Try to connect again because there is a chance user without - // remote pipes info but is in his home - return right(unit); - }); - } - return const Left(HubFailures.unexpected()); - } -} diff --git a/lib/infrastructure/hub_client/hub_requests_routing.dart b/lib/infrastructure/hub_client/hub_requests_routing.dart deleted file mode 100644 index 32cd3113..00000000 --- a/lib/infrastructure/hub_client/hub_requests_routing.dart +++ /dev/null @@ -1,221 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:cybearjinni/domain/device/i_device_repository.dart'; -import 'package:cybearjinni/domain/i_hub_connection_repository.dart'; -import 'package:cybearjinni/infrastructure/core/injection.dart'; -import 'package:cybearjinni/infrastructure/core/logger.dart'; -import 'package:grpc/grpc.dart'; - -@Deprecated( - 'Old architecture. Replaced with ConnectionsService. Delete after Re adding Hub comunication', -) -class HubRequestRouting { - static StreamSubscription? requestsFromHubSubscription; - - static Stream? connectivityChangedStream; - - static bool areWeRunning = false; - - // static int numberOfCrashes = 0; - static int numberOfConnectivityChange = 0; - - static Future navigateRequest() async { - if (areWeRunning) { - return; - } - - await Future.delayed(const Duration(milliseconds: 100)); - - if (areWeRunning) { - return; - } - areWeRunning = true; - - // await requestsFromHubSubscription?.cancel(); - // requestsFromHubSubscription = null; - connectivityChangedStream = null; - - requestsFromHubSubscription = HubRequestsToApp.streamRequestsToApp.stream - .listen((dynamic requestsAndStatusFromHub) { - if (requestsAndStatusFromHub is! RequestsAndStatusFromHub) { - return; - } - if (requestsAndStatusFromHub.sendingType == SendingType.entityType) { - navigateDeviceRequest(requestsAndStatusFromHub.allRemoteCommands); - } else if (requestsAndStatusFromHub.sendingType == SendingType.areaType) { - navigateAreaRequest(requestsAndStatusFromHub.allRemoteCommands); - } else if (requestsAndStatusFromHub.sendingType == - SendingType.sceneType) { - navigateSceneRequest(requestsAndStatusFromHub.allRemoteCommands); - } else { - logger.i( - 'Got from Hub unsupported massage type: ' - '${requestsAndStatusFromHub.sendingType}', - ); - } - }); - requestsFromHubSubscription?.onError((error) async { - if (error is GrpcError && error.code == 1) { - logger.t('Hub have been disconnected'); - } - // else if (error is GrpcError && error.code == 2) { - // logger.t('Hub have been terminated'); - // } - else { - logger.e('Hub stream error: $error'); - if (error.toString().contains('errorCode: 10')) { - areWeRunning = false; - - navigateRequest(); - } - } - }); - - connectivityChangedStream = Connectivity().onConnectivityChanged; - connectivityChangedStream?.listen((ConnectivityResult event) async { - numberOfConnectivityChange++; - logger.i('Connectivity changed ${event.name} And $event'); - if (event == ConnectivityResult.none || numberOfConnectivityChange <= 1) { - return; - } - areWeRunning = false; - navigateRequest(); - }); - - await IHubConnectionRepository.instance.connectWithHub(); - } - - static Future navigateAreaRequest( - String allRemoteCommands, - ) async { - // final Map requestAsJson = - // jsonDecode(allRemoteCommands) as Map; - - // final AreaEntityDtos areaEntityDtos = AreaEntityDtos( - // uniqueId: requestAsJson['uniqueId'] as String, - // cbjEntityName: requestAsJson['cbjEntityName'] as String, - // background: requestAsJson['background'] as String, - // areaTypes: Set.from(requestAsJson['areaTypes'] as Set), - // areaDevicesId: - // Set.from(requestAsJson['areaDevicesId'] as Set), - // areaScenesId: - // Set.from(requestAsJson['areaScenesId'] as Set), - // areaRoutinesId: - // Set.from(requestAsJson['areaRoutinesId'] as Set), - // areaBindingsId: - // Set.from(requestAsJson['areaBindingsId'] as Set), - // areaMostUsedBy: - // Set.from(requestAsJson['areaMostUsedBy'] as Set), - // areaPermissions: - // Set.from(requestAsJson['areaPermissions'] as Set), - // ); - - // final AreaEntity areaEntity = areaEntityDtos.toDomain(); - - // IAreaRepository.instance.addOrUpdateArea(areaEntity); - } - - static Future navigateDeviceRequest( - String allRemoteCommands, - ) async { - final Map requestAsJson = - jsonDecode(allRemoteCommands) as Map; - final String? deviceTypeAsString = requestAsJson['entityTypes'] as String?; - - final String? deviceStateAsString = - requestAsJson['entityStateGRPC'] as String?; - if (deviceTypeAsString == null || deviceStateAsString == null) { - return; - } - - ///TODO: add request type login support - - final EntityTypes? deviceType = EntityUtils.stringToDt(deviceTypeAsString); - - final EntityStateGRPC? entityStateGRPC = - EntityUtils.stringToDeviceState(deviceStateAsString); - - if (deviceType == null || entityStateGRPC == null) { - return; - } - - late DeviceEntityBase deviceEntity; - - switch (deviceType) { - case EntityTypes.light: - deviceEntity = - GenericLightDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Light device type'); - case EntityTypes.dimmableLight: - deviceEntity = - GenericDimmableLightDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Dimmable Light device type'); - case EntityTypes.rgbwLights: - deviceEntity = - GenericRgbwLightDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding rgbW light device type'); - case EntityTypes.blinds: - deviceEntity = - GenericBlindsDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Blinds device type'); - case EntityTypes.boiler: - deviceEntity = - GenericBoilerDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Boiler device type'); - case EntityTypes.smartTV: - deviceEntity = - GenericSmartTvDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart TV device type'); - case EntityTypes.switch_: - deviceEntity = - GenericSwitchDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Addin' - 'g Switch device type'); - case EntityTypes.smartPlug: - deviceEntity = - GenericSmartPlugDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart Plug device type'); - case EntityTypes.smartComputer: - deviceEntity = - GenericSmartComputerDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart Plug device type'); - case EntityTypes.printer: - deviceEntity = - GenericPrinterDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart printer device type'); - case EntityTypes.securityCamera: - deviceEntity = - GenericSecurityCameraDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.i('Adding Smart camera device type'); - default: - if (entityStateGRPC == EntityStateGRPC.pingNow) { - deviceEntity = - GenericPingDeviceDtos.fromJson(requestAsJson).toDomain(); - logger.t('Got Ping request'); - return; - } else { - logger.w( - 'Entity type is $deviceType is not supported $entityStateGRPC ', - ); - deviceEntity = - GenericUnsupportedDeviceDtos.fromJson(requestAsJson).toDomain(); - } - break; - } - IDeviceRepository.instance.addOrUpdateDevice(deviceEntity); - } - - static Future navigateSceneRequest( - String allRemoteCommands, - ) async { - final Map requestAsJson = - jsonDecode(allRemoteCommands) as Map; - final SceneCbjDtos sceneCbjDtos = SceneCbjDtos.fromJson(requestAsJson); - - getIt() - .addOrUpdateNewSceneInApp(sceneCbjDtos.toDomain()); - } -} diff --git a/lib/infrastructure/isar_local_db/isar_repository.dart b/lib/infrastructure/isar_local_db/isar_repository.dart index ad3e9678..127a9175 100644 --- a/lib/infrastructure/isar_local_db/isar_repository.dart +++ b/lib/infrastructure/isar_local_db/isar_repository.dart @@ -3,7 +3,7 @@ part of 'package:cybearjinni/domain/i_local_db_repository.dart'; class _IsarRepository implements ILocalDbRepository { late Isar isar; @override - Future asyncConstructor() async { + Future asyncConstructor() async { final dir = await getApplicationDocumentsDirectory(); isar = await Isar.open( [ diff --git a/lib/infrastructure/mqtt.dart b/lib/infrastructure/mqtt.dart index 281bc2bb..27a67a14 100644 --- a/lib/infrastructure/mqtt.dart +++ b/lib/infrastructure/mqtt.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:mqtt_client/mqtt_client.dart'; @@ -13,10 +11,10 @@ class MqttServerRepository extends IMqttServerRepository { } @override - Future allHubDevicesSubscriptions() async {} + Future allHubDevicesSubscriptions() async {} @override - Future asyncConstructor() async {} + Future asyncConstructor() async {} @override Future connect() async { @@ -45,25 +43,25 @@ class MqttServerRepository extends IMqttServerRepository { String getScenesTopicTypeName() => ''; @override - Future postSmartDeviceToAppMqtt({ + Future postSmartDeviceToAppMqtt({ required DeviceEntityBase entityFromTheHub, }) async { - HubRequestsToApp.streamRequestsToApp.sink.add( - RequestsAndStatusFromHub( - sendingType: SendingType.entityType, - allRemoteCommands: - DeviceHelper.convertDomainToJsonString(entityFromTheHub), - ), - ); + // HubRequestsToApp.streamRequestsToApp.sink.add( + // RequestsAndStatusFromHub( + // sendingType: SendingType.entityType.name, + // allRemoteCommands: + // DeviceHelper.convertDomainToJsonString(entityFromTheHub), + // ), + // ); } @override - Future postToAppMqtt({ + Future postToAppMqtt({ required DeviceEntityBase entityFromTheHub, }) async {} @override - Future postToHubMqtt({ + Future postToHubMqtt({ required dynamic entityFromTheApp, bool? gotFromApp, }) async { @@ -87,24 +85,24 @@ class MqttServerRepository extends IMqttServerRepository { // ISavedAreasRepo.instance.addOrUpdateArea(entityFromTheApp.toDomain()); /// Sends directly to device connector conjecture - HubRequestsToApp.streamRequestsToApp.add( - RequestsAndStatusFromHub( - sendingType: SendingType.areaType, - allRemoteCommands: jsonEncode(entityFromTheApp.toJson()), - ), - ); + // HubRequestsToApp.streamRequestsToApp.add( + // RequestsAndStatusFromHub( + // sendingType: SendingType.areaType.name, + // allRemoteCommands: jsonEncode(entityFromTheApp.toJson()), + // ), + // ); return; } logger.i('Type interaction support is missing $entityFromTheApp'); } @override - Future publishDeviceEntity( + Future publishDeviceEntity( DeviceEntityBase deviceEntityDtoAbstract, ) async {} @override - Future publishMessage(String topic, String message) async {} + Future publishMessage(String topic, String message) async {} @override Future?> readingFromMqttOnce(String topic) async { @@ -112,7 +110,7 @@ class MqttServerRepository extends IMqttServerRepository { } @override - Future sendToApp() async {} + Future sendToApp() async {} @override Stream>> @@ -150,5 +148,5 @@ class MqttServerRepository extends IMqttServerRepository { } @override - Future subscribeToTopic(String topic) async {} + Future subscribeToTopic(String topic) async {} } diff --git a/lib/infrastructure/security_bear_client/security_bear_connection_repository.dart b/lib/infrastructure/security_bear_client/security_bear_connection_repository.dart index ad290f5d..67904fa2 100644 --- a/lib/infrastructure/security_bear_client/security_bear_connection_repository.dart +++ b/lib/infrastructure/security_bear_client/security_bear_connection_repository.dart @@ -16,7 +16,7 @@ class _SecurityBearConnectionRepository static SecurityBearEntity? securityBearEntity; - // Future connectWithSecurityBear() async { + // Future connectWithSecurityBear() async { // if (securityBearEntity == null) { // try { // String? securityBearNetworkBssid; diff --git a/lib/infrastructure/software_info/software_info_repository.dart b/lib/infrastructure/software_info/software_info_repository.dart index 9f528ee2..b18f06ae 100644 --- a/lib/infrastructure/software_info/software_info_repository.dart +++ b/lib/infrastructure/software_info/software_info_repository.dart @@ -44,19 +44,19 @@ class _SoftwareInfoRepository implements ISoftwareInfoRepository { appInfoForHub ??= CompHubInfo(); - final Either hubResponse = - await IHubConnectionRepository.instance.getHubCompInfo(appInfoForHub); - - return hubResponse.fold( - (l) => left(const SoftwareInfoFailures.unexpected()), - (r) { - return right(SoftwareInfoEntity.compHubInfo(r)); - }, - ); + // final Either hubResponse = + // await IHubConnectionRepository.instance.getHubCompInfo(appInfoForHub); + + // return hubResponse.fold( + // (l) => left(const SoftwareInfoFailures.unexpected()), + // (r) { + // return right(SoftwareInfoEntity.compHubInfo(r)); + // }, + // ); } catch (e) { logger.e('Software info from hub error\n$e'); - return left(const SoftwareInfoFailures.unexpected()); } + return left(const SoftwareInfoFailures.unexpected()); } @override diff --git a/lib/presentation/atoms/scene_atom.dart b/lib/presentation/atoms/scene_atom.dart index 8f6d8a49..658d228e 100644 --- a/lib/presentation/atoms/scene_atom.dart +++ b/lib/presentation/atoms/scene_atom.dart @@ -17,7 +17,7 @@ class SceneAtom extends StatefulWidget { class _SceneAtomState extends State { late SceneCbjEntity sceneCbj; - Future _activateScene() async => ConnectionsService.instance + Future _activateScene() async => ConnectionsService.instance .activateScene(widget.currentScene.uniqueId.getOrCrash()); @override diff --git a/lib/presentation/molecules/devices/ac_molecule.dart b/lib/presentation/molecules/devices/ac_molecule.dart index 53d4c71c..903e0600 100644 --- a/lib/presentation/molecules/devices/ac_molecule.dart +++ b/lib/presentation/molecules/devices/ac_molecule.dart @@ -18,7 +18,7 @@ class AcMolecule extends StatefulWidget { } class _AcMoleculeState extends State { - Future _turnOnAllAcs() async { + Future _turnOnAllAcs() async { FlushbarHelper.createLoading( message: 'Turning_On_ac'.tr(), linearProgressIndicator: const LinearProgressIndicator(), @@ -47,7 +47,7 @@ class _AcMoleculeState extends State { ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: EntityProperties.acSwitchState, actionType: action, @@ -55,7 +55,7 @@ class _AcMoleculeState extends State { ); } - Future _turnOffAllAcs() async { + Future _turnOffAllAcs() async { FlushbarHelper.createLoading( message: 'Turning_Off_ac'.tr(), linearProgressIndicator: const LinearProgressIndicator(), diff --git a/lib/presentation/molecules/devices/blind_molecule.dart b/lib/presentation/molecules/devices/blind_molecule.dart index 4795a196..a95eb30f 100644 --- a/lib/presentation/molecules/devices/blind_molecule.dart +++ b/lib/presentation/molecules/devices/blind_molecule.dart @@ -21,7 +21,7 @@ class BlindMolecule extends StatefulWidget { } class _BlindMoleculeState extends State { - Future _moveUpAllBlinds() async { + Future _moveUpAllBlinds() async { FlushbarHelper.createLoading( message: 'Pulling_Up_all_blinds'.tr(), linearProgressIndicator: const LinearProgressIndicator(), @@ -50,7 +50,7 @@ class _BlindMoleculeState extends State { ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: EntityProperties.blindsSwitchState, actionType: action, @@ -58,7 +58,7 @@ class _BlindMoleculeState extends State { ); } - Future _stopAllBlinds(List blindsIdToStop) async { + Future _stopAllBlinds(List blindsIdToStop) async { FlushbarHelper.createLoading( message: 'Stopping_all_blinds'.tr(), linearProgressIndicator: const LinearProgressIndicator(), @@ -67,7 +67,7 @@ class _BlindMoleculeState extends State { setEntityState(EntityActions.stop); } - Future _moveDownAllBlinds(List blindsIdToTurnDown) async { + Future _moveDownAllBlinds(List blindsIdToTurnDown) async { FlushbarHelper.createLoading( message: 'Pulling_down_all_blinds'.tr(), linearProgressIndicator: const LinearProgressIndicator(), diff --git a/lib/presentation/molecules/devices/boiler_molecule.dart b/lib/presentation/molecules/devices/boiler_molecule.dart index 2987f8cd..c881dd98 100644 --- a/lib/presentation/molecules/devices/boiler_molecule.dart +++ b/lib/presentation/molecules/devices/boiler_molecule.dart @@ -18,7 +18,7 @@ class BoilerMolecule extends StatefulWidget { } class _BoilerMoleculeState extends State { - Future _turnOnAllBoilers() async { + Future _turnOnAllBoilers() async { FlushbarHelper.createLoading( message: 'Turning_On_boiler'.tr(), linearProgressIndicator: const LinearProgressIndicator(), @@ -47,7 +47,7 @@ class _BoilerMoleculeState extends State { ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: EntityProperties.boilerSwitchState, actionType: action, @@ -55,7 +55,7 @@ class _BoilerMoleculeState extends State { ); } - Future _turnOffAllBoilers() async { + Future _turnOffAllBoilers() async { FlushbarHelper.createLoading( message: 'Turning_Off_boiler'.tr(), linearProgressIndicator: const LinearProgressIndicator(), diff --git a/lib/presentation/molecules/devices/dimmable_light_molecule.dart b/lib/presentation/molecules/devices/dimmable_light_molecule.dart index e7a5e3da..5128c3f9 100644 --- a/lib/presentation/molecules/devices/dimmable_light_molecule.dart +++ b/lib/presentation/molecules/devices/dimmable_light_molecule.dart @@ -27,7 +27,7 @@ class _DimmableLightMoleculeState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { final GenericDimmableLightDE rgbwLightDe = widget.entity; double lightBrightness = @@ -42,7 +42,7 @@ class _DimmableLightMoleculeState extends State { }); } - Future _changeBrightness(double value) async { + Future _changeBrightness(double value) async { setState(() { brightness = value; }); @@ -90,7 +90,7 @@ class _DimmableLightMoleculeState extends State { ], ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: property, actionType: action, diff --git a/lib/presentation/molecules/devices/light_card_molecule.dart b/lib/presentation/molecules/devices/light_card_molecule.dart index eb6d16c2..bf5cb74f 100644 --- a/lib/presentation/molecules/devices/light_card_molecule.dart +++ b/lib/presentation/molecules/devices/light_card_molecule.dart @@ -1,5 +1,4 @@ import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/device/i_device_repository.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:flutter/material.dart'; @@ -8,19 +7,19 @@ class LightCardMolecule extends StatelessWidget { final GenericLightDE? entity; - Future _onChange(bool value) async { - final GenericLightDE tempDeviceEntity = entity! - ..entityStateGRPC = EntityState.state(EntityStateGRPC.waitingInCloud) - ..lightSwitchState = GenericLightSwitchState(value.toString()); + Future _onChange(bool value) async { + // final GenericLightDE tempDeviceEntity = entity! + // ..entityStateGRPC = EntityState.state(EntityStateGRPC.waitingInCloud) + // ..lightSwitchState = GenericLightSwitchState(value.toString()); if (value) { - await IDeviceRepository.instance.turnOnDevices( - devicesId: [tempDeviceEntity.deviceCbjUniqueId.getOrCrash()], - ); + // await IDeviceRepository.instance.turnOnDevices( + // devicesId: [tempDeviceEntity.deviceCbjUniqueId.getOrCrash()], + // ); } else { - await IDeviceRepository.instance.turnOffDevices( - devicesId: [tempDeviceEntity.deviceCbjUniqueId.getOrCrash()], - ); + // await IDeviceRepository.instance.turnOffDevices( + // devicesId: [tempDeviceEntity.deviceCbjUniqueId.getOrCrash()], + // ); } } diff --git a/lib/presentation/molecules/devices/light_molecule.dart b/lib/presentation/molecules/devices/light_molecule.dart index 62539a5e..70d820b3 100644 --- a/lib/presentation/molecules/devices/light_molecule.dart +++ b/lib/presentation/molecules/devices/light_molecule.dart @@ -35,7 +35,7 @@ class LightMolecule extends StatelessWidget { ], ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: EntityProperties.lightSwitchState, actionType: action, diff --git a/lib/presentation/molecules/devices/printer_molecule.dart b/lib/presentation/molecules/devices/printer_molecule.dart index 49637125..e0e3cfec 100644 --- a/lib/presentation/molecules/devices/printer_molecule.dart +++ b/lib/presentation/molecules/devices/printer_molecule.dart @@ -18,7 +18,7 @@ class PrinterMolecule extends StatefulWidget { } class _PrinterMoleculeState extends State { - Future _openPrintersWebPage() async { + Future _openPrintersWebPage() async { FlushbarHelper.createLoading( message: 'Opening printers Web Page', linearProgressIndicator: const LinearProgressIndicator(), diff --git a/lib/presentation/molecules/devices/rgb_light_molecule.dart b/lib/presentation/molecules/devices/rgb_light_molecule.dart index bff49486..687b51b3 100644 --- a/lib/presentation/molecules/devices/rgb_light_molecule.dart +++ b/lib/presentation/molecules/devices/rgb_light_molecule.dart @@ -30,7 +30,7 @@ class _RgbwLightMoleculeState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { final GenericRgbwLightDE rgbwLightDe = widget.entity; int lightColorTemperature = @@ -83,7 +83,7 @@ class _RgbwLightMoleculeState extends State { ], ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: entityProperties, actionType: action, @@ -92,7 +92,7 @@ class _RgbwLightMoleculeState extends State { ); } - Future _changeBrightness(double value) async { + Future _changeBrightness(double value) async { setState(() { brightness = value; }); @@ -184,7 +184,7 @@ class _LightColorMods extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { final GenericRgbwLightDE rgbwLightDe = widget.entity; int lightColorTemperature = @@ -230,7 +230,7 @@ class _LightColorMods extends State { ], ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: entityProperties, actionType: action, @@ -239,7 +239,7 @@ class _LightColorMods extends State { ); } - Future _changeColorTemperature(int newColorTemperature) async { + Future _changeColorTemperature(int newColorTemperature) async { setState(() { colorTemperature = newColorTemperature; }); @@ -250,7 +250,7 @@ class _LightColorMods extends State { ); } - Future _changeHsvColor(HSVColor newHsvColor) async { + Future _changeHsvColor(HSVColor newHsvColor) async { setState(() { hsvColor = newHsvColor; }); @@ -309,14 +309,14 @@ class _LightColorMods extends State { ); } - Future _showWhiteMode() async { + Future _showWhiteMode() async { setState(() { colorModFocus = 0; colorModeWidget = getWhiteModeWidget(); }); } - Future _showColorMode() async { + Future _showColorMode() async { setState(() { colorModFocus = 1; colorModeWidget = getHsvColorModeWidget(); diff --git a/lib/presentation/molecules/devices/security_camera_molecule.dart b/lib/presentation/molecules/devices/security_camera_molecule.dart index f530314a..ec964cae 100644 --- a/lib/presentation/molecules/devices/security_camera_molecule.dart +++ b/lib/presentation/molecules/devices/security_camera_molecule.dart @@ -19,7 +19,7 @@ class SecurityCameraMolecule extends StatefulWidget { } class _SecurityCameraMoleculeState extends State { - Future _openCameraPage() async { + Future _openCameraPage() async { FlushbarHelper.createLoading( message: 'Opening Camera', linearProgressIndicator: const LinearProgressIndicator(), diff --git a/lib/presentation/molecules/devices/smart_computer_molecule.dart b/lib/presentation/molecules/devices/smart_computer_molecule.dart index f30f7c3a..7328aeca 100644 --- a/lib/presentation/molecules/devices/smart_computer_molecule.dart +++ b/lib/presentation/molecules/devices/smart_computer_molecule.dart @@ -1,6 +1,5 @@ import 'package:another_flushbar/flushbar_helper.dart'; import 'package:cbj_integrations_controller/integrations_controller.dart'; -import 'package:cybearjinni/domain/device/i_device_repository.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; import 'package:flutter/material.dart'; @@ -18,22 +17,22 @@ class SmartComputerMolecule extends StatefulWidget { } class _SmartComputerMoleculeState extends State { - Future _suspendAllSmartComputers(List smartComputersId) async { + Future _suspendAllSmartComputers(List smartComputersId) async { FlushbarHelper.createLoading( message: 'Suspending all Smart Computers', linearProgressIndicator: const LinearProgressIndicator(), ).show(context); - IDeviceRepository.instance.suspendDevices(devicesId: smartComputersId); + // IDeviceRepository.instance.suspendDevices(deviDscesId: smartComputersId); } - Future _shutdownAllSmartComputers(List smartComputersId) async { + Future _shutdownAllSmartComputers(List smartComputersId) async { FlushbarHelper.createLoading( message: 'Suspending all Smart Computers', linearProgressIndicator: const LinearProgressIndicator(), ).show(context); - IDeviceRepository.instance.shutdownDevices(devicesId: smartComputersId); + // IDeviceRepository.instance.shutdownDevices(devicesId: smartComputersId); } void suspendComputer(BuildContext context) { diff --git a/lib/presentation/molecules/devices/smart_plug_molecule.dart b/lib/presentation/molecules/devices/smart_plug_molecule.dart index a215944c..19a3cfc6 100644 --- a/lib/presentation/molecules/devices/smart_plug_molecule.dart +++ b/lib/presentation/molecules/devices/smart_plug_molecule.dart @@ -23,7 +23,7 @@ class _SmartPlugsMoleculeState extends State { Timer? timeFromLastColorChange; HSVColor? lastColoredPicked; - Future _changeAction(bool value) async { + Future _changeAction(bool value) async { setEntityState(value ? EntityActions.on : EntityActions.off); } @@ -45,7 +45,7 @@ class _SmartPlugsMoleculeState extends State { ], ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: EntityProperties.lightSwitchState, actionType: action, diff --git a/lib/presentation/molecules/devices/smart_tv_molecule.dart b/lib/presentation/molecules/devices/smart_tv_molecule.dart index 750c5d80..8a6739c2 100644 --- a/lib/presentation/molecules/devices/smart_tv_molecule.dart +++ b/lib/presentation/molecules/devices/smart_tv_molecule.dart @@ -94,7 +94,7 @@ class _SmartTvMoleculeState extends State { ], ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: property, actionType: action, diff --git a/lib/presentation/molecules/devices/switch_molecule.dart b/lib/presentation/molecules/devices/switch_molecule.dart index af5f09ed..0594b522 100644 --- a/lib/presentation/molecules/devices/switch_molecule.dart +++ b/lib/presentation/molecules/devices/switch_molecule.dart @@ -23,7 +23,7 @@ class _SwitchMoleculeState extends State { Timer? timeFromLastColorChange; HSVColor? lastColoredPicked; - Future _changeAction(bool value) async { + Future _changeAction(bool value) async { setEntityState(value ? EntityActions.on : EntityActions.off); } @@ -45,7 +45,7 @@ class _SwitchMoleculeState extends State { ], ); ConnectionsService.instance.setEntityState( - ActionObject( + RequestActionObject( uniqueIdByVendor: uniqueIdByVendor, property: EntityProperties.lightSwitchState, actionType: action, diff --git a/lib/presentation/pages/add_action_page.dart b/lib/presentation/pages/add_action_page.dart index 61b19e62..c405ad66 100644 --- a/lib/presentation/pages/add_action_page.dart +++ b/lib/presentation/pages/add_action_page.dart @@ -28,13 +28,13 @@ class _AddActionPageState extends State { }); } - Future onActionSelected(String value) async { + Future onActionSelected(String value) async { setState(() { selectedAction = EntityActions.values.elementAt(int.parse(value)); }); } - Future _onPropertySelected(String property) async { + Future _onPropertySelected(String property) async { setState(() { selectedProperty = EntityProperties.values.elementAt(int.parse(property)); }); diff --git a/lib/presentation/pages/add_bindings/add_binding_page.dart b/lib/presentation/pages/add_bindings/add_binding_page.dart index a216165d..ef654864 100644 --- a/lib/presentation/pages/add_bindings/add_binding_page.dart +++ b/lib/presentation/pages/add_bindings/add_binding_page.dart @@ -42,16 +42,16 @@ class _AddBindingPageState extends State { bool showErrorMessages = false; bool isSubmitting = false; - Future initialzeEntities() async { + Future initialzeEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { entities = entitiesTemp; }); } - Future _sendBindingToHub() async { + Future _sendBindingToHub() async { // IBindingCbjRepository.instance // .addOrUpdateNewBindingInHubFromDevicesPropertyActionList( // bindingName, @@ -59,7 +59,7 @@ class _AddBindingPageState extends State { // ); } - Future _addFullAction(EntityActionObject value) async { + Future _addFullAction(EntityActionObject value) async { setState(() { allDevicesWithNewAction.add(value); }); @@ -142,7 +142,8 @@ class _AddBindingPageState extends State { ), onPressed: (_) async { final EntityActionObject? actionList = - await context.router.push( + await context.router + .push( AddActionRoute(entities: entities!), ); if (actionList != null) { diff --git a/lib/presentation/pages/add_new_area_page.dart b/lib/presentation/pages/add_new_area_page.dart index 8b6331dc..f9d8b4c5 100644 --- a/lib/presentation/pages/add_new_area_page.dart +++ b/lib/presentation/pages/add_new_area_page.dart @@ -44,7 +44,7 @@ class _AddNewAreaFormState extends State { bool showErrorMessages = false; bool isSubmitting = false; - // Future _initialized() async { + // Future _initialized() async { // IAreaRepository.instance.getAllAreas().fold((l) => null, (r) { // _allAreas = Set.from(r.iter); // }); @@ -60,7 +60,7 @@ class _AddNewAreaFormState extends State { // }); // } - Future _createArea() async { + Future _createArea() async { final AreaEntity areaEntity = AreaEntity( uniqueId: AreaUniqueId.fromUniqueString(areaUniqueId.getOrCrash()), cbjEntityName: AreaDefaultName(cbjEntityName.getOrCrash()), @@ -77,13 +77,13 @@ class _AddNewAreaFormState extends State { ConnectionsService.instance.setNewArea(areaEntity); } - Future _defaultNameChanged(String value) async { + Future _defaultNameChanged(String value) async { setState(() { cbjEntityName = AreaDefaultName(value); }); } - Future _areaTypesChanged(Set value) async { + Future _areaTypesChanged(Set value) async { setState(() { areaTypes = AreaTypes(value); }); @@ -148,14 +148,14 @@ class _AddNewAreaFormState extends State { } return MultiSelectItem( - areaPurposeType.value, + areaPurposeType.name, areaNameEdited, ); }).toList(), listType: MultiSelectListType.CHIP, - onConfirm: (List values) { + onConfirm: (List values) { _areaTypesChanged( - values.map((e) => e.toString()).toSet(), + values.map((e) => e).toSet(), ); }, ), diff --git a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart index 000a7f61..ffcc0553 100644 --- a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart +++ b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart @@ -18,7 +18,7 @@ class _VendorsListState extends State { initializeVendors(); } - Future initializeVendors() async { + Future initializeVendors() async { final List temp = await ConnectionsService.instance.getVendors(); temp.removeWhere( diff --git a/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart b/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart index 8e734e0f..6131c0e5 100644 --- a/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/computer_connection_check/widgets/computer_connection_check_widget.dart @@ -52,7 +52,7 @@ class _ComputerConnectionCheckWidgetState ).show(context); } - Future _checkConnectedToWiFiNetwork() async { + Future _checkConnectedToWiFiNetwork() async { if ((await WiFiScan.instance.canStartScan()) == CanStartScan.yes) { await WiFiScan.instance.startScan(); if ((await WiFiScan.instance.canGetScannedResults()) == @@ -79,7 +79,7 @@ class _ComputerConnectionCheckWidgetState _searchIfHubOnTheSameWifiNetwork(); } - Future _searchIfHubOnTheSameWifiNetwork() async { + Future _searchIfHubOnTheSameWifiNetwork() async { int connectionTimeout = 0; while (true) { diff --git a/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart b/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart index ee1affc7..982fb7d2 100644 --- a/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart @@ -48,7 +48,7 @@ class _ConfigureNewCbjCompWidgetsState _sendHotSpotInformation(widget.cbjCompEntity); } - Future _sendHotSpotInformation(CbjCompEntity cBJCompEntity) async { + Future _sendHotSpotInformation(CbjCompEntity cBJCompEntity) async { progressPercentage += 0.3; setState(() { state = ConfigureNewCbjCompState.actionInProgress; diff --git a/lib/presentation/pages/add_new_devices_process/connect_to_home_wifi/widgets/connect_to_home_wifi_widget.dart b/lib/presentation/pages/add_new_devices_process/connect_to_home_wifi/widgets/connect_to_home_wifi_widget.dart index 7e8d4cc8..b3c16849 100644 --- a/lib/presentation/pages/add_new_devices_process/connect_to_home_wifi/widgets/connect_to_home_wifi_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/connect_to_home_wifi/widgets/connect_to_home_wifi_widget.dart @@ -25,7 +25,7 @@ class _ConnectToHomeWiFiWidgetState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { final dartz.Either doesWiFiEnabled = await IManageNetworkRepository.instance.doesWiFiEnabled(); @@ -41,7 +41,7 @@ class _ConnectToHomeWiFiWidgetState extends State { }); } - Future _connectToWiFi() async { + Future _connectToWiFi() async { final ManageNetworkEntity manageWiFiEntity = ManageNetworkEntity( name: wifiName, pass: wifiPassword, diff --git a/lib/presentation/pages/add_new_devices_process/open_access_point/widgets/open_access_point_widget.dart b/lib/presentation/pages/add_new_devices_process/open_access_point/widgets/open_access_point_widget.dart index f6f293fd..6e742a21 100644 --- a/lib/presentation/pages/add_new_devices_process/open_access_point/widgets/open_access_point_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/open_access_point/widgets/open_access_point_widget.dart @@ -29,7 +29,7 @@ class _OpenAccessPointWidgetState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { OpenAccessPointState stateTemp; if (Platform.isAndroid) { final ManageNetworkEntity manageNetworkEntity = ManageNetworkEntity( @@ -52,7 +52,7 @@ class _OpenAccessPointWidgetState extends State { }); } - Future _doesAccessPointOpen() async { + Future _doesAccessPointOpen() async { OpenAccessPointState stateTemp; if (Platform.isAndroid) { diff --git a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart index 9e1bd7d8..682c1998 100644 --- a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart @@ -28,7 +28,8 @@ class _ScanForNewCBJCompsWidgetState extends State { _watchAllStarted(); } - Future _watchAllStarted() async { + Future + _watchAllStarted() async { await _cbjCompStreamSubscription?.cancel(); _cbjCompStreamSubscription = ICbjCompRepository.instance .getConnectedComputersIP() @@ -45,7 +46,7 @@ class _ScanForNewCBJCompsWidgetState extends State { }); } - Future _compDevicesReceived( + Future _compDevicesReceived( dartz.Either failureOrCBJCompList, ) async { final dynamic failureOrCompListDynamic = failureOrCBJCompList.fold( @@ -71,7 +72,8 @@ class _ScanForNewCBJCompsWidgetState extends State { } @override - Future dispose() async { + Future + dispose() async { await _cbjCompStreamSubscription?.cancel(); await ICbjCompRepository.instance.shutdownServer(); return super.dispose(); diff --git a/lib/presentation/pages/add_routine/add_routine_page.dart b/lib/presentation/pages/add_routine/add_routine_page.dart index 36aba05f..ab701e9f 100644 --- a/lib/presentation/pages/add_routine/add_routine_page.dart +++ b/lib/presentation/pages/add_routine/add_routine_page.dart @@ -52,16 +52,17 @@ class _AddRoutinePageState extends State { bool isSubmitting = false; HashMap? entities; - Future initialzeEntities() async { + Future initialzeEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { entities = entitiesTemp; }); } - Future _sendRoutineToHub() async { + Future + _sendRoutineToHub() async { if (daysToRepeat == null || hourToRepeat == null || minutesToRepeat == null || @@ -78,11 +79,11 @@ class _AddRoutinePageState extends State { // ); } - Future _routineNameChange(String value) async { + Future _routineNameChange(String value) async { routineName = value; } - Future _addFullAction(EntityActionObject value) async { + Future _addFullAction(EntityActionObject value) async { setState(() { allDevicesWithNewAction.add(value); }); diff --git a/lib/presentation/pages/add_scene/add_scene_page.dart b/lib/presentation/pages/add_scene/add_scene_page.dart index cce9e4f8..425d0a8c 100644 --- a/lib/presentation/pages/add_scene/add_scene_page.dart +++ b/lib/presentation/pages/add_scene/add_scene_page.dart @@ -33,9 +33,9 @@ class _AddScenePageState extends State { /// List of devices with entities, will be treated as actions HashSet entitiesWithActions = HashSet(); - Future initialzeEntities() async { + Future initialzeEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { entities = entitiesTemp; @@ -54,7 +54,7 @@ class _AddScenePageState extends State { ) .toList(); - Future _sendSceneToHub() async { + Future _sendSceneToHub() async { final List actions = entitiesWithActionsToActionsByVendor(); @@ -81,11 +81,7 @@ class _AddScenePageState extends State { ConnectionsService.instance.addScene(scene); } - void _sceneNameChange(String value) { - sceneName = value; - } - - Future _addFullAction(EntityActionObject value) async { + Future _addFullAction(EntityActionObject value) async { setState(() { entitiesWithActions.add(value); }); @@ -123,7 +119,7 @@ class _AddScenePageState extends State { labelText: 'Scene Name', ), style: const TextStyle(color: Colors.black), - onChanged: _sceneNameChange, + onChanged: (value) => sceneName = value, ), SizedBox( height: 300, diff --git a/lib/presentation/pages/change_area_for_devices_page.dart b/lib/presentation/pages/change_area_for_devices_page.dart index ea615a1e..9956c163 100644 --- a/lib/presentation/pages/change_area_for_devices_page.dart +++ b/lib/presentation/pages/change_area_for_devices_page.dart @@ -52,14 +52,14 @@ class _ChangeAreaForDevicesWidgetState _initialized(); } - Future _initialized() async { + Future _initialized() async { getAreas(); getEntities(); } Future getAreas() async { final HashMap areasTemp = - await ConnectionsService.instance.getAllAreas; + await ConnectionsService.instance.getAreas; setState(() { areas = areasTemp; }); @@ -67,7 +67,7 @@ class _ChangeAreaForDevicesWidgetState Future getEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { entities = entitiesTemp; }); diff --git a/lib/presentation/pages/connect_to_hub/connect_to_hub_page.dart b/lib/presentation/pages/connect_to_hub/connect_to_hub_page.dart index 8380df08..feed20bd 100644 --- a/lib/presentation/pages/connect_to_hub/connect_to_hub_page.dart +++ b/lib/presentation/pages/connect_to_hub/connect_to_hub_page.dart @@ -1,5 +1,4 @@ import 'package:auto_route/auto_route.dart'; -import 'package:cybearjinni/domain/i_hub_connection_repository.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/routes/app_router.gr.dart'; import 'package:cybearjinni/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart'; @@ -160,7 +159,7 @@ class ConnectToHubPage extends StatelessWidget { GestureDetector( onTap: () { context.router.push(const SmartCameraContainerRoute()); - IHubConnectionRepository.instance.closeConnection(); + // IHubConnectionRepository.instance.closeConnection(); }, child: Container( margin: const EdgeInsets.symmetric(horizontal: 30), diff --git a/lib/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart b/lib/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart index 967edd8a..26a4054f 100644 --- a/lib/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart +++ b/lib/presentation/pages/connect_to_hub/widgets/cbj_hub_in_network_widget.dart @@ -42,7 +42,7 @@ class _CbjHubInNetworkWidgetState extends State { }); final HashMap entities = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; if (entities.isNotEmpty) { if (!mounted || foundEntity) { diff --git a/lib/presentation/pages/connect_to_hub_more_page.dart b/lib/presentation/pages/connect_to_hub_more_page.dart index 7d89f66d..42e1e0fe 100644 --- a/lib/presentation/pages/connect_to_hub_more_page.dart +++ b/lib/presentation/pages/connect_to_hub_more_page.dart @@ -1,16 +1,12 @@ import 'dart:async'; import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/domain/connections_service.dart'; -import 'package:cybearjinni/domain/device/devices_failures.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/routes/app_router.gr.dart'; -import 'package:dartz/dartz.dart' as dartz; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:hexcolor/hexcolor.dart'; -import 'package:kt_dart/kt.dart'; @RoutePage() class ConnectToHubMorePage extends StatelessWidget { @@ -88,23 +84,13 @@ class ConnectToHubMoreWidget extends StatefulWidget { } class _ConnectToHubMoreWidgetState extends State { - StreamSubscription>>? - _deviceStreamSubscription; - bool isLoading = false; - Future _connectInDemoMode() async { + Future _connectInDemoMode() async { ConnectionsService.setCurrentConnectionType(ConnectionType.demo); context.router.replace(const HomeRoute()); } - @override - void dispose() { - _deviceStreamSubscription?.cancel(); - - super.dispose(); - } - @override Widget build(BuildContext context) { if (isLoading) { diff --git a/lib/presentation/pages/entities_in_area_page.dart b/lib/presentation/pages/entities_in_area_page.dart index 8d9208e4..315fd83b 100644 --- a/lib/presentation/pages/entities_in_area_page.dart +++ b/lib/presentation/pages/entities_in_area_page.dart @@ -33,7 +33,7 @@ class _EntitiesInAreaPageState extends State { Future initialzeDevices() async { final Map entitiesMap = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; final Set entityIdsInArea = widget.areaEntity.entitiesId.getOrCrash(); final Set entityTypes = widget.entityTypes; diff --git a/lib/presentation/pages/entities_in_network_page.dart b/lib/presentation/pages/entities_in_network_page.dart index 2c0e13cb..f2c60885 100644 --- a/lib/presentation/pages/entities_in_network_page.dart +++ b/lib/presentation/pages/entities_in_network_page.dart @@ -23,7 +23,7 @@ class _EntitiesInNetworkPageState extends State { Future initializeAllEntities() async { final Map entities = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; setState(() { allEntities = entities.values.toList(); }); diff --git a/lib/presentation/pages/home_page/home_page.dart b/lib/presentation/pages/home_page/home_page.dart index 13b50c09..11419604 100644 --- a/lib/presentation/pages/home_page/home_page.dart +++ b/lib/presentation/pages/home_page/home_page.dart @@ -45,9 +45,9 @@ class _HomePageState extends State { HashMap? areas; HashMap? entities; - Future initializedScenes() async { + Future initializedScenes() async { final HashMap scenecsTemp = - await ConnectionsService.instance.getScenes(); + await ConnectionsService.instance.getScenes; setState(() { scenes = scenecsTemp; @@ -72,7 +72,7 @@ class _HomePageState extends State { Future _initialzeAreas() async { final HashMap areasTemp = - await ConnectionsService.instance.getAllAreas; + await ConnectionsService.instance.getAreas; setState(() { areas ??= HashMap(); @@ -101,7 +101,7 @@ class _HomePageState extends State { Future _initialzeEntities() async { final HashMap entitiesTemp = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; entitiesTemp.removeWhere( (key, value) => value.entityTypes.type == EntityTypes.smartTypeNotSupported || diff --git a/lib/presentation/pages/introduction_screen/introduction_screen_body.dart b/lib/presentation/pages/introduction_screen/introduction_screen_body.dart index d4312805..6fe7822e 100644 --- a/lib/presentation/pages/introduction_screen/introduction_screen_body.dart +++ b/lib/presentation/pages/introduction_screen/introduction_screen_body.dart @@ -116,7 +116,7 @@ class _IntroductionScreenBodyState extends State { ), onDone: () async { final HashMap entities = - await ConnectionsService.instance.getAllEntities; + await ConnectionsService.instance.getEntities; if (!mounted) { return; } diff --git a/lib/presentation/pages/plus_button.dart b/lib/presentation/pages/plus_button.dart index 0d8d0369..7d2a9c26 100644 --- a/lib/presentation/pages/plus_button.dart +++ b/lib/presentation/pages/plus_button.dart @@ -10,7 +10,7 @@ import 'package:iconify_flutter/icons/simple_icons.dart'; @RoutePage() class PlusButtonPage extends StatelessWidget { - Future _logout(BuildContext context) async { + Future _logout(BuildContext context) async { context.router.replace(const ConnectToHubRoute()); ConnectionsService.setCurrentConnectionType(null); } diff --git a/lib/presentation/pages/remote_pipes_page.dart b/lib/presentation/pages/remote_pipes_page.dart index 1662f52b..f4bdc236 100644 --- a/lib/presentation/pages/remote_pipes_page.dart +++ b/lib/presentation/pages/remote_pipes_page.dart @@ -61,13 +61,13 @@ class RemotePipesWidget extends StatefulWidget { class _RemotePipesWidgetState extends State { String? remotePipesDomainName; - Future _remotePipesDomainChanged(String value) async { + Future _remotePipesDomainChanged(String value) async { setState(() { remotePipesDomainName = value; }); } - Future _addRemotePipeUrl() async { + Future _addRemotePipeUrl() async { if (remotePipesDomainName == null || remotePipesDomainName!.isEmpty) { return; } diff --git a/lib/presentation/pages/scenes/scenes_page.dart b/lib/presentation/pages/scenes/scenes_page.dart index 6e77c17a..74b221b4 100644 --- a/lib/presentation/pages/scenes/scenes_page.dart +++ b/lib/presentation/pages/scenes/scenes_page.dart @@ -29,9 +29,9 @@ class _ScenesPageState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { final HashMap scenecsTemp = - await ConnectionsService.instance.getScenes(); + await ConnectionsService.instance.getScenes; final HashMap scenesInArea = HashMap.fromEntries( widget.area.areaScenesId.getOrCrash().map((e) { diff --git a/lib/presentation/pages/software_info_page.dart b/lib/presentation/pages/software_info_page.dart index fb1f0bb5..98a68610 100644 --- a/lib/presentation/pages/software_info_page.dart +++ b/lib/presentation/pages/software_info_page.dart @@ -67,7 +67,7 @@ class _SoftwareInfoWidgetState extends State { _initialized(); } - Future _initialized() async { + Future _initialized() async { SoftwareInfoEntity? appInfoEntity; (await ISoftwareInfoRepository.instance.getAppSoftwareInfo()).fold( (l) => l, From 6c94c3bbbc6e22aa6fc726f2a075f40d3d8e0b30 Mon Sep 17 00:00:00 2001 From: Guy Luz Date: Sun, 21 Jan 2024 21:06:18 +0200 Subject: [PATCH 6/9] Added remove pipes support --- lib/domain/connections_service.dart | 15 +- .../app_connection_service.dart | 2 +- .../demo_connection_service.dart | 2 +- .../hub_connection_service.dart | 2 +- .../none_connection_service.dart | 2 +- .../remote_pipes_connection_service.dart | 239 ++++++++++++++++++ lib/infrastructure/core/injection.dart | 2 +- lib/main.dart | 2 - lib/presentation/pages/plus_button.dart | 2 +- lib/presentation/pages/remote_pipes_page.dart | 13 +- lib/presentation/pages/splash_page.dart | 5 + 11 files changed, 260 insertions(+), 26 deletions(-) create mode 100644 lib/infrastructure/connection_service/remote_pipes_connection_service.dart diff --git a/lib/domain/connections_service.dart b/lib/domain/connections_service.dart index d1f50712..05e55b68 100644 --- a/lib/domain/connections_service.dart +++ b/lib/domain/connections_service.dart @@ -22,6 +22,7 @@ part 'package:cybearjinni/infrastructure/connection_service/app_connection_servi part 'package:cybearjinni/infrastructure/connection_service/hub_connection_service.dart'; part 'package:cybearjinni/infrastructure/connection_service/demo_connection_service.dart'; part 'package:cybearjinni/infrastructure/connection_service/none_connection_service.dart'; +part 'package:cybearjinni/infrastructure/connection_service/remote_pipes_connection_service.dart'; enum ConnectionType { appAsHub, @@ -41,33 +42,31 @@ abstract interface class ConnectionsService { static ConnectionType _currentConnectionType = ConnectionType.appAsHub; - static void setCurrentConnectionType(ConnectionType? connectionType) { + static void setCurrentConnectionType(ConnectionType connectionType) { if (connectionType == _currentConnectionType) { return; } _instance?.dispose(); + _currentConnectionType = connectionType; + switch (connectionType) { case ConnectionType.appAsHub: _instance = _AppConnectionService(); - _currentConnectionType = ConnectionType.appAsHub; case ConnectionType.hub: - _currentConnectionType = ConnectionType.hub; _instance = _HubConnectionService(); - case ConnectionType.demo: case ConnectionType.remotePipes: + _instance = _RemotePipesConnectionService(); + case ConnectionType.demo: _instance = _DemoConnectionService(); - _currentConnectionType = ConnectionType.demo; case ConnectionType.none: - case null: _instance = _NoneConnectionService(); - _currentConnectionType = ConnectionType.none; } } static ConnectionType getCurrentConnectionType() => _currentConnectionType; - Future connect(); + Future connect({String? address}); Future searchDevices(); diff --git a/lib/infrastructure/connection_service/app_connection_service.dart b/lib/infrastructure/connection_service/app_connection_service.dart index af0dca37..dc042a96 100644 --- a/lib/infrastructure/connection_service/app_connection_service.dart +++ b/lib/infrastructure/connection_service/app_connection_service.dart @@ -63,5 +63,5 @@ class _AppConnectionService implements ConnectionsService { IcSynchronizer().getVendors(); @override - Future connect() async => true; + Future connect({String? address}) async => true; } diff --git a/lib/infrastructure/connection_service/demo_connection_service.dart b/lib/infrastructure/connection_service/demo_connection_service.dart index 1dd06616..b0f17dda 100644 --- a/lib/infrastructure/connection_service/demo_connection_service.dart +++ b/lib/infrastructure/connection_service/demo_connection_service.dart @@ -61,5 +61,5 @@ class _DemoConnectionService implements ConnectionsService { IcSynchronizer().getVendors(); @override - Future connect() async => true; + Future connect({String? address}) async => true; } diff --git a/lib/infrastructure/connection_service/hub_connection_service.dart b/lib/infrastructure/connection_service/hub_connection_service.dart index 6fde9032..70bb08be 100644 --- a/lib/infrastructure/connection_service/hub_connection_service.dart +++ b/lib/infrastructure/connection_service/hub_connection_service.dart @@ -270,7 +270,7 @@ class _HubConnectionService implements ConnectionsService { IcSynchronizer().getVendors(); @override - Future connect() async { + Future connect({String? address}) async { searchDevices(); if (hubIp == null) { return false; diff --git a/lib/infrastructure/connection_service/none_connection_service.dart b/lib/infrastructure/connection_service/none_connection_service.dart index fb1049d2..7908507e 100644 --- a/lib/infrastructure/connection_service/none_connection_service.dart +++ b/lib/infrastructure/connection_service/none_connection_service.dart @@ -59,5 +59,5 @@ class _NoneConnectionService implements ConnectionsService { Future> getVendors() async => []; @override - Future connect() async => true; + Future connect({String? address}) async => true; } diff --git a/lib/infrastructure/connection_service/remote_pipes_connection_service.dart b/lib/infrastructure/connection_service/remote_pipes_connection_service.dart new file mode 100644 index 00000000..3b092073 --- /dev/null +++ b/lib/infrastructure/connection_service/remote_pipes_connection_service.dart @@ -0,0 +1,239 @@ +part of 'package:cybearjinni/domain/connections_service.dart'; + +class _RemotePipesConnectionService implements ConnectionsService { + /// Port to connect to the cbj hub, will change according to the current + /// running environment + int hubPort = 50051; + + String? address; + String? networkBssid; + String? networkName; + + ClientChannel? channel; + CbjHubClient? stub; + + StreamController>? entitiesStream; + StreamController>? areasStream; + + BehaviorSubject hubMessagesToApp = + BehaviorSubject(); + + // StreamController appMessagesToHub = + // StreamController(); + + BehaviorSubject appMessagesToHub = BehaviorSubject(); + + @override + Future dispose() async { + entitiesStream?.close(); + } + + @override + Future> get getEntities async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allEntities.name), + ); + final HashMap entities = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allEntities) { + continue; + } + + try { + final Map entitiesMap = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + entities.addEntries( + entitiesMap.entries.map( + (e) => MapEntry( + e.key, + DeviceHelper.convertJsonStringToDomain(e.value), + ), + ), + ); + } catch (e) { + logger.e('Error converting entities\n$e'); + } + break; + } + + return entities; + } + + @override + Future> get getAreas async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allAreas.name), + ); + + final HashMap areas = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allAreas) { + continue; + } + + try { + final Map entitiesMap = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + areas.addEntries( + entitiesMap.entries.map( + (e) => MapEntry( + e.key, + AreaEntityDtos.fromJson( + jsonDecode(e.value) as Map, + ).toDomain(), + ), + ), + ); + } catch (e) { + logger.e('Error converting areas\n$e'); + } + break; + } + + return areas; + } + + @override + Future> get getScenes async { + appMessagesToHub.sink.add( + ClientStatusRequests(sendingType: SendingType.allScenes.name), + ); + + final HashMap scenesMap = HashMap(); + + await for (final RequestsAndStatusFromHub message + in hubMessagesToApp.stream) { + final SendingType sendingType = + SendingTypeExtension.fromString(message.sendingType); + if (sendingType != SendingType.allScenes) { + continue; + } + + try { + final Map entities = Map.from( + jsonDecode(message.allRemoteCommands) as Map, + ); + scenesMap.addEntries( + entities.entries.map( + (e) => MapEntry( + e.key, + SceneCbjDtos.fromJson(jsonDecode(e.value) as Map) + .toDomain(), + ), + ), + ); + } catch (e) { + logger.e('Error converting scenes\n$e'); + } + break; + } + + return scenesMap; + } + + @override + Future searchDevices() async {} + + @override + void setEntityState(RequestActionObject action) { + appMessagesToHub.sink.add( + ClientStatusRequests( + sendingType: SendingType.setEntitiesAction.name, + allRemoteCommands: action.toInfrastructure().toJsonString(), + ), + ); + } + + @override + Stream> watchEntities() { + entitiesStream?.close(); + + entitiesStream = StreamController.broadcast(); + return entitiesStream!.stream; + } + + @override + Stream> watchAreas() { + areasStream?.close(); + + areasStream = StreamController.broadcast(); + return areasStream!.stream; + } + + @override + Future setNewArea(AreaEntity area) async {} + + @override + Future setEtitiesToArea(String areaId, HashSet entities) async {} + + @override + Future addScene(SceneCbjEntity scene) async {} + + @override + Future activateScene(String id) async {} + + @override + Future loginVendor(VendorLoginEntity value) async {} + + @override + Future> getVendors() async => + IcSynchronizer().getVendors(); + + @override + Future connect({String? address}) async { + this.address = address; + if (this.address == null) { + return false; + } + + connectHelper(); + + return true; + } + + /// Connect directly to the Hub if possible + Future connectHelper() async { + if (address == null) { + return; + } + + try { + channel = ClientChannel( + address!, + port: hubPort, + options: + const ChannelOptions(credentials: ChannelCredentials.insecure()), + ); + + channel!.onConnectionStateChanged.listen((event) { + logger.i('gRPC connection state $event'); + }); + + stub = CbjHubClient(channel!); + + final ResponseStream response = + stub!.clientTransferEntities( + appMessagesToHub.stream, + ); + + // appMessagesToHub.sink + // .add(ClientStatusRequests(sendingType: SendingType.firstConnection)); + + hubMessagesToApp.addStream(response); + await Future.delayed(const Duration(seconds: 3)); + } catch (e) { + logger.e('Caught error while stream with hub\n$e'); + await channel?.shutdown(); + } + } +} diff --git a/lib/infrastructure/core/injection.dart b/lib/infrastructure/core/injection.dart index 512fd02b..45e0fe6e 100644 --- a/lib/infrastructure/core/injection.dart +++ b/lib/infrastructure/core/injection.dart @@ -1,4 +1,4 @@ -import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/infrastructure/core/injection.config.dart'; import 'package:cybearjinni/infrastructure/core/logger.dart'; import 'package:get_it/get_it.dart'; import 'package:injectable/injectable.dart'; diff --git a/lib/main.dart b/lib/main.dart index c28244d9..a370484f 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,3 @@ -import 'package:cbj_integrations_controller/integrations_controller.dart'; import 'package:cybearjinni/infrastructure/core/injection.dart'; import 'package:cybearjinni/presentation/core/app_widget.dart'; import 'package:cybearjinni/presentation/core/routes/app_router.dart'; @@ -8,7 +7,6 @@ import 'package:flutter/material.dart'; Future main() async { configureDependencies(EnvApp.dev); - configureInjection(Env.devPc); WidgetsFlutterBinding.ensureInitialized(); diff --git a/lib/presentation/pages/plus_button.dart b/lib/presentation/pages/plus_button.dart index 7d2a9c26..e325fcfc 100644 --- a/lib/presentation/pages/plus_button.dart +++ b/lib/presentation/pages/plus_button.dart @@ -12,7 +12,7 @@ import 'package:iconify_flutter/icons/simple_icons.dart'; class PlusButtonPage extends StatelessWidget { Future _logout(BuildContext context) async { context.router.replace(const ConnectToHubRoute()); - ConnectionsService.setCurrentConnectionType(null); + ConnectionsService.setCurrentConnectionType(ConnectionType.none); } @override diff --git a/lib/presentation/pages/remote_pipes_page.dart b/lib/presentation/pages/remote_pipes_page.dart index f4bdc236..00c78113 100644 --- a/lib/presentation/pages/remote_pipes_page.dart +++ b/lib/presentation/pages/remote_pipes_page.dart @@ -1,6 +1,6 @@ import 'package:adaptive_action_sheet/adaptive_action_sheet.dart'; import 'package:auto_route/auto_route.dart'; -import 'package:cbj_integrations_controller/integrations_controller.dart'; +import 'package:cybearjinni/domain/connections_service.dart'; import 'package:cybearjinni/presentation/atoms/atoms.dart'; import 'package:cybearjinni/presentation/core/snack_bar_service.dart'; import 'package:cybearjinni/presentation/molecules/molecules.dart'; @@ -71,15 +71,9 @@ class _RemotePipesWidgetState extends State { if (remotePipesDomainName == null || remotePipesDomainName!.isEmpty) { return; } - - final RemotePipesEntity remotePipesEntity = - RemotePipesEntity.empty().copyWith( - domainName: RemotePipesDomain(remotePipesDomainName!), - ); - + ConnectionsService.setCurrentConnectionType(ConnectionType.remotePipes); + ConnectionsService.instance.connect(address: remotePipesDomainName); context.router.pop(); - await IRemotePipesRepository.instance - .setRemotePipesDomainName(remotePipesEntity); } @override @@ -91,7 +85,6 @@ class _RemotePipesWidgetState extends State { children: [ const TextAtom( 'Please insert the Remote Pipes domain', - style: TextStyle(color: Colors.black, fontSize: 25), ), const SizedBox( height: 60, diff --git a/lib/presentation/pages/splash_page.dart b/lib/presentation/pages/splash_page.dart index ea0cda86..6c528ec6 100644 --- a/lib/presentation/pages/splash_page.dart +++ b/lib/presentation/pages/splash_page.dart @@ -28,16 +28,21 @@ class _SplashPageState extends State { } Future initilizeApp() async { + // TODO: can we remove await Hive.initFlutter(); AppCommands(); + // TODO: can we remove await Future.value([ IDbRepository.instance.initializeDb(isFlutter: true), ILocalDbRepository.instance.asyncConstructor(), // ISavedDevicesRepo.instance.setUpAllFromDb(), ]); + // TODO: can we remove MqttServerRepository(); + // TODO: Same as App Command? PhoneCommandsD(); SystemCommandsManager(); + // TODO: can we remove NodeRedRepository(); ConnectionsService.instance; _navigate(); From a7841952e3c1826d823c1171d44783e5c10ab250 Mon Sep 17 00:00:00 2001 From: Guy Luz Date: Thu, 25 Jan 2024 20:35:15 +0200 Subject: [PATCH 7/9] Added preset support --- .../molecules/devices/ac_molecule.dart | 20 ++------- .../molecules/devices/blind_molecule.dart | 21 ++------- .../molecules/devices/boiler_molecule.dart | 20 ++------- .../devices/dimmable_light_molecule.dart | 20 ++------- .../molecules/devices/light_molecule.dart | 19 ++------ .../molecules/devices/rgb_light_molecule.dart | 44 ++++--------------- .../devices/smart_plug_molecule.dart | 21 ++------- .../molecules/devices/smart_tv_molecule.dart | 21 ++------- .../molecules/devices/switch_molecule.dart | 21 ++------- lib/presentation/pages/add_new_area_page.dart | 32 +++++++------- .../pages/add_scene/add_scene_page.dart | 10 ++--- .../pages/scenes/scenes_page.dart | 2 +- 12 files changed, 56 insertions(+), 195 deletions(-) diff --git a/lib/presentation/molecules/devices/ac_molecule.dart b/lib/presentation/molecules/devices/ac_molecule.dart index 903e0600..bfd215bc 100644 --- a/lib/presentation/molecules/devices/ac_molecule.dart +++ b/lib/presentation/molecules/devices/ac_molecule.dart @@ -29,26 +29,12 @@ class _AcMoleculeState extends State { } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet entitiesId = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: entitiesId, property: EntityProperties.acSwitchState, actionType: action, ), diff --git a/lib/presentation/molecules/devices/blind_molecule.dart b/lib/presentation/molecules/devices/blind_molecule.dart index a95eb30f..a8af44ec 100644 --- a/lib/presentation/molecules/devices/blind_molecule.dart +++ b/lib/presentation/molecules/devices/blind_molecule.dart @@ -31,27 +31,12 @@ class _BlindMoleculeState extends State { } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: uniqueIdByVendor, property: EntityProperties.blindsSwitchState, actionType: action, ), diff --git a/lib/presentation/molecules/devices/boiler_molecule.dart b/lib/presentation/molecules/devices/boiler_molecule.dart index c881dd98..8a6fec90 100644 --- a/lib/presentation/molecules/devices/boiler_molecule.dart +++ b/lib/presentation/molecules/devices/boiler_molecule.dart @@ -29,26 +29,12 @@ class _BoilerMoleculeState extends State { } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: uniqueIdByVendor, property: EntityProperties.boilerSwitchState, actionType: action, ), diff --git a/lib/presentation/molecules/devices/dimmable_light_molecule.dart b/lib/presentation/molecules/devices/dimmable_light_molecule.dart index 5128c3f9..e6fd0a22 100644 --- a/lib/presentation/molecules/devices/dimmable_light_molecule.dart +++ b/lib/presentation/molecules/devices/dimmable_light_molecule.dart @@ -72,26 +72,12 @@ class _DimmableLightMoleculeState extends State { EntityActions action, { HashMap? value, }) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: uniqueIdByVendor, property: property, actionType: action, value: value, diff --git a/lib/presentation/molecules/devices/light_molecule.dart b/lib/presentation/molecules/devices/light_molecule.dart index 70d820b3..9772c14a 100644 --- a/lib/presentation/molecules/devices/light_molecule.dart +++ b/lib/presentation/molecules/devices/light_molecule.dart @@ -18,25 +18,12 @@ class LightMolecule extends StatelessWidget { } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } + final HashSet uniqueIdByVendor = + HashSet.from([entity.deviceCbjUniqueId.getOrCrash()]); - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet()..addAll([entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: uniqueIdByVendor, property: EntityProperties.lightSwitchState, actionType: action, ), diff --git a/lib/presentation/molecules/devices/rgb_light_molecule.dart b/lib/presentation/molecules/devices/rgb_light_molecule.dart index 687b51b3..8b331fa1 100644 --- a/lib/presentation/molecules/devices/rgb_light_molecule.dart +++ b/lib/presentation/molecules/devices/rgb_light_molecule.dart @@ -65,26 +65,12 @@ class _RgbwLightMoleculeState extends State { EntityActions action, { HashMap? value, }) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: uniqueIdByVendor, property: entityProperties, actionType: action, value: value, @@ -212,26 +198,12 @@ class _LightColorMods extends State { EntityActions action, { HashMap? value, }) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: uniqueIdByVendor, property: entityProperties, actionType: action, value: value, @@ -246,7 +218,7 @@ class _LightColorMods extends State { setEntityState( EntityProperties.lightColorTemperature, EntityActions.changeTemperature, - value: HashMap.from({ActionValues.temperature: newColorTemperature}), + value: HashMap.from({ActionValues.colorTemperature: newColorTemperature}), ); } @@ -262,7 +234,7 @@ class _LightColorMods extends State { ActionValues.alpha: newHsvColor.alpha, ActionValues.hue: newHsvColor.hue, ActionValues.saturation: newHsvColor.saturation, - ActionValues.value: newHsvColor.value, + ActionValues.colorValue: newHsvColor.value, }), ); } diff --git a/lib/presentation/molecules/devices/smart_plug_molecule.dart b/lib/presentation/molecules/devices/smart_plug_molecule.dart index 19a3cfc6..834879de 100644 --- a/lib/presentation/molecules/devices/smart_plug_molecule.dart +++ b/lib/presentation/molecules/devices/smart_plug_molecule.dart @@ -28,25 +28,12 @@ class _SmartPlugsMoleculeState extends State { } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); + ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: uniqueIdByVendor, property: EntityProperties.lightSwitchState, actionType: action, ), diff --git a/lib/presentation/molecules/devices/smart_tv_molecule.dart b/lib/presentation/molecules/devices/smart_tv_molecule.dart index 8a6739c2..6d47ee66 100644 --- a/lib/presentation/molecules/devices/smart_tv_molecule.dart +++ b/lib/presentation/molecules/devices/smart_tv_molecule.dart @@ -77,25 +77,12 @@ class _SmartTvMoleculeState extends State { EntityActions action, { HashMap? value, }) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); + ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: uniqueIdByVendor, property: property, actionType: action, value: value, diff --git a/lib/presentation/molecules/devices/switch_molecule.dart b/lib/presentation/molecules/devices/switch_molecule.dart index 0594b522..68a546d7 100644 --- a/lib/presentation/molecules/devices/switch_molecule.dart +++ b/lib/presentation/molecules/devices/switch_molecule.dart @@ -28,25 +28,12 @@ class _SwitchMoleculeState extends State { } void setEntityState(EntityActions action) { - final VendorsAndServices? vendor = - widget.entity.cbjDeviceVendor.vendorsAndServices; - if (vendor == null) { - return; - } - final HashMap> uniqueIdByVendor = - HashMap(); - uniqueIdByVendor.addEntries( - [ - MapEntry( - vendor, - HashSet() - ..addAll([widget.entity.deviceCbjUniqueId.getOrCrash()]), - ), - ], - ); + final HashSet uniqueIdByVendor = + HashSet.from([widget.entity.deviceCbjUniqueId.getOrCrash()]); + ConnectionsService.instance.setEntityState( RequestActionObject( - uniqueIdByVendor: uniqueIdByVendor, + entityIds: uniqueIdByVendor, property: EntityProperties.lightSwitchState, actionType: action, ), diff --git a/lib/presentation/pages/add_new_area_page.dart b/lib/presentation/pages/add_new_area_page.dart index f9d8b4c5..c1fc037f 100644 --- a/lib/presentation/pages/add_new_area_page.dart +++ b/lib/presentation/pages/add_new_area_page.dart @@ -34,7 +34,7 @@ class _AddNewAreaFormState extends State { AreaBackground background = AreaBackground( 'https://live.staticflickr.com/5220/5486044345_f67abff3e9_h.jpg', ); - AreaTypes areaTypes = AreaTypes(const {}); + AreaPurposes areaTypes = AreaPurposes(const {}); AreaEntitiesId areaDevicesId = AreaEntitiesId(const {}); AreaScenesId areaScenesId = AreaScenesId(const {}); AreaRoutinesId areaRoutinesId = AreaRoutinesId(const {}); @@ -63,15 +63,15 @@ class _AddNewAreaFormState extends State { Future _createArea() async { final AreaEntity areaEntity = AreaEntity( uniqueId: AreaUniqueId.fromUniqueString(areaUniqueId.getOrCrash()), - cbjEntityName: AreaDefaultName(cbjEntityName.getOrCrash()), - background: AreaBackground(background.getOrCrash()), - areaTypes: AreaTypes(areaTypes.getOrCrash()), - entitiesId: AreaEntitiesId(areaDevicesId.getOrCrash()), - areaScenesId: AreaScenesId(areaScenesId.getOrCrash()), - areaRoutinesId: AreaRoutinesId(areaRoutinesId.getOrCrash()), - areaBindingsId: AreaBindingsId(areaBindingsId.getOrCrash()), - areaMostUsedBy: AreaMostUsedBy(areaMostUsedBy.getOrCrash()), - areaPermissions: AreaPermissions(areaPermissions.getOrCrash()), + cbjEntityName: cbjEntityName, + background: background, + purposes: areaTypes, + entitiesId: areaDevicesId, + scenesId: areaScenesId, + routinesId: areaRoutinesId, + bindingsId: areaBindingsId, + areaMostUsedBy: areaMostUsedBy, + areaPermissions: areaPermissions, ); ConnectionsService.instance.setNewArea(areaEntity); @@ -83,9 +83,9 @@ class _AddNewAreaFormState extends State { }); } - Future _areaTypesChanged(Set value) async { + Future _areaTypesChanged(Set value) async { setState(() { - areaTypes = AreaTypes(value); + areaTypes = AreaPurposes(value); }); } @@ -148,15 +148,13 @@ class _AddNewAreaFormState extends State { } return MultiSelectItem( - areaPurposeType.name, + areaPurposeType, areaNameEdited, ); }).toList(), listType: MultiSelectListType.CHIP, - onConfirm: (List values) { - _areaTypesChanged( - values.map((e) => e).toSet(), - ); + onConfirm: (List values) { + _areaTypesChanged(values.toSet()); }, ), ], diff --git a/lib/presentation/pages/add_scene/add_scene_page.dart b/lib/presentation/pages/add_scene/add_scene_page.dart index 425d0a8c..db49ffe0 100644 --- a/lib/presentation/pages/add_scene/add_scene_page.dart +++ b/lib/presentation/pages/add_scene/add_scene_page.dart @@ -42,12 +42,11 @@ class _AddScenePageState extends State { }); } - List entitiesWithActionsToActionsByVendor() => + List entitiesWithActionsToActionsByVendor() => entitiesWithActions .map( - (e) => ActionObjectSingle( - vendor: e.entity.cbjDeviceVendor.vendorsAndServices!, - entityId: e.entity.getCbjDeviceId, + (e) => RequestActionObject( + entityIds: HashSet.from([e.entity.getCbjDeviceId]), property: e.property, actionType: e.action, ), @@ -55,7 +54,7 @@ class _AddScenePageState extends State { .toList(); Future _sendSceneToHub() async { - final List actions = + final List actions = entitiesWithActionsToActionsByVendor(); final SceneCbjEntity scene = SceneCbjEntity( @@ -76,6 +75,7 @@ class _AddScenePageState extends State { compUuid: SceneCbjCompUuid(''), entityStateGRPC: SceneCbjDeviceStateGRPC(EntityStateGRPC.ack.name), actions: actions, + areaPurposeType: AreaPurposesTypes.undefinedType, ); ConnectionsService.instance.addScene(scene); diff --git a/lib/presentation/pages/scenes/scenes_page.dart b/lib/presentation/pages/scenes/scenes_page.dart index 74b221b4..686f6c73 100644 --- a/lib/presentation/pages/scenes/scenes_page.dart +++ b/lib/presentation/pages/scenes/scenes_page.dart @@ -34,7 +34,7 @@ class _ScenesPageState extends State { await ConnectionsService.instance.getScenes; final HashMap scenesInArea = HashMap.fromEntries( - widget.area.areaScenesId.getOrCrash().map((e) { + widget.area.scenesId.getOrCrash().map((e) { final SceneCbjEntity? scene = scenecsTemp[e]; if (scene == null) { return null; From 9b40e057def1af05802df9e24118aa59397e65df Mon Sep 17 00:00:00 2001 From: Guy Luz Date: Sat, 27 Jan 2024 20:37:54 +0200 Subject: [PATCH 8/9] Refined color light bulb --- lib/presentation/core/entities_utils.dart | 2 +- .../molecules/device_by_type_molecule.dart | 2 +- .../devices/dimmable_light_molecule.dart | 2 +- .../molecules/devices/printer_molecule.dart | 5 +- .../molecules/devices/rgb_light_molecule.dart | 57 ++++++++----------- .../widgets/vendors_list.dart | 4 +- .../configure_new_cbj_comp_widget.dart | 3 +- .../cbj_comp_card_with_devices_controll.dart | 2 +- .../pages/add_scene/add_scene_page.dart | 2 +- .../pages/entities_in_area_page.dart | 3 +- .../pages/home_page/home_page.dart | 5 +- 11 files changed, 38 insertions(+), 49 deletions(-) diff --git a/lib/presentation/core/entities_utils.dart b/lib/presentation/core/entities_utils.dart index 912d3b0a..e3ef9a37 100644 --- a/lib/presentation/core/entities_utils.dart +++ b/lib/presentation/core/entities_utils.dart @@ -30,7 +30,7 @@ class EntitiesUtils { return MdiIcons.airConditioner; case EntityTypes.emptyEntity: case EntityTypes.pingEntity: - case EntityTypes.smartTypeNotSupported: + case EntityTypes.undefined: return Icons.question_mark; } } diff --git a/lib/presentation/molecules/device_by_type_molecule.dart b/lib/presentation/molecules/device_by_type_molecule.dart index de7fec35..17f6d75a 100644 --- a/lib/presentation/molecules/device_by_type_molecule.dart +++ b/lib/presentation/molecules/device_by_type_molecule.dart @@ -37,7 +37,7 @@ class DeviceByTypeMolecule extends StatelessWidget { return SecurityCameraMolecule(entity as GenericSecurityCameraDE); case EntityTypes.ac: return AcMolecule(entity as GenericAcDE); - case EntityTypes.smartTypeNotSupported: + case EntityTypes.undefined: case EntityTypes.emptyEntity: case EntityTypes.pingEntity: case null: diff --git a/lib/presentation/molecules/devices/dimmable_light_molecule.dart b/lib/presentation/molecules/devices/dimmable_light_molecule.dart index e6fd0a22..e1f034f0 100644 --- a/lib/presentation/molecules/devices/dimmable_light_molecule.dart +++ b/lib/presentation/molecules/devices/dimmable_light_molecule.dart @@ -55,7 +55,7 @@ class _DimmableLightMoleculeState extends State { setEntityState( EntityProperties.lightBrightness, - EntityActions.actionNotSupported, + EntityActions.undefined, value: hashValue, ); } diff --git a/lib/presentation/molecules/devices/printer_molecule.dart b/lib/presentation/molecules/devices/printer_molecule.dart index e0e3cfec..de2d9f15 100644 --- a/lib/presentation/molecules/devices/printer_molecule.dart +++ b/lib/presentation/molecules/devices/printer_molecule.dart @@ -24,9 +24,10 @@ class _PrinterMoleculeState extends State { linearProgressIndicator: const LinearProgressIndicator(), ).show(context); - final String printerIp = widget.entity.deviceLastKnownIp.getOrCrash()!; + final String printerAddress = widget.entity.srvTarget.getOrCrash() ?? + widget.entity.deviceLastKnownIp.getOrCrash()!; launchUrl( - Uri.parse('http://$printerIp'), + Uri.parse('http://$printerAddress'), mode: LaunchMode.externalApplication, ); } diff --git a/lib/presentation/molecules/devices/rgb_light_molecule.dart b/lib/presentation/molecules/devices/rgb_light_molecule.dart index 8b331fa1..c8539aa4 100644 --- a/lib/presentation/molecules/devices/rgb_light_molecule.dart +++ b/lib/presentation/molecules/devices/rgb_light_molecule.dart @@ -84,7 +84,7 @@ class _RgbwLightMoleculeState extends State { }); setEntityState( EntityProperties.lightBrightness, - EntityActions.actionNotSupported, + EntityActions.undefined, value: HashMap.from({ActionValues.brightness: value.round()}), ); } @@ -160,13 +160,18 @@ class _LightColorMods extends State { late int colorTemperature; late HSVColor hsvColor; late double brightness; + late ColorMode colorMode; + late Widget colorModeWidget; @override void initState() { super.initState(); + colorMode = widget.entity.colorMode.mode; hsvColor = widget.hsvColor ?? HSVColor.fromColor(Colors.white); colorTemperature = widget.colorTemperature; brightness = widget.brightness; + colorModeWidget = getColorModeWidget(colorMode); + _initialized(); } @@ -239,9 +244,6 @@ class _LightColorMods extends State { ); } - late Widget colorModeWidget; - int colorModFocus = 0; - Widget getWhiteModeWidget() { return Container( height: 100, @@ -281,21 +283,27 @@ class _LightColorMods extends State { ); } - Future _showWhiteMode() async { - setState(() { - colorModFocus = 0; - colorModeWidget = getWhiteModeWidget(); - }); + Widget getColorModeWidget(ColorMode colorMode) { + switch (colorMode) { + case ColorMode.undefined: + return const SizedBox(); + case ColorMode.rgb: + return getHsvColorModeWidget(); + case ColorMode.white: + return getWhiteModeWidget(); + } } - Future _showColorMode() async { + void setColorModeState(ColorMode colorMode) { + final Widget colorModeWidget = getColorModeWidget(colorMode); setState(() { - colorModFocus = 1; - colorModeWidget = getHsvColorModeWidget(); + this.colorMode = colorMode; + this.colorModeWidget = colorModeWidget; }); } - Widget lightModBarFocus() { + @override + Widget build(BuildContext context) { final ThemeData themeData = Theme.of(context); final ColorScheme colorScheme = themeData.colorScheme; @@ -310,44 +318,29 @@ class _LightColorMods extends State { child: TextAtom( 'White', style: TextStyle( - color: (colorModFocus == 0) + color: (colorMode == ColorMode.white) ? colorScheme.primary : colorScheme.onBackground, fontSize: 18, ), ), - onPressed: () { - _showWhiteMode(); - }, + onPressed: () => setColorModeState(ColorMode.white), ), OutlinedButton( child: TextAtom( 'Color', style: TextStyle( - color: (colorModFocus == 1) + color: (colorMode == ColorMode.rgb) ? colorScheme.primary : colorScheme.onBackground, fontSize: 18, ), ), - onPressed: () { - _showColorMode(); - }, + onPressed: () => setColorModeState(ColorMode.rgb), ), ], ), ], ); } - - @override - Widget build(BuildContext context) { - if (colorModFocus == 0) { - colorModeWidget = getWhiteModeWidget(); - } else { - colorModeWidget = getHsvColorModeWidget(); - } - - return lightModBarFocus(); - } } diff --git a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart index ffcc0553..f59c6113 100644 --- a/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart +++ b/lib/presentation/pages/add_new_devices_process/choose_device_vendor_to_add/widgets/vendors_list.dart @@ -22,9 +22,7 @@ class _VendorsListState extends State { final List temp = await ConnectionsService.instance.getVendors(); temp.removeWhere( - (element) => - element.vendorsAndServices == - VendorsAndServices.vendorsAndServicesNotSupported, + (element) => element.vendorsAndServices == VendorsAndServices.undefined, ); setState(() { vendorsList = temp; diff --git a/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart b/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart index 982fb7d2..d22b8324 100644 --- a/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/configure_new_cbj_comp/widgets/configure_new_cbj_comp_widget.dart @@ -149,8 +149,7 @@ class _ConfigureNewCbjCompWidgetsState final List widgetList = []; for (final GenericLightDE device in devicesList) { - if (device.entityTypes.getOrCrash() != - EntityTypes.smartTypeNotSupported.toString()) { + if (device.entityTypes.getOrCrash() != EntityTypes.undefined.toString()) { final TextEditingController textEditingControllerTemp = TextEditingController( text: device.cbjEntityName.value.getOrElse(() => ''), diff --git a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/cbj_comp_card_with_devices_controll.dart b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/cbj_comp_card_with_devices_controll.dart index a51554c5..4af47166 100644 --- a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/cbj_comp_card_with_devices_controll.dart +++ b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/cbj_comp_card_with_devices_controll.dart @@ -21,7 +21,7 @@ class CBJCompCardWithDevicesControll extends StatelessWidget { for (final GenericLightDE deviceEntity in deviceEntityList.asList()) { // if (deviceEntity.entityTypes.getOrCrash() != - EntityTypes.smartTypeNotSupported.toString()) { + EntityTypes.undefined.toString()) { typesList.add( ColoredBox( color: Colors.yellowAccent.withOpacity(0.3), diff --git a/lib/presentation/pages/add_scene/add_scene_page.dart b/lib/presentation/pages/add_scene/add_scene_page.dart index db49ffe0..58301d95 100644 --- a/lib/presentation/pages/add_scene/add_scene_page.dart +++ b/lib/presentation/pages/add_scene/add_scene_page.dart @@ -75,7 +75,7 @@ class _AddScenePageState extends State { compUuid: SceneCbjCompUuid(''), entityStateGRPC: SceneCbjDeviceStateGRPC(EntityStateGRPC.ack.name), actions: actions, - areaPurposeType: AreaPurposesTypes.undefinedType, + areaPurposeType: AreaPurposesTypes.undefined, ); ConnectionsService.instance.addScene(scene); diff --git a/lib/presentation/pages/entities_in_area_page.dart b/lib/presentation/pages/entities_in_area_page.dart index 315fd83b..731936b9 100644 --- a/lib/presentation/pages/entities_in_area_page.dart +++ b/lib/presentation/pages/entities_in_area_page.dart @@ -55,8 +55,7 @@ class _EntitiesInAreaPageState extends State { } bool supportedEntityType(EntityTypes type) { - return !(type == EntityTypes.smartTypeNotSupported || - type == EntityTypes.emptyEntity); + return !(type == EntityTypes.undefined || type == EntityTypes.emptyEntity); } @override diff --git a/lib/presentation/pages/home_page/home_page.dart b/lib/presentation/pages/home_page/home_page.dart index 11419604..72d130e4 100644 --- a/lib/presentation/pages/home_page/home_page.dart +++ b/lib/presentation/pages/home_page/home_page.dart @@ -104,7 +104,7 @@ class _HomePageState extends State { await ConnectionsService.instance.getEntities; entitiesTemp.removeWhere( (key, value) => - value.entityTypes.type == EntityTypes.smartTypeNotSupported || + value.entityTypes.type == EntityTypes.undefined || value.entityTypes.type == EntityTypes.emptyEntity, ); setState(() { @@ -123,8 +123,7 @@ class _HomePageState extends State { } bool unSupportedEntityType(EntityTypes type) { - return type == EntityTypes.smartTypeNotSupported || - type == EntityTypes.emptyEntity; + return type == EntityTypes.undefined || type == EntityTypes.emptyEntity; } /// Tab num, value will be the default tab to show From 9553d4080e6250f333258aa66fc740ff25c13ada Mon Sep 17 00:00:00 2001 From: github-actions Date: Sat, 27 Jan 2024 21:55:17 +0000 Subject: [PATCH 9/9] Automatic formatting --- .../widgets/scan_for_new_cbj_comps_widget.dart | 6 ++---- lib/presentation/pages/add_routine/add_routine_page.dart | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart index 682c1998..1af97831 100644 --- a/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart +++ b/lib/presentation/pages/add_new_devices_process/scan_for_new_cbj_comps/widgets/scan_for_new_cbj_comps_widget.dart @@ -28,8 +28,7 @@ class _ScanForNewCBJCompsWidgetState extends State { _watchAllStarted(); } - Future - _watchAllStarted() async { + Future _watchAllStarted() async { await _cbjCompStreamSubscription?.cancel(); _cbjCompStreamSubscription = ICbjCompRepository.instance .getConnectedComputersIP() @@ -72,8 +71,7 @@ class _ScanForNewCBJCompsWidgetState extends State { } @override - Future - dispose() async { + Future dispose() async { await _cbjCompStreamSubscription?.cancel(); await ICbjCompRepository.instance.shutdownServer(); return super.dispose(); diff --git a/lib/presentation/pages/add_routine/add_routine_page.dart b/lib/presentation/pages/add_routine/add_routine_page.dart index ab701e9f..0497f292 100644 --- a/lib/presentation/pages/add_routine/add_routine_page.dart +++ b/lib/presentation/pages/add_routine/add_routine_page.dart @@ -61,8 +61,7 @@ class _AddRoutinePageState extends State { }); } - Future - _sendRoutineToHub() async { + Future _sendRoutineToHub() async { if (daysToRepeat == null || hourToRepeat == null || minutesToRepeat == null ||