hoffmation-base 2.16.2 → 2.17.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/lib/models/deviceSettings/garageDoorOpenerSettings.d.ts +10 -0
- package/lib/models/deviceSettings/garageDoorOpenerSettings.js +24 -0
- package/lib/models/deviceSettings/index.d.ts +1 -0
- package/lib/models/deviceSettings/index.js +1 -0
- package/lib/server/devices/DeviceCapability.d.ts +1 -0
- package/lib/server/devices/DeviceCapability.js +1 -0
- package/lib/server/devices/baseDeviceInterfaces/iGarageDoorOpener.d.ts +9 -0
- package/lib/server/devices/baseDeviceInterfaces/iGarageDoorOpener.js +2 -0
- package/lib/server/devices/baseDeviceInterfaces/index.d.ts +1 -0
- package/lib/server/devices/baseDeviceInterfaces/index.js +1 -0
- package/lib/server/devices/deviceType.d.ts +1 -0
- package/lib/server/devices/deviceType.js +1 -0
- package/lib/server/devices/devices.d.ts +2 -0
- package/lib/server/devices/devices.js +25 -0
- package/lib/server/devices/espresense/espresenseDevice.d.ts +1 -1
- package/lib/server/devices/espresense/espresenseDevice.js +4 -4
- package/lib/server/devices/espresense/trilateration.js +8 -8
- package/lib/server/devices/espresense/trilaterationBasePoint.d.ts +1 -1
- package/lib/server/devices/espresense/trilaterationBasePoint.js +4 -4
- package/lib/server/devices/index.d.ts +1 -0
- package/lib/server/devices/index.js +1 -0
- package/lib/server/devices/tuya/index.d.ts +2 -0
- package/lib/server/devices/tuya/index.js +7 -0
- package/lib/server/devices/tuya/tuyaDevice.d.ts +12 -0
- package/lib/server/devices/tuya/tuyaDevice.js +36 -0
- package/lib/server/devices/tuya/tuyaGarageOpener.d.ts +18 -0
- package/lib/server/devices/tuya/tuyaGarageOpener.js +61 -0
- package/lib/server/ioBroker/connection.d.ts +2 -7
- package/lib/server/ioBroker/connection.js +0 -36
- package/lib/server/services/api/api-service.d.ts +1 -0
- package/lib/server/services/api/api-service.js +16 -0
- package/lib/server/services/utils/utils.js +4 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DeviceSettings } from './deviceSettings';
|
|
2
|
+
export declare class GarageDoorOpenerSettings extends DeviceSettings {
|
|
3
|
+
/**
|
|
4
|
+
* In case the sensor detects open door instead of closed
|
|
5
|
+
* @type {boolean}
|
|
6
|
+
*/
|
|
7
|
+
invertSensor: boolean;
|
|
8
|
+
fromPartialObject(data: Partial<GarageDoorOpenerSettings>): void;
|
|
9
|
+
protected toJSON(): Partial<GarageDoorOpenerSettings>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GarageDoorOpenerSettings = void 0;
|
|
4
|
+
const deviceSettings_1 = require("./deviceSettings");
|
|
5
|
+
const server_1 = require("../../server");
|
|
6
|
+
class GarageDoorOpenerSettings extends deviceSettings_1.DeviceSettings {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
/**
|
|
10
|
+
* In case the sensor detects open door instead of closed
|
|
11
|
+
* @type {boolean}
|
|
12
|
+
*/
|
|
13
|
+
this.invertSensor = false;
|
|
14
|
+
}
|
|
15
|
+
fromPartialObject(data) {
|
|
16
|
+
var _a;
|
|
17
|
+
this.invertSensor = (_a = data.invertSensor) !== null && _a !== void 0 ? _a : this.invertSensor;
|
|
18
|
+
super.fromPartialObject(data);
|
|
19
|
+
}
|
|
20
|
+
toJSON() {
|
|
21
|
+
return server_1.Utils.jsonFilter(this);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.GarageDoorOpenerSettings = GarageDoorOpenerSettings;
|
|
@@ -3,6 +3,7 @@ export * from './actuatorSettings';
|
|
|
3
3
|
export * from './cameraSettings';
|
|
4
4
|
export * from './deviceSettings';
|
|
5
5
|
export * from './dimmerSettings';
|
|
6
|
+
export * from './garageDoorOpenerSettings';
|
|
6
7
|
export * from './heaterSettings';
|
|
7
8
|
export * from './ledSettings';
|
|
8
9
|
export * from './motionSensorSettings';
|
|
@@ -19,6 +19,7 @@ __exportStar(require("./actuatorSettings"), exports);
|
|
|
19
19
|
__exportStar(require("./cameraSettings"), exports);
|
|
20
20
|
__exportStar(require("./deviceSettings"), exports);
|
|
21
21
|
__exportStar(require("./dimmerSettings"), exports);
|
|
22
|
+
__exportStar(require("./garageDoorOpenerSettings"), exports);
|
|
22
23
|
__exportStar(require("./heaterSettings"), exports);
|
|
23
24
|
__exportStar(require("./ledSettings"), exports);
|
|
24
25
|
__exportStar(require("./motionSensorSettings"), exports);
|
|
@@ -24,6 +24,7 @@ var DeviceCapability;
|
|
|
24
24
|
DeviceCapability[DeviceCapability["ledLamp"] = 18] = "ledLamp";
|
|
25
25
|
DeviceCapability[DeviceCapability["smokeSensor"] = 19] = "smokeSensor";
|
|
26
26
|
DeviceCapability[DeviceCapability["loadMetering"] = 20] = "loadMetering";
|
|
27
|
+
DeviceCapability[DeviceCapability["garageDoorOpener"] = 21] = "garageDoorOpener";
|
|
27
28
|
DeviceCapability[DeviceCapability["bluetoothDetector"] = 101] = "bluetoothDetector";
|
|
28
29
|
DeviceCapability[DeviceCapability["trackableDevice"] = 102] = "trackableDevice";
|
|
29
30
|
DeviceCapability[DeviceCapability["scene"] = 103] = "scene";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GarageDoorOpenerSettings } from '../../../models';
|
|
2
|
+
import { iRoomDevice } from './iRoomDevice';
|
|
3
|
+
export interface iGarageDoorOpener extends iRoomDevice {
|
|
4
|
+
settings: GarageDoorOpenerSettings;
|
|
5
|
+
readonly isClosed: boolean;
|
|
6
|
+
open(): void;
|
|
7
|
+
close(): void;
|
|
8
|
+
trigger(): void;
|
|
9
|
+
}
|
|
@@ -6,6 +6,7 @@ export * from './iButtonSwitch';
|
|
|
6
6
|
export * from './iCameraDevice';
|
|
7
7
|
export * from './iEnergyManager';
|
|
8
8
|
export * from './iExcessEnergyConsumer';
|
|
9
|
+
export * from './iGarageDoorOpener';
|
|
9
10
|
export * from './iHandleSensor';
|
|
10
11
|
export * from './iHeater';
|
|
11
12
|
export * from './iHumiditySensor';
|
|
@@ -22,6 +22,7 @@ __exportStar(require("./iButtonSwitch"), exports);
|
|
|
22
22
|
__exportStar(require("./iCameraDevice"), exports);
|
|
23
23
|
__exportStar(require("./iEnergyManager"), exports);
|
|
24
24
|
__exportStar(require("./iExcessEnergyConsumer"), exports);
|
|
25
|
+
__exportStar(require("./iGarageDoorOpener"), exports);
|
|
25
26
|
__exportStar(require("./iHandleSensor"), exports);
|
|
26
27
|
__exportStar(require("./iHeater"), exports);
|
|
27
28
|
__exportStar(require("./iHumiditySensor"), exports);
|
|
@@ -45,6 +45,7 @@ var DeviceType;
|
|
|
45
45
|
DeviceType[DeviceType["JsEnergyManager"] = 301] = "JsEnergyManager";
|
|
46
46
|
DeviceType[DeviceType["RoomScene"] = 401] = "RoomScene";
|
|
47
47
|
DeviceType[DeviceType["ShellyTrv"] = 402] = "ShellyTrv";
|
|
48
|
+
DeviceType[DeviceType["TuyaGarageDoorOpener"] = 501] = "TuyaGarageDoorOpener";
|
|
48
49
|
DeviceType[DeviceType["WledDevice"] = 1001] = "WledDevice";
|
|
49
50
|
DeviceType[DeviceType["Daikin"] = 2001] = "Daikin";
|
|
50
51
|
DeviceType[DeviceType["Sonos"] = 3001] = "Sonos";
|
|
@@ -6,6 +6,7 @@ export declare class Devices {
|
|
|
6
6
|
static IDENTIFIER_HOMEMATIC: string;
|
|
7
7
|
static IDENTIFIER_JS: string;
|
|
8
8
|
static IDENTIFIER_Shelly: string;
|
|
9
|
+
static IDENTIFIER_TUYA: string;
|
|
9
10
|
static IDENTIFIER_ZIGBEE: string;
|
|
10
11
|
static IDENTIFIER_WLED: string;
|
|
11
12
|
static alLDevices: {
|
|
@@ -21,6 +22,7 @@ export declare class Devices {
|
|
|
21
22
|
static resetDetectionsToday(): void;
|
|
22
23
|
static getBatteryInfo(): string;
|
|
23
24
|
private static processShellyDevice;
|
|
25
|
+
private static processTuyaDevice;
|
|
24
26
|
private static processZigbeeDevice;
|
|
25
27
|
private static processWledDevice;
|
|
26
28
|
private static processHMIPDevice;
|
|
@@ -11,6 +11,7 @@ const jsObject_1 = require("./jsObject");
|
|
|
11
11
|
const wledDevice_1 = require("./wledDevice");
|
|
12
12
|
const DeviceCapability_1 = require("./DeviceCapability");
|
|
13
13
|
const shelly_1 = require("./shelly");
|
|
14
|
+
const tuya_1 = require("./tuya");
|
|
14
15
|
class Devices {
|
|
15
16
|
constructor(pDeviceData, pRoomImportEnforcer, config) {
|
|
16
17
|
var _a;
|
|
@@ -39,6 +40,9 @@ class Devices {
|
|
|
39
40
|
else if (cName.indexOf('00-Shelly') === 0) {
|
|
40
41
|
Devices.processShellyDevice(cDevConf);
|
|
41
42
|
}
|
|
43
|
+
else if (cName.indexOf('00-Tuya') === 0) {
|
|
44
|
+
Devices.processTuyaDevice(cDevConf);
|
|
45
|
+
}
|
|
42
46
|
else if (cName.indexOf('00-EnergyManager') === 0 &&
|
|
43
47
|
cDevConf.type !== 'folder' &&
|
|
44
48
|
!((_a = config === null || config === void 0 ? void 0 : config.energyManager) === null || _a === void 0 ? void 0 : _a.disableJsEnergyManager)) {
|
|
@@ -49,6 +53,7 @@ class Devices {
|
|
|
49
53
|
hmIPDevices_1.HmIPDevice.checkMissing();
|
|
50
54
|
zigbee_1.ZigbeeDevice.checkMissing();
|
|
51
55
|
shelly_1.ShellyDevice.checkMissing();
|
|
56
|
+
tuya_1.TuyaDevice.checkMissing();
|
|
52
57
|
}
|
|
53
58
|
static midnightReset() {
|
|
54
59
|
// Nothing yet
|
|
@@ -105,6 +110,25 @@ class Devices {
|
|
|
105
110
|
}
|
|
106
111
|
Devices.alLDevices[fullName] = d;
|
|
107
112
|
}
|
|
113
|
+
static processTuyaDevice(cDevConf) {
|
|
114
|
+
const tuyaInfo = new IoBrokerDeviceInfo_1.IoBrokerDeviceInfo(cDevConf);
|
|
115
|
+
const fullName = `${Devices.IDENTIFIER_TUYA}-${tuyaInfo.devID}`;
|
|
116
|
+
tuyaInfo.allDevicesKey = fullName;
|
|
117
|
+
if (typeof Devices.alLDevices[fullName] !== 'undefined') {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
services_1.ServerLogService.writeLog(models_1.LogLevel.Trace, `Tuya ${tuyaInfo.devID} with Type "${tuyaInfo.deviceType}" doesn't exists --> create it`);
|
|
121
|
+
let d;
|
|
122
|
+
switch (tuyaInfo.deviceType) {
|
|
123
|
+
case 'Opener':
|
|
124
|
+
d = new tuya_1.TuyaGarageOpener(tuyaInfo);
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
services_1.ServerLogService.writeLog(models_1.LogLevel.Warn, `No Tuya Device Type for ${tuyaInfo.deviceType} defined`);
|
|
128
|
+
d = new tuya_1.TuyaDevice(tuyaInfo, deviceType_1.DeviceType.unknown);
|
|
129
|
+
}
|
|
130
|
+
Devices.alLDevices[fullName] = d;
|
|
131
|
+
}
|
|
108
132
|
static processZigbeeDevice(cDevConf) {
|
|
109
133
|
const zigbeeInfo = new IoBrokerDeviceInfo_1.IoBrokerDeviceInfo(cDevConf);
|
|
110
134
|
const fullName = `${Devices.IDENTIFIER_ZIGBEE}-${zigbeeInfo.devID}`;
|
|
@@ -274,6 +298,7 @@ exports.Devices = Devices;
|
|
|
274
298
|
Devices.IDENTIFIER_HOMEMATIC = 'hm-rpc';
|
|
275
299
|
Devices.IDENTIFIER_JS = 'javascript';
|
|
276
300
|
Devices.IDENTIFIER_Shelly = 'shelly';
|
|
301
|
+
Devices.IDENTIFIER_TUYA = 'tuya';
|
|
277
302
|
Devices.IDENTIFIER_ZIGBEE = 'zigbee';
|
|
278
303
|
Devices.IDENTIFIER_WLED = 'wled';
|
|
279
304
|
Devices.alLDevices = {};
|
|
@@ -14,7 +14,7 @@ export declare class EspresenseDevice implements iRoomDevice, iBluetoothDetector
|
|
|
14
14
|
deviceType: DeviceType;
|
|
15
15
|
readonly name: string;
|
|
16
16
|
private deviceMap;
|
|
17
|
-
private
|
|
17
|
+
private proximityCallbackMap;
|
|
18
18
|
constructor(name: string, roomName: string, x: number, y: number, z: number);
|
|
19
19
|
get customName(): string;
|
|
20
20
|
protected _info: DeviceInfo;
|
|
@@ -17,7 +17,7 @@ class EspresenseDevice {
|
|
|
17
17
|
this.deviceCapabilities = [DeviceCapability_1.DeviceCapability.bluetoothDetector];
|
|
18
18
|
this.deviceType = deviceType_1.DeviceType.Espresense;
|
|
19
19
|
this.deviceMap = new Map();
|
|
20
|
-
this.
|
|
20
|
+
this.proximityCallbackMap = new Map();
|
|
21
21
|
this.position = new trilaterationBasePoint_1.TrilaterationBasePoint(x, y, z, roomName);
|
|
22
22
|
this.name = name;
|
|
23
23
|
this._info = new DeviceInfo_1.DeviceInfo();
|
|
@@ -77,7 +77,7 @@ class EspresenseDevice {
|
|
|
77
77
|
}
|
|
78
78
|
dev.updateDistance(this, data.distance);
|
|
79
79
|
dev.guessRoom();
|
|
80
|
-
const cbs = this.
|
|
80
|
+
const cbs = this.proximityCallbackMap.get(dev.name);
|
|
81
81
|
if (cbs === undefined) {
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
@@ -125,12 +125,12 @@ class EspresenseDevice {
|
|
|
125
125
|
// Nothing
|
|
126
126
|
}
|
|
127
127
|
addProximityCallback(cb) {
|
|
128
|
-
let currentValue = this.
|
|
128
|
+
let currentValue = this.proximityCallbackMap.get(cb.deviceName);
|
|
129
129
|
if (currentValue == undefined) {
|
|
130
130
|
currentValue = [];
|
|
131
131
|
}
|
|
132
132
|
currentValue.push(cb);
|
|
133
|
-
this.
|
|
133
|
+
this.proximityCallbackMap.set(cb.deviceName, currentValue);
|
|
134
134
|
}
|
|
135
135
|
addDeviceTracking(devName) {
|
|
136
136
|
const dev = detectedBluetoothDevice_1.DetectedBluetoothDevice.getOrCreate(devName);
|
|
@@ -35,7 +35,7 @@ class Trilateration {
|
|
|
35
35
|
return bestMatches;
|
|
36
36
|
}
|
|
37
37
|
static getBestRatedCoordinates(distances) {
|
|
38
|
-
const
|
|
38
|
+
const allRatedCoordinatesMap = new Map();
|
|
39
39
|
for (const dist of distances) {
|
|
40
40
|
const point = this.basePoints.find((basePoint) => basePoint.ownPoint.coordinateName === dist.pointName);
|
|
41
41
|
if (point === undefined) {
|
|
@@ -49,16 +49,16 @@ class Trilateration {
|
|
|
49
49
|
const ratedCoordinates = point.getRatedCoordinates(dist.distance);
|
|
50
50
|
services_1.ServerLogService.writeLog(models_1.LogLevel.Debug, `Found ${ratedCoordinates.length} rated coordinates for ${dist.pointName} within distance of ${dist.distance}m`, { debugType: services_1.LogDebugType.Trilateration });
|
|
51
51
|
for (const ratedCoordinate of ratedCoordinates) {
|
|
52
|
-
const existingCoordinate =
|
|
52
|
+
const existingCoordinate = allRatedCoordinatesMap.get(ratedCoordinate.coordinateName);
|
|
53
53
|
if (existingCoordinate === undefined) {
|
|
54
|
-
|
|
54
|
+
allRatedCoordinatesMap.set(ratedCoordinate.coordinateName, ratedCoordinate);
|
|
55
55
|
continue;
|
|
56
56
|
}
|
|
57
57
|
existingCoordinate.rating += ratedCoordinate.rating;
|
|
58
58
|
existingCoordinate.matchCount++;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
return this.getBestRatedCoordinatesFromMap(
|
|
61
|
+
return this.getBestRatedCoordinatesFromMap(allRatedCoordinatesMap);
|
|
62
62
|
}
|
|
63
63
|
static checkRoom(distances) {
|
|
64
64
|
var _a;
|
|
@@ -71,13 +71,13 @@ class Trilateration {
|
|
|
71
71
|
return bestMatches[0].roomName;
|
|
72
72
|
}
|
|
73
73
|
// As we have multiple possible winners, we need to check how often which room occurs
|
|
74
|
-
const
|
|
74
|
+
const roomCountMap = new Map();
|
|
75
75
|
for (const point of bestMatches) {
|
|
76
76
|
const room = point.roomName;
|
|
77
|
-
const existingCount = (_a =
|
|
78
|
-
|
|
77
|
+
const existingCount = (_a = roomCountMap.get(room)) !== null && _a !== void 0 ? _a : 0;
|
|
78
|
+
roomCountMap.set(room, existingCount + 1);
|
|
79
79
|
}
|
|
80
|
-
return Array.from(
|
|
80
|
+
return Array.from(roomCountMap.entries()).sort((a, b) => b[1] - a[1])[0][0];
|
|
81
81
|
}
|
|
82
82
|
static getBestRatedCoordinatesFromMap(allRatedCoordinates) {
|
|
83
83
|
const sortedCoordinates = Array.from(allRatedCoordinates.values()).sort((a, b) => {
|
|
@@ -7,7 +7,7 @@ export declare class TrilaterationBasePoint {
|
|
|
7
7
|
readonly roomName: string;
|
|
8
8
|
private readonly _maximumDistance;
|
|
9
9
|
readonly ownPoint: TrilaterationPoint;
|
|
10
|
-
readonly
|
|
10
|
+
readonly precalculatedDistancesMap: Map<number, string[]>;
|
|
11
11
|
constructor(x: number, y: number, z: number, roomName: string, _maximumDistance?: number);
|
|
12
12
|
getRatedCoordinates(distance: number): TrilaterationRatedCoordinate[];
|
|
13
13
|
private rateCoordinates;
|
|
@@ -12,7 +12,7 @@ class TrilaterationBasePoint {
|
|
|
12
12
|
this.z = z;
|
|
13
13
|
this.roomName = roomName;
|
|
14
14
|
this._maximumDistance = _maximumDistance;
|
|
15
|
-
this.
|
|
15
|
+
this.precalculatedDistancesMap = new Map();
|
|
16
16
|
this.ownPoint = new trilaterationPoint_1.TrilaterationPoint(x, y, z, roomName);
|
|
17
17
|
}
|
|
18
18
|
getRatedCoordinates(distance) {
|
|
@@ -28,7 +28,7 @@ class TrilaterationBasePoint {
|
|
|
28
28
|
return result;
|
|
29
29
|
}
|
|
30
30
|
rateCoordinates(distance, result, rating) {
|
|
31
|
-
const possiblePoints = this.
|
|
31
|
+
const possiblePoints = this.precalculatedDistancesMap.get(distance);
|
|
32
32
|
if (possiblePoints !== undefined) {
|
|
33
33
|
for (const point of possiblePoints) {
|
|
34
34
|
result.push(new trilaterationRatedCoordinate_1.TrilaterationRatedCoordinate(point, rating));
|
|
@@ -44,9 +44,9 @@ class TrilaterationBasePoint {
|
|
|
44
44
|
continue;
|
|
45
45
|
}
|
|
46
46
|
count++;
|
|
47
|
-
const distancePoints = (_a = this.
|
|
47
|
+
const distancePoints = (_a = this.precalculatedDistancesMap.get(distance)) !== null && _a !== void 0 ? _a : [];
|
|
48
48
|
distancePoints.push(point.coordinateName);
|
|
49
|
-
this.
|
|
49
|
+
this.precalculatedDistancesMap.set(distance, distancePoints);
|
|
50
50
|
}
|
|
51
51
|
services_1.ServerLogService.writeLog(models_1.LogLevel.Info, `Filled ${count} distances for Trilateration in room: ${this.roomName}`);
|
|
52
52
|
}
|
|
@@ -8,6 +8,7 @@ export * from './jsObject/index';
|
|
|
8
8
|
export * from './models/index';
|
|
9
9
|
export * from './scene/index';
|
|
10
10
|
export * from './shelly/index';
|
|
11
|
+
export * from './tuya/index';
|
|
11
12
|
export * from './zigbee/index';
|
|
12
13
|
export * from './device-cluster';
|
|
13
14
|
export * from './device-cluster-type';
|
|
@@ -24,6 +24,7 @@ __exportStar(require("./jsObject/index"), exports);
|
|
|
24
24
|
__exportStar(require("./models/index"), exports);
|
|
25
25
|
__exportStar(require("./scene/index"), exports);
|
|
26
26
|
__exportStar(require("./shelly/index"), exports);
|
|
27
|
+
__exportStar(require("./tuya/index"), exports);
|
|
27
28
|
__exportStar(require("./zigbee/index"), exports);
|
|
28
29
|
__exportStar(require("./device-cluster"), exports);
|
|
29
30
|
__exportStar(require("./device-cluster-type"), exports);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TuyaGarageOpener = exports.TuyaDevice = void 0;
|
|
4
|
+
var tuyaDevice_1 = require("./tuyaDevice");
|
|
5
|
+
Object.defineProperty(exports, "TuyaDevice", { enumerable: true, get: function () { return tuyaDevice_1.TuyaDevice; } });
|
|
6
|
+
var tuyaGarageOpener_1 = require("./tuyaGarageOpener");
|
|
7
|
+
Object.defineProperty(exports, "TuyaGarageOpener", { enumerable: true, get: function () { return tuyaGarageOpener_1.TuyaGarageOpener; } });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IoBrokerBaseDevice } from '../IoBrokerBaseDevice';
|
|
2
|
+
import { iDisposable } from '../../services';
|
|
3
|
+
import { IoBrokerDeviceInfo } from '../IoBrokerDeviceInfo';
|
|
4
|
+
import { DeviceType } from '../deviceType';
|
|
5
|
+
export declare class TuyaDevice extends IoBrokerBaseDevice implements iDisposable {
|
|
6
|
+
private _lastUpdate;
|
|
7
|
+
get lastUpdate(): Date;
|
|
8
|
+
stateMap: Map<string, ioBroker.State>;
|
|
9
|
+
constructor(pInfo: IoBrokerDeviceInfo, pType: DeviceType);
|
|
10
|
+
update(idSplit: string[], state: ioBroker.State, initial?: boolean, pOverride?: boolean): void;
|
|
11
|
+
dispose(): void;
|
|
12
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TuyaDevice = void 0;
|
|
4
|
+
const IoBrokerBaseDevice_1 = require("../IoBrokerBaseDevice");
|
|
5
|
+
const models_1 = require("../../../models");
|
|
6
|
+
class TuyaDevice extends IoBrokerBaseDevice_1.IoBrokerBaseDevice {
|
|
7
|
+
get lastUpdate() {
|
|
8
|
+
return this._lastUpdate;
|
|
9
|
+
}
|
|
10
|
+
constructor(pInfo, pType) {
|
|
11
|
+
super(pInfo, pType);
|
|
12
|
+
this._lastUpdate = new Date(0);
|
|
13
|
+
this.stateMap = new Map();
|
|
14
|
+
}
|
|
15
|
+
update(idSplit, state, initial = false, pOverride = false) {
|
|
16
|
+
this.log(models_1.LogLevel.DeepTrace, `Tuya: ${initial ? 'Initiales ' : ''}Update: ID: ${idSplit.join('.')} JSON: ${JSON.stringify(state)}`);
|
|
17
|
+
if (!pOverride) {
|
|
18
|
+
this.log(models_1.LogLevel.Warn, `Keine Update Überschreibung:\n\tID: ${idSplit.join('.')}\n\tData: ${JSON.stringify(state)}`);
|
|
19
|
+
}
|
|
20
|
+
const stateLastUpdate = new Date(state.ts);
|
|
21
|
+
if (stateLastUpdate > this._lastUpdate) {
|
|
22
|
+
this._lastUpdate = stateLastUpdate;
|
|
23
|
+
}
|
|
24
|
+
this.stateMap.set(idSplit[3], state);
|
|
25
|
+
const individualCallbacks = this.individualStateCallbacks.get(idSplit[3]);
|
|
26
|
+
if (individualCallbacks !== undefined) {
|
|
27
|
+
for (const cb of individualCallbacks) {
|
|
28
|
+
cb(state.val);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
dispose() {
|
|
33
|
+
// Nothing yet
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.TuyaDevice = TuyaDevice;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TuyaDevice } from './tuyaDevice';
|
|
2
|
+
import { GarageDoorOpenerSettings } from '../../../models';
|
|
3
|
+
import { IoBrokerDeviceInfo } from '../IoBrokerDeviceInfo';
|
|
4
|
+
import { iGarageDoorOpener } from '../baseDeviceInterfaces';
|
|
5
|
+
export declare class TuyaGarageOpener extends TuyaDevice implements iGarageDoorOpener {
|
|
6
|
+
settings: GarageDoorOpenerSettings;
|
|
7
|
+
private readonly _switchId;
|
|
8
|
+
private readonly _doorContactId;
|
|
9
|
+
private _isClosed;
|
|
10
|
+
private _switchState;
|
|
11
|
+
get isClosed(): boolean;
|
|
12
|
+
constructor(pInfo: IoBrokerDeviceInfo);
|
|
13
|
+
update(idSplit: string[], state: ioBroker.State, initial?: boolean): void;
|
|
14
|
+
open(): void;
|
|
15
|
+
close(): void;
|
|
16
|
+
trigger(): void;
|
|
17
|
+
dispose(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TuyaGarageOpener = void 0;
|
|
4
|
+
const tuyaDevice_1 = require("./tuyaDevice");
|
|
5
|
+
const models_1 = require("../../../models");
|
|
6
|
+
const deviceType_1 = require("../deviceType");
|
|
7
|
+
const DeviceCapability_1 = require("../DeviceCapability");
|
|
8
|
+
class TuyaGarageOpener extends tuyaDevice_1.TuyaDevice {
|
|
9
|
+
get isClosed() {
|
|
10
|
+
return this._isClosed;
|
|
11
|
+
}
|
|
12
|
+
constructor(pInfo) {
|
|
13
|
+
super(pInfo, deviceType_1.DeviceType.TuyaGarageDoorOpener);
|
|
14
|
+
this.settings = new models_1.GarageDoorOpenerSettings();
|
|
15
|
+
this._isClosed = true;
|
|
16
|
+
this._switchState = false;
|
|
17
|
+
this.deviceCapabilities.push(DeviceCapability_1.DeviceCapability.garageDoorOpener);
|
|
18
|
+
this._switchId = `${this.info.fullID}.1`;
|
|
19
|
+
this._doorContactId = `${this.info.fullID}.3`;
|
|
20
|
+
}
|
|
21
|
+
update(idSplit, state, initial = false) {
|
|
22
|
+
const fullId = idSplit.join('.');
|
|
23
|
+
switch (fullId) {
|
|
24
|
+
case this._doorContactId:
|
|
25
|
+
if (this.settings.invertSensor) {
|
|
26
|
+
this._isClosed = state.val === true;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
this._isClosed = state.val === false;
|
|
30
|
+
}
|
|
31
|
+
break;
|
|
32
|
+
case this._switchId:
|
|
33
|
+
this._switchState = state.val === true;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
super.update(idSplit, state, initial, true);
|
|
37
|
+
}
|
|
38
|
+
open() {
|
|
39
|
+
if (!this.isClosed) {
|
|
40
|
+
this.log(models_1.LogLevel.Info, 'Garage door is already open');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
this.log(models_1.LogLevel.Info, 'Opening garage door');
|
|
44
|
+
this.setState(this._switchId, !this.settings.invertSensor);
|
|
45
|
+
}
|
|
46
|
+
close() {
|
|
47
|
+
if (this.isClosed) {
|
|
48
|
+
this.log(models_1.LogLevel.Info, 'Garage door is already closed');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.log(models_1.LogLevel.Info, 'Closing garage door');
|
|
52
|
+
this.setState(this._switchId, this.settings.invertSensor);
|
|
53
|
+
}
|
|
54
|
+
trigger() {
|
|
55
|
+
this.setState(this._switchId, !this._switchState);
|
|
56
|
+
}
|
|
57
|
+
dispose() {
|
|
58
|
+
super.dispose();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.TuyaGarageOpener = TuyaGarageOpener;
|
|
@@ -40,16 +40,12 @@ export declare class IOBrokerConnection implements iDisposable {
|
|
|
40
40
|
* Getter enums
|
|
41
41
|
* @return {unknown}
|
|
42
42
|
*/
|
|
43
|
-
get enums():
|
|
44
|
-
[groupName: string]: Record<string, ioBroker.Enum>;
|
|
45
|
-
} | undefined;
|
|
43
|
+
get enums(): Record<string, ioBroker.EnumObject> | undefined;
|
|
46
44
|
/**
|
|
47
45
|
* Setter enums
|
|
48
46
|
* @param {unknown} value
|
|
49
47
|
*/
|
|
50
|
-
set enums(value:
|
|
51
|
-
[groupName: string]: Record<string, ioBroker.Enum>;
|
|
52
|
-
} | undefined);
|
|
48
|
+
set enums(value: Record<string, ioBroker.EnumObject> | undefined);
|
|
53
49
|
private _isAuthDone;
|
|
54
50
|
/**
|
|
55
51
|
* Getter isAuthDone
|
|
@@ -129,7 +125,6 @@ export declare class IOBrokerConnection implements iDisposable {
|
|
|
129
125
|
getObjects(useCache: boolean, callback: ioBroker.GetObjectsCallback): void;
|
|
130
126
|
getChildren(id: string, useCache: boolean, callback: (err?: Error | null, children?: string[]) => void, ...args: unknown[]): void;
|
|
131
127
|
getObject(id: string, useCache: boolean, callback: ioBroker.GetObjectCallback): void;
|
|
132
|
-
getEnums(enumName: string, useCache: boolean, callback: ioBroker.GetEnumsCallback): void;
|
|
133
128
|
getSyncTime(): Date;
|
|
134
129
|
addObject(objId: unknown, obj: unknown, callback: unknown): void;
|
|
135
130
|
delObject(objId: string): void;
|
|
@@ -949,42 +949,6 @@ class IOBrokerConnection {
|
|
|
949
949
|
return callback(null, obj);
|
|
950
950
|
});
|
|
951
951
|
}
|
|
952
|
-
getEnums(enumName, useCache, callback) {
|
|
953
|
-
// If cache used
|
|
954
|
-
if (this._useStorage && useCache) {
|
|
955
|
-
if (typeof storage !== 'undefined') {
|
|
956
|
-
// @ts-ignore
|
|
957
|
-
const enums = this._enums || storage.get('enums');
|
|
958
|
-
if (enums)
|
|
959
|
-
return callback(null, enums);
|
|
960
|
-
}
|
|
961
|
-
else if (this._enums) {
|
|
962
|
-
return callback(null, this._enums);
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
if (this._type === 'local') {
|
|
966
|
-
return callback(null, {});
|
|
967
|
-
}
|
|
968
|
-
enumName = enumName ? enumName + '.' : '';
|
|
969
|
-
// Read all enums
|
|
970
|
-
this._socket.emit('getObjectView', 'system', 'enum', { startkey: 'enum.' + enumName, endkey: 'enum.' + enumName + '\u9999' }, (err, res) => {
|
|
971
|
-
if (err) {
|
|
972
|
-
callback(err);
|
|
973
|
-
return;
|
|
974
|
-
}
|
|
975
|
-
const enums = {};
|
|
976
|
-
for (const row of res.rows) {
|
|
977
|
-
if (row.value !== null) {
|
|
978
|
-
enums[row.id] = row.value;
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
if (this._useStorage && typeof storage !== 'undefined') {
|
|
982
|
-
// @ts-ignore
|
|
983
|
-
storage.set('enums', enums);
|
|
984
|
-
}
|
|
985
|
-
callback(null, enums);
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
952
|
// return time when the objects were synchronized
|
|
989
953
|
getSyncTime() {
|
|
990
954
|
if (this._useStorage && typeof storage !== 'undefined') {
|
|
@@ -92,6 +92,7 @@ export declare class API {
|
|
|
92
92
|
* @returns {Error | null} In case it failed the Error containing the reason
|
|
93
93
|
*/
|
|
94
94
|
static startScene(deviceId: string, turnOffTimeout?: number): Error | null;
|
|
95
|
+
static switchGarageDoor(deviceId: string, open: boolean): Error | null;
|
|
95
96
|
/**
|
|
96
97
|
* Changes the settings of a given device
|
|
97
98
|
* @param {string} deviceId The id of the device to change the settings
|
|
@@ -232,6 +232,22 @@ class API {
|
|
|
232
232
|
d.startScene(turnOffTimeout);
|
|
233
233
|
return null;
|
|
234
234
|
}
|
|
235
|
+
static switchGarageDoor(deviceId, open) {
|
|
236
|
+
const d = this.getDevice(deviceId);
|
|
237
|
+
if (d === undefined) {
|
|
238
|
+
return new Error(`Device with ID ${deviceId} not found`);
|
|
239
|
+
}
|
|
240
|
+
if (!d.deviceCapabilities.includes(DeviceCapability_1.DeviceCapability.garageDoorOpener)) {
|
|
241
|
+
return new Error(`Device with ID ${deviceId} is no Garage Door Opener`);
|
|
242
|
+
}
|
|
243
|
+
if (open) {
|
|
244
|
+
d.open();
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
d.close();
|
|
248
|
+
}
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
235
251
|
/**
|
|
236
252
|
* Changes the settings of a given device
|
|
237
253
|
* @param {string} deviceId The id of the device to change the settings
|
|
@@ -185,6 +185,10 @@ class Utils {
|
|
|
185
185
|
const newKey = lowerKey.replace('map', 'dict');
|
|
186
186
|
const dict = {};
|
|
187
187
|
const map = value;
|
|
188
|
+
if (typeof map.keys !== 'function') {
|
|
189
|
+
log_service_1.ServerLogService.writeLog(models_1.LogLevel.Error, `Map ${currentKey}.${lowerKey} is not a map`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
188
192
|
for (const mapName of map.keys()) {
|
|
189
193
|
dict[mapName] = lodash_1.default.isObject(map.get(mapName))
|
|
190
194
|
? this.deepOmit(map.get(mapName), keysToOmit, level + 1, `${currentKey}.${lowerKey}.${mapName}`)
|