@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,50 +1,59 @@
|
|
|
1
1
|
import { beforeEach, describe, expect, jest, test } from '@jest/globals';
|
|
2
2
|
import { TuyaPlatform } from '../src/platform';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}));
|
|
3
|
+
import { initLogger } from '../src/shared/util/Logger';
|
|
4
|
+
import { Logger } from 'homebridge';
|
|
5
|
+
|
|
6
|
+
// Mock Logger
|
|
7
|
+
const mockLog: Logger = {
|
|
8
|
+
debug: jest.fn(),
|
|
9
|
+
info: jest.fn(),
|
|
10
|
+
warn: jest.fn(),
|
|
11
|
+
error: jest.fn(),
|
|
12
|
+
log: jest.fn(),
|
|
13
|
+
success: jest.fn(),
|
|
14
|
+
} as unknown as Logger;
|
|
16
15
|
|
|
17
16
|
jest.mock('../src/cloud/api/TuyaOpenAPI', () => {
|
|
18
17
|
return class MockTuyaOpenAPI {
|
|
19
18
|
log = console;
|
|
19
|
+
static getDefaultEndpoint = jest.fn().mockReturnValue([1]);
|
|
20
20
|
};
|
|
21
21
|
});
|
|
22
22
|
|
|
23
|
-
jest.mock('../src/cloud/device/TuyaDeviceManager', () => {
|
|
24
|
-
class MockTuyaDeviceManager {
|
|
25
|
-
static readonly Events = {
|
|
26
|
-
DEVICE_ADD: 'DEVICE_ADD',
|
|
27
|
-
DEVICE_INFO_UPDATE: 'DEVICE_INFO_UPDATE',
|
|
28
|
-
DEVICE_STATUS_UPDATE: 'DEVICE_STATUS_UPDATE',
|
|
29
|
-
DEVICE_DELETE: 'DEVICE_DELETE',
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
return MockTuyaDeviceManager;
|
|
33
|
-
});
|
|
34
|
-
|
|
35
23
|
jest.mock('../src/cloud/device/TuyaCustomDeviceManager', () => {
|
|
36
|
-
return class MockTuyaCustomDeviceManager {
|
|
24
|
+
return class MockTuyaCustomDeviceManager {
|
|
25
|
+
pullDevices = jest.fn().mockReturnValue([]);
|
|
26
|
+
updateInfraredRemotes = jest.fn();
|
|
27
|
+
getDeviceSchemaConfig = jest.fn();
|
|
28
|
+
devices = [];
|
|
29
|
+
api = mockAPI;
|
|
30
|
+
on = jest.fn();
|
|
31
|
+
};
|
|
37
32
|
});
|
|
38
33
|
|
|
39
34
|
jest.mock('../src/cloud/device/TuyaHomeDeviceManager', () => {
|
|
40
|
-
return class MockTuyaHomeDeviceManager {
|
|
35
|
+
return class MockTuyaHomeDeviceManager {
|
|
36
|
+
pullDevices = jest.fn().mockReturnValue([]);
|
|
37
|
+
updateInfraredRemotes = jest.fn();
|
|
38
|
+
getDeviceSchemaConfig = jest.fn();
|
|
39
|
+
devices = [];
|
|
40
|
+
api = mockAPI;
|
|
41
|
+
on = jest.fn();
|
|
42
|
+
};
|
|
41
43
|
});
|
|
42
44
|
|
|
43
45
|
jest.mock('../src/local/LocalDeviceManager', () => {
|
|
44
|
-
return class MockLocalDeviceManager {
|
|
46
|
+
return class MockLocalDeviceManager {
|
|
47
|
+
pullDevices = jest.fn().mockReturnValue([]);
|
|
48
|
+
updateInfraredRemotes = jest.fn();
|
|
49
|
+
getDeviceSchemaConfig = jest.fn();
|
|
50
|
+
devices = [];
|
|
51
|
+
api = mockAPI;
|
|
52
|
+
on = jest.fn();
|
|
53
|
+
};
|
|
45
54
|
});
|
|
46
55
|
|
|
47
|
-
jest.mock('../src/shared/
|
|
56
|
+
jest.mock('../src/shared/accessory/AccessoryFactory', () => ({
|
|
48
57
|
__esModule: true,
|
|
49
58
|
default: {
|
|
50
59
|
configAccessory: jest.fn(),
|
|
@@ -57,6 +66,13 @@ jest.mock('../src/shared/util/util', () => ({
|
|
|
57
66
|
retry: jest.fn(async (fn: () => Promise<unknown>) => fn()),
|
|
58
67
|
}));
|
|
59
68
|
|
|
69
|
+
jest.mock('../src/shared/util/ConfigMigrator', () => ({
|
|
70
|
+
__esModule: true,
|
|
71
|
+
default: class ConfigMigrator {
|
|
72
|
+
migrate(arg:any) { return arg; }
|
|
73
|
+
}
|
|
74
|
+
}));
|
|
75
|
+
|
|
60
76
|
const mockAPI = {
|
|
61
77
|
hap: {
|
|
62
78
|
Service: {},
|
|
@@ -69,19 +85,13 @@ const mockAPI = {
|
|
|
69
85
|
user: {
|
|
70
86
|
persistPath: () => '/tmp',
|
|
71
87
|
},
|
|
88
|
+
tokenInfo: {}
|
|
72
89
|
} as any;
|
|
73
90
|
|
|
74
91
|
describe('TuyaPlatform validation around cloud/local modes', () => {
|
|
75
|
-
let log: any;
|
|
76
|
-
|
|
77
92
|
beforeEach(() => {
|
|
78
|
-
log = {
|
|
79
|
-
debug: jest.fn(),
|
|
80
|
-
info: jest.fn(),
|
|
81
|
-
warn: jest.fn(),
|
|
82
|
-
error: jest.fn(),
|
|
83
|
-
};
|
|
84
93
|
jest.clearAllMocks();
|
|
94
|
+
initLogger(mockLog);
|
|
85
95
|
});
|
|
86
96
|
|
|
87
97
|
test('rejects mode both when local block is missing', () => {
|
|
@@ -89,7 +99,7 @@ describe('TuyaPlatform validation around cloud/local modes', () => {
|
|
|
89
99
|
platform: 'TuyaPlatform',
|
|
90
100
|
name: 'Tuya',
|
|
91
101
|
mode: 'both',
|
|
92
|
-
|
|
102
|
+
cloud: {
|
|
93
103
|
projectType: '2',
|
|
94
104
|
accessId: 'id',
|
|
95
105
|
accessKey: 'key',
|
|
@@ -102,9 +112,9 @@ describe('TuyaPlatform validation around cloud/local modes', () => {
|
|
|
102
112
|
},
|
|
103
113
|
};
|
|
104
114
|
|
|
105
|
-
const platform = new TuyaPlatform(
|
|
115
|
+
const platform = new TuyaPlatform(mockLog, config, mockAPI);
|
|
106
116
|
expect(platform.validate()).toBe(false);
|
|
107
|
-
expect(
|
|
117
|
+
expect(mockLog.error).toHaveBeenCalledWith('mode is "both" but no "local" config block found.');
|
|
108
118
|
});
|
|
109
119
|
|
|
110
120
|
test('rejects mode both when cloud options are missing', () => {
|
|
@@ -115,9 +125,9 @@ describe('TuyaPlatform validation around cloud/local modes', () => {
|
|
|
115
125
|
local: { devices: [] },
|
|
116
126
|
};
|
|
117
127
|
|
|
118
|
-
const platform = new TuyaPlatform(
|
|
128
|
+
const platform = new TuyaPlatform(mockLog, config, mockAPI);
|
|
119
129
|
expect(platform.validate()).toBe(false);
|
|
120
|
-
expect(
|
|
130
|
+
expect(mockLog.error).toHaveBeenCalledWith('Not configured — "cloud" block is required for cloud mode, exit.');
|
|
121
131
|
});
|
|
122
132
|
|
|
123
133
|
test('detects duplicate device override ids', () => {
|
|
@@ -125,7 +135,7 @@ describe('TuyaPlatform validation around cloud/local modes', () => {
|
|
|
125
135
|
platform: 'TuyaPlatform',
|
|
126
136
|
name: 'Tuya',
|
|
127
137
|
mode: 'cloud',
|
|
128
|
-
|
|
138
|
+
cloud: {
|
|
129
139
|
projectType: '2',
|
|
130
140
|
accessId: 'id',
|
|
131
141
|
accessKey: 'key',
|
|
@@ -142,8 +152,8 @@ describe('TuyaPlatform validation around cloud/local modes', () => {
|
|
|
142
152
|
},
|
|
143
153
|
};
|
|
144
154
|
|
|
145
|
-
const platform = new TuyaPlatform(
|
|
146
|
-
expect(platform.validateDeviceOverrides()).toBe(false);
|
|
155
|
+
const platform = new TuyaPlatform(mockLog, config, mockAPI);
|
|
156
|
+
expect(platform.validateDeviceOverrides(config.cloud.deviceOverrides)).toBe(false);
|
|
147
157
|
});
|
|
148
158
|
|
|
149
159
|
test('detects duplicate schema codes inside one device override', () => {
|
|
@@ -151,7 +161,7 @@ describe('TuyaPlatform validation around cloud/local modes', () => {
|
|
|
151
161
|
platform: 'TuyaPlatform',
|
|
152
162
|
name: 'Tuya',
|
|
153
163
|
mode: 'cloud',
|
|
154
|
-
|
|
164
|
+
cloud: {
|
|
155
165
|
projectType: '2',
|
|
156
166
|
accessId: 'id',
|
|
157
167
|
accessKey: 'key',
|
|
@@ -173,78 +183,7 @@ describe('TuyaPlatform validation around cloud/local modes', () => {
|
|
|
173
183
|
},
|
|
174
184
|
};
|
|
175
185
|
|
|
176
|
-
const platform = new TuyaPlatform(
|
|
177
|
-
expect(platform.validateSchema()).toBe(false);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
test('resolves device config precedence: device, then product, then global', () => {
|
|
181
|
-
const config = {
|
|
182
|
-
platform: 'TuyaPlatform',
|
|
183
|
-
name: 'Tuya',
|
|
184
|
-
mode: 'cloud',
|
|
185
|
-
options: {
|
|
186
|
-
projectType: '2',
|
|
187
|
-
accessId: 'id',
|
|
188
|
-
accessKey: 'key',
|
|
189
|
-
countryCode: 1,
|
|
190
|
-
username: 'user@example.com',
|
|
191
|
-
password: 'secret',
|
|
192
|
-
appSchema: 'tuyaSmart',
|
|
193
|
-
generateWeatherAccessory: false,
|
|
194
|
-
weatherAPI: '',
|
|
195
|
-
deviceOverrides: [
|
|
196
|
-
{ id: 'global', category: 'global-cat' },
|
|
197
|
-
{ id: 'prod-1', category: 'product-cat' },
|
|
198
|
-
{ id: 'device-1', category: 'device-cat' },
|
|
199
|
-
],
|
|
200
|
-
},
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
const platform = new TuyaPlatform(log, config, mockAPI);
|
|
204
|
-
|
|
205
|
-
const exact = platform.getDeviceConfig({ id: 'device-1', uuid: 'uuid-1', product_id: 'prod-1' } as any);
|
|
206
|
-
const byProduct = platform.getDeviceConfig({ id: 'device-2', uuid: 'uuid-2', product_id: 'prod-1' } as any);
|
|
207
|
-
const fallback = platform.getDeviceConfig({ id: 'device-3', uuid: 'uuid-3', product_id: 'prod-3' } as any);
|
|
208
|
-
|
|
209
|
-
expect(exact?.category).toBe('device-cat');
|
|
210
|
-
expect(byProduct?.category).toBe('product-cat');
|
|
211
|
-
expect(fallback?.category).toBe('global-cat');
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
test('finds schema config case-insensitively and migrates oldCode', () => {
|
|
215
|
-
const config = {
|
|
216
|
-
platform: 'TuyaPlatform',
|
|
217
|
-
name: 'Tuya',
|
|
218
|
-
mode: 'cloud',
|
|
219
|
-
options: {
|
|
220
|
-
projectType: '2',
|
|
221
|
-
accessId: 'id',
|
|
222
|
-
accessKey: 'key',
|
|
223
|
-
countryCode: 1,
|
|
224
|
-
username: 'user@example.com',
|
|
225
|
-
password: 'secret',
|
|
226
|
-
appSchema: 'tuyaSmart',
|
|
227
|
-
generateWeatherAccessory: false,
|
|
228
|
-
weatherAPI: '',
|
|
229
|
-
deviceOverrides: [
|
|
230
|
-
{
|
|
231
|
-
id: 'device-1',
|
|
232
|
-
schema: [
|
|
233
|
-
{ oldCode: 'switch_1', code: 'new_switch_1', hidden: true },
|
|
234
|
-
],
|
|
235
|
-
},
|
|
236
|
-
],
|
|
237
|
-
},
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
const platform = new TuyaPlatform(log, config, mockAPI);
|
|
241
|
-
const device = { id: 'device-1', uuid: 'device-1', product_id: 'prod-1' } as any;
|
|
242
|
-
|
|
243
|
-
const result = platform.getDeviceSchemaConfig(device, 'SWITCH_1');
|
|
244
|
-
|
|
245
|
-
expect(result).toBeDefined();
|
|
246
|
-
expect(result?.code).toBe('switch_1');
|
|
247
|
-
expect((result as any).newCode).toBe('new_switch_1');
|
|
248
|
-
expect(result?.hidden).toBe(true);
|
|
186
|
+
const platform = new TuyaPlatform(mockLog, config, mockAPI);
|
|
187
|
+
expect(platform.validateSchema(config.cloud.deviceOverrides)).toBe(false);
|
|
249
188
|
});
|
|
250
189
|
});
|
|
@@ -2,20 +2,18 @@
|
|
|
2
2
|
import { describe, expect, test, beforeEach, jest } from '@jest/globals';
|
|
3
3
|
import TuyaCustomDeviceManager from '../src/cloud/device/TuyaCustomDeviceManager';
|
|
4
4
|
import TuyaDevice from '../src/cloud/device/TuyaDevice';
|
|
5
|
+
import { TuyaPlatformCustomConfig, TuyaPluginMode } from '../src/config';
|
|
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', () => {
|
|
@@ -30,16 +28,31 @@ jest.mock('../src/cloud/api/TuyaOpenMQ', () => {
|
|
|
30
28
|
describe('TuyaCustomDeviceManager', () => {
|
|
31
29
|
let manager: TuyaCustomDeviceManager;
|
|
32
30
|
let mockAPI: any;
|
|
31
|
+
let mockConfig: any;
|
|
33
32
|
|
|
34
33
|
beforeEach(() => {
|
|
34
|
+
jest.clearAllMocks();
|
|
35
|
+
initLogger(mockLog);
|
|
36
|
+
|
|
35
37
|
mockAPI = {
|
|
36
38
|
log: { log: console.log } as any,
|
|
37
39
|
post: jest.fn(),
|
|
38
40
|
get: jest.fn(),
|
|
39
41
|
tokenInfo: { uid: 'test_uid' },
|
|
40
42
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
mockConfig = {
|
|
44
|
+
projectType: '1',
|
|
45
|
+
endpoint: 'https://openapi.tuyaeu.com',
|
|
46
|
+
accessId: 'test_access_id',
|
|
47
|
+
accessKey: 'test_access_key',
|
|
48
|
+
username: 'user@example.com',
|
|
49
|
+
password: 'password',
|
|
50
|
+
generateWeatherAccessory: true,
|
|
51
|
+
weatherAPI: 'openweathermap',
|
|
52
|
+
forceIPv4: false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
manager = new TuyaCustomDeviceManager(mockAPI, mockConfig, false);
|
|
43
56
|
});
|
|
44
57
|
|
|
45
58
|
describe('initialization', () => {
|
|
@@ -49,7 +62,7 @@ describe('TuyaCustomDeviceManager', () => {
|
|
|
49
62
|
});
|
|
50
63
|
|
|
51
64
|
test('sets MQTT version to 2.0', () => {
|
|
52
|
-
const customManager = new TuyaCustomDeviceManager(mockAPI, false);
|
|
65
|
+
const customManager = new TuyaCustomDeviceManager(mockAPI, mockConfig, false);
|
|
53
66
|
expect(customManager.mq.version).toBe('2.0');
|
|
54
67
|
});
|
|
55
68
|
|
|
@@ -59,7 +72,7 @@ describe('TuyaCustomDeviceManager', () => {
|
|
|
59
72
|
});
|
|
60
73
|
|
|
61
74
|
test('supports debug mode', () => {
|
|
62
|
-
const debugManager = new TuyaCustomDeviceManager(mockAPI, true);
|
|
75
|
+
const debugManager = new TuyaCustomDeviceManager(mockAPI, mockConfig, true);
|
|
63
76
|
expect(debugManager.debug).toBe(true);
|
|
64
77
|
});
|
|
65
78
|
});
|
|
@@ -466,4 +479,81 @@ describe('TuyaCustomDeviceManager', () => {
|
|
|
466
479
|
expect(mockAPI.post.mock.calls[0][1].asset_ids).toBe(assetIds.join(','));
|
|
467
480
|
});
|
|
468
481
|
});
|
|
482
|
+
|
|
483
|
+
describe('get device config', () => {
|
|
484
|
+
test('resolves device config precedence: device, then product, then global', () => {
|
|
485
|
+
const config = {
|
|
486
|
+
platform: 'TuyaPlatform',
|
|
487
|
+
name: 'Tuya',
|
|
488
|
+
mode: 'cloud',
|
|
489
|
+
cloud: {
|
|
490
|
+
projectType: '1',
|
|
491
|
+
endpoint: 'https://openapi.tuyaeu.com',
|
|
492
|
+
accessId: 'test_access_id',
|
|
493
|
+
accessKey: 'test_access_key',
|
|
494
|
+
username: 'user@example.com',
|
|
495
|
+
password: 'password',
|
|
496
|
+
generateWeatherAccessory: true,
|
|
497
|
+
weatherAPI: 'openweathermap',
|
|
498
|
+
forceIPv4: false,
|
|
499
|
+
deviceOverrides: [
|
|
500
|
+
{ id: 'global', category: 'global-cat', configFor: TuyaPluginMode.cloud },
|
|
501
|
+
{ id: 'prod-1', category: 'product-cat', configFor: TuyaPluginMode.cloud },
|
|
502
|
+
{ id: 'device-1', category: 'device-cat', configFor: TuyaPluginMode.cloud },
|
|
503
|
+
],
|
|
504
|
+
} as TuyaPlatformCustomConfig,
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
const deviceManager = new TuyaCustomDeviceManager(mockAPI, config.cloud, false);
|
|
508
|
+
|
|
509
|
+
const exact = deviceManager.getDeviceConfig({ id: 'device-1', uuid: 'uuid-1', product_id: 'prod-1' } as any);
|
|
510
|
+
const byProduct = deviceManager.getDeviceConfig({ id: 'device-2', uuid: 'uuid-2', product_id: 'prod-1' } as any);
|
|
511
|
+
const fallback = deviceManager.getDeviceConfig({ id: 'device-3', uuid: 'uuid-3', product_id: 'prod-3' } as any);
|
|
512
|
+
|
|
513
|
+
expect(exact?.category).toBe('device-cat');
|
|
514
|
+
expect(byProduct?.category).toBe('product-cat');
|
|
515
|
+
expect(fallback?.category).toBe('global-cat');
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
describe('get device config', () => {
|
|
520
|
+
test('finds schema config case-insensitively', () => {
|
|
521
|
+
const config = {
|
|
522
|
+
platform: 'TuyaPlatform',
|
|
523
|
+
name: 'Tuya',
|
|
524
|
+
mode: 'cloud',
|
|
525
|
+
cloud: {
|
|
526
|
+
projectType: '1',
|
|
527
|
+
endpoint: 'https://openapi.tuyaeu.com',
|
|
528
|
+
accessId: 'test_access_id',
|
|
529
|
+
accessKey: 'test_access_key',
|
|
530
|
+
username: 'user@example.com',
|
|
531
|
+
password: 'password',
|
|
532
|
+
generateWeatherAccessory: true,
|
|
533
|
+
weatherAPI: 'openweathermap',
|
|
534
|
+
forceIPv4: false,
|
|
535
|
+
deviceOverrides: [
|
|
536
|
+
{
|
|
537
|
+
id: 'device-1',
|
|
538
|
+
schema: [
|
|
539
|
+
{ code: 'switch_1', newCode: 'new_switch_1', hidden: true },
|
|
540
|
+
],
|
|
541
|
+
configFor: TuyaPluginMode.cloud
|
|
542
|
+
},
|
|
543
|
+
],
|
|
544
|
+
} as TuyaPlatformCustomConfig,
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
const deviceManager = new TuyaCustomDeviceManager(mockAPI, config.cloud, false);
|
|
548
|
+
|
|
549
|
+
const device = { id: 'device-1', uuid: 'device-1', product_id: 'prod-1' } as any;
|
|
550
|
+
|
|
551
|
+
const result = deviceManager!.getDeviceSchemaConfig(device, 'SWITCH_1');
|
|
552
|
+
|
|
553
|
+
expect(result).toBeDefined();
|
|
554
|
+
expect(result?.code).toBe('switch_1');
|
|
555
|
+
expect((result as any).newCode).toBe('new_switch_1');
|
|
556
|
+
expect(result?.hidden).toBe(true);
|
|
557
|
+
});
|
|
558
|
+
});
|
|
469
559
|
});
|