Skip to content

Commit

Permalink
Moved esphome python function to run inside new isolate using compute…
Browse files Browse the repository at this point in the history
… function
  • Loading branch information
guyluz11 committed Nov 26, 2022
1 parent 10825e3 commit a2dd4b3
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:collection';

import 'package:cbj_hub/domain/generic_devices/abstract_device/core_failures.dart';
import 'package:cbj_hub/domain/generic_devices/abstract_device/device_entity_abstract.dart';
Expand All @@ -17,6 +18,7 @@ class EspHomeConnectorConjector implements AbstractCompanyConnectorConjector {
static const List<String> mdnsTypes = ['_esphomelib._tcp'];

static Map<String, DeviceEntityAbstract> companyDevices = {};
static HashSet<String> lastMdnsName = HashSet<String>();

/// Add new devices to [companyDevices] if not exist
Future<void> addNewDeviceByMdnsName({
Expand All @@ -27,6 +29,15 @@ class EspHomeConnectorConjector implements AbstractCompanyConnectorConjector {
}) async {
CoreUniqueId? tempCoreUniqueId;

// Python process take so much that the same result can arrive again
// before the device completed the process and got add
// This fixe it
if (lastMdnsName.contains(mDnsName)) {
return;
}

lastMdnsName.add(mDnsName);

for (final DeviceEntityAbstract device in companyDevices.values) {
if (device is EspHomeLightEntity &&
mDnsName == device.vendorUniqueId.getOrCrash()) {
Expand Down
15 changes: 12 additions & 3 deletions lib/infrastructure/devices/esphome/esphome_helpers.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import 'package:cbj_hub/domain/generic_devices/abstract_device/device_entity_abstract.dart';
import 'package:cbj_hub/infrastructure/devices/esphome/esphome_python_api/esphome_python_api.dart';
import 'package:cbj_hub/infrastructure/system_commands/system_commands_manager_d.dart';
import 'package:cbj_hub/injection.dart';

class EspHomeHelpers {
static Future<List<DeviceEntityAbstract>> addDiscoverdEntities({
required String address,
required String mDnsName,
String port = '6053',
}) async {
final List<DeviceEntityAbstract> deviceEntityList =
await EspHomePythonApi.getAllEntities(
final HelperEspHomeDeviceInfo helperEspHomeDeviceInfo =
HelperEspHomeDeviceInfo(
address: address,
mDnsName: mDnsName,
port: port,
deviceKey: 'null',
newState: 'null',
mDnsName: mDnsName,
devicePassword: 'null',
getProjectFilesLocation:
await getIt<SystemCommandsManager>().getProjectFilesLocation(),
);
final List<DeviceEntityAbstract> deviceEntityList =
await EspHomePythonApi.getAllEntities(helperEspHomeDeviceInfo);

return deviceEntityList;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import 'package:cbj_hub/domain/generic_devices/generic_light_device/generic_ligh
import 'package:cbj_hub/domain/generic_devices/generic_light_device/generic_light_value_objects.dart';
import 'package:cbj_hub/infrastructure/devices/esphome/esphome_python_api/esphome_python_api.dart';
import 'package:cbj_hub/infrastructure/gen/cbj_hub_server/protoc_as_dart/cbj_hub_server.pbgrpc.dart';
import 'package:cbj_hub/infrastructure/system_commands/system_commands_manager_d.dart';
import 'package:cbj_hub/injection.dart';
import 'package:cbj_hub/utils.dart';
import 'package:compute/compute.dart';
import 'package:dartz/dartz.dart';

class EspHomeLightEntity extends GenericLightDE {
Expand Down Expand Up @@ -98,13 +101,25 @@ class EspHomeLightEntity extends GenericLightDE {
lightSwitchState = GenericLightSwitchState(DeviceActions.on.toString());

try {
logger.v('Turn on ESPHome Light');
await EspHomePythonApi.turnOnOffLightEntity(
final HelperEspHomeDeviceInfo helperEspHomeDeviceInfo =
HelperEspHomeDeviceInfo(
address: lastKnownIp!.getOrCrash(),
port: devicePort.getOrCrash(),
deviceKey: espHomeKey.getOrCrash(),
newState: 'True',
mDnsName: 'null',
devicePassword: 'null',
getProjectFilesLocation:
await getIt<SystemCommandsManager>().getProjectFilesLocation(),
);

logger.v('Turn on ESPHome Light');
await compute(
EspHomePythonApi.turnOnOffLightEntity,
helperEspHomeDeviceInfo,
);

await EspHomePythonApi.turnOnOffLightEntity(helperEspHomeDeviceInfo);
return right(unit);
} catch (e) {
return left(const CoreFailure.unexpected());
Expand All @@ -116,11 +131,21 @@ class EspHomeLightEntity extends GenericLightDE {
lightSwitchState = GenericLightSwitchState(DeviceActions.off.toString());

try {
await EspHomePythonApi.turnOnOffLightEntity(
final HelperEspHomeDeviceInfo helperEspHomeDeviceInfo =
HelperEspHomeDeviceInfo(
address: lastKnownIp!.getOrCrash(),
port: devicePort.getOrCrash(),
deviceKey: espHomeKey.getOrCrash(),
newState: 'False',
mDnsName: 'null',
devicePassword: 'null',
getProjectFilesLocation:
await getIt<SystemCommandsManager>().getProjectFilesLocation(),
);

await compute(
EspHomePythonApi.turnOnOffLightEntity,
helperEspHomeDeviceInfo,
);
return right(unit);
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import 'package:cbj_hub/domain/generic_devices/abstract_device/device_entity_abstract.dart';
import 'package:cbj_hub/infrastructure/devices/esphome/esphome_python_api/esphome_python_json_objects_type.dart';
import 'package:cbj_hub/infrastructure/system_commands/system_commands_manager_d.dart';
import 'package:cbj_hub/injection.dart';
import 'package:cbj_hub/utils.dart';
import 'package:python_shell/python_shell.dart';

Expand All @@ -17,22 +15,21 @@ class EspHomePythonApi {

_shell = PythonShell(PythonShellConfig());
await _shell!.initialize();
final instance = ShellManager.getInstance("default");
instance.installRequires(requeiredPythonPackages);
return _shell!;
}

static Future<List<DeviceEntityAbstract>> getAllEntities({
required String address,
required String mDnsName,
required String port,
}) async {
static Future<List<DeviceEntityAbstract>> getAllEntities(
HelperEspHomeDeviceInfo helperEspHomeDeviceInfo,
) async {
const String devicePassword = 'MyPassword';
final List<DeviceEntityAbstract> devicesList = [];

try {
await getShell();

final instance = ShellManager.getInstance("default");
instance.installRequires(requeiredPythonPackages);

String? currentType;

Expand All @@ -43,9 +40,9 @@ class EspHomePythonApi {
EsphomePythonJsonObjectsType.getDeviceAsAbstractIfExist(
currentType: currentType!,
deviceJson: message,
address: address,
mDnsName: mDnsName,
port: port,
address: helperEspHomeDeviceInfo.address,
mDnsName: helperEspHomeDeviceInfo.mDnsName,
port: helperEspHomeDeviceInfo.port,
);
if (convertedDevice != null) {
devicesList.add(convertedDevice);
Expand All @@ -64,11 +61,11 @@ class EspHomePythonApi {
);

await instance.runFile(
'${await getIt<SystemCommandsManager>().getProjectFilesLocation()}/lib/infrastructure/devices/esphome/esphome_python_api/esphome_python_files/get_esphome_entities.py',
'${helperEspHomeDeviceInfo.getProjectFilesLocation}/lib/infrastructure/devices/esphome/esphome_python_api/esphome_python_files/get_esphome_entities.py',
listener: shellListener,
arguments: [
address,
port,
helperEspHomeDeviceInfo.address,
helperEspHomeDeviceInfo.port,
devicePassword,
],
echo: false,
Expand All @@ -79,18 +76,14 @@ class EspHomePythonApi {
return devicesList;
}

static Future<void> turnOnOffLightEntity({
required String address,
required String port,
required String deviceKey,
required String newState,
}) async {
static Future<void> turnOnOffLightEntity(
HelperEspHomeDeviceInfo helperEspHomeDeviceInfo,
) async {
const String devicePassword = 'MyPassword';

await getShell();

final instance = ShellManager.getInstance("default");
instance.installRequires(requeiredPythonPackages);

final ShellListener shellListener = ShellListener(
onMessage: (String message) {},
Expand All @@ -103,31 +96,27 @@ class EspHomePythonApi {
);

await instance.runFile(
'${await getIt<SystemCommandsManager>().getProjectFilesLocation()}/lib/infrastructure/devices/esphome/esphome_python_api/esphome_python_files/turn_on_off_light_entity_esphome_devices.py',
'${helperEspHomeDeviceInfo.getProjectFilesLocation}/lib/infrastructure/devices/esphome/esphome_python_api/esphome_python_files/turn_on_off_light_entity_esphome_devices.py',
listener: shellListener,
arguments: [
address,
port,
devicePassword,
deviceKey,
newState,
helperEspHomeDeviceInfo.address,
helperEspHomeDeviceInfo.port,
helperEspHomeDeviceInfo.devicePassword,
helperEspHomeDeviceInfo.deviceKey,
helperEspHomeDeviceInfo.newState,
],
echo: false,
);
}

static Future<void> turnOnOffSwitchEntity({
required String address,
required String port,
required String deviceKey,
required String newState,
}) async {
static Future<void> turnOnOffSwitchEntity(
HelperEspHomeDeviceInfo helperEspHomeDeviceInfo,
) async {
const String devicePassword = 'MyPassword';

await getShell();

final instance = ShellManager.getInstance("default");
instance.installRequires(requeiredPythonPackages);

final ShellListener shellListener = ShellListener(
onMessage: (String message) {},
Expand All @@ -140,16 +129,36 @@ class EspHomePythonApi {
);

await instance.runFile(
'${await getIt<SystemCommandsManager>().getProjectFilesLocation()}/lib/infrastructure/devices/esphome/esphome_python_api/esphome_python_files/turn_on_off_switch_entity_esphome_devices.py',
'${helperEspHomeDeviceInfo.getProjectFilesLocation}/lib/infrastructure/devices/esphome/esphome_python_api/esphome_python_files/turn_on_off_switch_entity_esphome_devices.py',
listener: shellListener,
arguments: [
address,
port,
devicePassword,
deviceKey,
newState,
helperEspHomeDeviceInfo.address,
helperEspHomeDeviceInfo.port,
helperEspHomeDeviceInfo.devicePassword,
helperEspHomeDeviceInfo.deviceKey,
helperEspHomeDeviceInfo.newState,
],
echo: false,
);
}
}

class HelperEspHomeDeviceInfo {
HelperEspHomeDeviceInfo({
required this.address,
required this.port,
required this.deviceKey,
required this.newState,
required this.mDnsName,
required this.devicePassword,
required this.getProjectFilesLocation,
});

String address;
String port;
String deviceKey;
String newState;
String mDnsName;
String devicePassword;
String getProjectFilesLocation;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import 'package:cbj_hub/domain/generic_devices/generic_switch_device/generic_swi
import 'package:cbj_hub/domain/generic_devices/generic_switch_device/generic_switch_value_objects.dart';
import 'package:cbj_hub/infrastructure/devices/esphome/esphome_python_api/esphome_python_api.dart';
import 'package:cbj_hub/infrastructure/gen/cbj_hub_server/protoc_as_dart/cbj_hub_server.pbgrpc.dart';
import 'package:cbj_hub/infrastructure/system_commands/system_commands_manager_d.dart';
import 'package:cbj_hub/injection.dart';
import 'package:cbj_hub/utils.dart';
import 'package:compute/compute.dart';
import 'package:dartz/dartz.dart';

class EspHomeSwitchEntity extends GenericSwitchDE {
Expand Down Expand Up @@ -97,11 +100,21 @@ class EspHomeSwitchEntity extends GenericSwitchDE {
switchState = GenericSwitchSwitchState(DeviceActions.on.toString());

try {
await EspHomePythonApi.turnOnOffSwitchEntity(
final HelperEspHomeDeviceInfo helperEspHomeDeviceInfo =
HelperEspHomeDeviceInfo(
address: lastKnownIp!.getOrCrash(),
port: devicePort.getOrCrash(),
deviceKey: espHomeKey.getOrCrash(),
newState: 'True',
mDnsName: 'null',
devicePassword: 'null',
getProjectFilesLocation:
await getIt<SystemCommandsManager>().getProjectFilesLocation(),
);

await compute(
EspHomePythonApi.turnOnOffSwitchEntity,
helperEspHomeDeviceInfo,
);
logger.v('Turn on ESPHome switch');
return right(unit);
Expand All @@ -115,12 +128,22 @@ class EspHomeSwitchEntity extends GenericSwitchDE {
switchState = GenericSwitchSwitchState(DeviceActions.off.toString());

try {
logger.v('Turn off ESPHome device');
await EspHomePythonApi.turnOnOffSwitchEntity(
final HelperEspHomeDeviceInfo helperEspHomeDeviceInfo =
HelperEspHomeDeviceInfo(
address: lastKnownIp!.getOrCrash(),
port: devicePort.getOrCrash(),
deviceKey: espHomeKey.getOrCrash(),
newState: 'False',
mDnsName: 'null',
devicePassword: 'null',
getProjectFilesLocation:
await getIt<SystemCommandsManager>().getProjectFilesLocation(),
);

logger.v('Turn off ESPHome device');
await compute(
EspHomePythonApi.turnOnOffSwitchEntity,
helperEspHomeDeviceInfo,
);
return right(unit);
} catch (e) {
Expand Down
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ dependencies:
async: ^2.10.0
# Package to create, convert, alter, and compare colors in a variety of colorspaces.
color: ^3.0.0
# Compute function made available for all non-Flutter Dart programs
compute: ^1.0.2
# Collection of cyclic redundancy check (CRC) routines as Dart converters.
crclib: ^3.0.0
# Functional programming thingies, let you use multiple return types
Expand Down

0 comments on commit a2dd4b3

Please sign in to comment.