Skip to content

Commit

Permalink
Merge branch 'main' of github.com:koush/scrypted
Browse files Browse the repository at this point in the history
  • Loading branch information
koush committed Mar 19, 2023
2 parents a86fb12 + 407afa1 commit 35b5cdd
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 44 deletions.
7 changes: 6 additions & 1 deletion plugins/ring/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ Do not enable prebuffer on Ring cameras and doorbells.
### Other Devices
- Security Panel
- Location Modes
- Contact Sensor / Retrofit Alarm Zones / Tilt Sensor
- Contact Sensor
- Retrofit Alarm Zones
- Tilt Sensor
- Glassbreak Sensor
- Motion Sensor
- Outdoor Motion Sensor
- Flood / Freeze Sensor
- Water Sensor
- Mailbox Sensor
- Smart Locks

## Problems and Solutions
Expand Down
4 changes: 2 additions & 2 deletions plugins/ring/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion plugins/ring/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@
"got": "11.8.6",
"socket.io-client": "^2.5.0"
},
"version": "0.0.102"
"version": "0.0.103"
}
89 changes: 49 additions & 40 deletions plugins/ring/src/location.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,17 @@ class RingLock extends ScryptedDeviceBase implements Battery, Lock {
}

class RingSensor extends ScryptedDeviceBase implements TamperSensor, Battery, EntrySensor, MotionSensor, FloodSensor {
device: RingDevice;
data: RingDeviceData;

constructor(nativeId: string, device: RingDevice) {
super(nativeId);
this.device = device;
this.data = device.data;
this.updateState(device.data);

device.onData.subscribe(async (data: RingDeviceData) => {
this.data = data;
this.updateState(data);
});
}
Expand All @@ -54,9 +62,13 @@ class RingSensor extends ScryptedDeviceBase implements TamperSensor, Battery, En
this.tampered = data.tamperStatus === 'tamper';
this.batteryLevel = data.batteryLevel;
this.entryOpen = data.faulted;
this.motionDetected = data.faulted;
this.motionDetected = this.device.deviceType === RingDeviceType.BeamsMotionSensor ? data.motionStatus === 'faulted' : data.faulted;
this.flooded = data.flood?.faulted || data.faulted;
}

isBypassable() {
return (this.device.deviceType === RingDeviceType.ContactSensor || this.device.deviceType === RingDeviceType.RetrofitZone) && this.data.faulted;
}
}

export class RingLocationDevice extends ScryptedDeviceBase implements DeviceProvider, SecuritySystem {
Expand All @@ -68,39 +80,14 @@ export class RingLocationDevice extends ScryptedDeviceBase implements DeviceProv
super(nativeId);
this.location = location;

const updateLocationMode = (f: LocationMode) => {
let mode: SecuritySystemMode;
if (f === 'away')
mode = SecuritySystemMode.AwayArmed;
else if (f === 'home')
mode = SecuritySystemMode.HomeArmed;
else
mode = SecuritySystemMode.Disarmed;

let supportedModes = [
SecuritySystemMode.Disarmed,
SecuritySystemMode.AwayArmed,
SecuritySystemMode.HomeArmed
]
if (plugin.settingsStorage.values.nightModeBypassAlarmState !== 'Disabled') {
supportedModes.push(SecuritySystemMode.NightArmed)
}

this.securitySystemState = {
mode,
// how to get this?
triggered: false,
supportedModes
}
}
this.location.onLocationMode.subscribe(updateLocationMode);
this.location.onLocationMode.subscribe(this.updateLocationMode);

// if the location has a base station, updates when arming/disarming are not sent to the `onLocationMode` subscription
// instead we subscribe to the security panel, which is updated during arming actions
this.location.getSecurityPanel().then(panel => {
panel.onData.subscribe(_ => {
this.location.getLocationMode().then(response => {
updateLocationMode(response.mode);
this.updateLocationMode(response.mode);
});
});
}).catch(error => {
Expand All @@ -110,11 +97,11 @@ export class RingLocationDevice extends ScryptedDeviceBase implements DeviceProv

if (this.location.hasAlarmBaseStation) {
this.location.getLocationMode().then(response => {
updateLocationMode(response.mode);
this.updateLocationMode(response.mode);
});

if (!this.securitySystemState) {
updateLocationMode('disabled');
this.updateLocationMode('disabled');
}
}

Expand Down Expand Up @@ -179,11 +166,13 @@ export class RingLocationDevice extends ScryptedDeviceBase implements DeviceProv
case RingDeviceType.ContactSensor:
case RingDeviceType.RetrofitZone:
case RingDeviceType.TiltSensor:
case RingDeviceType.GlassbreakSensor:
nativeId = locationDevice.id.toString() + '-sensor';
type = ScryptedDeviceType.Sensor
interfaces.push(ScryptedInterface.TamperSensor, ScryptedInterface.EntrySensor);
break;
case RingDeviceType.MotionSensor:
case RingDeviceType.BeamsMotionSensor:
nativeId = locationDevice.id.toString() + '-sensor';
type = ScryptedDeviceType.Sensor
interfaces.push(ScryptedInterface.TamperSensor, ScryptedInterface.MotionSensor);
Expand Down Expand Up @@ -249,25 +238,45 @@ export class RingLocationDevice extends ScryptedDeviceBase implements DeviceProv

async releaseDevice(id: string, nativeId: string): Promise<void> {}

updateLocationMode(locationMode: LocationMode) {
let mode: SecuritySystemMode;
if (locationMode === 'away')
mode = SecuritySystemMode.AwayArmed;
else if (locationMode === 'home')
mode = SecuritySystemMode.HomeArmed;
else
mode = SecuritySystemMode.Disarmed;

let supportedModes = [
SecuritySystemMode.Disarmed,
SecuritySystemMode.AwayArmed,
SecuritySystemMode.HomeArmed
]
if (this.plugin.settingsStorage.values.nightModeBypassAlarmState !== 'Disabled') {
supportedModes.push(SecuritySystemMode.NightArmed)
}

this.securitySystemState = {
mode,
// how to get this?
triggered: false,
supportedModes
}
}

async armSecuritySystem(mode: SecuritySystemMode): Promise<void> {
if (mode === SecuritySystemMode.AwayArmed) {
await this.location.armAway();
}
else if (mode === SecuritySystemMode.HomeArmed) {
} else if (mode === SecuritySystemMode.HomeArmed) {
await this.location.armHome();
}
else if (mode === SecuritySystemMode.NightArmed) {
const bypassContactSensors = Object.values(this.locationDevices).filter(device => {
return ((device.deviceType === RingDeviceType.ContactSensor || device.deviceType === RingDeviceType.RetrofitZone) && device.data.faulted)
}).map(sensor => sensor.id);

} else if (mode === SecuritySystemMode.NightArmed) {
const bypassContactSensors = Object.values(this.locationDevices).filter(device => device.isBypassable()).map(sensor => sensor.id);
if (this.plugin.settingsStorage.values.nightModeBypassAlarmState === 'Away') {
await this.location.armAway(bypassContactSensors);
} else {
await this.location.armHome(bypassContactSensors);
}
}
else if (mode === SecuritySystemMode.Disarmed) {
} else if (mode === SecuritySystemMode.Disarmed) {
await this.location.disarm();
}
}
Expand Down

0 comments on commit 35b5cdd

Please sign in to comment.