@homebridge-plugins/homebridge-tuya 2.2.1 → 3.0.0-beta.1
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/CHANGELOG.md +19 -0
- package/README.md +161 -144
- package/config.schema.json +976 -11
- package/dist/{core → cloud/api}/TuyaOpenAPI.js +6 -7
- package/dist/cloud/api/TuyaOpenAPI.js.map +1 -0
- package/dist/{core → cloud/api}/TuyaOpenMQ.js +13 -11
- package/dist/cloud/api/TuyaOpenMQ.js.map +1 -0
- package/dist/cloud/device/TuyaCustomDeviceManager.js.map +1 -0
- package/dist/{device → cloud/device}/TuyaDevice.js +14 -1
- package/dist/cloud/device/TuyaDevice.js.map +1 -0
- package/dist/{device → cloud/device}/TuyaDeviceManager.js +8 -3
- package/dist/cloud/device/TuyaDeviceManager.js.map +1 -0
- package/dist/cloud/device/TuyaHomeDeviceManager.js.map +1 -0
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/local/CloudLocalReconciliation.js +180 -0
- package/dist/local/CloudLocalReconciliation.js.map +1 -0
- package/dist/local/DynamicChildDiscovery.js +154 -0
- package/dist/local/DynamicChildDiscovery.js.map +1 -0
- package/dist/local/LocalDevice.js +419 -0
- package/dist/local/LocalDevice.js.map +1 -0
- package/dist/local/LocalDeviceManager.js +833 -0
- package/dist/local/LocalDeviceManager.js.map +1 -0
- package/dist/local/TuyaDiscovery.js +248 -0
- package/dist/local/TuyaDiscovery.js.map +1 -0
- package/dist/local/ZigbeeEventDetection.js +213 -0
- package/dist/local/ZigbeeEventDetection.js.map +1 -0
- package/dist/local/ZigbeeGatewayDetection.js +109 -0
- package/dist/local/ZigbeeGatewayDetection.js.map +1 -0
- package/dist/local/config.js +6 -0
- package/dist/local/config.js.map +1 -0
- package/dist/local/protocol/ChildPayloadUtility.js +94 -0
- package/dist/local/protocol/ChildPayloadUtility.js.map +1 -0
- package/dist/local/protocol/Protocol.js +3 -0
- package/dist/local/protocol/Protocol.js.map +1 -0
- package/dist/local/protocol/ProtocolFactory.js +27 -0
- package/dist/local/protocol/ProtocolFactory.js.map +1 -0
- package/dist/local/protocol/ProtocolUtilities.js +329 -0
- package/dist/local/protocol/ProtocolUtilities.js.map +1 -0
- package/dist/local/protocol/ProtocolV31V32.js +60 -0
- package/dist/local/protocol/ProtocolV31V32.js.map +1 -0
- package/dist/local/protocol/ProtocolV33.js +52 -0
- package/dist/local/protocol/ProtocolV33.js.map +1 -0
- package/dist/local/protocol/ProtocolV34.js +104 -0
- package/dist/local/protocol/ProtocolV34.js.map +1 -0
- package/dist/local/protocol/ProtocolV35.js +77 -0
- package/dist/local/protocol/ProtocolV35.js.map +1 -0
- package/dist/platform.js +149 -69
- package/dist/platform.js.map +1 -1
- package/dist/shared/AccessoryFactory.js +276 -0
- package/dist/shared/AccessoryFactory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/AccessoryFactory.js +2 -2
- package/dist/shared/accessories/AccessoryFactory.js.map +1 -0
- package/dist/shared/accessories/AirConditionerAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/AirPurifierAccessory.js +1 -1
- package/dist/shared/accessories/AirPurifierAccessory.js.map +1 -0
- package/dist/shared/accessories/AirQualitySensorAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/BaseAccessory.js +99 -30
- package/dist/shared/accessories/BaseAccessory.js.map +1 -0
- package/dist/shared/accessories/BlindsAccessory.js +199 -0
- package/dist/shared/accessories/BlindsAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/CameraAccessory.js +7 -3
- package/dist/shared/accessories/CameraAccessory.js.map +1 -0
- package/dist/shared/accessories/CarbonDioxideSensorAccessory.js.map +1 -0
- package/dist/shared/accessories/CarbonMonoxideSensorAccessory.js.map +1 -0
- package/dist/shared/accessories/ContactSensorAccessory.js.map +1 -0
- package/dist/shared/accessories/DehumidifierAccessory.js.map +1 -0
- package/dist/shared/accessories/DiffuserAccessory.js.map +1 -0
- package/dist/shared/accessories/DimmerAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/DoorbellAccessory.js +3 -1
- package/dist/shared/accessories/DoorbellAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/ExtractionHoodAccessory.js +4 -2
- package/dist/shared/accessories/ExtractionHoodAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/FanAccessory.js +10 -4
- package/dist/shared/accessories/FanAccessory.js.map +1 -0
- package/dist/shared/accessories/GarageDoorAccessory.js.map +1 -0
- package/dist/shared/accessories/HeaterAccessory.js.map +1 -0
- package/dist/shared/accessories/HeaterAccessory_old.js.map +1 -0
- package/dist/shared/accessories/HumanPresenceSensorAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/HumidifierAccessory.js +3 -1
- package/dist/shared/accessories/HumidifierAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/IRAirConditionerAccessory.js +2 -2
- package/dist/shared/accessories/IRAirConditionerAccessory.js.map +1 -0
- package/dist/shared/accessories/IRControlHubAccessory.js.map +1 -0
- package/dist/shared/accessories/IRControlHubSubAccessory.js.map +1 -0
- package/dist/shared/accessories/IRGenericAccessory.js.map +1 -0
- package/dist/shared/accessories/LeakSensorAccessory.js.map +1 -0
- package/dist/shared/accessories/LightAccessory.js.map +1 -0
- package/dist/shared/accessories/LightSensorAccessory.js.map +1 -0
- package/dist/shared/accessories/LocationWeatherAccessory.js.map +1 -0
- package/dist/shared/accessories/LockAccessory.js.map +1 -0
- package/dist/shared/accessories/MotionSensorAccessory.js.map +1 -0
- package/dist/shared/accessories/OutletAccessory.js.map +1 -0
- package/dist/shared/accessories/PetFeederAccessory.js.map +1 -0
- package/dist/shared/accessories/SceneAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/SceneSwitchAccessory.js +1 -1
- package/dist/shared/accessories/SceneSwitchAccessory.js.map +1 -0
- package/dist/shared/accessories/SecuritySystemAccessory.js.map +1 -0
- package/dist/shared/accessories/SmokeSensorAccessory.js.map +1 -0
- package/dist/shared/accessories/SwitchAccessory.js +148 -0
- package/dist/shared/accessories/SwitchAccessory.js.map +1 -0
- package/dist/shared/accessories/TemperatureHumiditySensorAccessory.js.map +1 -0
- package/dist/shared/accessories/ThermostatAccessory.js.map +1 -0
- package/dist/shared/accessories/TowerRackAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/ValveAccessory.js +1 -1
- package/dist/shared/accessories/ValveAccessory.js.map +1 -0
- package/dist/{accessory → shared/accessories}/VibrationSensorAccessory.js +7 -3
- package/dist/shared/accessories/VibrationSensorAccessory.js.map +1 -0
- package/dist/shared/accessories/WeatherStationAccessory.js.map +1 -0
- package/dist/shared/accessories/WetBulbGlobeTemperatureAccessory.js.map +1 -0
- package/dist/shared/accessories/WhiteNoiseLightAccessory.js.map +1 -0
- package/dist/shared/accessories/WindowAccessory.js.map +1 -0
- package/dist/shared/accessories/WindowCoveringAccessory.js.map +1 -0
- package/dist/shared/accessories/WirelessSwitchAccessory.js.map +1 -0
- package/dist/shared/accessories/characteristic/Active.js.map +1 -0
- package/dist/{accessory → shared/accessories}/characteristic/AirQuality.js +1 -1
- package/dist/shared/accessories/characteristic/AirQuality.js.map +1 -0
- package/dist/shared/accessories/characteristic/CurrentRelativeHumidity.js.map +1 -0
- package/dist/shared/accessories/characteristic/CurrentTemperature.js.map +1 -0
- package/dist/shared/accessories/characteristic/CurrentWeather.js.map +1 -0
- package/dist/shared/accessories/characteristic/CurrentWeatherByOpenMeteo.js.map +1 -0
- package/dist/shared/accessories/characteristic/CurrentWetBulbGlobeTemperature.js.map +1 -0
- package/dist/shared/accessories/characteristic/EnergyUsage.js.map +1 -0
- package/dist/shared/accessories/characteristic/Light.js.map +1 -0
- package/dist/shared/accessories/characteristic/LightSensor.js.map +1 -0
- package/dist/shared/accessories/characteristic/LockPhysicalControls.js.map +1 -0
- package/dist/{accessory → shared/accessories}/characteristic/MotionDetected.js +1 -1
- package/dist/shared/accessories/characteristic/MotionDetected.js.map +1 -0
- package/dist/shared/accessories/characteristic/Name.js.map +1 -0
- package/dist/shared/accessories/characteristic/OccupancyDetected.js.map +1 -0
- package/dist/{accessory → shared/accessories}/characteristic/On.js +1 -1
- package/dist/shared/accessories/characteristic/On.js.map +1 -0
- package/dist/shared/accessories/characteristic/OutletInUse.js.map +1 -0
- package/dist/{accessory → shared/accessories}/characteristic/ProgrammableSwitchEvent.js +2 -2
- package/dist/shared/accessories/characteristic/ProgrammableSwitchEvent.js.map +1 -0
- package/dist/shared/accessories/characteristic/RelativeHumidityDehumidifierThreshold.js.map +1 -0
- package/dist/shared/accessories/characteristic/RotationSpeed.js.map +1 -0
- package/dist/shared/accessories/characteristic/SecuritySystemState.js.map +1 -0
- package/dist/shared/accessories/characteristic/SwingMode.js.map +1 -0
- package/dist/shared/accessories/characteristic/TargetTemperature.js.map +1 -0
- package/dist/shared/accessories/characteristic/TemperatureDisplayUnits.js.map +1 -0
- package/dist/shared/util/ConfigHash.js +79 -0
- package/dist/shared/util/ConfigHash.js.map +1 -0
- package/dist/shared/util/FfmpegStreamingProcess.js.map +1 -0
- package/dist/shared/util/InfraredTool.js.map +1 -0
- package/dist/shared/util/Logger.js.map +1 -0
- package/dist/shared/util/TuyaRecordingDelegate.js.map +1 -0
- package/dist/shared/util/TuyaStreamDelegate.js.map +1 -0
- package/dist/shared/util/color.js.map +1 -0
- package/dist/shared/util/util.js +135 -0
- package/dist/shared/util/util.js.map +1 -0
- package/eslint.config.mjs +52 -0
- package/jest.config.js +6 -0
- package/package.json +22 -27
- package/test/__mocks__/@homebridge-camera-utils.js +10 -0
- package/test/__mocks__/color-convert.js +24 -0
- package/test/__mocks__/kelvin-to-rgb.js +21 -0
- package/test/accessoryFactory.test.ts +522 -0
- package/test/config.test.ts +430 -0
- package/test/custom.test.ts +4 -4
- package/test/errorHandling.test.ts +570 -0
- package/test/errorHandlingCoverage.test.ts +410 -0
- package/test/home.test.ts +4 -4
- package/test/localDevice.test.ts +616 -0
- package/test/localDeviceManager.behavior.test.ts +185 -0
- package/test/localDeviceManager.test.ts +268 -0
- package/test/mqttMessages.test.ts +495 -0
- package/test/platform.test.ts +515 -0
- package/test/platform.validation.local.test.ts +250 -0
- package/test/protocol.test.ts +446 -0
- package/test/protocolUtilities.test.ts +351 -0
- package/test/sanitizeName.test.ts +2 -1
- package/test/tuyaCustomDeviceManager.test.ts +469 -0
- package/test/tuyaDevice.test.ts +425 -0
- package/test/tuyaDeviceManager.test.ts +813 -0
- package/test/tuyaDiscovery.test.ts +439 -0
- package/test/tuyaHomeDeviceManager.test.ts +540 -0
- package/test/tuyaOpenAPI.test.ts +404 -0
- package/test/tuyaOpenMQ.test.ts +444 -0
- package/test/util.test.ts +318 -0
- package/test/util.ts +4 -3
- package/test/zigbee/ChildPayloadUtility.test.ts +199 -0
- package/test/zigbee/CloudLocalReconciliation.test.ts +284 -0
- package/test/zigbee/DynamicChildDiscovery.test.ts +333 -0
- package/test/zigbee/LocalDevice.zigbee.test.ts +274 -0
- package/test/zigbee/LocalDeviceManager.cloud-discovery.test.ts +163 -0
- package/test/zigbee/LocalDeviceManager.zigbee.reconnect.test.ts +200 -0
- package/test/zigbee/LocalDeviceManager.zigbee.test.ts +344 -0
- package/test/zigbee/ZigbeeEventDetection.test.ts +418 -0
- package/test/zigbee/ZigbeeGatewayDetection.test.ts +222 -0
- package/tuya-local-configs/dev-1.hash +1 -0
- package/tuya-local-configs/device1.hash +1 -0
- package/wiki/Get-Local-Keys-for-Your-Devices.md +85 -0
- package/dist/accessory/AccessoryFactory.js.map +0 -1
- package/dist/accessory/AirConditionerAccessory.js.map +0 -1
- package/dist/accessory/AirPurifierAccessory.js.map +0 -1
- package/dist/accessory/AirQualitySensorAccessory.js.map +0 -1
- package/dist/accessory/BaseAccessory.js.map +0 -1
- package/dist/accessory/CameraAccessory.js.map +0 -1
- package/dist/accessory/CarbonDioxideSensorAccessory.js.map +0 -1
- package/dist/accessory/CarbonMonoxideSensorAccessory.js.map +0 -1
- package/dist/accessory/ContactSensorAccessory.js.map +0 -1
- package/dist/accessory/DehumidifierAccessory.js.map +0 -1
- package/dist/accessory/DiffuserAccessory.js.map +0 -1
- package/dist/accessory/DimmerAccessory.js.map +0 -1
- package/dist/accessory/DoorbellAccessory.js.map +0 -1
- package/dist/accessory/ExtractionHoodAccessory.js.map +0 -1
- package/dist/accessory/FanAccessory.js.map +0 -1
- package/dist/accessory/GarageDoorAccessory.js.map +0 -1
- package/dist/accessory/HeaterAccessory.js.map +0 -1
- package/dist/accessory/HeaterAccessory_old.js.map +0 -1
- package/dist/accessory/HumanPresenceSensorAccessory.js.map +0 -1
- package/dist/accessory/HumidifierAccessory.js.map +0 -1
- package/dist/accessory/IRAirConditionerAccessory.js.map +0 -1
- package/dist/accessory/IRControlHubAccessory.js.map +0 -1
- package/dist/accessory/IRControlHubSubAccessory.js.map +0 -1
- package/dist/accessory/IRGenericAccessory.js.map +0 -1
- package/dist/accessory/LeakSensorAccessory.js.map +0 -1
- package/dist/accessory/LightAccessory.js.map +0 -1
- package/dist/accessory/LightSensorAccessory.js.map +0 -1
- package/dist/accessory/LocationWeatherAccessory.js.map +0 -1
- package/dist/accessory/LockAccessory.js.map +0 -1
- package/dist/accessory/MotionSensorAccessory.js.map +0 -1
- package/dist/accessory/OutletAccessory.js.map +0 -1
- package/dist/accessory/PetFeederAccessory.js.map +0 -1
- package/dist/accessory/SceneAccessory.js.map +0 -1
- package/dist/accessory/SceneSwitchAccessory.js.map +0 -1
- package/dist/accessory/SecuritySystemAccessory.js.map +0 -1
- package/dist/accessory/SmokeSensorAccessory.js.map +0 -1
- package/dist/accessory/SwitchAccessory.js +0 -85
- package/dist/accessory/SwitchAccessory.js.map +0 -1
- package/dist/accessory/TemperatureHumiditySensorAccessory.js.map +0 -1
- package/dist/accessory/ThermostatAccessory.js.map +0 -1
- package/dist/accessory/TowerRackAccessory.js.map +0 -1
- package/dist/accessory/ValveAccessory.js.map +0 -1
- package/dist/accessory/VibrationSensorAccessory.js.map +0 -1
- package/dist/accessory/WeatherStationAccessory.js.map +0 -1
- package/dist/accessory/WetBulbGlobeTemperatureAccessory.js.map +0 -1
- package/dist/accessory/WhiteNoiseLightAccessory.js.map +0 -1
- package/dist/accessory/WindowAccessory.js.map +0 -1
- package/dist/accessory/WindowCoveringAccessory.js.map +0 -1
- package/dist/accessory/WirelessSwitchAccessory.js.map +0 -1
- package/dist/accessory/characteristic/Active.js.map +0 -1
- package/dist/accessory/characteristic/AirQuality.js.map +0 -1
- package/dist/accessory/characteristic/CurrentRelativeHumidity.js.map +0 -1
- package/dist/accessory/characteristic/CurrentTemperature.js.map +0 -1
- package/dist/accessory/characteristic/CurrentWeather.js.map +0 -1
- package/dist/accessory/characteristic/CurrentWeatherByOpenMeteo.js.map +0 -1
- package/dist/accessory/characteristic/CurrentWetBulbGlobeTemperature.js.map +0 -1
- package/dist/accessory/characteristic/EnergyUsage.js.map +0 -1
- package/dist/accessory/characteristic/Light.js.map +0 -1
- package/dist/accessory/characteristic/LightSensor.js.map +0 -1
- package/dist/accessory/characteristic/LockPhysicalControls.js.map +0 -1
- package/dist/accessory/characteristic/MotionDetected.js.map +0 -1
- package/dist/accessory/characteristic/Name.js.map +0 -1
- package/dist/accessory/characteristic/OccupancyDetected.js.map +0 -1
- package/dist/accessory/characteristic/On.js.map +0 -1
- package/dist/accessory/characteristic/OutletInUse.js.map +0 -1
- package/dist/accessory/characteristic/ProgrammableSwitchEvent.js.map +0 -1
- package/dist/accessory/characteristic/RelativeHumidityDehumidifierThreshold.js.map +0 -1
- package/dist/accessory/characteristic/RotationSpeed.js.map +0 -1
- package/dist/accessory/characteristic/SecuritySystemState.js.map +0 -1
- package/dist/accessory/characteristic/SwingMode.js.map +0 -1
- package/dist/accessory/characteristic/TargetTemperature.js.map +0 -1
- package/dist/accessory/characteristic/TemperatureDisplayUnits.js.map +0 -1
- package/dist/core/TuyaOpenAPI.js.map +0 -1
- package/dist/core/TuyaOpenMQ.js.map +0 -1
- package/dist/device/TuyaCustomDeviceManager.js.map +0 -1
- package/dist/device/TuyaDevice.js.map +0 -1
- package/dist/device/TuyaDeviceManager.js.map +0 -1
- package/dist/device/TuyaHomeDeviceManager.js.map +0 -1
- package/dist/util/FfmpegStreamingProcess.js.map +0 -1
- package/dist/util/InfraredTool.js.map +0 -1
- package/dist/util/Logger.js.map +0 -1
- package/dist/util/TuyaRecordingDelegate.js.map +0 -1
- package/dist/util/TuyaStreamDelegate.js.map +0 -1
- package/dist/util/color.js.map +0 -1
- package/dist/util/util.js +0 -63
- package/dist/util/util.js.map +0 -1
- /package/dist/{device → cloud/device}/TuyaCustomDeviceManager.js +0 -0
- /package/dist/{device → cloud/device}/TuyaHomeDeviceManager.js +0 -0
- /package/dist/{accessory → shared/accessories}/AirConditionerAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/AirQualitySensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/CarbonDioxideSensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/CarbonMonoxideSensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/ContactSensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/DehumidifierAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/DiffuserAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/DimmerAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/GarageDoorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/HeaterAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/HeaterAccessory_old.js +0 -0
- /package/dist/{accessory → shared/accessories}/HumanPresenceSensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/IRControlHubAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/IRControlHubSubAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/IRGenericAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/LeakSensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/LightAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/LightSensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/LocationWeatherAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/LockAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/MotionSensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/OutletAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/PetFeederAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/SceneAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/SecuritySystemAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/SmokeSensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/TemperatureHumiditySensorAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/ThermostatAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/TowerRackAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/WeatherStationAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/WetBulbGlobeTemperatureAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/WhiteNoiseLightAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/WindowAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/WindowCoveringAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/WirelessSwitchAccessory.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/Active.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/CurrentRelativeHumidity.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/CurrentTemperature.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/CurrentWeather.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/CurrentWeatherByOpenMeteo.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/CurrentWetBulbGlobeTemperature.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/EnergyUsage.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/Light.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/LightSensor.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/LockPhysicalControls.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/Name.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/OccupancyDetected.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/OutletInUse.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/RelativeHumidityDehumidifierThreshold.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/RotationSpeed.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/SecuritySystemState.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/SwingMode.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/TargetTemperature.js +0 -0
- /package/dist/{accessory → shared/accessories}/characteristic/TemperatureDisplayUnits.js +0 -0
- /package/dist/{util → shared/util}/FfmpegStreamingProcess.js +0 -0
- /package/dist/{util → shared/util}/InfraredTool.js +0 -0
- /package/dist/{util → shared/util}/Logger.js +0 -0
- /package/dist/{util → shared/util}/TuyaRecordingDelegate.js +0 -0
- /package/dist/{util → shared/util}/TuyaStreamDelegate.js +0 -0
- /package/dist/{util → shared/util}/color.js +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ZigbeeGatewayDetection – resolves parent-child (gateway/sub-device) relationships
|
|
4
|
+
* from the local device configuration.
|
|
5
|
+
*
|
|
6
|
+
* Tuya Zigbee devices operate through a WiFi gateway:
|
|
7
|
+
* - The **parent** gateway holds the TCP connection (it has an IP + localKey).
|
|
8
|
+
* - Each **child** sub-device is addressed via a CID (Child ID / node_id) that
|
|
9
|
+
* is embedded in the payload forwarded through the parent's connection.
|
|
10
|
+
*
|
|
11
|
+
* Hierarchy is expressed through two config fields:
|
|
12
|
+
* - `parentDeviceId`: tuyaDeviceId of the gateway (set on each child)
|
|
13
|
+
* - `zigbeeChildId`: 16-char hex CID assigned by the gateway (set on each child)
|
|
14
|
+
*
|
|
15
|
+
* This module validates those relationships and returns a structured map of
|
|
16
|
+
* parent → children that LocalDeviceManager uses during device setup.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.ZigbeeGatewayDetection = void 0;
|
|
20
|
+
class ZigbeeGatewayDetection {
|
|
21
|
+
/**
|
|
22
|
+
* Scan `devices` for `parentDeviceId` / `zigbeeChildId` entries and build a
|
|
23
|
+
* map of parentId → GatewayRelationship.
|
|
24
|
+
*
|
|
25
|
+
* Throws a descriptive Error for any of the following invalid configurations:
|
|
26
|
+
* - A child has `parentDeviceId` but no `zigbeeChildId` (or vice-versa)
|
|
27
|
+
* - A `zigbeeChildId` is not a valid 16-hex-character string
|
|
28
|
+
* - A `parentDeviceId` references a device not present in the list
|
|
29
|
+
* - Two children under the same parent share the same CID
|
|
30
|
+
*
|
|
31
|
+
* @param devices Full list of LocalDeviceConfig entries (may be empty)
|
|
32
|
+
* @returns Map from parentId to its GatewayRelationship (empty if none)
|
|
33
|
+
*/
|
|
34
|
+
static detectFromDevices(devices) {
|
|
35
|
+
const relationships = new Map();
|
|
36
|
+
const deviceIds = new Set(devices.map(d => d.tuyaDeviceId));
|
|
37
|
+
for (const cfg of devices) {
|
|
38
|
+
const hasParent = !!cfg.parentDeviceId;
|
|
39
|
+
const hasCid = !!cfg.zigbeeChildId;
|
|
40
|
+
// Both fields must be set together
|
|
41
|
+
if (hasParent && !hasCid) {
|
|
42
|
+
throw new Error(`Device "${cfg.tuyaDeviceId}" has parentDeviceId but is missing zigbeeChildId. ` +
|
|
43
|
+
'Both fields are required for Zigbee sub-devices.');
|
|
44
|
+
}
|
|
45
|
+
if (!hasParent && hasCid) {
|
|
46
|
+
throw new Error(`Device "${cfg.tuyaDeviceId}" has zigbeeChildId but is missing parentDeviceId. ` +
|
|
47
|
+
'Both fields are required for Zigbee sub-devices.');
|
|
48
|
+
}
|
|
49
|
+
if (!hasParent) {
|
|
50
|
+
continue; // standalone / parent device — nothing to do here
|
|
51
|
+
}
|
|
52
|
+
const parentId = cfg.parentDeviceId;
|
|
53
|
+
const cid = cfg.zigbeeChildId;
|
|
54
|
+
// Validate CID format
|
|
55
|
+
if (!/^[0-9a-f]{16}$/i.test(cid)) {
|
|
56
|
+
throw new Error(`Device "${cfg.tuyaDeviceId}" has an invalid zigbeeChildId "${cid}". ` +
|
|
57
|
+
'The CID must be exactly 16 hexadecimal characters (e.g. "0011223344556601").');
|
|
58
|
+
}
|
|
59
|
+
// Validate parent exists in the same config list
|
|
60
|
+
if (!deviceIds.has(parentId)) {
|
|
61
|
+
throw new Error(`Device "${cfg.tuyaDeviceId}" references parent "${parentId}" ` +
|
|
62
|
+
'which was not found in the local devices list. ' +
|
|
63
|
+
'Make sure the gateway device is also listed in local.devices.');
|
|
64
|
+
}
|
|
65
|
+
// Parent must not itself be a child
|
|
66
|
+
const parentCfg = devices.find(d => d.tuyaDeviceId === parentId);
|
|
67
|
+
if (parentCfg?.parentDeviceId) {
|
|
68
|
+
throw new Error(`Device "${parentId}" is used as a parent gateway for "${cfg.tuyaDeviceId}" ` +
|
|
69
|
+
'but it is itself configured as a child device. Chained gateways are not supported.');
|
|
70
|
+
}
|
|
71
|
+
// Build / update the relationship entry
|
|
72
|
+
if (!relationships.has(parentId)) {
|
|
73
|
+
relationships.set(parentId, { parentId, children: [] });
|
|
74
|
+
}
|
|
75
|
+
const rel = relationships.get(parentId);
|
|
76
|
+
// Check for duplicate CIDs under the same parent
|
|
77
|
+
const dupCid = rel.children.find(c => c.cid.toLowerCase() === cid.toLowerCase());
|
|
78
|
+
if (dupCid) {
|
|
79
|
+
throw new Error(`Duplicate Zigbee CID "${cid}" under gateway "${parentId}": ` +
|
|
80
|
+
`used by both "${dupCid.deviceId}" and "${cfg.tuyaDeviceId}".`);
|
|
81
|
+
}
|
|
82
|
+
rel.children.push({
|
|
83
|
+
deviceId: cfg.tuyaDeviceId,
|
|
84
|
+
cid: cid.toLowerCase(),
|
|
85
|
+
name: cfg.name ?? cfg.tuyaDeviceId,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return relationships;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Return true if a device config represents a Zigbee child (sub-device).
|
|
92
|
+
*/
|
|
93
|
+
static isChild(cfg) {
|
|
94
|
+
return !!cfg.parentDeviceId;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Return true if a device config is (or should be treated as) a gateway.
|
|
98
|
+
* A device is a gateway if it is explicitly flagged OR if any other device
|
|
99
|
+
* in the list references it as a parent.
|
|
100
|
+
*/
|
|
101
|
+
static isGateway(cfg, allDevices) {
|
|
102
|
+
if (cfg.isZigbeeGateway) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
return allDevices.some(d => d.parentDeviceId === cfg.tuyaDeviceId);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.ZigbeeGatewayDetection = ZigbeeGatewayDetection;
|
|
109
|
+
//# sourceMappingURL=ZigbeeGatewayDetection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZigbeeGatewayDetection.js","sourceRoot":"","sources":["../../src/local/ZigbeeGatewayDetection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/local/config.ts"],"names":[],"mappings":";AAAA;;GAEG"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ChildPayloadUtility – helpers for Zigbee sub-device (gateway/child) payloads.
|
|
4
|
+
*
|
|
5
|
+
* Tuya gateways route commands to Zigbee sub-devices by embedding a CID
|
|
6
|
+
* (Child ID, also called node_id) inside the normal DP-update payload.
|
|
7
|
+
* The exact structure differs between protocol versions:
|
|
8
|
+
*
|
|
9
|
+
* v3.3: { cid: "0011…", dps: { "1": true } }
|
|
10
|
+
* v3.4+: { protocol: 5, data: { cid: "0011…", dps: { "1": true } } }
|
|
11
|
+
*
|
|
12
|
+
* This file also provides the inverse – extracting CID + DPS from a response
|
|
13
|
+
* payload coming *from* the gateway on behalf of a child device.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ChildPayloadUtility = void 0;
|
|
17
|
+
/** CID regex: exactly 16 lowercase hexadecimal characters */
|
|
18
|
+
const CID_RE = /^[0-9a-f]{16}$/i;
|
|
19
|
+
class ChildPayloadUtility {
|
|
20
|
+
/**
|
|
21
|
+
* Validate that a CID string conforms to the expected 16-hex-character format.
|
|
22
|
+
*/
|
|
23
|
+
static isValidCid(cid) {
|
|
24
|
+
return CID_RE.test(cid);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build the DPS-update payload that the parent gateway forwards to a child.
|
|
28
|
+
*
|
|
29
|
+
* @param childId Zigbee CID (16-char hex, e.g. "0011223344556601")
|
|
30
|
+
* @param dps DP values to set on the child, e.g. { "1": true, "2": 100 }
|
|
31
|
+
* @param version Protocol version of the *parent* gateway connection
|
|
32
|
+
*/
|
|
33
|
+
static prepareChildPayload(childId, dps, version) {
|
|
34
|
+
if (!ChildPayloadUtility.isValidCid(childId)) {
|
|
35
|
+
throw new Error(`Invalid Zigbee CID "${childId}" – must be a 16-character hex string`);
|
|
36
|
+
}
|
|
37
|
+
if (version === '3.3') {
|
|
38
|
+
// v3.3 format: { cid, dps } (gwId is filled in by the gateway firmware)
|
|
39
|
+
return { cid: childId, dps };
|
|
40
|
+
}
|
|
41
|
+
// v3.4 / v3.5 format: { protocol: 5, data: { cid, dps } }
|
|
42
|
+
return {
|
|
43
|
+
protocol: 5,
|
|
44
|
+
data: { cid: childId, dps },
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build a DPS-query payload to request the current state of a Zigbee child.
|
|
49
|
+
*
|
|
50
|
+
* @param childId Zigbee CID
|
|
51
|
+
* @param version Protocol version of the parent gateway connection
|
|
52
|
+
*/
|
|
53
|
+
static prepareChildQueryPayload(childId, version) {
|
|
54
|
+
if (!ChildPayloadUtility.isValidCid(childId)) {
|
|
55
|
+
throw new Error(`Invalid Zigbee CID "${childId}" – must be a 16-character hex string`);
|
|
56
|
+
}
|
|
57
|
+
if (version === '3.3') {
|
|
58
|
+
return { cid: childId, dps: {} };
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
protocol: 5,
|
|
62
|
+
data: { cid: childId, dps: {} },
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Extract the child CID and DPS values from an incoming gateway payload.
|
|
67
|
+
* Returns `null` when the payload does not contain child routing information
|
|
68
|
+
* (i.e. it is a regular parent/standalone device update).
|
|
69
|
+
*
|
|
70
|
+
* @param payload Decoded JSON payload received from the parent gateway
|
|
71
|
+
*/
|
|
72
|
+
static extractChildData(payload) {
|
|
73
|
+
// v3.3 format: { gwId?, cid, dps }
|
|
74
|
+
if (typeof payload.cid === 'string' && payload.dps !== undefined) {
|
|
75
|
+
return {
|
|
76
|
+
childId: payload.cid,
|
|
77
|
+
dps: payload.dps,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// v3.4 / v3.5 format: { protocol: 5, data: { cid, dps } }
|
|
81
|
+
if (payload.protocol === 5 && payload.data !== null && typeof payload.data === 'object') {
|
|
82
|
+
const data = payload.data;
|
|
83
|
+
if (typeof data.cid === 'string' && data.dps !== undefined) {
|
|
84
|
+
return {
|
|
85
|
+
childId: data.cid,
|
|
86
|
+
dps: data.dps,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.ChildPayloadUtility = ChildPayloadUtility;
|
|
94
|
+
//# sourceMappingURL=ChildPayloadUtility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChildPayloadUtility.js","sourceRoot":"","sources":["../../../src/local/protocol/ChildPayloadUtility.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;AAWH,6DAA6D;AAC7D,MAAM,MAAM,GAAG,iBAAiB,CAAC;AAEjC,MAAa,mBAAmB;IAC9B;;OAEG;IACH,MAAM,CAAC,UAAU,CAAC,GAAW;QAC3B,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,mBAAmB,CACxB,OAAe,EACf,GAA4B,EAC5B,OAA+B;QAE/B,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,uCAAuC,CAAC,CAAC;QACzF,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;YACtB,yEAAyE;YACzE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;QAC/B,CAAC;QAED,0DAA0D;QAC1D,OAAO;YACL,QAAQ,EAAE,CAAC;YACX,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE;SAC5B,CAAC;IACJ,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,wBAAwB,CAC7B,OAAe,EACf,OAA+B;QAE/B,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,uCAAuC,CAAC,CAAC;QACzF,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;YACtB,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;QACnC,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,CAAC;YACX,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE;SAChC,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,gBAAgB,CAAC,OAAgC;QACtD,mCAAmC;QACnC,IAAI,OAAO,OAAO,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YACjE,OAAO;gBACL,OAAO,EAAE,OAAO,CAAC,GAAG;gBACpB,GAAG,EAAE,OAAO,CAAC,GAA8B;aAC5C,CAAC;QACJ,CAAC;QAED,0DAA0D;QAC1D,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxF,MAAM,IAAI,GAAG,OAAO,CAAC,IAA+B,CAAC;YACrD,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;gBAC3D,OAAO;oBACL,OAAO,EAAE,IAAI,CAAC,GAAG;oBACjB,GAAG,EAAE,IAAI,CAAC,GAA8B;iBACzC,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAzFD,kDAyFC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Protocol.js","sourceRoot":"","sources":["../../../src/local/protocol/Protocol.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProtocolFactory = void 0;
|
|
4
|
+
const ProtocolV31V32_1 = require("./ProtocolV31V32");
|
|
5
|
+
const ProtocolV33_1 = require("./ProtocolV33");
|
|
6
|
+
const ProtocolV34_1 = require("./ProtocolV34");
|
|
7
|
+
const ProtocolV35_1 = require("./ProtocolV35");
|
|
8
|
+
class ProtocolFactory {
|
|
9
|
+
static createProtocol(version) {
|
|
10
|
+
switch (version) {
|
|
11
|
+
case '3.1':
|
|
12
|
+
return new ProtocolV31V32_1.ProtocolV31V32('3.1');
|
|
13
|
+
case '3.2':
|
|
14
|
+
return new ProtocolV31V32_1.ProtocolV31V32('3.2');
|
|
15
|
+
case '3.3':
|
|
16
|
+
return new ProtocolV33_1.ProtocolV33();
|
|
17
|
+
case '3.4':
|
|
18
|
+
return new ProtocolV34_1.ProtocolV34();
|
|
19
|
+
case '3.5':
|
|
20
|
+
return new ProtocolV35_1.ProtocolV35();
|
|
21
|
+
default:
|
|
22
|
+
throw new Error(`Unsupported protocol version: ${version}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.ProtocolFactory = ProtocolFactory;
|
|
27
|
+
//# sourceMappingURL=ProtocolFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProtocolFactory.js","sourceRoot":"","sources":["../../../src/local/protocol/ProtocolFactory.ts"],"names":[],"mappings":";;;AAIA,qDAAkD;AAClD,+CAA4C;AAC5C,+CAA4C;AAC5C,+CAA4C;AAE5C,MAAa,eAAe;IAC1B,MAAM,CAAC,cAAc,CAAC,OAAe;QACnC,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,KAAK;gBACR,OAAO,IAAI,+BAAc,CAAC,KAAK,CAAC,CAAC;YACnC,KAAK,KAAK;gBACR,OAAO,IAAI,+BAAc,CAAC,KAAK,CAAC,CAAC;YACnC,KAAK,KAAK;gBACR,OAAO,IAAI,yBAAW,EAAE,CAAC;YAC3B,KAAK,KAAK;gBACR,OAAO,IAAI,yBAAW,EAAE,CAAC;YAC3B,KAAK,KAAK;gBACR,OAAO,IAAI,yBAAW,EAAE,CAAC;YAC3B;gBACE,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;CACF;AAjBD,0CAiBC"}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NO_VERSION_HEADER_CMDS = exports.HEADER_SIZE_6699 = exports.HEADER_SIZE_55AA = exports.SUFFIX_6699 = exports.PREFIX_6699 = exports.SUFFIX_55AA = exports.PREFIX_55AA = void 0;
|
|
4
|
+
exports.hmac = hmac;
|
|
5
|
+
exports.encryptECB = encryptECB;
|
|
6
|
+
exports.decryptECB = decryptECB;
|
|
7
|
+
exports.encryptECBNoPad = encryptECBNoPad;
|
|
8
|
+
exports.encryptGCM = encryptGCM;
|
|
9
|
+
exports.decryptGCM = decryptGCM;
|
|
10
|
+
exports.getCRC32 = getCRC32;
|
|
11
|
+
exports.packMessage55AA = packMessage55AA;
|
|
12
|
+
exports.unpackMessage55AA = unpackMessage55AA;
|
|
13
|
+
exports.packMessage6699 = packMessage6699;
|
|
14
|
+
exports.unpackMessage6699 = unpackMessage6699;
|
|
15
|
+
exports.isFrameComplete = isFrameComplete;
|
|
16
|
+
exports.extractFrame = extractFrame;
|
|
17
|
+
exports.generateSessionKey = generateSessionKey;
|
|
18
|
+
/**
|
|
19
|
+
* Shared protocol utilities for encryption/decryption, CRC, and Tuya frame
|
|
20
|
+
* packing/unpacking.
|
|
21
|
+
*
|
|
22
|
+
* Frame formats follow TinyTuya's message_helper.py / header.py exactly.
|
|
23
|
+
*
|
|
24
|
+
* 0x55AA frame layout (v3.1–v3.4):
|
|
25
|
+
* prefix uint32 BE 0x000055AA
|
|
26
|
+
* seqno uint32 BE
|
|
27
|
+
* cmd uint32 BE
|
|
28
|
+
* length uint32 BE (bytes from payload start up to and including CRC/HMAC+suffix)
|
|
29
|
+
* payload variable
|
|
30
|
+
* crc uint32 BE (CRC32 for v3.1/3.2/3.3; HMAC-SHA256 32 bytes for v3.4)
|
|
31
|
+
* suffix uint32 BE 0x0000AA55
|
|
32
|
+
*
|
|
33
|
+
* 0x6699 frame layout (v3.5):
|
|
34
|
+
* prefix uint32 BE 0x00006699
|
|
35
|
+
* unknown uint16 BE 0x0000
|
|
36
|
+
* seqno uint32 BE
|
|
37
|
+
* cmd uint32 BE
|
|
38
|
+
* length uint32 BE (bytes: IV(12) + ciphertext + GCM-tag(16) + suffix(4))
|
|
39
|
+
* iv 12 bytes
|
|
40
|
+
* ciphertext variable
|
|
41
|
+
* tag 16 bytes
|
|
42
|
+
* suffix uint32 BE 0x00009966
|
|
43
|
+
*/
|
|
44
|
+
const crypto_1 = require("crypto");
|
|
45
|
+
// ── Constants (mirror TinyTuya header.py) ────────────────────────────────────
|
|
46
|
+
exports.PREFIX_55AA = 0x000055AA;
|
|
47
|
+
exports.SUFFIX_55AA = 0x0000AA55;
|
|
48
|
+
exports.PREFIX_6699 = 0x00006699;
|
|
49
|
+
exports.SUFFIX_6699 = 0x00009966;
|
|
50
|
+
/** Header size for 0x55AA frames: 4*uint32 = 16 bytes */
|
|
51
|
+
exports.HEADER_SIZE_55AA = 16;
|
|
52
|
+
/** Header size for 0x6699 frames: uint32+uint16+uint16+uint32+uint32 = 18 bytes */
|
|
53
|
+
exports.HEADER_SIZE_6699 = 18;
|
|
54
|
+
/**
|
|
55
|
+
* Commands that must NOT have a protocol version header prepended to their
|
|
56
|
+
* payload (matches TinyTuya NO_PROTOCOL_HEADER_CMDS).
|
|
57
|
+
*/
|
|
58
|
+
exports.NO_VERSION_HEADER_CMDS = new Set([
|
|
59
|
+
3, // SESS_KEY_NEG_START
|
|
60
|
+
4, // SESS_KEY_NEG_RESP
|
|
61
|
+
5, // SESS_KEY_NEG_FINISH
|
|
62
|
+
9, // HEART_BEAT
|
|
63
|
+
0x0a, // DP_QUERY (10)
|
|
64
|
+
0x10, // DP_QUERY_NEW (16)
|
|
65
|
+
0x12, // UPDATEDPS (18)
|
|
66
|
+
0x40, // LAN_EXT_STREAM (64)
|
|
67
|
+
]);
|
|
68
|
+
// ── Crypto helpers ────────────────────────────────────────────────────────────
|
|
69
|
+
/** HMAC-SHA256 */
|
|
70
|
+
function hmac(data, key) {
|
|
71
|
+
return (0, crypto_1.createHmac)('sha256', key).update(data).digest();
|
|
72
|
+
}
|
|
73
|
+
/** AES-128-ECB encrypt, PKCS7 padding handled by Node crypto */
|
|
74
|
+
function encryptECB(data, key) {
|
|
75
|
+
const cipher = (0, crypto_1.createCipheriv)('aes-128-ecb', key, '');
|
|
76
|
+
return Buffer.concat([cipher.update(data), cipher.final()]);
|
|
77
|
+
}
|
|
78
|
+
/** AES-128-ECB decrypt */
|
|
79
|
+
function decryptECB(data, key) {
|
|
80
|
+
const decipher = (0, crypto_1.createDecipheriv)('aes-128-ecb', key, '');
|
|
81
|
+
return Buffer.concat([decipher.update(data), decipher.final()]);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* AES-128-ECB encrypt WITHOUT padding (pad=False in TinyTuya).
|
|
85
|
+
* Used for key-exchange payloads and session-key derivation where the caller
|
|
86
|
+
* guarantees the data is already a multiple of 16 bytes.
|
|
87
|
+
*/
|
|
88
|
+
function encryptECBNoPad(data, key) {
|
|
89
|
+
const cipher = (0, crypto_1.createCipheriv)('aes-128-ecb', key, '');
|
|
90
|
+
cipher.setAutoPadding(false);
|
|
91
|
+
return Buffer.concat([cipher.update(data), cipher.final()]);
|
|
92
|
+
}
|
|
93
|
+
/** AES-128-GCM encrypt – returns { ciphertext, authTag } */
|
|
94
|
+
function encryptGCM(data, key, iv, aad) {
|
|
95
|
+
const cipher = (0, crypto_1.createCipheriv)('aes-128-gcm', key, iv);
|
|
96
|
+
if (aad)
|
|
97
|
+
cipher.setAAD(aad);
|
|
98
|
+
const ciphertext = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
99
|
+
return { ciphertext, authTag: cipher.getAuthTag() };
|
|
100
|
+
}
|
|
101
|
+
/** AES-128-GCM decrypt */
|
|
102
|
+
function decryptGCM(ciphertext, key, iv, authTag, aad) {
|
|
103
|
+
const decipher = (0, crypto_1.createDecipheriv)('aes-128-gcm', key, iv);
|
|
104
|
+
decipher.setAuthTag(authTag);
|
|
105
|
+
if (aad)
|
|
106
|
+
decipher.setAAD(aad);
|
|
107
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
108
|
+
}
|
|
109
|
+
// ── CRC32 ─────────────────────────────────────────────────────────────────────
|
|
110
|
+
let crc32Table = null;
|
|
111
|
+
function makeCRC32Table() {
|
|
112
|
+
const poly = 0xedb88320;
|
|
113
|
+
const table = [];
|
|
114
|
+
for (let i = 0; i < 256; i++) {
|
|
115
|
+
let c = i;
|
|
116
|
+
for (let k = 0; k < 8; k++) {
|
|
117
|
+
c = c & 1 ? poly ^ (c >>> 1) : c >>> 1;
|
|
118
|
+
}
|
|
119
|
+
table[i] = c >>> 0;
|
|
120
|
+
}
|
|
121
|
+
return table;
|
|
122
|
+
}
|
|
123
|
+
function getCRC32(buf) {
|
|
124
|
+
if (!crc32Table)
|
|
125
|
+
crc32Table = makeCRC32Table();
|
|
126
|
+
let crc = 0xffffffff;
|
|
127
|
+
for (let i = 0; i < buf.length; i++) {
|
|
128
|
+
crc = crc32Table[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
|
|
129
|
+
}
|
|
130
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
131
|
+
}
|
|
132
|
+
// ── 0x55AA frame pack / unpack ────────────────────────────────────────────────
|
|
133
|
+
/**
|
|
134
|
+
* Pack a 0x55AA Tuya message into bytes.
|
|
135
|
+
*
|
|
136
|
+
* @param seqno Message sequence number
|
|
137
|
+
* @param cmd Command byte
|
|
138
|
+
* @param payload Already-processed payload (encrypted/prefixed by caller)
|
|
139
|
+
* @param hmacKey If provided, appends HMAC-SHA256(header+payload, hmacKey)
|
|
140
|
+
* as the checksum instead of CRC32.
|
|
141
|
+
*/
|
|
142
|
+
function packMessage55AA(seqno, cmd, payload, hmacKey) {
|
|
143
|
+
// length field = payload.length + checksum(4 or 32) + suffix(4)
|
|
144
|
+
const checksumLen = hmacKey ? 32 : 4;
|
|
145
|
+
const length = payload.length + checksumLen + 4;
|
|
146
|
+
const header = Buffer.allocUnsafe(exports.HEADER_SIZE_55AA);
|
|
147
|
+
header.writeUInt32BE(exports.PREFIX_55AA, 0);
|
|
148
|
+
header.writeUInt32BE(seqno, 4);
|
|
149
|
+
header.writeUInt32BE(cmd, 8);
|
|
150
|
+
header.writeUInt32BE(length, 12);
|
|
151
|
+
const body = Buffer.concat([header, payload]);
|
|
152
|
+
const suffix = Buffer.allocUnsafe(4);
|
|
153
|
+
suffix.writeUInt32BE(exports.SUFFIX_55AA, 0);
|
|
154
|
+
let checksum;
|
|
155
|
+
if (hmacKey) {
|
|
156
|
+
checksum = hmac(body, hmacKey);
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
const crc = getCRC32(body);
|
|
160
|
+
checksum = Buffer.allocUnsafe(4);
|
|
161
|
+
checksum.writeUInt32BE(crc, 0);
|
|
162
|
+
}
|
|
163
|
+
return Buffer.concat([body, checksum, suffix]);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Unpack a complete 0x55AA frame.
|
|
167
|
+
*
|
|
168
|
+
* @param data Full frame buffer (prefix through suffix inclusive)
|
|
169
|
+
* @param hmacKey If provided, verifies HMAC-SHA256; otherwise verifies CRC32
|
|
170
|
+
* @param noRetcode If true, skip stripping the 4-byte retcode field
|
|
171
|
+
*/
|
|
172
|
+
function unpackMessage55AA(data, hmacKey, noRetcode = false) {
|
|
173
|
+
if (data.length < exports.HEADER_SIZE_55AA + 8)
|
|
174
|
+
return null;
|
|
175
|
+
if (data.readUInt32BE(0) !== exports.PREFIX_55AA)
|
|
176
|
+
return null;
|
|
177
|
+
const seqno = data.readUInt32BE(4);
|
|
178
|
+
const cmd = data.readUInt32BE(8);
|
|
179
|
+
const payloadLen = data.readUInt32BE(12); // includes checksum + suffix
|
|
180
|
+
const checksumLen = hmacKey ? 32 : 4;
|
|
181
|
+
const totalLen = exports.HEADER_SIZE_55AA + payloadLen;
|
|
182
|
+
if (data.length < totalLen)
|
|
183
|
+
return null;
|
|
184
|
+
// payload sits between header and checksum
|
|
185
|
+
const payloadEnd = totalLen - checksumLen - 4; // before checksum
|
|
186
|
+
const rawPayload = data.subarray(exports.HEADER_SIZE_55AA, payloadEnd);
|
|
187
|
+
// verify checksum
|
|
188
|
+
let hmacOk = false;
|
|
189
|
+
if (hmacKey) {
|
|
190
|
+
const expectedHmac = hmac(data.subarray(0, payloadEnd), hmacKey);
|
|
191
|
+
const receivedHmac = data.subarray(payloadEnd, payloadEnd + 32);
|
|
192
|
+
hmacOk = expectedHmac.equals(receivedHmac);
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
const expectedCrc = getCRC32(data.subarray(0, payloadEnd));
|
|
196
|
+
const receivedCrc = data.readUInt32BE(payloadEnd);
|
|
197
|
+
hmacOk = expectedCrc === receivedCrc;
|
|
198
|
+
}
|
|
199
|
+
// strip optional 4-byte retcode prefix (most server→client messages have it)
|
|
200
|
+
let payload = rawPayload;
|
|
201
|
+
let retcode = 0;
|
|
202
|
+
if (!noRetcode && payload.length >= 4) {
|
|
203
|
+
retcode = payload.readUInt32BE(0);
|
|
204
|
+
payload = payload.subarray(4);
|
|
205
|
+
}
|
|
206
|
+
return { seqno, cmd, retcode, payload, hmacOk };
|
|
207
|
+
}
|
|
208
|
+
// ── 0x6699 frame pack / unpack (v3.5) ─────────────────────────────────────────
|
|
209
|
+
/**
|
|
210
|
+
* Pack a 0x6699 (v3.5) frame. The payload must be the *plaintext* that will
|
|
211
|
+
* be encrypted with AES-128-GCM. The header bytes [4:18] are used as AAD.
|
|
212
|
+
*
|
|
213
|
+
* length field = IV(12) + ciphertext + GCM-tag(16) + suffix(4)
|
|
214
|
+
*/
|
|
215
|
+
function packMessage6699(seqno, cmd, plaintext, hmacKey) {
|
|
216
|
+
// Generate IV from current time (matches TinyTuya debug=False behaviour)
|
|
217
|
+
const iv = Buffer.from(String(Date.now() / 100).slice(0, 12).padStart(12, '0'), 'latin1');
|
|
218
|
+
// header (18 bytes): prefix(4) + unknown(2) + seqno(4) + cmd(4) + length(4)
|
|
219
|
+
const length = 12 + plaintext.length + 16 + 4; // IV(12) + cipher(N) + tag(16) + suffix(4)
|
|
220
|
+
const header = Buffer.allocUnsafe(exports.HEADER_SIZE_6699);
|
|
221
|
+
header.writeUInt32BE(exports.PREFIX_6699, 0);
|
|
222
|
+
header.writeUInt16BE(0x0000, 4);
|
|
223
|
+
header.writeUInt32BE(seqno, 6);
|
|
224
|
+
header.writeUInt32BE(cmd, 10);
|
|
225
|
+
header.writeUInt32BE(length, 14);
|
|
226
|
+
// AAD = header bytes [4:18]
|
|
227
|
+
const aad = header.subarray(4);
|
|
228
|
+
const { ciphertext, authTag } = encryptGCM(plaintext, hmacKey, iv, aad);
|
|
229
|
+
const suffix = Buffer.allocUnsafe(4);
|
|
230
|
+
suffix.writeUInt32BE(exports.SUFFIX_6699, 0);
|
|
231
|
+
return Buffer.concat([header, iv, ciphertext, authTag, suffix]);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Unpack a complete 0x6699 frame.
|
|
235
|
+
*/
|
|
236
|
+
function unpackMessage6699(data, hmacKey) {
|
|
237
|
+
if (data.length < exports.HEADER_SIZE_6699 + 12 + 16 + 4)
|
|
238
|
+
return null;
|
|
239
|
+
if (data.readUInt32BE(0) !== exports.PREFIX_6699)
|
|
240
|
+
return null;
|
|
241
|
+
const seqno = data.readUInt32BE(6);
|
|
242
|
+
const cmd = data.readUInt32BE(10);
|
|
243
|
+
const length = data.readUInt32BE(14);
|
|
244
|
+
const totalLen = exports.HEADER_SIZE_6699 + length;
|
|
245
|
+
if (data.length < totalLen)
|
|
246
|
+
return null;
|
|
247
|
+
const iv = data.subarray(exports.HEADER_SIZE_6699, exports.HEADER_SIZE_6699 + 12);
|
|
248
|
+
const tag = data.subarray(totalLen - 4 - 16, totalLen - 4);
|
|
249
|
+
const ciphertext = data.subarray(exports.HEADER_SIZE_6699 + 12, totalLen - 4 - 16);
|
|
250
|
+
const aad = data.subarray(4, exports.HEADER_SIZE_6699);
|
|
251
|
+
let payload;
|
|
252
|
+
let hmacOk = false;
|
|
253
|
+
try {
|
|
254
|
+
payload = decryptGCM(ciphertext, hmacKey, iv, tag, aad);
|
|
255
|
+
hmacOk = true;
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
// strip 4-byte retcode if present
|
|
261
|
+
if (payload.length >= 4 && payload[0] === 0 && payload[1] === 0) {
|
|
262
|
+
payload = payload.subarray(4);
|
|
263
|
+
}
|
|
264
|
+
return { seqno, cmd, payload, hmacOk };
|
|
265
|
+
}
|
|
266
|
+
// ── Frame boundary helpers ────────────────────────────────────────────────────
|
|
267
|
+
/** True when `buffer` starts with a complete 0x55AA or 0x6699 frame */
|
|
268
|
+
function isFrameComplete(buffer) {
|
|
269
|
+
if (buffer.length < 4)
|
|
270
|
+
return false;
|
|
271
|
+
const prefix = buffer.readUInt32BE(0);
|
|
272
|
+
if (prefix === exports.PREFIX_55AA) {
|
|
273
|
+
if (buffer.length < exports.HEADER_SIZE_55AA)
|
|
274
|
+
return false;
|
|
275
|
+
const payloadLen = buffer.readUInt32BE(12);
|
|
276
|
+
return buffer.length >= exports.HEADER_SIZE_55AA + payloadLen;
|
|
277
|
+
}
|
|
278
|
+
if (prefix === exports.PREFIX_6699) {
|
|
279
|
+
if (buffer.length < exports.HEADER_SIZE_6699)
|
|
280
|
+
return false;
|
|
281
|
+
const length = buffer.readUInt32BE(14);
|
|
282
|
+
return buffer.length >= exports.HEADER_SIZE_6699 + length;
|
|
283
|
+
}
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
/** Extract the first complete frame from buffer; returns frame + tail */
|
|
287
|
+
function extractFrame(buffer) {
|
|
288
|
+
// Find a valid prefix, tolerating leading garbage
|
|
289
|
+
let start = -1;
|
|
290
|
+
for (let i = 0; i <= buffer.length - 4; i++) {
|
|
291
|
+
const p = buffer.readUInt32BE(i);
|
|
292
|
+
if (p === exports.PREFIX_55AA || p === exports.PREFIX_6699) {
|
|
293
|
+
start = i;
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (start < 0)
|
|
298
|
+
return null;
|
|
299
|
+
const slice = buffer.subarray(start);
|
|
300
|
+
const prefix = slice.readUInt32BE(0);
|
|
301
|
+
if (prefix === exports.PREFIX_55AA) {
|
|
302
|
+
if (slice.length < exports.HEADER_SIZE_55AA)
|
|
303
|
+
return null;
|
|
304
|
+
const payloadLen = slice.readUInt32BE(12);
|
|
305
|
+
const frameLen = exports.HEADER_SIZE_55AA + payloadLen;
|
|
306
|
+
if (slice.length < frameLen)
|
|
307
|
+
return null;
|
|
308
|
+
return {
|
|
309
|
+
frame: Buffer.from(slice.subarray(0, frameLen)),
|
|
310
|
+
remaining: Buffer.from(slice.subarray(frameLen)),
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
// PREFIX_6699
|
|
314
|
+
if (slice.length < exports.HEADER_SIZE_6699)
|
|
315
|
+
return null;
|
|
316
|
+
const length = slice.readUInt32BE(14);
|
|
317
|
+
const frameLen = exports.HEADER_SIZE_6699 + length;
|
|
318
|
+
if (slice.length < frameLen)
|
|
319
|
+
return null;
|
|
320
|
+
return {
|
|
321
|
+
frame: Buffer.from(slice.subarray(0, frameLen)),
|
|
322
|
+
remaining: Buffer.from(slice.subarray(frameLen)),
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
/** Random 16-byte key */
|
|
326
|
+
function generateSessionKey() {
|
|
327
|
+
return (0, crypto_1.randomBytes)(16);
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=ProtocolUtilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProtocolUtilities.js","sourceRoot":"","sources":["../../../src/local/protocol/ProtocolUtilities.ts"],"names":[],"mappings":"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"}
|