homebridge-tuya-without-developer-account 1.0.0
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 +10 -0
- package/LICENSE +20 -0
- package/PUBLISHING.md +80 -0
- package/README.md +233 -0
- package/SUPPORTED_DEVICES.md +206 -0
- package/config.schema.json +131 -0
- package/dist/cloud/api/TuyaHACloudAPI.js +286 -0
- package/dist/cloud/api/TuyaHASharingMQ.js +114 -0
- package/dist/cloud/device/TuyaDevice.js +50 -0
- package/dist/cloud/device/TuyaHADeviceManager.js +355 -0
- package/dist/index.js +7 -0
- package/dist/platform.js +397 -0
- package/dist/settings.js +18 -0
- package/dist/shared/AccessoryFactory.js +276 -0
- package/dist/shared/accessories/AccessoryFactory.js +305 -0
- package/dist/shared/accessories/AirConditionerAccessory.js +307 -0
- package/dist/shared/accessories/AirPurifierAccessory.js +90 -0
- package/dist/shared/accessories/AirQualitySensorAccessory.js +30 -0
- package/dist/shared/accessories/BaseAccessory.js +406 -0
- package/dist/shared/accessories/BlindsAccessory.js +199 -0
- package/dist/shared/accessories/CameraAccessory.js +121 -0
- package/dist/shared/accessories/CarbonDioxideSensorAccessory.js +52 -0
- package/dist/shared/accessories/CarbonMonoxideSensorAccessory.js +52 -0
- package/dist/shared/accessories/ContactSensorAccessory.js +30 -0
- package/dist/shared/accessories/DehumidifierAccessory.js +68 -0
- package/dist/shared/accessories/DiffuserAccessory.js +55 -0
- package/dist/shared/accessories/DimmerAccessory.js +94 -0
- package/dist/shared/accessories/DoorbellAccessory.js +91 -0
- package/dist/shared/accessories/ExtractionHoodAccessory.js +120 -0
- package/dist/shared/accessories/FanAccessory.js +129 -0
- package/dist/shared/accessories/GarageDoorAccessory.js +69 -0
- package/dist/shared/accessories/HeaterAccessory.js +102 -0
- package/dist/shared/accessories/HeaterAccessory_old.js +96 -0
- package/dist/shared/accessories/HumanPresenceSensorAccessory.js +20 -0
- package/dist/shared/accessories/HumidifierAccessory.js +137 -0
- package/dist/shared/accessories/IRAirConditionerAccessory.js +278 -0
- package/dist/shared/accessories/IRControlHubAccessory.js +49 -0
- package/dist/shared/accessories/IRControlHubSubAccessory.js +52 -0
- package/dist/shared/accessories/IRGenericAccessory.js +49 -0
- package/dist/shared/accessories/LeakSensorAccessory.js +36 -0
- package/dist/shared/accessories/LightAccessory.js +36 -0
- package/dist/shared/accessories/LightSensorAccessory.js +32 -0
- package/dist/shared/accessories/LocationWeatherAccessory.js +72 -0
- package/dist/shared/accessories/LockAccessory.js +56 -0
- package/dist/shared/accessories/MotionSensorAccessory.js +20 -0
- package/dist/shared/accessories/OutletAccessory.js +23 -0
- package/dist/shared/accessories/PetFeederAccessory.js +139 -0
- package/dist/shared/accessories/SceneAccessory.js +32 -0
- package/dist/shared/accessories/SceneSwitchAccessory.js +44 -0
- package/dist/shared/accessories/SecuritySystemAccessory.js +30 -0
- package/dist/shared/accessories/SmokeSensorAccessory.js +35 -0
- package/dist/shared/accessories/SwitchAccessory.js +148 -0
- package/dist/shared/accessories/TemperatureHumiditySensorAccessory.js +24 -0
- package/dist/shared/accessories/ThermostatAccessory.js +192 -0
- package/dist/shared/accessories/TowerRackAccessory.js +157 -0
- package/dist/shared/accessories/ValveAccessory.js +45 -0
- package/dist/shared/accessories/VibrationSensorAccessory.js +46 -0
- package/dist/shared/accessories/WeatherStationAccessory.js +58 -0
- package/dist/shared/accessories/WetBulbGlobeTemperatureAccessory.js +23 -0
- package/dist/shared/accessories/WhiteNoiseLightAccessory.js +59 -0
- package/dist/shared/accessories/WindowAccessory.js +14 -0
- package/dist/shared/accessories/WindowCoveringAccessory.js +156 -0
- package/dist/shared/accessories/WirelessSwitchAccessory.js +42 -0
- package/dist/shared/accessories/characteristic/Active.js +22 -0
- package/dist/shared/accessories/characteristic/AirQuality.js +74 -0
- package/dist/shared/accessories/characteristic/CurrentRelativeHumidity.js +23 -0
- package/dist/shared/accessories/characteristic/CurrentTemperature.js +23 -0
- package/dist/shared/accessories/characteristic/CurrentWeather.js +49 -0
- package/dist/shared/accessories/characteristic/CurrentWeatherByOpenMeteo.js +49 -0
- package/dist/shared/accessories/characteristic/CurrentWetBulbGlobeTemperature.js +48 -0
- package/dist/shared/accessories/characteristic/EnergyUsage.js +98 -0
- package/dist/shared/accessories/characteristic/Light.js +268 -0
- package/dist/shared/accessories/characteristic/LightSensor.js +23 -0
- package/dist/shared/accessories/characteristic/LockPhysicalControls.js +21 -0
- package/dist/shared/accessories/characteristic/MotionDetected.js +22 -0
- package/dist/shared/accessories/characteristic/Name.js +15 -0
- package/dist/shared/accessories/characteristic/OccupancyDetected.js +19 -0
- package/dist/shared/accessories/characteristic/On.js +25 -0
- package/dist/shared/accessories/characteristic/OutletInUse.js +14 -0
- package/dist/shared/accessories/characteristic/ProgrammableSwitchEvent.js +89 -0
- package/dist/shared/accessories/characteristic/RelativeHumidityDehumidifierThreshold.js +28 -0
- package/dist/shared/accessories/characteristic/RotationSpeed.js +78 -0
- package/dist/shared/accessories/characteristic/SecuritySystemState.js +74 -0
- package/dist/shared/accessories/characteristic/SwingMode.js +21 -0
- package/dist/shared/accessories/characteristic/TargetTemperature.js +29 -0
- package/dist/shared/accessories/characteristic/TemperatureDisplayUnits.js +25 -0
- package/dist/shared/util/ConfigHash.js +79 -0
- package/dist/shared/util/FfmpegStreamingProcess.js +126 -0
- package/dist/shared/util/InfraredTool.js +392 -0
- package/dist/shared/util/Logger.js +42 -0
- package/dist/shared/util/TuyaRecordingDelegate.js +22 -0
- package/dist/shared/util/TuyaStreamDelegate.js +329 -0
- package/dist/shared/util/color.js +23 -0
- package/dist/shared/util/util.js +135 -0
- package/homebridge-ui/public/index.html +329 -0
- package/homebridge-ui/server.js +224 -0
- package/package.json +61 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const BaseAccessory_1 = __importDefault(require("./BaseAccessory"));
|
|
7
|
+
const MotionDetected_1 = require("./characteristic/MotionDetected");
|
|
8
|
+
const SCHEMA_CODE = {
|
|
9
|
+
PIR: ['pir'],
|
|
10
|
+
};
|
|
11
|
+
class MotionSensorAccessory extends BaseAccessory_1.default {
|
|
12
|
+
requiredSchema() {
|
|
13
|
+
return [SCHEMA_CODE.PIR];
|
|
14
|
+
}
|
|
15
|
+
configureServices() {
|
|
16
|
+
(0, MotionDetected_1.configureMotionDetected)(this, undefined, this.getSchema(...SCHEMA_CODE.PIR));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.default = MotionSensorAccessory;
|
|
20
|
+
//# sourceMappingURL=MotionSensorAccessory.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const OutletInUse_1 = require("./characteristic/OutletInUse");
|
|
7
|
+
const SwitchAccessory_1 = __importDefault(require("./SwitchAccessory"));
|
|
8
|
+
const SCHEMA_CODE = {
|
|
9
|
+
CURRENT: ['cur_current'],
|
|
10
|
+
};
|
|
11
|
+
class OutletAccessory extends SwitchAccessory_1.default {
|
|
12
|
+
mainService() {
|
|
13
|
+
return this.Service.Outlet;
|
|
14
|
+
}
|
|
15
|
+
configureSwitch(schema, name) {
|
|
16
|
+
super.configureSwitch(schema, name);
|
|
17
|
+
const service = this.accessory.getService(schema.code)
|
|
18
|
+
|| this.accessory.addService(this.mainService(), name, schema.code);
|
|
19
|
+
(0, OutletInUse_1.configureOutletInUse)(this, service, this.getSchema(...SCHEMA_CODE.CURRENT));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.default = OutletAccessory;
|
|
23
|
+
//# sourceMappingURL=OutletAccessory.js.map
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const BaseAccessory_1 = __importDefault(require("./BaseAccessory"));
|
|
7
|
+
const Active_1 = require("./characteristic/Active");
|
|
8
|
+
const SCHEMA_CODE = {
|
|
9
|
+
ACTIVE: ['switch'],
|
|
10
|
+
LIGHT: ['light'],
|
|
11
|
+
QUICK_FEED: ['quick_feed'],
|
|
12
|
+
SLOW_FEED: ['slow_feed'],
|
|
13
|
+
MANUAL_FEED: ['manual_feed'],
|
|
14
|
+
MEAL_PLAN: ['meal_plan'],
|
|
15
|
+
BATTERY_PERCENTAGE: ['battery_percentage'],
|
|
16
|
+
FEED_REPORT: ['feed_report'],
|
|
17
|
+
FEED_STATE: ['feed_state'],
|
|
18
|
+
};
|
|
19
|
+
class PetFeederAccessory extends BaseAccessory_1.default {
|
|
20
|
+
requiredSchema() {
|
|
21
|
+
return [SCHEMA_CODE.ACTIVE];
|
|
22
|
+
}
|
|
23
|
+
configureServices() {
|
|
24
|
+
(0, Active_1.configureActive)(this, this.mainService(), this.getSchema(...SCHEMA_CODE.ACTIVE));
|
|
25
|
+
this.configureLight();
|
|
26
|
+
this.configureQuickFeed();
|
|
27
|
+
this.configureSlowFeed();
|
|
28
|
+
this.configureManualFeed();
|
|
29
|
+
this.configureMealPlan();
|
|
30
|
+
this.configureBatteryPercentage();
|
|
31
|
+
this.configureFeedReport();
|
|
32
|
+
this.configureFeedState();
|
|
33
|
+
}
|
|
34
|
+
mainService() {
|
|
35
|
+
return this.accessory.getService(this.Service.Switch)
|
|
36
|
+
|| this.accessory.addService(this.Service.Switch);
|
|
37
|
+
}
|
|
38
|
+
configureLight() {
|
|
39
|
+
const schema = this.getSchema(...SCHEMA_CODE.LIGHT);
|
|
40
|
+
if (!schema) {
|
|
41
|
+
this.log.warn('Light is not supported.');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.mainService().getCharacteristic(this.Characteristic.On)
|
|
45
|
+
.onSet(async (value) => {
|
|
46
|
+
await this.sendCommands([{ code: schema.code, value: value }]);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
configureQuickFeed() {
|
|
50
|
+
const schema = this.getSchema(...SCHEMA_CODE.QUICK_FEED);
|
|
51
|
+
if (!schema) {
|
|
52
|
+
this.log.warn('Quick feed is not supported.');
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
this.mainService().getCharacteristic(this.Characteristic.On)
|
|
56
|
+
.onSet(async (value) => {
|
|
57
|
+
if (value) {
|
|
58
|
+
await this.sendCommands([{ code: schema.code, value: true }]);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
configureSlowFeed() {
|
|
63
|
+
const schema = this.getSchema(...SCHEMA_CODE.SLOW_FEED);
|
|
64
|
+
if (!schema) {
|
|
65
|
+
this.log.warn('Slow feed is not supported.');
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.mainService().getCharacteristic(this.Characteristic.On)
|
|
69
|
+
.onSet(async (value) => {
|
|
70
|
+
if (value) {
|
|
71
|
+
await this.sendCommands([{ code: schema.code, value: true }]);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
configureManualFeed() {
|
|
76
|
+
const schema = this.getSchema(...SCHEMA_CODE.MANUAL_FEED);
|
|
77
|
+
if (!schema) {
|
|
78
|
+
this.log.warn('Manual feed is not supported.');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this.mainService().getCharacteristic(this.Characteristic.On)
|
|
82
|
+
.onSet(async (value) => {
|
|
83
|
+
if (value) {
|
|
84
|
+
await this.sendCommands([{ code: schema.code, value: 1 }]);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
configureMealPlan() {
|
|
89
|
+
const schema = this.getSchema(...SCHEMA_CODE.MEAL_PLAN);
|
|
90
|
+
if (!schema) {
|
|
91
|
+
this.log.warn('Meal plan is not supported.');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
this.mainService().getCharacteristic(this.Characteristic.On)
|
|
95
|
+
.onSet(async (value) => {
|
|
96
|
+
if (value) {
|
|
97
|
+
await this.sendCommands([{ code: schema.code, value: value }]);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
configureBatteryPercentage() {
|
|
102
|
+
const schema = this.getSchema(...SCHEMA_CODE.BATTERY_PERCENTAGE);
|
|
103
|
+
if (!schema) {
|
|
104
|
+
this.log.warn('Battery percentage is not supported.');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.mainService().getCharacteristic(this.Characteristic.BatteryLevel)
|
|
108
|
+
.onGet(() => {
|
|
109
|
+
const status = this.getStatus(schema.code);
|
|
110
|
+
return status.value;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
configureFeedReport() {
|
|
114
|
+
const schema = this.getSchema(...SCHEMA_CODE.FEED_REPORT);
|
|
115
|
+
if (!schema) {
|
|
116
|
+
this.log.warn('Feed report is not supported.');
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
this.mainService().getCharacteristic(this.Characteristic.StatusActive)
|
|
120
|
+
.onGet(() => {
|
|
121
|
+
const status = this.getStatus(schema.code);
|
|
122
|
+
return status.value;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
configureFeedState() {
|
|
126
|
+
const schema = this.getSchema(...SCHEMA_CODE.FEED_STATE);
|
|
127
|
+
if (!schema) {
|
|
128
|
+
this.log.warn('Feed state is not supported.');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
this.mainService().getCharacteristic(this.Characteristic.StatusActive)
|
|
132
|
+
.onGet(() => {
|
|
133
|
+
const status = this.getStatus(schema.code);
|
|
134
|
+
return status.value === 'feeding';
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.default = PetFeederAccessory;
|
|
139
|
+
//# sourceMappingURL=PetFeederAccessory.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const BaseAccessory_1 = __importDefault(require("./BaseAccessory"));
|
|
7
|
+
class SceneAccessory extends BaseAccessory_1.default {
|
|
8
|
+
constructor(platform, accessory) {
|
|
9
|
+
super(platform, accessory);
|
|
10
|
+
const service = this.accessory.getService(this.Service.Switch)
|
|
11
|
+
|| this.accessory.addService(this.Service.Switch);
|
|
12
|
+
service.getCharacteristic(this.Characteristic.On)
|
|
13
|
+
.onGet(() => false)
|
|
14
|
+
.onSet(async (value) => {
|
|
15
|
+
if (value === false) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const deviceManager = this.platform.deviceManager;
|
|
19
|
+
const res = await deviceManager.executeScene(this.device.owner_id, this.device.id);
|
|
20
|
+
setTimeout(() => {
|
|
21
|
+
service.getCharacteristic(this.Characteristic.On).updateValue(false);
|
|
22
|
+
}, 150);
|
|
23
|
+
if (res.success === false) {
|
|
24
|
+
this.log.warn('ExecuteScene failed. homeId = %s, code = %s, msg = %s', this.device.owner_id, res.code, res.msg);
|
|
25
|
+
const { HapStatusError, HAPStatus } = this.platform.api.hap;
|
|
26
|
+
throw new HapStatusError(-70402 /* HAPStatus.SERVICE_COMMUNICATION_FAILURE */);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.default = SceneAccessory;
|
|
32
|
+
//# sourceMappingURL=SceneAccessory.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const TuyaDevice_1 = require("../../cloud/device/TuyaDevice");
|
|
7
|
+
const BaseAccessory_1 = __importDefault(require("./BaseAccessory"));
|
|
8
|
+
const Name_1 = require("./characteristic/Name");
|
|
9
|
+
class SceneSwitchAccessory extends BaseAccessory_1.default {
|
|
10
|
+
configureServices() {
|
|
11
|
+
const schema = this.device.schema.filter((schema) => schema.code.startsWith('switch') && schema.type === TuyaDevice_1.TuyaDeviceSchemaType.Boolean);
|
|
12
|
+
for (const _schema of schema) {
|
|
13
|
+
const name = (schema.length === 1) ? this.device.name : _schema.code;
|
|
14
|
+
this.configureSwitch(_schema, name);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
configureSwitch(schema, name) {
|
|
18
|
+
if (!schema) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const service = this.accessory.getService(schema.code)
|
|
22
|
+
|| this.accessory.addService(this.Service.Switch, name, schema.code);
|
|
23
|
+
(0, Name_1.configureName)(this, service, name);
|
|
24
|
+
const suffix = schema.code.replace('switch', '');
|
|
25
|
+
const modeSchema = this.getSchema('mode' + suffix);
|
|
26
|
+
service.getCharacteristic(this.Characteristic.On)
|
|
27
|
+
.onGet(() => {
|
|
28
|
+
const status = this.getStatus(schema.code);
|
|
29
|
+
return status.value;
|
|
30
|
+
})
|
|
31
|
+
.onSet(async (value) => {
|
|
32
|
+
if (modeSchema) {
|
|
33
|
+
const mode = this.getStatus(modeSchema.code);
|
|
34
|
+
if (mode.value.startsWith('scene')) {
|
|
35
|
+
await this.sendCommands([{ code: schema.code, value: false }]);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
await this.sendCommands([{ code: schema.code, value: value }]);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.default = SceneSwitchAccessory;
|
|
44
|
+
//# sourceMappingURL=SceneSwitchAccessory.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const BaseAccessory_1 = __importDefault(require("./BaseAccessory"));
|
|
7
|
+
const SecuritySystemState_1 = require("./characteristic/SecuritySystemState");
|
|
8
|
+
const Name_1 = require("./characteristic/Name");
|
|
9
|
+
const SCHEMA_CODE = {
|
|
10
|
+
MASTER_MODE: ['master_mode'],
|
|
11
|
+
SOS_STATE: ['sos_state'],
|
|
12
|
+
};
|
|
13
|
+
class SecuritySystemAccessory extends BaseAccessory_1.default {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(...arguments);
|
|
16
|
+
this.isNightArm = false;
|
|
17
|
+
}
|
|
18
|
+
requiredSchema() {
|
|
19
|
+
return [SCHEMA_CODE.MASTER_MODE, SCHEMA_CODE.SOS_STATE];
|
|
20
|
+
}
|
|
21
|
+
configureServices() {
|
|
22
|
+
const service = this.accessory.getService(this.Service.SecuritySystem)
|
|
23
|
+
|| this.accessory.addService(this.Service.SecuritySystem);
|
|
24
|
+
(0, Name_1.configureName)(this, service, this.device.name);
|
|
25
|
+
(0, SecuritySystemState_1.configureSecuritySystemCurrentState)(this, service, this.getSchema(...SCHEMA_CODE.MASTER_MODE), this.getSchema(...SCHEMA_CODE.SOS_STATE));
|
|
26
|
+
(0, SecuritySystemState_1.configureSecuritySystemTargetState)(this, service, this.getSchema(...SCHEMA_CODE.MASTER_MODE), this.getSchema(...SCHEMA_CODE.SOS_STATE));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.default = SecuritySystemAccessory;
|
|
30
|
+
//# sourceMappingURL=SecuritySystemAccessory.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const BaseAccessory_1 = __importDefault(require("./BaseAccessory"));
|
|
7
|
+
const SCHEMA_CODE = {
|
|
8
|
+
SENSOR_STATUS: ['smoke_sensor_status', 'smoke_sensor_state'],
|
|
9
|
+
};
|
|
10
|
+
class SmokeSensor extends BaseAccessory_1.default {
|
|
11
|
+
requiredSchema() {
|
|
12
|
+
return [SCHEMA_CODE.SENSOR_STATUS];
|
|
13
|
+
}
|
|
14
|
+
configureServices() {
|
|
15
|
+
const schema = this.getSchema(...SCHEMA_CODE.SENSOR_STATUS);
|
|
16
|
+
if (!schema) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const { SMOKE_NOT_DETECTED, SMOKE_DETECTED } = this.Characteristic.SmokeDetected;
|
|
20
|
+
const service = this.accessory.getService(this.Service.SmokeSensor)
|
|
21
|
+
|| this.accessory.addService(this.Service.SmokeSensor);
|
|
22
|
+
service.getCharacteristic(this.Characteristic.SmokeDetected)
|
|
23
|
+
.onGet(() => {
|
|
24
|
+
const status = this.getStatus(schema.code);
|
|
25
|
+
if ((status.value === 'alarm' || status.value === '1')) {
|
|
26
|
+
return SMOKE_DETECTED;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
return SMOKE_NOT_DETECTED;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.default = SmokeSensor;
|
|
35
|
+
//# sourceMappingURL=SmokeSensorAccessory.js.map
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const TuyaDevice_1 = require("../../cloud/device/TuyaDevice");
|
|
7
|
+
const BaseAccessory_1 = __importDefault(require("./BaseAccessory"));
|
|
8
|
+
const Name_1 = require("./characteristic/Name");
|
|
9
|
+
const On_1 = require("./characteristic/On");
|
|
10
|
+
const EnergyUsage_1 = require("./characteristic/EnergyUsage");
|
|
11
|
+
const CurrentTemperature_1 = require("./characteristic/CurrentTemperature");
|
|
12
|
+
const CurrentRelativeHumidity_1 = require("./characteristic/CurrentRelativeHumidity");
|
|
13
|
+
const SCHEMA_CODE = {
|
|
14
|
+
ON: ['switch', 'switch_1'], // switch_2, switch_3, switch_4, ..., switch_usb1, switch_usb2, switch_usb3, ..., switch_backlight
|
|
15
|
+
CURRENT: ['cur_current'],
|
|
16
|
+
POWER: ['cur_power'],
|
|
17
|
+
VOLTAGE: ['cur_voltage'],
|
|
18
|
+
TOTAL_POWER: ['add_ele'],
|
|
19
|
+
CURRENT_TEMP: ['va_temperature', 'temp_current'],
|
|
20
|
+
CURRENT_HUMIDITY: ['va_humidity', 'humidity_value'],
|
|
21
|
+
INCHING: ['switch_inching'],
|
|
22
|
+
};
|
|
23
|
+
class SwitchAccessory extends BaseAccessory_1.default {
|
|
24
|
+
requiredSchema() {
|
|
25
|
+
return [SCHEMA_CODE.ON];
|
|
26
|
+
}
|
|
27
|
+
configureServices() {
|
|
28
|
+
const oldService = this.accessory.getService(this.mainService());
|
|
29
|
+
if (oldService && oldService?.subtype === undefined) {
|
|
30
|
+
this.platform.log.warn('Remove old service:', oldService.UUID);
|
|
31
|
+
this.accessory.removeService(oldService);
|
|
32
|
+
}
|
|
33
|
+
const schemata = this.device.schema.filter((schema) => schema.code.startsWith('switch') && schema.type === TuyaDevice_1.TuyaDeviceSchemaType.Boolean);
|
|
34
|
+
this.log.info(`[SwitchAccessory] Found ${schemata.length} switch schemas: ${schemata.map(s => s.code).join(', ')}`);
|
|
35
|
+
// Track which switch services should exist
|
|
36
|
+
const validSubtypes = new Set(schemata.map(s => s.code));
|
|
37
|
+
// Remove any old switch services that are no longer in the schema.
|
|
38
|
+
// Match both Switch and Outlet UUIDs since OutletAccessory uses Service.Outlet.
|
|
39
|
+
const switchOrOutletUUIDs = new Set([this.Service.Switch.UUID, this.Service.Outlet.UUID]);
|
|
40
|
+
const allSwitchServices = this.accessory.services.filter(s => switchOrOutletUUIDs.has(s.UUID) && s.subtype);
|
|
41
|
+
// Check early if we'll be keeping services due to auto-detect or config unchanged
|
|
42
|
+
const configChanged = this.device?.configChanged ?? true;
|
|
43
|
+
const isAutoDetecting = this.device?.isAutoDetecting ?? false;
|
|
44
|
+
const shouldRemoveExtras = configChanged && !isAutoDetecting;
|
|
45
|
+
if (allSwitchServices.length > schemata.length) {
|
|
46
|
+
if (shouldRemoveExtras) {
|
|
47
|
+
this.log.warn(`[SwitchAccessory] Found ${allSwitchServices.length} cached switch services but only ${schemata.length} in schema. Removing extras...`);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.log.info(`[SwitchAccessory] Found ${allSwitchServices.length} cached switch services but only ${schemata.length} in schema. ${isAutoDetecting ? 'Auto-detect in progress' : 'Config unchanged'} – keeping for now...`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const keptCachedServices = new Map();
|
|
54
|
+
for (const oldService of allSwitchServices) {
|
|
55
|
+
if (!validSubtypes.has(oldService.subtype)) {
|
|
56
|
+
if (shouldRemoveExtras) {
|
|
57
|
+
// Config changed and not in auto-detect, so enforce the new schema
|
|
58
|
+
this.log.warn(`Removing old switch service: ${oldService.displayName} (subtype: ${oldService.subtype})`);
|
|
59
|
+
this.accessory.removeService(oldService);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// Either config didn't change, or we're in auto-detect mode – keep cached services for now
|
|
63
|
+
// Auto-detection will add new ones when complete
|
|
64
|
+
this.log.debug(`${isAutoDetecting ? 'Auto-detect in progress' : 'Config unchanged'} for this device, keeping cached switch service: ` +
|
|
65
|
+
`${oldService.displayName} (subtype: ${oldService.subtype})`);
|
|
66
|
+
// Track the kept service to configure it
|
|
67
|
+
keptCachedServices.set(oldService.subtype, oldService);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Now configure the switches in the schema
|
|
72
|
+
schemata.forEach((schema, index) => {
|
|
73
|
+
// Use human-readable names instead of raw code names (which contain underscores)
|
|
74
|
+
let name;
|
|
75
|
+
if (schemata.length === 1) {
|
|
76
|
+
name = this.device.name;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// For multiple switches, append "#1", "#2", etc. or use "Switch 1", "Switch 2"
|
|
80
|
+
const switchMatch = schema.code.match(/^switch_(\d+)$/);
|
|
81
|
+
const switchNum = switchMatch ? switchMatch[1] : (index + 1).toString();
|
|
82
|
+
name = `${this.device.name} ${switchNum}`;
|
|
83
|
+
}
|
|
84
|
+
this.configureSwitch(schema, name);
|
|
85
|
+
});
|
|
86
|
+
// Also configure cached services that aren't in schema (but weren't removed because config unchanged)
|
|
87
|
+
for (const [subtype, service] of keptCachedServices.entries()) {
|
|
88
|
+
const switchMatch = subtype.match(/^switch_(\d+)$/);
|
|
89
|
+
const switchNum = switchMatch ? switchMatch[1] : subtype;
|
|
90
|
+
const name = schemata.length === 1 ? this.device.name : `${this.device.name} ${switchNum}`;
|
|
91
|
+
// Extract schema info from the cached service's current state
|
|
92
|
+
// In this case we reuse the service without re-adding it
|
|
93
|
+
(0, Name_1.configureName)(this, service, name);
|
|
94
|
+
}
|
|
95
|
+
// Other
|
|
96
|
+
(0, CurrentTemperature_1.configureCurrentTemperature)(this, undefined, this.getSchema(...SCHEMA_CODE.CURRENT_TEMP));
|
|
97
|
+
(0, CurrentRelativeHumidity_1.configureCurrentRelativeHumidity)(this, undefined, this.getSchema(...SCHEMA_CODE.CURRENT_HUMIDITY));
|
|
98
|
+
this.configureInching();
|
|
99
|
+
}
|
|
100
|
+
async onDeviceInfoUpdate(info) {
|
|
101
|
+
// Re-run service configuration so newly auto-detected switches get their handlers registered.
|
|
102
|
+
this.configureServices();
|
|
103
|
+
this.configureStatusActive();
|
|
104
|
+
await this.updateAllValues();
|
|
105
|
+
}
|
|
106
|
+
mainService() {
|
|
107
|
+
return this.Service.Switch;
|
|
108
|
+
}
|
|
109
|
+
configureSwitch(schema, name) {
|
|
110
|
+
const service = this.accessory.getService(schema.code)
|
|
111
|
+
|| this.accessory.addService(this.mainService(), name, schema.code);
|
|
112
|
+
(0, Name_1.configureName)(this, service, name);
|
|
113
|
+
(0, On_1.configureOn)(this, service, schema);
|
|
114
|
+
if (schema.code === this.getSchema(...SCHEMA_CODE.ON)?.code) {
|
|
115
|
+
(0, EnergyUsage_1.configureEnergyUsage)(this.platform.api, this, service, this.getSchema(...SCHEMA_CODE.CURRENT), this.getSchema(...SCHEMA_CODE.POWER), this.getSchema(...SCHEMA_CODE.VOLTAGE), this.getSchema(...SCHEMA_CODE.TOTAL_POWER));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
configureInching() {
|
|
119
|
+
const schema = this.getSchema(...SCHEMA_CODE.INCHING);
|
|
120
|
+
if (!schema || schema.type !== TuyaDevice_1.TuyaDeviceSchemaType.String) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const service = this.accessory.getService(schema.code)
|
|
124
|
+
|| this.accessory.addService(this.Service.Switch, schema.code, schema.code);
|
|
125
|
+
(0, Name_1.configureName)(this, service, schema.code);
|
|
126
|
+
service.getCharacteristic(this.Characteristic.On)
|
|
127
|
+
.onGet(() => {
|
|
128
|
+
this.checkOnlineStatus();
|
|
129
|
+
const status = this.getStatus(schema.code);
|
|
130
|
+
const buffer = Buffer.from(status.value, 'base64');
|
|
131
|
+
return (buffer.length === 3) && (buffer[0] === 1);
|
|
132
|
+
})
|
|
133
|
+
.onSet(async (value) => {
|
|
134
|
+
const status = this.getStatus(schema.code);
|
|
135
|
+
let buffer = Buffer.from(status.value, 'base64');
|
|
136
|
+
if (buffer.length !== 3) {
|
|
137
|
+
buffer = Buffer.alloc(3);
|
|
138
|
+
}
|
|
139
|
+
buffer[0] = value ? 1 : 0;
|
|
140
|
+
await this.sendCommands([{
|
|
141
|
+
code: schema.code,
|
|
142
|
+
value: buffer.toString('base64'),
|
|
143
|
+
}], true);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.default = SwitchAccessory;
|
|
148
|
+
//# sourceMappingURL=SwitchAccessory.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const BaseAccessory_1 = __importDefault(require("./BaseAccessory"));
|
|
7
|
+
const CurrentRelativeHumidity_1 = require("./characteristic/CurrentRelativeHumidity");
|
|
8
|
+
const CurrentTemperature_1 = require("./characteristic/CurrentTemperature");
|
|
9
|
+
const SCHEMA_CODE = {
|
|
10
|
+
SENSOR_STATUS: ['va_temperature', 'va_humidity', 'humidity_value'],
|
|
11
|
+
CURRENT_TEMP: ['va_temperature', 'temp_value'],
|
|
12
|
+
CURRENT_HUMIDITY: ['va_humidity', 'humidity_value'],
|
|
13
|
+
};
|
|
14
|
+
class TemperatureHumiditySensorAccessory extends BaseAccessory_1.default {
|
|
15
|
+
requiredSchema() {
|
|
16
|
+
return [SCHEMA_CODE.SENSOR_STATUS];
|
|
17
|
+
}
|
|
18
|
+
configureServices() {
|
|
19
|
+
(0, CurrentTemperature_1.configureCurrentTemperature)(this, undefined, this.getSchema(...SCHEMA_CODE.CURRENT_TEMP));
|
|
20
|
+
(0, CurrentRelativeHumidity_1.configureCurrentRelativeHumidity)(this, undefined, this.getSchema(...SCHEMA_CODE.CURRENT_HUMIDITY));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.default = TemperatureHumiditySensorAccessory;
|
|
24
|
+
//# sourceMappingURL=TemperatureHumiditySensorAccessory.js.map
|