@homebridge-plugins/homebridge-tuya 3.0.0-beta.2 → 3.0.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +354 -142
- package/config.schema.json +1221 -893
- package/dist/cloud/api/TuyaOpenAPI.js +108 -60
- package/dist/cloud/api/TuyaOpenAPI.js.map +1 -1
- package/dist/cloud/api/TuyaOpenMQ.js +45 -22
- package/dist/cloud/api/TuyaOpenMQ.js.map +1 -1
- package/dist/cloud/device/{TuyaDeviceManager.js → TuyaCloudDeviceManager.js} +146 -96
- package/dist/cloud/device/TuyaCloudDeviceManager.js.map +1 -0
- package/dist/cloud/device/TuyaCustomDeviceManager.js +75 -5
- package/dist/cloud/device/TuyaCustomDeviceManager.js.map +1 -1
- package/dist/cloud/device/TuyaDevice.js.map +1 -1
- package/dist/cloud/device/TuyaHomeDeviceManager.js +81 -13
- package/dist/cloud/device/TuyaHomeDeviceManager.js.map +1 -1
- package/dist/config.js +26 -5
- package/dist/config.js.map +1 -1
- package/dist/local/DynamicChildDiscovery.js +2 -1
- package/dist/local/DynamicChildDiscovery.js.map +1 -1
- package/dist/local/LocalDevice.js +16 -3
- package/dist/local/LocalDevice.js.map +1 -1
- package/dist/local/LocalDeviceManager.js +361 -164
- package/dist/local/LocalDeviceManager.js.map +1 -1
- package/dist/local/TuyaDiscovery.js +16 -7
- package/dist/local/TuyaDiscovery.js.map +1 -1
- package/dist/local/ZigbeeGatewayDetection.js +7 -4
- package/dist/local/ZigbeeGatewayDetection.js.map +1 -1
- package/dist/local/protocol/ProtocolUtilities.js +34 -17
- package/dist/local/protocol/ProtocolUtilities.js.map +1 -1
- package/dist/local/protocol/ProtocolV31V32.js +4 -2
- package/dist/local/protocol/ProtocolV31V32.js.map +1 -1
- package/dist/local/protocol/ProtocolV33.js +4 -2
- package/dist/local/protocol/ProtocolV33.js.map +1 -1
- package/dist/local/protocol/ProtocolV34.js +10 -5
- package/dist/local/protocol/ProtocolV34.js.map +1 -1
- package/dist/local/protocol/ProtocolV35.js +8 -4
- package/dist/local/protocol/ProtocolV35.js.map +1 -1
- package/dist/platform.js +253 -493
- package/dist/platform.js.map +1 -1
- package/dist/settings.js +0 -2
- package/dist/settings.js.map +1 -1
- package/dist/shared/TuyaDeviceManager.js +147 -0
- package/dist/shared/TuyaDeviceManager.js.map +1 -0
- package/dist/shared/TuyaHybridDeviceManager.js +215 -0
- package/dist/shared/TuyaHybridDeviceManager.js.map +1 -0
- package/dist/shared/accessory/AccessoryFactory.js +350 -0
- package/dist/shared/accessory/AccessoryFactory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/AirConditionerAccessory.js +21 -15
- package/dist/shared/accessory/AirConditionerAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/AirPurifierAccessory.js.map +1 -1
- package/dist/shared/accessory/AirQualitySensorAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/BaseAccessory.js +16 -95
- package/dist/shared/accessory/BaseAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/BlindsAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/CameraAccessory.js +2 -2
- package/dist/shared/accessory/CameraAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/CarbonDioxideSensorAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/CarbonMonoxideSensorAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/ContactSensorAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/DehumidifierAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/DiffuserAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/DimmerAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/DoorbellAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/ExtractionHoodAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/FanAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/GarageDoorAccessory.js +19 -2
- package/dist/shared/accessory/GarageDoorAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/HeaterAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/HeaterAccessory_old.js.map +1 -1
- package/dist/shared/accessory/HumanPresenceSensorAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/HumidifierAccessory.js.map +1 -1
- package/dist/shared/accessory/IRAdapter.js +167 -0
- package/dist/shared/accessory/IRAdapter.js.map +1 -0
- package/dist/shared/accessory/IRAirConditionerAccessory.js.map +1 -0
- package/dist/shared/accessory/IRControlHubAccessory.js.map +1 -0
- package/dist/shared/accessory/IRControlHubSubAccessory.js.map +1 -0
- package/dist/shared/accessory/IRFanAccessory.js +90 -0
- package/dist/shared/accessory/IRFanAccessory.js.map +1 -0
- package/dist/shared/accessory/IRGenericAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/LeakSensorAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/LightAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/LightSensorAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/LocationWeatherAccessory.js +1 -1
- package/dist/shared/accessory/LocationWeatherAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/LockAccessory.js +3 -3
- package/dist/shared/{accessories → accessory}/LockAccessory.js.map +1 -1
- package/dist/shared/accessory/MotionSensorAccessory.js.map +1 -0
- package/dist/shared/accessory/OutletAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/PetFeederAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/SceneAccessory.js +1 -1
- package/dist/shared/accessory/SceneAccessory.js.map +1 -0
- package/dist/shared/accessory/SceneSwitchAccessory.js.map +1 -0
- package/dist/shared/accessory/SecuritySystemAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/SmokeSensorAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/SwitchAccessory.js +1 -45
- package/dist/shared/accessory/SwitchAccessory.js.map +1 -0
- package/dist/shared/accessory/TemperatureHumiditySensorAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/ThermostatAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/TowerRackAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/ValveAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/VibrationSensorAccessory.js.map +1 -1
- package/dist/shared/accessory/WeatherStationAccessory.js.map +1 -0
- package/dist/shared/accessory/WetBulbGlobeTemperatureAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/WhiteNoiseLightAccessory.js +1 -0
- package/dist/shared/accessory/WhiteNoiseLightAccessory.js.map +1 -0
- package/dist/shared/accessory/WindowAccessory.js.map +1 -0
- package/dist/shared/{accessories → accessory}/WindowCoveringAccessory.js.map +1 -1
- package/dist/shared/{accessories → accessory}/WirelessSwitchAccessory.js.map +1 -1
- package/dist/shared/accessory/characteristic/Active.js.map +1 -0
- package/dist/shared/accessory/characteristic/AirQuality.js.map +1 -0
- package/dist/shared/{accessories → accessory}/characteristic/CurrentRelativeHumidity.js +3 -0
- package/dist/shared/accessory/characteristic/CurrentRelativeHumidity.js.map +1 -0
- package/dist/shared/accessory/characteristic/CurrentTemperature.js.map +1 -0
- package/dist/shared/accessory/characteristic/CurrentWeather.js.map +1 -0
- package/dist/shared/accessory/characteristic/CurrentWeatherByOpenMeteo.js.map +1 -0
- package/dist/shared/{accessories → accessory}/characteristic/CurrentWetBulbGlobeTemperature.js +3 -2
- package/dist/shared/accessory/characteristic/CurrentWetBulbGlobeTemperature.js.map +1 -0
- package/dist/shared/{accessories → accessory}/characteristic/EnergyUsage.js +0 -5
- package/dist/shared/accessory/characteristic/EnergyUsage.js.map +1 -0
- package/dist/shared/{accessories → accessory}/characteristic/Light.js +28 -5
- package/dist/shared/accessory/characteristic/Light.js.map +1 -0
- package/dist/shared/accessory/characteristic/LightSensor.js.map +1 -0
- package/dist/shared/{accessories → accessory}/characteristic/LockPhysicalControls.js +3 -0
- package/dist/shared/accessory/characteristic/LockPhysicalControls.js.map +1 -0
- package/dist/shared/accessory/characteristic/MotionDetected.js.map +1 -0
- package/dist/shared/accessory/characteristic/Name.js.map +1 -0
- package/dist/shared/accessory/characteristic/OccupancyDetected.js.map +1 -0
- package/dist/shared/{accessories → accessory}/characteristic/On.js +1 -0
- package/dist/shared/accessory/characteristic/On.js.map +1 -0
- package/dist/shared/accessory/characteristic/OutletInUse.js.map +1 -0
- package/dist/shared/accessory/characteristic/ProgrammableSwitchEvent.js.map +1 -0
- package/dist/shared/{accessories → accessory}/characteristic/RelativeHumidityDehumidifierThreshold.js +3 -0
- package/dist/shared/accessory/characteristic/RelativeHumidityDehumidifierThreshold.js.map +1 -0
- package/dist/shared/accessory/characteristic/RotationSpeed.js.map +1 -0
- package/dist/shared/accessory/characteristic/SecuritySystemState.js.map +1 -0
- package/dist/shared/{accessories → accessory}/characteristic/SwingMode.js +3 -0
- package/dist/shared/accessory/characteristic/SwingMode.js.map +1 -0
- package/dist/shared/accessory/characteristic/TargetTemperature.js.map +1 -0
- package/dist/shared/accessory/characteristic/TemperatureDisplayUnits.js.map +1 -0
- package/dist/shared/util/ConfigHash.js +2 -2
- package/dist/shared/util/ConfigHash.js.map +1 -1
- package/dist/shared/util/ConfigMigrator.js +222 -0
- package/dist/shared/util/ConfigMigrator.js.map +1 -0
- package/dist/shared/util/FfmpegStreamingProcess.js +62 -0
- package/dist/shared/util/FfmpegStreamingProcess.js.map +1 -1
- package/dist/shared/util/InfraredTool.js +0 -2
- package/dist/shared/util/InfraredTool.js.map +1 -1
- package/dist/shared/util/Logger.js +85 -10
- package/dist/shared/util/Logger.js.map +1 -1
- package/dist/shared/util/TuyaStreamDelegate.js +194 -97
- package/dist/shared/util/TuyaStreamDelegate.js.map +1 -1
- package/dist/shared/util/util.js +59 -4
- package/dist/shared/util/util.js.map +1 -1
- package/docs/ADVANCED_OPTIONS.md +603 -0
- package/docs/CONFIG_GUIDE.md +616 -0
- package/docs/Get-Local-Keys-for-Your-Devices.md +246 -0
- package/{SUPPORTED_DEVICES.md → docs/SUPPORTED_DEVICES.md} +24 -3
- package/eslint.config.mjs +0 -1
- package/{jest.config.js → jest.config.ts} +5 -2
- package/package.json +12 -9
- package/test/ConfigMigrator.test.ts +1060 -0
- package/test/Logger.test.ts +482 -0
- package/test/accessoryFactory.data.test.ts +172 -0
- package/test/accessoryFactory.test.ts +64 -35
- package/test/airConditioner.test.ts +742 -0
- package/test/config.test.ts +17 -13
- package/test/custom.test.ts +2 -2
- package/test/errorHandling.test.ts +12 -12
- package/test/home.test.ts +1 -1
- package/test/hybridDeviceManager.test.ts +808 -0
- package/test/light.test.ts +250 -0
- package/test/localDevice.test.ts +21 -50
- package/test/localDeviceManager.behavior.test.ts +196 -31
- package/test/localDeviceManager.test.ts +124 -41
- package/test/mqttMessages.test.ts +33 -14
- package/test/platform.test.ts +337 -814
- package/test/platform.validation.local.test.ts +58 -119
- package/test/tuyaCustomDeviceManager.test.ts +106 -16
- package/test/tuyaDeviceManager.test.ts +636 -639
- package/test/tuyaDiscovery.test.ts +21 -33
- package/test/tuyaHomeDeviceManager.test.ts +109 -18
- package/test/tuyaOpenAPI.test.ts +25 -44
- package/test/tuyaOpenMQ.test.ts +15 -23
- package/test/util.test.ts +107 -7
- package/test/zigbee/LocalDevice.zigbee.test.ts +14 -18
- package/test/zigbee/LocalDeviceManager.cloud-discovery.test.ts +19 -20
- package/test/zigbee/LocalDeviceManager.zigbee.reconnect.test.ts +19 -20
- package/test/zigbee/LocalDeviceManager.zigbee.test.ts +73 -35
- package/test/zigbee/ZigbeeGatewayDetection.test.ts +2 -2
- package/ADVANCED_OPTIONS.md +0 -267
- package/dist/cloud/device/TuyaDeviceManager.js.map +0 -1
- package/dist/local/CloudLocalReconciliation.js +0 -180
- package/dist/local/CloudLocalReconciliation.js.map +0 -1
- package/dist/shared/AccessoryFactory.js +0 -276
- package/dist/shared/AccessoryFactory.js.map +0 -1
- package/dist/shared/accessories/AccessoryFactory.js +0 -305
- package/dist/shared/accessories/AccessoryFactory.js.map +0 -1
- package/dist/shared/accessories/AirConditionerAccessory.js.map +0 -1
- package/dist/shared/accessories/AirQualitySensorAccessory.js.map +0 -1
- package/dist/shared/accessories/BaseAccessory.js.map +0 -1
- package/dist/shared/accessories/CameraAccessory.js.map +0 -1
- package/dist/shared/accessories/GarageDoorAccessory.js.map +0 -1
- package/dist/shared/accessories/HumanPresenceSensorAccessory.js.map +0 -1
- package/dist/shared/accessories/IRAirConditionerAccessory.js.map +0 -1
- package/dist/shared/accessories/IRControlHubAccessory.js.map +0 -1
- package/dist/shared/accessories/IRControlHubSubAccessory.js.map +0 -1
- package/dist/shared/accessories/IRGenericAccessory.js.map +0 -1
- package/dist/shared/accessories/LocationWeatherAccessory.js.map +0 -1
- package/dist/shared/accessories/MotionSensorAccessory.js.map +0 -1
- package/dist/shared/accessories/OutletAccessory.js.map +0 -1
- package/dist/shared/accessories/SceneAccessory.js.map +0 -1
- package/dist/shared/accessories/SceneSwitchAccessory.js.map +0 -1
- package/dist/shared/accessories/SecuritySystemAccessory.js.map +0 -1
- package/dist/shared/accessories/SwitchAccessory.js.map +0 -1
- package/dist/shared/accessories/TemperatureHumiditySensorAccessory.js.map +0 -1
- package/dist/shared/accessories/WeatherStationAccessory.js.map +0 -1
- package/dist/shared/accessories/WetBulbGlobeTemperatureAccessory.js.map +0 -1
- package/dist/shared/accessories/WhiteNoiseLightAccessory.js.map +0 -1
- package/dist/shared/accessories/WindowAccessory.js.map +0 -1
- package/dist/shared/accessories/characteristic/Active.js.map +0 -1
- package/dist/shared/accessories/characteristic/AirQuality.js.map +0 -1
- package/dist/shared/accessories/characteristic/CurrentRelativeHumidity.js.map +0 -1
- package/dist/shared/accessories/characteristic/CurrentTemperature.js.map +0 -1
- package/dist/shared/accessories/characteristic/CurrentWeather.js.map +0 -1
- package/dist/shared/accessories/characteristic/CurrentWeatherByOpenMeteo.js.map +0 -1
- package/dist/shared/accessories/characteristic/CurrentWetBulbGlobeTemperature.js.map +0 -1
- package/dist/shared/accessories/characteristic/EnergyUsage.js.map +0 -1
- package/dist/shared/accessories/characteristic/Light.js.map +0 -1
- package/dist/shared/accessories/characteristic/LightSensor.js.map +0 -1
- package/dist/shared/accessories/characteristic/LockPhysicalControls.js.map +0 -1
- package/dist/shared/accessories/characteristic/MotionDetected.js.map +0 -1
- package/dist/shared/accessories/characteristic/Name.js.map +0 -1
- package/dist/shared/accessories/characteristic/OccupancyDetected.js.map +0 -1
- package/dist/shared/accessories/characteristic/On.js.map +0 -1
- package/dist/shared/accessories/characteristic/OutletInUse.js.map +0 -1
- package/dist/shared/accessories/characteristic/ProgrammableSwitchEvent.js.map +0 -1
- package/dist/shared/accessories/characteristic/RelativeHumidityDehumidifierThreshold.js.map +0 -1
- package/dist/shared/accessories/characteristic/RotationSpeed.js.map +0 -1
- package/dist/shared/accessories/characteristic/SecuritySystemState.js.map +0 -1
- package/dist/shared/accessories/characteristic/SwingMode.js.map +0 -1
- package/dist/shared/accessories/characteristic/TargetTemperature.js.map +0 -1
- package/dist/shared/accessories/characteristic/TemperatureDisplayUnits.js.map +0 -1
- package/test/zigbee/CloudLocalReconciliation.test.ts +0 -284
- package/tuya-local-configs/dev-1.hash +0 -1
- package/tuya-local-configs/device1.hash +0 -1
- package/wiki/Get-Local-Keys-for-Your-Devices.md +0 -85
- /package/dist/shared/{accessories → accessory}/AirPurifierAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/AirQualitySensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/BlindsAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/CarbonDioxideSensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/CarbonMonoxideSensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/ContactSensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/DehumidifierAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/DiffuserAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/DimmerAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/DoorbellAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/ExtractionHoodAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/FanAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/HeaterAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/HeaterAccessory_old.js +0 -0
- /package/dist/shared/{accessories → accessory}/HumanPresenceSensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/HumidifierAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/IRAirConditionerAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/IRControlHubAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/IRControlHubSubAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/IRGenericAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/LeakSensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/LightAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/LightSensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/MotionSensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/OutletAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/PetFeederAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/SceneSwitchAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/SecuritySystemAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/SmokeSensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/TemperatureHumiditySensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/ThermostatAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/TowerRackAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/ValveAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/VibrationSensorAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/WeatherStationAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/WetBulbGlobeTemperatureAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/WindowAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/WindowCoveringAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/WirelessSwitchAccessory.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/Active.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/AirQuality.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/CurrentTemperature.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/CurrentWeather.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/CurrentWeatherByOpenMeteo.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/LightSensor.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/MotionDetected.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/Name.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/OccupancyDetected.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/OutletInUse.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/ProgrammableSwitchEvent.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/RotationSpeed.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/SecuritySystemState.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/TargetTemperature.js +0 -0
- /package/dist/shared/{accessories → accessory}/characteristic/TemperatureDisplayUnits.js +0 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, jest, test } from '@jest/globals';
|
|
2
2
|
import LocalDeviceManager from '../src/local/LocalDeviceManager';
|
|
3
3
|
import type { LocalConfig } from '../src/local/config';
|
|
4
|
+
import { TuyaPluginMode } from '../src/config';
|
|
5
|
+
import { TuyaDeviceSchemaType } from '../src/cloud/device/TuyaDevice';
|
|
6
|
+
import { ExLogger, initLogger } from '../src/shared/util/Logger';
|
|
4
7
|
|
|
5
8
|
const createdConnections: any[] = [];
|
|
6
9
|
|
|
@@ -29,37 +32,22 @@ jest.mock('../src/local/TuyaDiscovery', () => ({
|
|
|
29
32
|
},
|
|
30
33
|
}));
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
PrefixLogger: class PrefixLogger {
|
|
42
|
-
constructor(public parentLog: unknown, public name: string, public debugMode: boolean) {}
|
|
43
|
-
log() {}
|
|
44
|
-
info() {}
|
|
45
|
-
warn() {}
|
|
46
|
-
error() {}
|
|
47
|
-
debug() {}
|
|
48
|
-
},
|
|
49
|
-
}));
|
|
35
|
+
// Mock Logger
|
|
36
|
+
const mockLog: ExLogger = {
|
|
37
|
+
debug: jest.fn(),
|
|
38
|
+
info: jest.fn(),
|
|
39
|
+
warn: jest.fn(),
|
|
40
|
+
error: jest.fn(),
|
|
41
|
+
log: jest.fn(),
|
|
42
|
+
success: jest.fn(),
|
|
43
|
+
} as unknown as ExLogger;
|
|
50
44
|
|
|
51
45
|
describe('LocalDeviceManager command and local mapping behavior', () => {
|
|
52
46
|
let log: any;
|
|
53
47
|
|
|
54
48
|
beforeEach(() => {
|
|
49
|
+
initLogger(mockLog);
|
|
55
50
|
createdConnections.length = 0;
|
|
56
|
-
log = {
|
|
57
|
-
log: jest.fn(),
|
|
58
|
-
info: jest.fn(),
|
|
59
|
-
warn: jest.fn(),
|
|
60
|
-
error: jest.fn(),
|
|
61
|
-
debug: jest.fn(),
|
|
62
|
-
};
|
|
63
51
|
jest.clearAllMocks();
|
|
64
52
|
});
|
|
65
53
|
|
|
@@ -74,7 +62,7 @@ describe('LocalDeviceManager command and local mapping behavior', () => {
|
|
|
74
62
|
],
|
|
75
63
|
};
|
|
76
64
|
|
|
77
|
-
const manager = new LocalDeviceManager(config
|
|
65
|
+
const manager = new LocalDeviceManager(config);
|
|
78
66
|
await manager.initLocalDevices();
|
|
79
67
|
|
|
80
68
|
expect(manager.getDevice('dev-1')).toBeDefined();
|
|
@@ -98,7 +86,7 @@ describe('LocalDeviceManager command and local mapping behavior', () => {
|
|
|
98
86
|
],
|
|
99
87
|
};
|
|
100
88
|
|
|
101
|
-
const manager = new LocalDeviceManager(config
|
|
89
|
+
const manager = new LocalDeviceManager(config);
|
|
102
90
|
await manager.initLocalDevices();
|
|
103
91
|
|
|
104
92
|
const result = await manager.sendCommands('dev-1', [
|
|
@@ -121,12 +109,12 @@ describe('LocalDeviceManager command and local mapping behavior', () => {
|
|
|
121
109
|
devices: [],
|
|
122
110
|
};
|
|
123
111
|
|
|
124
|
-
const manager = new LocalDeviceManager(config
|
|
112
|
+
const manager = new LocalDeviceManager(config);
|
|
125
113
|
await manager.initLocalDevices();
|
|
126
114
|
|
|
127
115
|
const result = await manager.sendCommands('missing-device', [{ code: 'switch_1', value: true }]);
|
|
128
116
|
|
|
129
|
-
expect(result).
|
|
117
|
+
expect(result).toBe(false);
|
|
130
118
|
});
|
|
131
119
|
|
|
132
120
|
test('updates existing configured device IP on discovery and disconnects stale connection', async () => {
|
|
@@ -142,7 +130,7 @@ describe('LocalDeviceManager command and local mapping behavior', () => {
|
|
|
142
130
|
],
|
|
143
131
|
};
|
|
144
132
|
|
|
145
|
-
const manager = new LocalDeviceManager(config
|
|
133
|
+
const manager = new LocalDeviceManager(config);
|
|
146
134
|
await manager.initLocalDevices();
|
|
147
135
|
manager.connectAllDevices();
|
|
148
136
|
|
|
@@ -166,7 +154,7 @@ describe('LocalDeviceManager command and local mapping behavior', () => {
|
|
|
166
154
|
devices: [],
|
|
167
155
|
};
|
|
168
156
|
|
|
169
|
-
const manager = new LocalDeviceManager(config
|
|
157
|
+
const manager = new LocalDeviceManager(config);
|
|
170
158
|
await manager.initLocalDevices();
|
|
171
159
|
|
|
172
160
|
(manager as any)._onDiscovered({
|
|
@@ -182,4 +170,181 @@ describe('LocalDeviceManager command and local mapping behavior', () => {
|
|
|
182
170
|
expect(discovered?.ip).toBe('192.168.1.30');
|
|
183
171
|
expect(discovered?.product_id).toBe('prod1');
|
|
184
172
|
});
|
|
173
|
+
|
|
174
|
+
test('keeps DP mapping when a local override uses the same code as a no-op rename', async () => {
|
|
175
|
+
const config: LocalConfig = {
|
|
176
|
+
autoDiscoverDevices: false,
|
|
177
|
+
deviceOverrides: [{
|
|
178
|
+
id: 'dev-1',
|
|
179
|
+
configFor: TuyaPluginMode.local,
|
|
180
|
+
schema: [{
|
|
181
|
+
code: 'humidity_indoor',
|
|
182
|
+
newCode: 'humidity_indoor',
|
|
183
|
+
type: TuyaDeviceSchemaType.Integer,
|
|
184
|
+
property: { min: 0, max: 100, scale: 0, step: 1 },
|
|
185
|
+
}],
|
|
186
|
+
}],
|
|
187
|
+
devices: [{
|
|
188
|
+
tuyaDeviceId: 'dev-1',
|
|
189
|
+
ip: '192.168.1.10',
|
|
190
|
+
tuyaKey: 'abcdef1234567890',
|
|
191
|
+
protocolVersion: '3.5',
|
|
192
|
+
dpMapping: {
|
|
193
|
+
humidity_indoor: 6,
|
|
194
|
+
},
|
|
195
|
+
}],
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
const manager = new LocalDeviceManager(config);
|
|
199
|
+
await manager.initLocalDevices();
|
|
200
|
+
|
|
201
|
+
const device = manager.getDevice('dev-1');
|
|
202
|
+
const dpMap = (manager as any).dpMaps.get('dev-1');
|
|
203
|
+
const reverseMap = (manager as any).reverseDpMaps.get('dev-1');
|
|
204
|
+
|
|
205
|
+
expect(dpMap?.humidity_indoor).toBe(6);
|
|
206
|
+
expect(reverseMap?.[6]).toBe('humidity_indoor');
|
|
207
|
+
expect(device?.schema.some(schema => schema.code === 'humidity_indoor' && schema.type === TuyaDeviceSchemaType.Integer)).toBe(true);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test('applies local overrides without a rename using the original code', async () => {
|
|
211
|
+
const config: LocalConfig = {
|
|
212
|
+
autoDiscoverDevices: false,
|
|
213
|
+
deviceOverrides: [{
|
|
214
|
+
id: 'dev-1',
|
|
215
|
+
configFor: TuyaPluginMode.local,
|
|
216
|
+
schema: [{
|
|
217
|
+
code: 'humidity_indoor',
|
|
218
|
+
type: TuyaDeviceSchemaType.Integer,
|
|
219
|
+
property: { min: 0, max: 100, scale: 0, step: 1 },
|
|
220
|
+
}],
|
|
221
|
+
}],
|
|
222
|
+
devices: [{
|
|
223
|
+
tuyaDeviceId: 'dev-1',
|
|
224
|
+
ip: '192.168.1.10',
|
|
225
|
+
tuyaKey: 'abcdef1234567890',
|
|
226
|
+
protocolVersion: '3.5',
|
|
227
|
+
dpMapping: {
|
|
228
|
+
humidity_indoor: 6,
|
|
229
|
+
},
|
|
230
|
+
}],
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const manager = new LocalDeviceManager(config);
|
|
234
|
+
await manager.initLocalDevices();
|
|
235
|
+
|
|
236
|
+
const device = manager.getDevice('dev-1');
|
|
237
|
+
const schema = device?.schema.find(item => item.code === 'humidity_indoor');
|
|
238
|
+
|
|
239
|
+
expect(schema).toBeDefined();
|
|
240
|
+
expect(schema?.type).toBe(TuyaDeviceSchemaType.Integer);
|
|
241
|
+
expect(device?.schema.every(item => !!item.code)).toBe(true);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('applies local overrides', async () => {
|
|
245
|
+
const config: LocalConfig = {
|
|
246
|
+
autoDiscoverDevices: false,
|
|
247
|
+
devices: [],
|
|
248
|
+
deviceOverrides: [{
|
|
249
|
+
id: 'dev-1',
|
|
250
|
+
category: 'jsq',
|
|
251
|
+
configFor: TuyaPluginMode.local,
|
|
252
|
+
schema: [{
|
|
253
|
+
code: 'humidity_indoor',
|
|
254
|
+
type: TuyaDeviceSchemaType.Integer,
|
|
255
|
+
property: { min: 0, max: 100, scale: 0, step: 1 },
|
|
256
|
+
}],
|
|
257
|
+
}],
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const manager = new LocalDeviceManager(config);
|
|
261
|
+
await manager.initLocalDevices();
|
|
262
|
+
|
|
263
|
+
(manager as any)._onDiscovered({
|
|
264
|
+
id: 'dev-1',
|
|
265
|
+
ip: '192.168.0.1',
|
|
266
|
+
version: '3.3',
|
|
267
|
+
productKey: 'prod1',
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
const device = manager.getDevice('dev-1');
|
|
271
|
+
|
|
272
|
+
expect(device).toBeDefined();
|
|
273
|
+
expect(device?.ip).toBe('192.168.0.1');
|
|
274
|
+
expect(device?.product_id).toBe('prod1');
|
|
275
|
+
expect(device?.category).toBe('jsq');
|
|
276
|
+
expect(device?.schema?.length).toBe(1);
|
|
277
|
+
expect(device?.schema?.[0].code).toBe('humidity_indoor');
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
test('do not apply cloud overrides to local devices', async () => {
|
|
281
|
+
const config: LocalConfig = {
|
|
282
|
+
autoDiscoverDevices: false,
|
|
283
|
+
devices: [],
|
|
284
|
+
deviceOverrides: [{
|
|
285
|
+
id: 'dev-1',
|
|
286
|
+
category: 'jsq',
|
|
287
|
+
configFor: TuyaPluginMode.cloud,
|
|
288
|
+
schema: [{
|
|
289
|
+
code: 'humidity_indoor',
|
|
290
|
+
type: TuyaDeviceSchemaType.Integer,
|
|
291
|
+
property: { min: 0, max: 100, scale: 0, step: 1 },
|
|
292
|
+
}],
|
|
293
|
+
}],
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const manager = new LocalDeviceManager(config);
|
|
297
|
+
await manager.initLocalDevices();
|
|
298
|
+
|
|
299
|
+
(manager as any)._onDiscovered({
|
|
300
|
+
id: 'dev-1',
|
|
301
|
+
ip: '192.168.0.1',
|
|
302
|
+
version: '3.3',
|
|
303
|
+
productKey: 'prod1',
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
const device = manager.getDevice('dev-1');
|
|
307
|
+
|
|
308
|
+
expect(device).toBeDefined();
|
|
309
|
+
expect(device?.ip).toBe('192.168.0.1');
|
|
310
|
+
expect(device?.product_id).toBe('prod1');
|
|
311
|
+
expect(device?.category).toBe('unknown');
|
|
312
|
+
expect(device?.schema?.length).toBe(0);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
test('applies overrides local device (configFor:both)', async () => {
|
|
316
|
+
const config: LocalConfig = {
|
|
317
|
+
autoDiscoverDevices: false,
|
|
318
|
+
devices: [],
|
|
319
|
+
deviceOverrides: [{
|
|
320
|
+
id: 'dev-1',
|
|
321
|
+
category: 'jsq',
|
|
322
|
+
configFor: TuyaPluginMode.both,
|
|
323
|
+
schema: [{
|
|
324
|
+
code: 'humidity_indoor',
|
|
325
|
+
type: TuyaDeviceSchemaType.Integer,
|
|
326
|
+
property: { min: 0, max: 100, scale: 0, step: 1 },
|
|
327
|
+
}],
|
|
328
|
+
}],
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const manager = new LocalDeviceManager(config);
|
|
332
|
+
await manager.initLocalDevices();
|
|
333
|
+
|
|
334
|
+
(manager as any)._onDiscovered({
|
|
335
|
+
id: 'dev-1',
|
|
336
|
+
ip: '192.168.0.1',
|
|
337
|
+
version: '3.3',
|
|
338
|
+
productKey: 'prod1',
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
const device = manager.getDevice('dev-1');
|
|
342
|
+
|
|
343
|
+
expect(device).toBeDefined();
|
|
344
|
+
expect(device?.ip).toBe('192.168.0.1');
|
|
345
|
+
expect(device?.product_id).toBe('prod1');
|
|
346
|
+
expect(device?.category).toBe('jsq');
|
|
347
|
+
expect(device?.schema?.length).toBe(1);
|
|
348
|
+
expect(device?.schema?.[0].code).toBe('humidity_indoor');
|
|
349
|
+
});
|
|
185
350
|
});
|
|
@@ -2,17 +2,19 @@
|
|
|
2
2
|
import { describe, expect, test, beforeEach, afterEach, jest } from '@jest/globals';
|
|
3
3
|
import LocalDeviceManager from '../src/local/LocalDeviceManager';
|
|
4
4
|
import { LocalConfig } from '../src/local/config';
|
|
5
|
-
import
|
|
5
|
+
import ExLogger, { initLogger, logger } from '../src/shared/util/Logger';
|
|
6
|
+
import { ConfigHash } from '../src/shared/util/ConfigHash';
|
|
6
7
|
import TuyaDevice from '../src/cloud/device/TuyaDevice';
|
|
7
8
|
|
|
8
9
|
// Mock Logger
|
|
9
|
-
const mockLog:
|
|
10
|
+
const mockLog: ExLogger = {
|
|
10
11
|
debug: jest.fn(),
|
|
11
12
|
info: jest.fn(),
|
|
12
13
|
warn: jest.fn(),
|
|
13
14
|
error: jest.fn(),
|
|
14
15
|
log: jest.fn(),
|
|
15
|
-
|
|
16
|
+
success: jest.fn(),
|
|
17
|
+
} as unknown as ExLogger;
|
|
16
18
|
|
|
17
19
|
describe('LocalDeviceManager', () => {
|
|
18
20
|
let manager: LocalDeviceManager;
|
|
@@ -21,7 +23,8 @@ describe('LocalDeviceManager', () => {
|
|
|
21
23
|
const config: LocalConfig = {
|
|
22
24
|
devices: [],
|
|
23
25
|
};
|
|
24
|
-
manager = new LocalDeviceManager(config
|
|
26
|
+
manager = new LocalDeviceManager(config);
|
|
27
|
+
initLogger(mockLog);
|
|
25
28
|
});
|
|
26
29
|
|
|
27
30
|
afterEach(() => {
|
|
@@ -73,7 +76,7 @@ describe('LocalDeviceManager', () => {
|
|
|
73
76
|
const config: LocalConfig = {
|
|
74
77
|
devices: [],
|
|
75
78
|
};
|
|
76
|
-
const mgr = new LocalDeviceManager(config
|
|
79
|
+
const mgr = new LocalDeviceManager(config);
|
|
77
80
|
expect(mgr).toBeDefined();
|
|
78
81
|
});
|
|
79
82
|
|
|
@@ -88,7 +91,7 @@ describe('LocalDeviceManager', () => {
|
|
|
88
91
|
},
|
|
89
92
|
],
|
|
90
93
|
};
|
|
91
|
-
const mgr = new LocalDeviceManager(config
|
|
94
|
+
const mgr = new LocalDeviceManager(config);
|
|
92
95
|
expect(mgr).toBeDefined();
|
|
93
96
|
});
|
|
94
97
|
|
|
@@ -108,9 +111,107 @@ describe('LocalDeviceManager', () => {
|
|
|
108
111
|
},
|
|
109
112
|
],
|
|
110
113
|
};
|
|
111
|
-
const mgr = new LocalDeviceManager(config
|
|
114
|
+
const mgr = new LocalDeviceManager(config);
|
|
112
115
|
expect(mgr).toBeDefined();
|
|
113
116
|
});
|
|
117
|
+
|
|
118
|
+
test('uses outletCount for effective switch count hashing when switchCount is absent', () => {
|
|
119
|
+
const cfg = {
|
|
120
|
+
tuyaDeviceId: 'device1',
|
|
121
|
+
name: 'Patio Lights',
|
|
122
|
+
outletCount: 2,
|
|
123
|
+
};
|
|
124
|
+
const mgr = new LocalDeviceManager({ devices: [cfg as any] });
|
|
125
|
+
const device = new TuyaDevice({ id: 'device1', uuid: 'device1', name: 'Patio Lights', schema: [], status: [] });
|
|
126
|
+
(device as any).switchCount = 1;
|
|
127
|
+
|
|
128
|
+
const hash = mgr.createDeviceConfigHash(device);
|
|
129
|
+
const expectedHash = ConfigHash.computeHash({
|
|
130
|
+
tuyaDeviceId: cfg.tuyaDeviceId,
|
|
131
|
+
name: cfg.name,
|
|
132
|
+
tuyaKey: undefined,
|
|
133
|
+
dpMapping: (mgr as any)._getDPMap(cfg.tuyaDeviceId),
|
|
134
|
+
switchCount: 2,
|
|
135
|
+
outletCount: 2,
|
|
136
|
+
protocolVersion: undefined,
|
|
137
|
+
category: undefined,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
expect(hash).toBe(expectedHash);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test('creates a DP map from dpMapping and dpMappingArray', () => {
|
|
144
|
+
const mgr = new LocalDeviceManager({ devices: [] });
|
|
145
|
+
const cfg = {
|
|
146
|
+
tuyaDeviceId: 'device1',
|
|
147
|
+
dpMapping: {
|
|
148
|
+
switch_1: 1,
|
|
149
|
+
bright_value: 2,
|
|
150
|
+
},
|
|
151
|
+
dpMappingArray: [
|
|
152
|
+
{ dpCode: 'switch_2', dpID: 2 },
|
|
153
|
+
{ dpCode: 'temp_value', dpID: 3 },
|
|
154
|
+
],
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const dpMap = (mgr as any)._createDPMap(cfg);
|
|
158
|
+
|
|
159
|
+
expect(dpMap).toEqual({
|
|
160
|
+
switch_1: 1,
|
|
161
|
+
bright_value: 2,
|
|
162
|
+
switch_2: 2,
|
|
163
|
+
temp_value: 3,
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test('applies schema rename overrides when creating DP map', () => {
|
|
168
|
+
const mgr = new LocalDeviceManager({
|
|
169
|
+
devices: [],
|
|
170
|
+
deviceOverrides: [{
|
|
171
|
+
id: 'device1',
|
|
172
|
+
configFor: 'local',
|
|
173
|
+
schema: [{ code: 'switch_1', newCode: 'relay_1' }],
|
|
174
|
+
} as any],
|
|
175
|
+
});
|
|
176
|
+
const cfg = {
|
|
177
|
+
tuyaDeviceId: 'device1',
|
|
178
|
+
dpMapping: {
|
|
179
|
+
switch_1: 1,
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const dpMap = (mgr as any)._createDPMap(cfg);
|
|
184
|
+
|
|
185
|
+
expect(dpMap).toEqual({
|
|
186
|
+
relay_1: 1,
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
test('creating DP map with DEFAULT', () => {
|
|
191
|
+
const mgr = new LocalDeviceManager({
|
|
192
|
+
devices: [],
|
|
193
|
+
});
|
|
194
|
+
const cfg = {};
|
|
195
|
+
|
|
196
|
+
const dpMap = (mgr as any)._createDPMap(cfg);
|
|
197
|
+
|
|
198
|
+
expect(dpMap).toEqual({
|
|
199
|
+
"switch_1": 1,
|
|
200
|
+
"switch_2": 2,
|
|
201
|
+
"switch_3": 3,
|
|
202
|
+
"switch_4": 4,
|
|
203
|
+
"bright_value": 2,
|
|
204
|
+
"bright_value_v2": 22,
|
|
205
|
+
"temp_value": 3,
|
|
206
|
+
"temp_value_v2": 23,
|
|
207
|
+
"work_mode": 2,
|
|
208
|
+
"colour_data": 5,
|
|
209
|
+
"colour_data_v2": 24,
|
|
210
|
+
"switch_led": 1,
|
|
211
|
+
"countdown_1": 9,
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
114
215
|
});
|
|
115
216
|
|
|
116
217
|
describe('device discovery', () => {
|
|
@@ -118,7 +219,7 @@ describe('LocalDeviceManager', () => {
|
|
|
118
219
|
const config: LocalConfig = {
|
|
119
220
|
devices: [],
|
|
120
221
|
};
|
|
121
|
-
const mgr = new LocalDeviceManager(config
|
|
222
|
+
const mgr = new LocalDeviceManager(config);
|
|
122
223
|
|
|
123
224
|
// Should not throw
|
|
124
225
|
await expect(mgr.initLocalDevices()).resolves.not.toThrow();
|
|
@@ -139,15 +240,15 @@ describe('LocalDeviceManager', () => {
|
|
|
139
240
|
};
|
|
140
241
|
|
|
141
242
|
// Should create manager without crashing
|
|
142
|
-
const mgr = new LocalDeviceManager(config
|
|
243
|
+
const mgr = new LocalDeviceManager(config);
|
|
143
244
|
expect(mgr).toBeDefined();
|
|
144
245
|
});
|
|
145
246
|
|
|
146
247
|
test('falls back when local command has no response after 10 seconds', async () => {
|
|
147
248
|
jest.useFakeTimers();
|
|
148
|
-
const mgr = new LocalDeviceManager({ devices: [] }
|
|
249
|
+
const mgr = new LocalDeviceManager({ devices: [] });
|
|
149
250
|
mgr['dpMaps'].set('device1', { switch_1: 1 });
|
|
150
|
-
mgr['
|
|
251
|
+
mgr['devices'].push(new TuyaDevice({ id: 'device1', uuid: 'device1', name: 'Device 1', schema: [], status: [] }));
|
|
151
252
|
|
|
152
253
|
const conn = new (require('events').EventEmitter)();
|
|
153
254
|
conn.connected = true;
|
|
@@ -157,15 +258,15 @@ describe('LocalDeviceManager', () => {
|
|
|
157
258
|
const sendPromise = mgr.sendCommands('device1', [{ code: 'switch_1', value: true }]);
|
|
158
259
|
jest.advanceTimersByTime(10000);
|
|
159
260
|
|
|
160
|
-
await expect(sendPromise).
|
|
261
|
+
await expect(sendPromise).resolves.toBe(false);
|
|
161
262
|
jest.useRealTimers();
|
|
162
263
|
});
|
|
163
264
|
|
|
164
265
|
test('cancels older pending local responses when newer command supersedes same DP', async () => {
|
|
165
266
|
jest.useFakeTimers();
|
|
166
|
-
const mgr = new LocalDeviceManager({ devices: [] }
|
|
267
|
+
const mgr = new LocalDeviceManager({ devices: [] });
|
|
167
268
|
mgr['dpMaps'].set('device1', { switch_1: 1 });
|
|
168
|
-
mgr['
|
|
269
|
+
mgr['devices'].push(new TuyaDevice({ id: 'device1', uuid: 'device1', name: 'Device 1', schema: [], status: [] }));
|
|
169
270
|
|
|
170
271
|
const conn = new (require('events').EventEmitter)();
|
|
171
272
|
conn.connected = true;
|
|
@@ -177,7 +278,7 @@ describe('LocalDeviceManager', () => {
|
|
|
177
278
|
|
|
178
279
|
await expect(firstSend).resolves.toBe(true);
|
|
179
280
|
jest.advanceTimersByTime(10000);
|
|
180
|
-
await expect(secondSend).
|
|
281
|
+
await expect(secondSend).resolves.toBe(false);
|
|
181
282
|
jest.useRealTimers();
|
|
182
283
|
});
|
|
183
284
|
|
|
@@ -192,7 +293,7 @@ describe('LocalDeviceManager', () => {
|
|
|
192
293
|
},
|
|
193
294
|
],
|
|
194
295
|
};
|
|
195
|
-
const mgr = new LocalDeviceManager(config
|
|
296
|
+
const mgr = new LocalDeviceManager(config);
|
|
196
297
|
|
|
197
298
|
// Should not throw during init
|
|
198
299
|
await expect(mgr.initLocalDevices()).resolves.not.toThrow();
|
|
@@ -211,7 +312,7 @@ describe('LocalDeviceManager', () => {
|
|
|
211
312
|
};
|
|
212
313
|
|
|
213
314
|
// Should create manager without immediate error
|
|
214
|
-
const mgr = new LocalDeviceManager(config
|
|
315
|
+
const mgr = new LocalDeviceManager(config);
|
|
215
316
|
expect(mgr).toBeDefined();
|
|
216
317
|
});
|
|
217
318
|
|
|
@@ -227,7 +328,7 @@ describe('LocalDeviceManager', () => {
|
|
|
227
328
|
} as any,
|
|
228
329
|
],
|
|
229
330
|
};
|
|
230
|
-
const mgr = new LocalDeviceManager(config
|
|
331
|
+
const mgr = new LocalDeviceManager(config);
|
|
231
332
|
(mgr as any)._registerDeviceConfig(config.devices![0]);
|
|
232
333
|
|
|
233
334
|
expect(mgr.devices.length).toBe(0);
|
|
@@ -242,7 +343,7 @@ describe('LocalDeviceManager', () => {
|
|
|
242
343
|
const config: LocalConfig = {
|
|
243
344
|
devices: [],
|
|
244
345
|
};
|
|
245
|
-
const mgr = new LocalDeviceManager(config
|
|
346
|
+
const mgr = new LocalDeviceManager(config);
|
|
246
347
|
expect(mgr).toBeDefined();
|
|
247
348
|
// Default mappings should be applied internally
|
|
248
349
|
});
|
|
@@ -264,25 +365,7 @@ describe('LocalDeviceManager', () => {
|
|
|
264
365
|
},
|
|
265
366
|
],
|
|
266
367
|
};
|
|
267
|
-
const mgr = new LocalDeviceManager(config
|
|
268
|
-
expect(mgr).toBeDefined();
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
describe('logging', () => {
|
|
273
|
-
test('uses provided logger', () => {
|
|
274
|
-
const customLog: Logger = {
|
|
275
|
-
debug: jest.fn(),
|
|
276
|
-
info: jest.fn(),
|
|
277
|
-
warn: jest.fn(),
|
|
278
|
-
error: jest.fn(),
|
|
279
|
-
log: jest.fn(),
|
|
280
|
-
} as unknown as Logger;
|
|
281
|
-
|
|
282
|
-
const config: LocalConfig = {
|
|
283
|
-
devices: [],
|
|
284
|
-
};
|
|
285
|
-
const mgr = new LocalDeviceManager(config, customLog);
|
|
368
|
+
const mgr = new LocalDeviceManager(config);
|
|
286
369
|
expect(mgr).toBeDefined();
|
|
287
370
|
});
|
|
288
371
|
});
|
|
@@ -305,8 +388,8 @@ describe('LocalDeviceManager Integration', () => {
|
|
|
305
388
|
],
|
|
306
389
|
};
|
|
307
390
|
|
|
308
|
-
const mgr1 = new LocalDeviceManager(config1
|
|
309
|
-
const mgr2 = new LocalDeviceManager(config2
|
|
391
|
+
const mgr1 = new LocalDeviceManager(config1);
|
|
392
|
+
const mgr2 = new LocalDeviceManager(config2);
|
|
310
393
|
|
|
311
394
|
expect(mgr1).toBeDefined();
|
|
312
395
|
expect(mgr2).toBeDefined();
|
|
@@ -317,7 +400,7 @@ describe('LocalDeviceManager Integration', () => {
|
|
|
317
400
|
const config: LocalConfig = {
|
|
318
401
|
devices: [],
|
|
319
402
|
};
|
|
320
|
-
const mgr = new LocalDeviceManager(config
|
|
403
|
+
const mgr = new LocalDeviceManager(config);
|
|
321
404
|
|
|
322
405
|
await mgr.initLocalDevices();
|
|
323
406
|
await mgr.initLocalDevices(); // Should handle multiple inits
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
import { describe, expect, test, beforeEach, jest } from '@jest/globals';
|
|
3
|
-
import TuyaDeviceManager from '../src/cloud/device/
|
|
3
|
+
import TuyaDeviceManager from '../src/cloud/device/TuyaCloudDeviceManager';
|
|
4
4
|
import TuyaDevice from '../src/cloud/device/TuyaDevice';
|
|
5
|
+
import TuyaHomeDeviceManager from '../src/cloud/device/TuyaHomeDeviceManager';
|
|
6
|
+
import { ExLogger, initLogger } from '../src/shared/util/Logger';
|
|
5
7
|
|
|
6
8
|
// Mock Logger
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
PrefixLogger: class PrefixLogger {
|
|
16
|
-
constructor(public log: any, public name: string, public debug: boolean) {}
|
|
17
|
-
},
|
|
18
|
-
}));
|
|
9
|
+
const mockLog: ExLogger = {
|
|
10
|
+
debug: jest.fn(),
|
|
11
|
+
info: jest.fn(),
|
|
12
|
+
warn: jest.fn(),
|
|
13
|
+
error: jest.fn(),
|
|
14
|
+
log: jest.fn(),
|
|
15
|
+
success: jest.fn(),
|
|
16
|
+
} as unknown as ExLogger;
|
|
19
17
|
|
|
20
18
|
// Mock TuyaOpenMQ
|
|
21
19
|
jest.mock('../src/cloud/api/TuyaOpenMQ', () => {
|
|
@@ -44,8 +42,11 @@ jest.mock('../src/cloud/api/TuyaOpenMQ', () => {
|
|
|
44
42
|
describe('MQTT Device Updates - TuyaDeviceManager Message Handling', () => {
|
|
45
43
|
let manager: TuyaDeviceManager;
|
|
46
44
|
let mockAPI: any;
|
|
45
|
+
let mockConfig: any;
|
|
47
46
|
|
|
48
47
|
beforeEach(() => {
|
|
48
|
+
initLogger(mockLog);
|
|
49
|
+
|
|
49
50
|
mockAPI = {
|
|
50
51
|
log: { log: console.log } as any,
|
|
51
52
|
post: jest.fn(),
|
|
@@ -53,7 +54,25 @@ describe('MQTT Device Updates - TuyaDeviceManager Message Handling', () => {
|
|
|
53
54
|
tokenInfo: { uid: 'test_uid' },
|
|
54
55
|
};
|
|
55
56
|
|
|
56
|
-
|
|
57
|
+
mockConfig = {
|
|
58
|
+
platform: 'TuyaPlatform',
|
|
59
|
+
name: 'Tuya',
|
|
60
|
+
mode: 'cloud',
|
|
61
|
+
cloud: {
|
|
62
|
+
projectType: '2',
|
|
63
|
+
accessId: 'test_id',
|
|
64
|
+
accessKey: 'test_key',
|
|
65
|
+
countryCode: 1,
|
|
66
|
+
username: 'user@example.com',
|
|
67
|
+
password: 'password',
|
|
68
|
+
appSchema: 'tuyaSmart',
|
|
69
|
+
generateWeatherAccessory: false,
|
|
70
|
+
weatherAPI: '',
|
|
71
|
+
forceIPv4: false,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
manager = new TuyaHomeDeviceManager(mockAPI, mockConfig.cloud, false);
|
|
57
76
|
});
|
|
58
77
|
|
|
59
78
|
describe('device status updates', () => {
|