mirror of
https://github.com/koush/scrypted.git
synced 2026-09-17 09:10:38 +01:00
reolink: Add polling to reolink discovered devices (#1744)
* Add polling to reolink discovered devices * Don't poll battery devices * Logic moved to forever cycle * Poll battery devices only when they wake up * Wrap each poll in try/catch --------- Co-authored-by: Gianluca Ruocco <gianluca.ruocco@xarvio.com>
This commit is contained in:
@@ -14,7 +14,6 @@ class ReolinkCameraSiren extends ScryptedDeviceBase implements OnOff {
|
||||
|
||||
constructor(public camera: ReolinkCamera, nativeId: string) {
|
||||
super(nativeId);
|
||||
this.on = false;
|
||||
}
|
||||
|
||||
async turnOff() {
|
||||
@@ -53,7 +52,6 @@ class ReolinkCameraSiren extends ScryptedDeviceBase implements OnOff {
|
||||
class ReolinkCameraFloodlight extends ScryptedDeviceBase implements OnOff, Brightness {
|
||||
constructor(public camera: ReolinkCamera, nativeId: string) {
|
||||
super(nativeId);
|
||||
this.on = false;
|
||||
}
|
||||
|
||||
async setBrightness(brightness: number): Promise<void> {
|
||||
@@ -81,7 +79,6 @@ class ReolinkCameraFloodlight extends ScryptedDeviceBase implements OnOff, Brigh
|
||||
class ReolinkCameraPirSensor extends ScryptedDeviceBase implements OnOff {
|
||||
constructor(public camera: ReolinkCamera, nativeId: string) {
|
||||
super(nativeId);
|
||||
this.on = false;
|
||||
}
|
||||
|
||||
async turnOff() {
|
||||
@@ -240,12 +237,63 @@ class ReolinkCamera extends RtspSmartCamera implements Camera, DeviceProvider, R
|
||||
await this.updateAbilities();
|
||||
await this.updateDevice();
|
||||
await this.reportDevices();
|
||||
this.startDevicesStatesPolling();
|
||||
})()
|
||||
.catch(e => {
|
||||
this.console.log('device refresh failed', e);
|
||||
});
|
||||
}
|
||||
|
||||
async pollDeviceStates() {
|
||||
try {
|
||||
const api = this.getClient();
|
||||
|
||||
try {
|
||||
if (this.hasFloodlight() && this.floodlight) {
|
||||
const { enabled } = await api.getWhiteLedState();
|
||||
|
||||
if (enabled !== this.floodlight.on) {
|
||||
this.floodlight.on = enabled;
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
|
||||
try {
|
||||
if (this.hasSiren() && this.siren) {
|
||||
const { enabled } = await api.getSiren();
|
||||
|
||||
if (enabled !== this.siren.on) {
|
||||
this.siren.on = enabled;
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
|
||||
try {
|
||||
if (this.hasPirSensor() && this.pirSensor) {
|
||||
const { enabled } = await api.getPirState();
|
||||
|
||||
if (enabled !== this.pirSensor.on) {
|
||||
this.pirSensor.on = enabled;
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
} catch (e) {
|
||||
this.console.error('Error in pollDeviceStates', e);
|
||||
}
|
||||
}
|
||||
|
||||
async startDevicesStatesPolling() {
|
||||
if (
|
||||
!this.hasBattery() &&
|
||||
(this.hasFloodlight() || this.hasSiren() || this.hasPirSensor())
|
||||
) {
|
||||
while (true) {
|
||||
await this.pollDeviceStates();
|
||||
await sleep(1000 * 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async getVideoTextOverlays(): Promise<Record<string, VideoTextOverlay>> {
|
||||
const client = this.getClient();
|
||||
const osd = await client.getOsd();
|
||||
@@ -458,6 +506,9 @@ class ReolinkCamera extends RtspSmartCamera implements Camera, DeviceProvider, R
|
||||
|
||||
if (sleeping !== this.sleeping) {
|
||||
this.sleeping = sleeping;
|
||||
if (!sleeping) {
|
||||
await this.pollDeviceStates();
|
||||
}
|
||||
}
|
||||
if (batteryPercent !== this.batteryLevel) {
|
||||
this.batteryLevel = batteryPercent;
|
||||
|
||||
@@ -476,6 +476,31 @@ export class ReolinkCameraClient {
|
||||
}
|
||||
}
|
||||
|
||||
async getSiren() {
|
||||
const url = new URL(`http://${this.host}/api.cgi`);
|
||||
|
||||
const body = [{
|
||||
cmd: 'GetAudioAlarmV20',
|
||||
action: 0,
|
||||
param: { channel: this.channelId }
|
||||
}];
|
||||
|
||||
const response = await this.requestWithLogin({
|
||||
url,
|
||||
method: 'POST',
|
||||
responseType: 'json',
|
||||
}, this.createReadable(body));
|
||||
|
||||
const error = response.body?.[0]?.error;
|
||||
if (error) {
|
||||
this.console.error('error during call to getSiren', JSON.stringify(body), error);
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: response.body?.[0]?.value?.Audio?.enable === 1
|
||||
};
|
||||
}
|
||||
|
||||
async setSiren(on: boolean, duration?: number) {
|
||||
const url = new URL(`http://${this.host}/api.cgi`);
|
||||
const params = url.searchParams;
|
||||
@@ -515,6 +540,31 @@ export class ReolinkCameraClient {
|
||||
};
|
||||
}
|
||||
|
||||
async getWhiteLedState() {
|
||||
const url = new URL(`http://${this.host}/api.cgi`);
|
||||
|
||||
const body = [{
|
||||
cmd: 'GetWhiteLed',
|
||||
action: 0,
|
||||
param: { channel: this.channelId }
|
||||
}];
|
||||
|
||||
const response = await this.requestWithLogin({
|
||||
url,
|
||||
method: 'POST',
|
||||
responseType: 'json',
|
||||
}, this.createReadable(body));
|
||||
|
||||
const error = response.body?.[0]?.error;
|
||||
if (error) {
|
||||
this.console.error('error during call to getWhiteLedState', JSON.stringify(body), error);
|
||||
}
|
||||
|
||||
return {
|
||||
enabled: response.body?.[0]?.value?.WhiteLed?.state === 1
|
||||
};
|
||||
}
|
||||
|
||||
async setWhiteLedState(on?: boolean, brightness?: number) {
|
||||
const url = new URL(`http://${this.host}/api.cgi`);
|
||||
|
||||
@@ -608,7 +658,7 @@ export class ReolinkCameraClient {
|
||||
};
|
||||
}
|
||||
|
||||
async getPirState(on?: boolean) {
|
||||
async getPirState() {
|
||||
const url = new URL(`http://${this.host}/api.cgi`);
|
||||
|
||||
const body = [{
|
||||
@@ -625,10 +675,13 @@ export class ReolinkCameraClient {
|
||||
|
||||
const error = response.body?.[0]?.error;
|
||||
if (error) {
|
||||
this.console.error('error during call to setWhiteLedState', JSON.stringify(body), error);
|
||||
this.console.error('error during call to getPirState', JSON.stringify(body), error);
|
||||
}
|
||||
|
||||
return response.body?.[0]?.value?.pirInfo;
|
||||
return {
|
||||
enabled: response.body?.[0]?.value?.pirInfo?.enable === 1,
|
||||
state: response.body?.[0]?.value?.pirInfo
|
||||
};
|
||||
}
|
||||
|
||||
async setPirState(on: boolean) {
|
||||
@@ -637,7 +690,7 @@ export class ReolinkCameraClient {
|
||||
const currentPir = await this.getPirState();
|
||||
const newState = on ? 1 : 0;
|
||||
|
||||
if (!currentPir || currentPir.enable === newState) {
|
||||
if (!currentPir || currentPir.state?.enable === newState) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user