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 Apr 3, 2023
2 parents 298ac96 + 62d4d55 commit df09d8e
Showing 6 changed files with 58 additions and 13 deletions.
2 changes: 1 addition & 1 deletion plugins/alexa/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/alexa",
"version": "0.2.3",
"version": "0.2.4",
"scripts": {
"scrypted-setup-project": "scrypted-setup-project",
"prescrypted-setup-project": "scrypted-package-json",
40 changes: 34 additions & 6 deletions plugins/alexa/src/main.ts
Original file line number Diff line number Diff line change
@@ -15,6 +15,11 @@ const includeToken = 4;

export let DEBUG = false;

function debug(...args: any[]) {
if (DEBUG)
console.debug(...args);
}

class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, MixinProvider, Settings {
storageSettings = new StorageSettings(this, {
tokenInfo: {
@@ -34,6 +39,14 @@ class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, Mixi
description: 'This is the endpoint Alexa will use to send events to. This is set after you login.',
type: 'string',
readonly: true
},
debug: {
title: 'Debug Events',
description: 'Log all events to the console. This will be very noisy and should not be left enabled.',
type: 'boolean',
onPut(oldValue: boolean, newValue: boolean) {
DEBUG = newValue;
}
}
});

@@ -44,6 +57,8 @@ class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, Mixi
constructor(nativeId?: string) {
super(nativeId);

DEBUG = this.storageSettings.values.debug ?? false;

alexaHandlers.set('Alexa.Authorization/AcceptGrant', this.onAlexaAuthorization);
alexaHandlers.set('Alexa.Discovery/Discover', this.onDiscoverEndpoints);

@@ -141,12 +156,23 @@ class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, Mixi
if (!supportedType)
return;

const report = await supportedType.sendEvent(eventSource, eventDetails, eventData);
let report = await supportedType.sendEvent(eventSource, eventDetails, eventData);

if (!report && eventDetails.eventInterface === ScryptedInterface.Online) {
report = {};
}

if (!report && eventDetails.eventInterface === ScryptedInterface.Battery) {
report = {};
}

if (!report) {
this.console.warn(`${eventDetails.eventInterface}.${eventDetails.property} not supported for device ${eventSource.type}`);
return;
}

debug("event", eventDetails.eventInterface, eventDetails.property, eventSource.type);

let data = {
"event": {
"header": {
@@ -234,7 +260,7 @@ class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, Mixi
const endpoint = await this.getAlexaEndpoint();
const self = this;

this.console.assert(!DEBUG, `event:`, data);
debug("send event to alexa", data);

return axios.post(`https://${endpoint}/v3/events`, data, {
headers: {
@@ -570,6 +596,8 @@ class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, Mixi
const { authorization } = request.headers;
if (!this.validAuths.has(authorization)) {
try {
debug("making authorization request to Scrypted");

await axios.get('https://home.scrypted.app/_punch/getcookie', {
headers: {
'Authorization': authorization,
@@ -590,11 +618,11 @@ class AlexaPlugin extends ScryptedDeviceBase implements HttpRequestHandler, Mixi
const { directive } = body;
const { namespace, name } = directive.header;

this.console.assert(!DEBUG, `request: ${namespace}/${name}`);

const mapName = `${namespace}/${name}`;
const handler = alexaHandlers.get(mapName);

debug("received directive from alexa", mapName, body);

const handler = alexaHandlers.get(mapName);
if (handler)
return handler.apply(this, [request, response, directive]);

@@ -641,7 +669,7 @@ class HttpResponseLoggingImpl implements AlexaHttpResponse {
if (options.code !== 200)
this.console.error(`response error ${options.code}:`, body);
else
this.console.assert(!DEBUG, `response ${options.code}:`, body);
debug("response to alexa directive", options.code, body);

if (typeof body === 'object')
body = JSON.stringify(body);
6 changes: 3 additions & 3 deletions plugins/unifi-protect/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/unifi-protect/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@scrypted/unifi-protect",
"version": "0.0.131",
"version": "0.0.132",
"description": "Unifi Protect Plugin for Scrypted",
"author": "Scrypted",
"license": "Apache",
18 changes: 16 additions & 2 deletions plugins/unifi-protect/src/camera.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ffmpegLogInitialOutput, safeKillFFmpeg } from '@scrypted/common/src/media-helpers';
import { fitHeightToWidth } from "@scrypted/common/src/resolution-utils";
import sdk, { Camera, DeviceProvider, FFmpegInput, Intercom, MediaObject, MediaStreamOptions, MediaStreamUrl, MotionSensor, Notifier, NotifierOptions, ObjectDetectionTypes, ObjectDetector, ObjectsDetected, OnOff, PictureOptions, ResponseMediaStreamOptions, ResponsePictureOptions, ScryptedDeviceBase, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, VideoCamera, VideoCameraConfiguration } from "@scrypted/sdk";
import sdk, { Camera, DeviceProvider, FFmpegInput, Intercom, MediaObject, MediaStreamOptions, MediaStreamUrl, MotionSensor, Notifier, NotifierOptions, ObjectDetectionTypes, ObjectDetector, ObjectsDetected, OnOff, Online, PanTiltZoom, PanTiltZoomCommand, PictureOptions, ResponseMediaStreamOptions, ResponsePictureOptions, ScryptedDeviceBase, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, VideoCamera, VideoCameraConfiguration } from "@scrypted/sdk";
import child_process, { ChildProcess } from 'child_process';
import { once } from "events";
import { Readable } from "stream";
@@ -38,7 +38,7 @@ export class UnifiPackageCamera extends ScryptedDeviceBase implements Camera, Vi
}
}

export class UnifiCamera extends ScryptedDeviceBase implements Notifier, Intercom, Camera, VideoCamera, VideoCameraConfiguration, MotionSensor, Settings, ObjectDetector, DeviceProvider, OnOff {
export class UnifiCamera extends ScryptedDeviceBase implements Notifier, Intercom, Camera, VideoCamera, VideoCameraConfiguration, MotionSensor, Settings, ObjectDetector, DeviceProvider, OnOff, PanTiltZoom, Online {
motionTimeout: NodeJS.Timeout;
detectionTimeout: NodeJS.Timeout;
ringTimeout: NodeJS.Timeout;
@@ -61,6 +61,15 @@ export class UnifiCamera extends ScryptedDeviceBase implements Notifier, Interco
this.updateState(protectCamera);
}

async ptzCommand(command: PanTiltZoomCommand): Promise<void> {
const camera = this.findCamera() as any;
await this.protect.api.updateCamera(camera, {
ispSettings: {
zoomPosition: Math.abs(command.zoom * 100),
}
});
}

async setStatusLight(on: boolean) {
const camera = this.findCamera() as any;
await this.protect.api.updateCamera(camera, {
@@ -411,6 +420,11 @@ export class UnifiCamera extends ScryptedDeviceBase implements Notifier, Interco
if (!camera)
return;
this.on = !!camera.ledSettings?.isEnabled;
this.online = !!camera.isConnected;
this.setMotionDetected(!!camera.isMotionDetected);

if (!!camera.featureFlags.canOpticalZoom) {
this.ptzCapabilities = { pan: false, tilt: false, zoom: true };
}
}
}
3 changes: 3 additions & 0 deletions plugins/unifi-protect/src/main.ts
Original file line number Diff line number Diff line change
@@ -376,6 +376,9 @@ export class UnifiProtect extends ScryptedDeviceBase implements Settings, Device
if (camera.featureFlags.hasLedStatus) {
d.interfaces.push(ScryptedInterface.OnOff);
}
if (camera.featureFlags.canOpticalZoom) {
d.interfaces.push(ScryptedInterface.PanTiltZoom);
}
d.interfaces.push(ScryptedInterface.ObjectDetector);
devices.push(d);
}

0 comments on commit df09d8e

Please sign in to comment.