@homebridge-plugins/homebridge-eufy-security 0.0.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 +5 -0
- package/FUNDING.yml +1 -0
- package/LICENSE +176 -0
- package/README.md +67 -0
- package/config.schema.json +6 -0
- package/dist/accessories/AutoSyncStationAccessory.js +156 -0
- package/dist/accessories/AutoSyncStationAccessory.js.map +1 -0
- package/dist/accessories/BaseAccessory.js +247 -0
- package/dist/accessories/BaseAccessory.js.map +1 -0
- package/dist/accessories/CameraAccessory.js +431 -0
- package/dist/accessories/CameraAccessory.js.map +1 -0
- package/dist/accessories/Device.js +67 -0
- package/dist/accessories/Device.js.map +1 -0
- package/dist/accessories/EntrySensorAccessory.js +48 -0
- package/dist/accessories/EntrySensorAccessory.js.map +1 -0
- package/dist/accessories/LockAccessory.js +142 -0
- package/dist/accessories/LockAccessory.js.map +1 -0
- package/dist/accessories/MotionSensorAccessory.js +48 -0
- package/dist/accessories/MotionSensorAccessory.js.map +1 -0
- package/dist/accessories/SmartDropAccessory.js +145 -0
- package/dist/accessories/SmartDropAccessory.js.map +1 -0
- package/dist/accessories/StationAccessory.js +371 -0
- package/dist/accessories/StationAccessory.js.map +1 -0
- package/dist/config.js +25 -0
- package/dist/config.js.map +1 -0
- package/dist/controller/LocalLivestreamManager.js +116 -0
- package/dist/controller/LocalLivestreamManager.js.map +1 -0
- package/dist/controller/recordingDelegate.js +208 -0
- package/dist/controller/recordingDelegate.js.map +1 -0
- package/dist/controller/snapshotDelegate.js +345 -0
- package/dist/controller/snapshotDelegate.js.map +1 -0
- package/dist/controller/streamingDelegate.js +345 -0
- package/dist/controller/streamingDelegate.js.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.js +2 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/media/Snapshot-Unavailable.png +0 -0
- package/dist/media/Snapshot-Unavailable.xcf +0 -0
- package/dist/media/Snapshot-black.png +0 -0
- package/dist/media/camera-disabled.png +0 -0
- package/dist/media/camera-offline.png +0 -0
- package/dist/media/media/Snapshot-Unavailable.png +0 -0
- package/dist/media/media/Snapshot-Unavailable.xcf +0 -0
- package/dist/media/media/Snapshot-black.png +0 -0
- package/dist/media/media/camera-disabled.png +0 -0
- package/dist/media/media/camera-offline.png +0 -0
- package/dist/platform.js +716 -0
- package/dist/platform.js.map +1 -0
- package/dist/settings.js +38 -0
- package/dist/settings.js.map +1 -0
- package/dist/utils/Talkback.js +92 -0
- package/dist/utils/Talkback.js.map +1 -0
- package/dist/utils/accessoriesStore.js +206 -0
- package/dist/utils/accessoriesStore.js.map +1 -0
- package/dist/utils/configTypes.js +35 -0
- package/dist/utils/configTypes.js.map +1 -0
- package/dist/utils/ffmpeg.js +843 -0
- package/dist/utils/ffmpeg.js.map +1 -0
- package/dist/utils/interfaces.js +8 -0
- package/dist/utils/interfaces.js.map +1 -0
- package/dist/utils/utils.js +44 -0
- package/dist/utils/utils.js.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/eslint.config.mjs +18 -0
- package/homebridge-eufy-security.png +0 -0
- package/homebridge-ui/public/app.js +225 -0
- package/homebridge-ui/public/assets/devices/4g_lte_starlight_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/BATTERY_DOORBELL_C30.png +0 -0
- package/homebridge-ui/public/assets/devices/BATTERY_DOORBELL_C31.png +0 -0
- package/homebridge-ui/public/assets/devices/batterydoorbell1080p_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/batterydoorbell2kdual_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/batterydoorbell_e340_large.png +0 -0
- package/homebridge-ui/public/assets/devices/eufy-security-client.png +0 -0
- package/homebridge-ui/public/assets/devices/eufycam2_large.png +0 -0
- package/homebridge-ui/public/assets/devices/eufycam2c_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam2cpro_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam2pro_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam3_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam3c_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycam3pro_large.png +0 -0
- package/homebridge-ui/public/assets/devices/eufycam_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/eufycame330_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/floodlight2_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/floodlight2pro_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/floodlight_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/floodlightcame340_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/garage_camera_t8452_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/homebase2_large.png +0 -0
- package/homebridge-ui/public/assets/devices/homebase3_large.png +0 -0
- package/homebridge-ui/public/assets/devices/homebase_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/homebasemini_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamC210_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamC220_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamE30_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamc120_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcammini_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/indoorcamp24_large.png +0 -0
- package/homebridge-ui/public/assets/devices/indoorcams350_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/keypad_large.png +0 -0
- package/homebridge-ui/public/assets/devices/minibase_chime_T8023_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/motionsensor_large.png +0 -0
- package/homebridge-ui/public/assets/devices/sensor_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartdrop_t8790_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8500_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8500_wifibridge_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8503_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8504_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_t8510P_t8520P_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_and_wifi_t8502_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_and_wifi_t8506_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_and_wifi_t8520_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_t8510_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_touch_t8510_wifibridge_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/smartlock_video_t8530_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartlockwifibridge_t8021_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/smartsafe_s10_t7400_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smartsafe_s12_t7401_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smarttrack_card_t87B2_large.png +0 -0
- package/homebridge-ui/public/assets/devices/smarttrack_link_t87B0_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solocamc210_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocamc35_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solocame20_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocame30_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solocame40_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocaml20_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocams220_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solocams340_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solocams40_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/soloindoorcamc24_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/solooutdoorcamc22_large.png +0 -0
- package/homebridge-ui/public/assets/devices/solooutdoorcamc24_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/unknown.png +0 -0
- package/homebridge-ui/public/assets/devices/walllight_s100_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/walllight_s120_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/wireddoorbell1080p_large.jpg +0 -0
- package/homebridge-ui/public/assets/devices/wireddoorbell2k_large.png +0 -0
- package/homebridge-ui/public/assets/devices/wireddoorbelldual_large.jpg +0 -0
- package/homebridge-ui/public/assets/icons/attach.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_0.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_1.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_2.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_3.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_4.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_5.svg +1 -0
- package/homebridge-ui/public/assets/icons/battery_6.svg +1 -0
- package/homebridge-ui/public/assets/icons/bolt.svg +1 -0
- package/homebridge-ui/public/assets/icons/bug-report.svg +1 -0
- package/homebridge-ui/public/assets/icons/copy.svg +1 -0
- package/homebridge-ui/public/assets/icons/delete.svg +1 -0
- package/homebridge-ui/public/assets/icons/download.svg +1 -0
- package/homebridge-ui/public/assets/icons/info.svg +1 -0
- package/homebridge-ui/public/assets/icons/inventory.svg +1 -0
- package/homebridge-ui/public/assets/icons/refresh.svg +1 -0
- package/homebridge-ui/public/assets/icons/satellite_alt.svg +1 -0
- package/homebridge-ui/public/assets/icons/settings.svg +1 -0
- package/homebridge-ui/public/assets/icons/settings_backup_restore.svg +1 -0
- package/homebridge-ui/public/assets/icons/solar_power.svg +1 -0
- package/homebridge-ui/public/assets/icons/warning.svg +1 -0
- package/homebridge-ui/public/components/device-card.js +162 -0
- package/homebridge-ui/public/components/guard-modes.js +88 -0
- package/homebridge-ui/public/components/number-input.js +121 -0
- package/homebridge-ui/public/components/select.js +73 -0
- package/homebridge-ui/public/components/toggle.js +68 -0
- package/homebridge-ui/public/index.html +27 -0
- package/homebridge-ui/public/services/api.js +214 -0
- package/homebridge-ui/public/services/config.js +144 -0
- package/homebridge-ui/public/style.css +775 -0
- package/homebridge-ui/public/utils/countries.js +73 -0
- package/homebridge-ui/public/utils/device-images.js +89 -0
- package/homebridge-ui/public/utils/helpers.js +87 -0
- package/homebridge-ui/public/views/dashboard.js +226 -0
- package/homebridge-ui/public/views/device-detail.js +610 -0
- package/homebridge-ui/public/views/diagnostics.js +296 -0
- package/homebridge-ui/public/views/login.js +636 -0
- package/homebridge-ui/public/views/settings.js +192 -0
- package/homebridge-ui/public/views/unsupported-detail.js +296 -0
- package/homebridge-ui/server.js +1327 -0
- package/media/Snapshot-Unavailable.png +0 -0
- package/media/Snapshot-Unavailable.xcf +0 -0
- package/media/Snapshot-black.png +0 -0
- package/media/camera-disabled.png +0 -0
- package/media/camera-offline.png +0 -0
- package/package.json +64 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { BaseAccessory } from './BaseAccessory.js';
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
import { DeviceType, PropertyName, AlarmEvent, GuardMode } from 'eufy-security-client';
|
|
4
|
+
import { CHAR, SERV, log } from '../utils/utils.js';
|
|
5
|
+
export var HKGuardMode;
|
|
6
|
+
(function (HKGuardMode) {
|
|
7
|
+
HKGuardMode[HKGuardMode["STAY_ARM"] = 0] = "STAY_ARM";
|
|
8
|
+
HKGuardMode[HKGuardMode["AWAY_ARM"] = 1] = "AWAY_ARM";
|
|
9
|
+
HKGuardMode[HKGuardMode["NIGHT_ARM"] = 2] = "NIGHT_ARM";
|
|
10
|
+
HKGuardMode[HKGuardMode["DISARM"] = 3] = "DISARM";
|
|
11
|
+
})(HKGuardMode || (HKGuardMode = {}));
|
|
12
|
+
/**
|
|
13
|
+
* Platform Accessory
|
|
14
|
+
* An instance of this class is created for each accessory your platform registers
|
|
15
|
+
* Each accessory may expose multiple services of different service types.
|
|
16
|
+
*/
|
|
17
|
+
export class StationAccessory extends BaseAccessory {
|
|
18
|
+
stationConfig;
|
|
19
|
+
hasKeyPad = false;
|
|
20
|
+
modes;
|
|
21
|
+
alarm_triggered;
|
|
22
|
+
alarm_delayed;
|
|
23
|
+
alarm_delay_timeout;
|
|
24
|
+
guardModeChangeTimeout = { timeout: null, delay: 5000 };
|
|
25
|
+
constructor(platform, accessory, device) {
|
|
26
|
+
super(platform, accessory, device);
|
|
27
|
+
this.log.debug(`Constructed Station`);
|
|
28
|
+
this.hasKeyPad = this.device.hasDeviceWithType(DeviceType.KEYPAD);
|
|
29
|
+
this.log.debug(`has keypad:`, this.hasKeyPad);
|
|
30
|
+
this.stationConfig = this.getStationConfig();
|
|
31
|
+
this.modes = this.mappingHKEufy();
|
|
32
|
+
this.alarm_triggered = false;
|
|
33
|
+
this.alarm_delayed = false;
|
|
34
|
+
const validValues = [
|
|
35
|
+
CHAR.SecuritySystemTargetState.AWAY_ARM,
|
|
36
|
+
CHAR.SecuritySystemTargetState.STAY_ARM,
|
|
37
|
+
CHAR.SecuritySystemTargetState.DISARM,
|
|
38
|
+
];
|
|
39
|
+
const SecuritySettings = [
|
|
40
|
+
PropertyName.StationHomeSecuritySettings,
|
|
41
|
+
PropertyName.StationAwaySecuritySettings,
|
|
42
|
+
PropertyName.StationOffSecuritySettings,
|
|
43
|
+
PropertyName.StationCustom1SecuritySettings,
|
|
44
|
+
PropertyName.StationCustom2SecuritySettings,
|
|
45
|
+
PropertyName.StationCustom3SecuritySettings,
|
|
46
|
+
];
|
|
47
|
+
SecuritySettings.forEach(item => {
|
|
48
|
+
if (this.device.hasPropertyValue(item) && this.getPropertyValue(item) !== '') {
|
|
49
|
+
this.log.debug(`- ${item} :`, this.getPropertyValue(item));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
// if (this.stationConfig.hkNight) {
|
|
53
|
+
validValues.push(CHAR.SecuritySystemTargetState.NIGHT_ARM);
|
|
54
|
+
// }
|
|
55
|
+
this.registerCharacteristic({
|
|
56
|
+
serviceType: SERV.SecuritySystem,
|
|
57
|
+
characteristicType: CHAR.SecuritySystemCurrentState,
|
|
58
|
+
getValue: () => this.handleSecuritySystemCurrentStateGet(),
|
|
59
|
+
onValue: (service, characteristic) => {
|
|
60
|
+
this.device.on('current mode', (station, currentMode) => {
|
|
61
|
+
this.onStationCurrentModePushNotification(characteristic, currentMode);
|
|
62
|
+
});
|
|
63
|
+
this.device.on('alarm event', (station, alarmEvent) => this.onStationAlarmEventPushNotification(characteristic, alarmEvent));
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
this.registerCharacteristic({
|
|
67
|
+
serviceType: SERV.SecuritySystem,
|
|
68
|
+
characteristicType: CHAR.SecuritySystemTargetState,
|
|
69
|
+
getValue: () => this.handleSecuritySystemTargetStateGet(),
|
|
70
|
+
setValue: (value) => this.handleSecuritySystemTargetStateSet(value),
|
|
71
|
+
onValue: (service, characteristic) => {
|
|
72
|
+
this.device.on('guard mode', (station, guardMode) => {
|
|
73
|
+
this.onStationGuardModePushNotification(characteristic, station, guardMode);
|
|
74
|
+
});
|
|
75
|
+
this.device.on('alarm arm delay event', this.onStationAlarmDelayedEvent.bind(this));
|
|
76
|
+
this.device.on('alarm armed event', this.onStationAlarmArmedEvent.bind(this));
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
this.getService(SERV.SecuritySystem)
|
|
80
|
+
.getCharacteristic(CHAR.SecuritySystemTargetState)
|
|
81
|
+
.setProps({ validValues });
|
|
82
|
+
this.registerCharacteristic({
|
|
83
|
+
serviceType: SERV.Switch,
|
|
84
|
+
characteristicType: CHAR.On,
|
|
85
|
+
name: this.accessory.displayName + ' Siren',
|
|
86
|
+
getValue: () => this.handleManualTriggerSwitchStateGet(),
|
|
87
|
+
setValue: (value) => this.handleManualTriggerSwitchStateSet(value),
|
|
88
|
+
});
|
|
89
|
+
this.pruneUnusedServices();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get the current value of the "propertyName" characteristic
|
|
93
|
+
*/
|
|
94
|
+
getPropertyValue(propertyName) {
|
|
95
|
+
return this.device.getPropertyValue(propertyName);
|
|
96
|
+
}
|
|
97
|
+
async setPropertyValue(propertyName, value) {
|
|
98
|
+
await this.platform.eufyClient.setStationProperty(this.SN, propertyName, value);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Gets the station configuration based on several possible sources.
|
|
102
|
+
* Priority is given to custom configurations (if available), then falls back to global configs,
|
|
103
|
+
* and lastly uses default values if neither custom nor global configs are set.
|
|
104
|
+
*
|
|
105
|
+
* @returns {StationConfig} The final configuration settings for the station
|
|
106
|
+
*/
|
|
107
|
+
getStationConfig() {
|
|
108
|
+
// Find the station configuration based on the serial number, if it exists
|
|
109
|
+
const stationConfig = this.platform.config.stations?.find((station) => station.serialNumber === this.SN);
|
|
110
|
+
// Debug log to show the retrieved station configuration
|
|
111
|
+
this.log.debug(`Config:`, stationConfig);
|
|
112
|
+
// Initialize the config object with prioritized values
|
|
113
|
+
const config = {
|
|
114
|
+
// For each setting (e.g., hkHome), check if it is defined in the custom config,
|
|
115
|
+
// if not, check the global config, and as a last resort, use the default value
|
|
116
|
+
hkHome: stationConfig?.hkHome ?? this.platform.config.hkHome,
|
|
117
|
+
hkAway: stationConfig?.hkAway ?? this.platform.config.hkAway,
|
|
118
|
+
hkNight: stationConfig?.hkNight ?? this.platform.config.hkNight,
|
|
119
|
+
// Default HomeKit mode for 'Off':
|
|
120
|
+
// - If a keypad is present, set to 6 (Special value)
|
|
121
|
+
// - Otherwise, set to 63 (Default value)
|
|
122
|
+
hkOff: stationConfig?.hkOff ?? this.hasKeyPad ? 6 : this.platform.config.hkOff,
|
|
123
|
+
// Use optional chaining to safely access manualTriggerModes and manualAlarmSeconds
|
|
124
|
+
manualTriggerModes: stationConfig?.manualTriggerModes ?? [],
|
|
125
|
+
manualAlarmSeconds: stationConfig?.manualAlarmSeconds ?? 30,
|
|
126
|
+
};
|
|
127
|
+
// Log the manual trigger modes for debugging purposes
|
|
128
|
+
this.log.debug(`manual alarm will be triggered only in these hk modes:\r${config.manualTriggerModes}`);
|
|
129
|
+
// Return the final configuration object
|
|
130
|
+
return config;
|
|
131
|
+
}
|
|
132
|
+
mappingHKEufy() {
|
|
133
|
+
// Initialize the modes array with HomeKit and Eufy mode mappings
|
|
134
|
+
const modes = [
|
|
135
|
+
{ hk: 0, eufy: this.stationConfig.hkHome },
|
|
136
|
+
{ hk: 1, eufy: this.stationConfig.hkAway },
|
|
137
|
+
{ hk: 2, eufy: this.stationConfig.hkNight },
|
|
138
|
+
{ hk: 3, eufy: this.stationConfig.hkOff },
|
|
139
|
+
];
|
|
140
|
+
// Log the mapping for station modes for debugging purposes
|
|
141
|
+
this.log.debug(`Mapping for station modes:`, modes);
|
|
142
|
+
return modes;
|
|
143
|
+
}
|
|
144
|
+
onStationGuardModePushNotification(characteristic, station, guardMode) {
|
|
145
|
+
this.log.debug(`ON SecurityGuardMode: ${guardMode}`);
|
|
146
|
+
const homekitCurrentMode = this.convertEufytoHK(guardMode);
|
|
147
|
+
characteristic.updateValue(homekitCurrentMode);
|
|
148
|
+
}
|
|
149
|
+
onStationCurrentModePushNotification(characteristic, currentMode) {
|
|
150
|
+
if (this.guardModeChangeTimeout.timeout) {
|
|
151
|
+
// If there's an existing timeout, clear it
|
|
152
|
+
clearTimeout(this.guardModeChangeTimeout.timeout);
|
|
153
|
+
}
|
|
154
|
+
this.log.debug(`ON SecuritySystemCurrentState: ${currentMode}`);
|
|
155
|
+
const homekitCurrentMode = this.convertEufytoHK(currentMode);
|
|
156
|
+
characteristic.updateValue(homekitCurrentMode);
|
|
157
|
+
}
|
|
158
|
+
onStationAlarmEventPushNotification(characteristic, alarmEvent) {
|
|
159
|
+
let currentValue = this.device.getPropertyValue(PropertyName.StationCurrentMode);
|
|
160
|
+
if (alarmEvent === 0) {
|
|
161
|
+
// do not resset alarm if alarm was triggered manually
|
|
162
|
+
// since the alarm can only be triggered for 30 seconds for now (limitation of @homebridge-eufy-security/eufy-security-client)
|
|
163
|
+
// this would mean that the alarm is always reset after 30 seconds
|
|
164
|
+
// see here: https://github.com/bropat/@homebridge-eufy-security/eufy-security-client/issues/178
|
|
165
|
+
currentValue = -1;
|
|
166
|
+
}
|
|
167
|
+
switch (alarmEvent) {
|
|
168
|
+
case 2: // Alarm triggered by GSENSOR
|
|
169
|
+
case 3: // Alarm triggered by PIR
|
|
170
|
+
case 4: // Alarm triggered by EUFY_APP
|
|
171
|
+
case 6: // Alarm triggered by DOOR
|
|
172
|
+
case 7: // Alarm triggered by CAMERA_PIR
|
|
173
|
+
case 8: // Alarm triggered by MOTION_SENSOR
|
|
174
|
+
case 9: // Alarm triggered by CAMERA_GSENSOR
|
|
175
|
+
log.warn('ON StationAlarmEvent - ALARM TRIGGERED - alarmEvent:', AlarmEvent[alarmEvent]);
|
|
176
|
+
this.alarm_triggered = true;
|
|
177
|
+
characteristic.updateValue(CHAR.SecuritySystemCurrentState.ALARM_TRIGGERED); // Alarm !!!
|
|
178
|
+
break;
|
|
179
|
+
case 0: // Alarm off by Hub
|
|
180
|
+
case 15: // Alarm off by Keypad
|
|
181
|
+
case 16: // Alarm off by Eufy App
|
|
182
|
+
case 17: // Alarm off by HomeBase button
|
|
183
|
+
log.warn('ON StationAlarmEvent - ALARM OFF - alarmEvent:', AlarmEvent[alarmEvent]);
|
|
184
|
+
this.alarm_triggered = false;
|
|
185
|
+
if (currentValue !== -1) {
|
|
186
|
+
characteristic.updateValue(this.convertEufytoHK(currentValue)); // reset alarm state
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
default:
|
|
190
|
+
log.warn('ON StationAlarmEvent - ALARM UNKNOWN - alarmEvent:', AlarmEvent[alarmEvent]);
|
|
191
|
+
characteristic.updateValue(CHAR.StatusFault.GENERAL_FAULT);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
this.updateManuelTriggerButton(this.alarm_triggered);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Convert a HomeKit mode number to its corresponding Eufy mode number.
|
|
198
|
+
* Searches the `this.modes` array to find a matching HomeKit mode.
|
|
199
|
+
* Throws an error if a matching mode is not found.
|
|
200
|
+
*
|
|
201
|
+
* @param {number} hkMode - The HomeKit mode to convert
|
|
202
|
+
* @returns {number} The corresponding Eufy mode
|
|
203
|
+
* @throws {Error} If a matching mode is not found
|
|
204
|
+
*/
|
|
205
|
+
convertHKtoEufy(hkMode) {
|
|
206
|
+
const modeObj = this.modes.find((m) => m.hk === hkMode);
|
|
207
|
+
if (!modeObj) {
|
|
208
|
+
throw new Error(`${this.accessory.displayName} No matching Eufy mode found for HomeKit mode ${hkMode}`);
|
|
209
|
+
}
|
|
210
|
+
return modeObj.eufy;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Convert a Eufy mode number to its corresponding HomeKit mode number.
|
|
214
|
+
* Searches the `this.modes` array to find a matching Eufy mode.
|
|
215
|
+
* Throws an error if a matching mode is not found.
|
|
216
|
+
*
|
|
217
|
+
* @param {number} eufyMode - The Eufy mode to convert
|
|
218
|
+
* @returns {number} The corresponding HomeKit mode
|
|
219
|
+
* @throws {Error} If a matching mode is not found
|
|
220
|
+
*/
|
|
221
|
+
convertEufytoHK(eufyMode) {
|
|
222
|
+
const modeObj = this.modes.find((m) => m.eufy === eufyMode);
|
|
223
|
+
if (!modeObj) {
|
|
224
|
+
throw new Error(`${this.accessory.displayName} No matching HomeKit mode found for Eufy mode ${eufyMode}`);
|
|
225
|
+
}
|
|
226
|
+
return modeObj.hk;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Handle requests to get the current value of the 'Security System Current State' characteristic
|
|
230
|
+
*/
|
|
231
|
+
handleSecuritySystemCurrentStateGet() {
|
|
232
|
+
if (this.alarm_triggered) {
|
|
233
|
+
return CHAR.SecuritySystemCurrentState.ALARM_TRIGGERED;
|
|
234
|
+
}
|
|
235
|
+
return this.handleSecuritySystemTargetStateGet('handleSecuritySystemCurrentStateGets');
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Handle requests to get the current value of the 'Security System Target State' characteristic
|
|
239
|
+
*/
|
|
240
|
+
handleSecuritySystemTargetStateGet(stateCharacteristic = 'handleSecuritySystemTargetStateGet') {
|
|
241
|
+
try {
|
|
242
|
+
const currentValue = this.device.getPropertyValue(PropertyName.StationCurrentMode);
|
|
243
|
+
if (currentValue === -1) {
|
|
244
|
+
this.log.warn(`${stateCharacteristic}: Device state not initialized, returning safe default (DISARM)`);
|
|
245
|
+
return CHAR.SecuritySystemTargetState.DISARM;
|
|
246
|
+
}
|
|
247
|
+
this.log.debug(`GET StationCurrentMode: ${currentValue}`);
|
|
248
|
+
return this.convertEufytoHK(currentValue);
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
this.log.error(`${stateCharacteristic}: Failed to retrieve security system state`, error);
|
|
252
|
+
return CHAR.SecuritySystemTargetState.DISARM;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Handle requests to set the 'Security System Target State' characteristic
|
|
257
|
+
*/
|
|
258
|
+
handleSecuritySystemTargetStateSet(value) {
|
|
259
|
+
try {
|
|
260
|
+
this.alarm_triggered = false;
|
|
261
|
+
const NameMode = this.getGuardModeName(value);
|
|
262
|
+
this.log.debug(`SET StationGuardMode HomeKit: ${NameMode}`);
|
|
263
|
+
const mode = this.convertHKtoEufy(value);
|
|
264
|
+
if (isNaN(mode)) {
|
|
265
|
+
throw new Error(`${this.accessory.displayName}:
|
|
266
|
+
Could not convert guard mode value to valid number. Aborting guard mode change...'`);
|
|
267
|
+
}
|
|
268
|
+
this.log.debug(`SET StationGuardMode Eufy: ${GuardMode[mode]}(${mode})`);
|
|
269
|
+
this.log.info(`Request to change station guard mode to: ${NameMode}`);
|
|
270
|
+
// Call the device's setGuardMode method to initiate the action
|
|
271
|
+
this.device.setGuardMode(mode);
|
|
272
|
+
// Set a new timeout
|
|
273
|
+
this.guardModeChangeTimeout.timeout = setTimeout(() => {
|
|
274
|
+
// This code is executed when the timeout elapses, indicating that the action may not have completed yet.
|
|
275
|
+
// You can include a message indicating that the action is being retried.
|
|
276
|
+
this.log.warn(`Changing guard mode to ${NameMode} did not complete. Retry...'`);
|
|
277
|
+
// Call the device's setGuardMode method to initiate the action
|
|
278
|
+
this.device.setGuardMode(mode);
|
|
279
|
+
// Set a secondary timeout for retry, if needed
|
|
280
|
+
const retryTimeout = setTimeout(() => {
|
|
281
|
+
// This code is executed if the retry also times out, indicating a failure.
|
|
282
|
+
this.log.error(`Changing guard mode to ${NameMode} timed out!`);
|
|
283
|
+
}, this.guardModeChangeTimeout.delay);
|
|
284
|
+
// Store the retry timeout as part of guardModeChangeTimeout
|
|
285
|
+
this.guardModeChangeTimeout.timeout = retryTimeout;
|
|
286
|
+
}, this.guardModeChangeTimeout.delay);
|
|
287
|
+
this.updateManuelTriggerButton(false);
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
this.log.error(`Error Setting security mode! ${error}`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
handleManualTriggerSwitchStateGet() {
|
|
294
|
+
return this.alarm_triggered;
|
|
295
|
+
}
|
|
296
|
+
async handleManualTriggerSwitchStateSet(value) {
|
|
297
|
+
if (value) { // trigger alarm
|
|
298
|
+
try {
|
|
299
|
+
const currentValue = this.device.getPropertyValue(PropertyName.StationCurrentMode);
|
|
300
|
+
if (currentValue === -1) {
|
|
301
|
+
throw 'Something wrong with this device';
|
|
302
|
+
}
|
|
303
|
+
// check if alarm is allowed for this guard mode
|
|
304
|
+
// and alarm is not delayed
|
|
305
|
+
if (this.stationConfig.manualTriggerModes.indexOf(this.convertEufytoHK(currentValue)) !== -1 && !this.alarm_delayed) {
|
|
306
|
+
this.device.triggerStationAlarmSound(this.stationConfig.manualAlarmSeconds)
|
|
307
|
+
.then(() => log.debug(this.accessory.displayName, 'alarm manually triggered for ' + this.stationConfig.manualAlarmSeconds + ' seconds.'))
|
|
308
|
+
.catch(error => this.log.error(`alarm could not be manually triggered: ${error}`));
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
const message = this.alarm_delayed ?
|
|
312
|
+
'tried to trigger alarm, but the alarm delayed event was triggered beforehand.' :
|
|
313
|
+
'tried to trigger alarm, but the current station mode prevents the alarm from being triggered. ' +
|
|
314
|
+
'Please look in in the configuration if you want to change this behaviour.';
|
|
315
|
+
setTimeout(() => {
|
|
316
|
+
this.log.info(`${message}`);
|
|
317
|
+
this.updateManuelTriggerButton(false);
|
|
318
|
+
}, 1000);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
this.log.error(`handleSecuritySystemTargetStateGet: ${value}`);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else { // reset alarm
|
|
327
|
+
const resetPromise = this.device.resetStationAlarmSound();
|
|
328
|
+
if (resetPromise) {
|
|
329
|
+
resetPromise
|
|
330
|
+
.then(() => this.log.debug(`alarm manually reset`))
|
|
331
|
+
.catch(error => this.log.error(`alarm could not be reset: ${error}`));
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
this.log.warn(`resetStationAlarmSound returned undefined`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
onStationAlarmDelayedEvent(station, armDelay) {
|
|
339
|
+
this.log.debug(`alarm for this station will be delayed by ${armDelay} seconds.`);
|
|
340
|
+
this.alarm_delayed = true;
|
|
341
|
+
if (this.alarm_delay_timeout) {
|
|
342
|
+
clearTimeout(this.alarm_delay_timeout);
|
|
343
|
+
}
|
|
344
|
+
this.alarm_delay_timeout = setTimeout(() => {
|
|
345
|
+
this.log.debug(`alarm for this station is armed now (due to timeout).`);
|
|
346
|
+
this.alarm_delayed = false;
|
|
347
|
+
}, (armDelay + 1) * 1000);
|
|
348
|
+
}
|
|
349
|
+
onStationAlarmArmedEvent() {
|
|
350
|
+
this.log.debug(`alarm for this station is armed now.`);
|
|
351
|
+
this.alarm_delayed = false;
|
|
352
|
+
if (this.alarm_delay_timeout) {
|
|
353
|
+
clearTimeout(this.alarm_delay_timeout);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
getGuardModeName(value) {
|
|
357
|
+
try {
|
|
358
|
+
return `${HKGuardMode[value]}(${value})`;
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
this.log.error(`Error getting guard mode name! ${error}`);
|
|
362
|
+
return 'Unknown';
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
updateManuelTriggerButton(state) {
|
|
366
|
+
this.getService(SERV.Switch, this.accessory.displayName + ' Siren')
|
|
367
|
+
.getCharacteristic(CHAR.On)
|
|
368
|
+
.updateValue(state);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=StationAccessory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StationAccessory.js","sourceRoot":"","sources":["../../src/accessories/StationAccessory.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const DEFAULT_CONFIG_VALUES = {
|
|
2
|
+
platform: 'EufySecurity',
|
|
3
|
+
name: 'EufySecurity',
|
|
4
|
+
username: '',
|
|
5
|
+
password: '',
|
|
6
|
+
deviceName: 'MyPhone',
|
|
7
|
+
enableDetailedLogging: false,
|
|
8
|
+
omitLogFiles: false,
|
|
9
|
+
CameraMaxLivestreamDuration: 30,
|
|
10
|
+
pollingIntervalMinutes: 10,
|
|
11
|
+
hkHome: 1,
|
|
12
|
+
hkAway: 0,
|
|
13
|
+
hkNight: 3,
|
|
14
|
+
hkOff: 63,
|
|
15
|
+
ignoreStations: [],
|
|
16
|
+
ignoreDevices: [],
|
|
17
|
+
country: 'US',
|
|
18
|
+
stations: [],
|
|
19
|
+
cameras: [],
|
|
20
|
+
cleanCache: true,
|
|
21
|
+
ignoreMultipleDevicesWarning: false,
|
|
22
|
+
autoSyncStation: false,
|
|
23
|
+
enableEmbeddedPKCS1Support: false,
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAgCA,MAAM,CAAC,MAAM,qBAAqB,GAA+B;IAC/D,QAAQ,EAAE,cAAc;IACxB,IAAI,EAAE,cAAc;IACpB,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,SAAS;IACrB,qBAAqB,EAAE,KAAK;IAC5B,YAAY,EAAE,KAAK;IACnB,2BAA2B,EAAE,EAAE;IAC/B,sBAAsB,EAAE,EAAE;IAC1B,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,CAAC;IACT,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,EAAE;IACT,cAAc,EAAE,EAAE;IAClB,aAAa,EAAE,EAAE;IACjB,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,EAAE;IACZ,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,IAAI;IAChB,4BAA4B,EAAE,KAAK;IACnC,eAAe,EAAE,KAAK;IACtB,0BAA0B,EAAE,KAAK;CAClC,CAAC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { Deferred } from '../utils/utils.js';
|
|
2
|
+
const P2P_TIMEOUT_MS = 15_000;
|
|
3
|
+
const DUPLICATE_STREAM_GUARD_S = 5;
|
|
4
|
+
export class LocalLivestreamManager {
|
|
5
|
+
stationStream = null;
|
|
6
|
+
pending = null;
|
|
7
|
+
eufyClient;
|
|
8
|
+
log;
|
|
9
|
+
serialNumber;
|
|
10
|
+
constructor(camera) {
|
|
11
|
+
this.eufyClient = camera.platform.eufyClient;
|
|
12
|
+
this.serialNumber = camera.device.getSerial();
|
|
13
|
+
this.log = camera.log;
|
|
14
|
+
this.log.debug(`LocalLivestreamManager initialized for ${camera.device.getName()} (serial: ${this.serialNumber})`);
|
|
15
|
+
this.eufyClient.on('station livestream start', this.onStationLivestreamStart);
|
|
16
|
+
this.eufyClient.on('station livestream stop', this.onStationLivestreamStop);
|
|
17
|
+
}
|
|
18
|
+
/** Destroy active streams and reset state. */
|
|
19
|
+
destroyStreams() {
|
|
20
|
+
if (this.stationStream) {
|
|
21
|
+
this.stationStream.audiostream.unpipe();
|
|
22
|
+
this.stationStream.audiostream.destroy();
|
|
23
|
+
this.stationStream.videostream.unpipe();
|
|
24
|
+
this.stationStream.videostream.destroy();
|
|
25
|
+
this.stationStream = null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Return the active livestream, or start a new one. Concurrent callers share the same pending request. */
|
|
29
|
+
async getLocalLiveStream() {
|
|
30
|
+
if (this.stationStream) {
|
|
31
|
+
const runtime = ((Date.now() - this.stationStream.createdAt) / 1000).toFixed(1);
|
|
32
|
+
this.log.debug(`Reusing livestream started ${runtime}s ago.`);
|
|
33
|
+
return this.stationStream;
|
|
34
|
+
}
|
|
35
|
+
return this.startLocalLiveStream();
|
|
36
|
+
}
|
|
37
|
+
/** True when a P2P livestream is currently active. */
|
|
38
|
+
isStreamActive() {
|
|
39
|
+
return this.stationStream !== null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Requests a P2P livestream from the eufy station and waits for the
|
|
43
|
+
* 'station livestream start' event. If a start is already in progress,
|
|
44
|
+
* the caller piggy-backs on the existing promise instead of issuing a
|
|
45
|
+
* duplicate request.
|
|
46
|
+
*/
|
|
47
|
+
startLocalLiveStream() {
|
|
48
|
+
if (this.pending) {
|
|
49
|
+
this.log.debug('Livestream already starting — waiting on existing request.');
|
|
50
|
+
return this.pending.deferred.promise;
|
|
51
|
+
}
|
|
52
|
+
this.log.debug(`Starting station livestream for serial: ${this.serialNumber}...`);
|
|
53
|
+
const deferred = new Deferred();
|
|
54
|
+
const timer = setTimeout(() => {
|
|
55
|
+
this.log.error(`Livestream timeout: no P2P stream event received within ${P2P_TIMEOUT_MS / 1000}s for serial ${this.serialNumber}.`);
|
|
56
|
+
this.log.warn('If using a recent Node.js version, try enabling "Embedded PKCS1 Support" in the plugin settings.');
|
|
57
|
+
this.settlePending('reject', 'Livestream timeout — try enabling Embedded PKCS1 Support in settings.');
|
|
58
|
+
}, P2P_TIMEOUT_MS);
|
|
59
|
+
this.pending = { deferred, timer };
|
|
60
|
+
this.eufyClient.startStationLivestream(this.serialNumber).catch((err) => {
|
|
61
|
+
this.log.error(`startStationLivestream failed: ${err}`);
|
|
62
|
+
this.settlePending('reject', err);
|
|
63
|
+
});
|
|
64
|
+
return deferred.promise;
|
|
65
|
+
}
|
|
66
|
+
settlePending(action, payload) {
|
|
67
|
+
const p = this.pending;
|
|
68
|
+
if (!p)
|
|
69
|
+
return;
|
|
70
|
+
clearTimeout(p.timer);
|
|
71
|
+
this.pending = null;
|
|
72
|
+
if (action === 'resolve') {
|
|
73
|
+
p.deferred.resolve(payload);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
p.deferred.reject(payload instanceof Error ? payload : new Error(String(payload)));
|
|
77
|
+
this.stopLocalLiveStream();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
stopLocalLiveStream() {
|
|
81
|
+
this.log.debug('Stopping station livestream.');
|
|
82
|
+
this.eufyClient.stopStationLivestream(this.serialNumber).catch((err) => {
|
|
83
|
+
this.log.warn(`stopStationLivestream failed: ${err}`);
|
|
84
|
+
});
|
|
85
|
+
this.destroyStreams();
|
|
86
|
+
}
|
|
87
|
+
/** True when the event belongs to this camera instance. */
|
|
88
|
+
isOwnDevice(device) {
|
|
89
|
+
return device.getSerial() === this.serialNumber;
|
|
90
|
+
}
|
|
91
|
+
onStationLivestreamStop = (_station, device) => {
|
|
92
|
+
if (!this.isOwnDevice(device))
|
|
93
|
+
return;
|
|
94
|
+
this.log.debug(`Station livestream for ${device.getName()} has stopped.`);
|
|
95
|
+
this.destroyStreams();
|
|
96
|
+
};
|
|
97
|
+
onStationLivestreamStart = (station, device, metadata, videostream, audiostream) => {
|
|
98
|
+
if (!this.isOwnDevice(device))
|
|
99
|
+
return;
|
|
100
|
+
// Guard against duplicate events fired in quick succession.
|
|
101
|
+
if (this.stationStream) {
|
|
102
|
+
const elapsed = (Date.now() - this.stationStream.createdAt) / 1000;
|
|
103
|
+
if (elapsed < DUPLICATE_STREAM_GUARD_S) {
|
|
104
|
+
this.log.warn('Duplicate livestream event received — ignoring.');
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Tear down any prior stream before storing the new one.
|
|
109
|
+
this.destroyStreams();
|
|
110
|
+
this.log.debug(`${station.getName()} P2P livestream for ${device.getName()} started.`);
|
|
111
|
+
this.log.debug('Stream metadata:', JSON.stringify(metadata));
|
|
112
|
+
this.stationStream = { videostream, audiostream, createdAt: Date.now() };
|
|
113
|
+
this.settlePending('resolve', this.stationStream);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=LocalLivestreamManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalLivestreamManager.js","sourceRoot":"","sources":["../../src/controller/LocalLivestreamManager.ts"],"names":[],"mappings":"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"}
|