diff --git a/build/main.js b/build/main.js index c91c10c0..d575d4ac 100644 --- a/build/main.js +++ b/build/main.js @@ -1,7 +1,4 @@ "use strict"; -/* - * Created with @iobroker/create-adapter v1.34.1 - */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); @@ -30,8 +27,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RingAdapter = void 0; -// The adapter-core module gives you access to the core ioBroker functions -// you need to create an adapter const utils = __importStar(require("@iobroker/adapter-core")); const adapter_core_1 = require("@iobroker/adapter-core"); const path_1 = __importDefault(require("path")); @@ -64,8 +59,6 @@ class RingAdapter extends adapter_core_1.Adapter { this.sunset = 0; this.on("ready", this.onReady.bind(this)); this.on("stateChange", this.onStateChange.bind(this)); - // this.on("objectChange", this.onObjectChange.bind(this)); - // this.on("message", this.onMessage.bind(this)); this.on("unload", this.onUnload.bind(this)); } static getSplitIds(id) { @@ -84,24 +77,80 @@ class RingAdapter extends adapter_core_1.Adapter { } return { device, channel, stateName }; } + /** + * This method ensures that the state is updated or created if it doesn't exist. + */ async upsertState(id, common, value, ack = true, subscribe = false) { if (this.states[id] === value && !subscribe) { - // Unchanged and from user not changeable Value return; } - // noinspection JSIgnoredPromiseFromCall await this.upsertStateAsync(id, common, value, ack, subscribe); } /** - * Is called when adapter shuts down - callback has to be called under any circumstances! + * This method handles the creation of devices, channels, and states as necessary. + */ + async upsertStateAsync(id, common, value, ack = true, subscribe = false) { + var _a; + try { + if (this.states[id] !== undefined) { + this.states[id] = value; + await this.setStateAsync(id, value, ack); + return; + } + const { device, channel, stateName } = RingAdapter.getSplitIds(id); + // Create a complete `common` object to avoid type issues + const completeCommon = { + name: "Default Name", + type: "string", + role: "state", + read: true, + write: false, + ...common, + }; + // Create the device if it doesn't exist yet + if (device && !channel) { + await this.setObjectNotExistsAsync(device, { + type: "device", + common: { + name: device, + }, + native: {}, + }); + } + // Create the channel if it doesn't exist yet + if (device && channel) { + await this.setObjectNotExistsAsync(`${device}.${channel}`, { + type: "channel", + common: { + name: channel, + }, + native: {}, + }); + } + // Create the state if it doesn't exist yet + await this.setObjectNotExistsAsync(`${device}.${channel ? channel + "." : ""}${stateName}`, { + type: "state", + common: completeCommon, + native: {}, + }); + this.states[id] = value; + await this.setStateAsync(id, value, ack); + if (subscribe) { + await this.subscribeStatesAsync(id); + } + } + catch (e) { + this.log.warn(`Error Updating State ${id} to ${value}: ${(_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : e}`); + if ((e === null || e === void 0 ? void 0 : e.stack) !== undefined) { + this.log.debug(`Error Stack: ${e.stack}`); + } + } + } + /** + * Is called when the adapter is unloaded - make sure to clean up timers and intervals. */ onUnload(callback) { try { - // Here you must clear all timeouts or intervals that may still be active - // clearTimeout(timeout1); - // clearTimeout(timeout2); - // ... - // clearInterval(interval1); if (this.apiClient) { this.apiClient.unload(); } @@ -111,20 +160,9 @@ class RingAdapter extends adapter_core_1.Adapter { callback(); } } - // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor. - // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`. - // /** - // * Is called if a subscribed object changes - // */ - // private onObjectChange(id: string, obj: ioBroker.Object | null | undefined): void { - // if (obj) { - // // The object was changed - // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`); - // } else { - // // The object was deleted - // this.log.info(`object ${id} deleted`); - // } - // } + /** + * Retrieves a state value as a string from the cache or from the state object. + */ async tryGetStringState(id) { var _a, _b; const cachedVal = this.states[id]; @@ -133,42 +171,33 @@ class RingAdapter extends adapter_core_1.Adapter { } return ((_b = (_a = (await this.getStateAsync(id))) === null || _a === void 0 ? void 0 : _a.val) !== null && _b !== void 0 ? _b : "") + ""; } - // If you need to accept messages in your adapter, uncomment the following block and the corresponding line in the constructor. - // /** - // * Some message was sent to this instance over the message box. Used by email, pushover, text2speech, ... - // * Using this method requires "common.messagebox" property to be set to true in io-package.json - // */ - // private onMessage(obj: ioBroker.Message): void { - // if (typeof obj === "object" && obj.message) { - // if (obj.command === "send") { - // // e.g. send email or pushover or whatever - // this.log.info("send command"); - // // Send response in callback if required - // if (obj.callback) this.sendTo(obj.from, obj.command, "Message received", obj.callback); - // } - // } - // } + /** + * Returns the refresh token if available. + */ async getRefreshToken() { const newTokenStateVal = await this.tryGetStringState("next_refresh_token"); const oldTokenStateVal = await this.tryGetStringState("old_user_refresh_token"); if (newTokenStateVal && oldTokenStateVal === this.config.refreshtoken) { - this.log.debug(`As the configured refresh token hasn't changed the state one will be used`); + this.log.debug(`As the configured refresh token hasn't changed, the stored one will be used`); return newTokenStateVal; } return this.config.refreshtoken; } + /** + * Calculates the sun data (sunrise and sunset) based on the current latitude and longitude. + */ async CalcSunData() { try { this.log.debug("Run CalcSunData"); if (this.latitude && this.longitude) { const today = new Date(); const sunData = suncalc_1.default.getTimes(today, typeof this.latitude === "string" ? parseFloat(this.latitude) : this.latitude, typeof this.longitude === "string" ? parseFloat(this.longitude) : this.longitude); - this.sunset = sunData.night.getTime(); // night is really dark, sunset is too early - this.sunrise = sunData.nightEnd.getTime(); // same here vice versa + this.sunset = sunData.night.getTime(); + this.sunrise = sunData.nightEnd.getTime(); this.log.debug(`Sunset: ${new Date(this.sunset).toLocaleString()}, Sunrise: ${new Date(this.sunrise).toLocaleString()}`); } else { - this.log.error("Latitude or Longitude not defined in System"); + this.log.error("Latitude or Longitude not defined in the system"); } } catch (error) { @@ -178,27 +207,14 @@ class RingAdapter extends adapter_core_1.Adapter { } } /** - * Is called when databases are connected and adapter received configuration. + * Called when the adapter is ready - initializes the API client and schedules tasks. */ async onReady() { - // Initialize your adapter here - // The adapters config (in the instance object everything under the attribute "native") is accessible via - // this.config: this.apiClient = new ringApiClient_1.RingApiClient(this); if (!this.apiClient.validateRefreshToken()) { this.terminate(`Invalid Refresh Token, please follow steps provided within Readme to generate a new one`); return; } - /* - this.log.debug(`Configured Path: "${this.config.path}"`); - const dataDir = (this.systemConfig) ? this.systemConfig.dataDir : ""; - this.log.silly(`DataDir: ${dataDir}`); - if (!this.config.path) { - this.config.path = path.join(utils.getAbsoluteDefaultDataDir(), "files", this.namespace) - this.log.debug(`New Config Path: "${this.config.path}"`); - } - await FileService.prepareFolder(this.config.path); - */ const config_path = [this.config.path_snapshot, this.config.path_livestream]; for (const index in config_path) { this.log.debug(`Configured Path: "${config_path[index]}"`); @@ -216,15 +232,10 @@ class RingAdapter extends adapter_core_1.Adapter { } await file_service_1.FileService.prepareFolder(config_path[index]); } - const objectDevices = this.getDevicesAsync(); - for (const objectDevice in objectDevices) { - this.deleteDevice(objectDevice); - } this.log.info(`Initializing Api Client`); await this.apiClient.init(); this.log.info(`Get sunset and sunrise`); await this.CalcSunData(); - // Daily schedule sometime from 00:00:20 to 00:00:40 const scheduleSeconds = Math.round(Math.random() * 20 + 20); this.log.info(`Daily sun parameter calculation scheduled for 00:00:${scheduleSeconds}`); node_schedule_1.default.scheduleJob("SunData", `${scheduleSeconds} 0 0 * * *`, async () => { @@ -233,19 +244,16 @@ class RingAdapter extends adapter_core_1.Adapter { }); } /** - * Is called if a subscribed state changes + * Called when a subscribed state changes - handles user input and updates the state. */ onStateChange(id, state) { if (!state || !this.apiClient) { - // The state was deleted this.log.silly(`state ${id} deleted`); return; } if (state.ack) { - // As it is already ack, don't react on it (could be set by us). return; } - // The state was changed this.log.silly(`state ${id} changed: ${state.val} (ack = ${state.ack})`); const splits = id.split("."); const targetId = splits[2]; @@ -261,38 +269,13 @@ class RingAdapter extends adapter_core_1.Adapter { this.log.info(message); this.log.debug(`Reason: "${reason}"`); } - async upsertStateAsync(id, common, value, ack = true, subscribe = false) { - var _a; - try { - if (this.states[id] !== undefined) { - this.states[id] = value; - await this.setStateAsync(id, value, ack); - return; - } - const { device, channel, stateName } = RingAdapter.getSplitIds(id); - await this.createStateAsync(device, channel, stateName, common); - this.states[id] = value; - await this.setStateAsync(id, value, ack); - if (subscribe) { - await this.subscribeStatesAsync(id); - } - } - catch (e) { - this.log.warn(`Error Updating State ${id} to ${value}: ${(_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : e}`); - if ((e === null || e === void 0 ? void 0 : e.stack) !== undefined) { - this.log.debug(`Error Stack: ${e.stack}`); - } - } - } } exports.RingAdapter = RingAdapter; RingAdapter.isWindows = process.platform.startsWith("win"); if (require.main !== module) { - // Export the constructor in compact mode module.exports = (options) => new RingAdapter(options); } else { - // otherwise start the instance directly (() => new RingAdapter())(); } //# sourceMappingURL=main.js.map \ No newline at end of file diff --git a/build/main.js.map b/build/main.js.map index 7c230561..8d6b3aea 100644 --- a/build/main.js.map +++ b/build/main.js.map @@ -1 +1 @@ -{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 6a277c8f..a243564f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "iobroker.ring", - "version": "6.1.0", + "version": "6.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "iobroker.ring", - "version": "6.1.0", + "version": "6.2.0", "license": "MIT", "dependencies": { "@homebridge/camera-utils": "2.2.6", diff --git a/src/main.ts b/src/main.ts index adbd81ba..7fe4ebeb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,15 +1,8 @@ -/* - * Created with @iobroker/create-adapter v1.34.1 - */ - -// The adapter-core module gives you access to the core ioBroker functions -// you need to create an adapter import * as utils from "@iobroker/adapter-core"; import { Adapter } from "@iobroker/adapter-core"; import path from "path"; import schedule from "node-schedule"; import suncalc, { GetTimesResult } from "suncalc"; - import { RingApiClient } from "./lib/ringApiClient"; import { FileService } from "./lib/services/file-service"; @@ -42,8 +35,6 @@ export class RingAdapter extends Adapter { }); this.on("ready", this.onReady.bind(this)); this.on("stateChange", this.onStateChange.bind(this)); - // this.on("objectChange", this.onObjectChange.bind(this)); - // this.on("message", this.onMessage.bind(this)); this.on("unload", this.onUnload.bind(this)); } @@ -63,6 +54,9 @@ export class RingAdapter extends Adapter { return { device, channel, stateName }; } + /** + * This method ensures that the state is updated or created if it doesn't exist. + */ public async upsertState( id: string, common: Partial, @@ -71,23 +65,87 @@ export class RingAdapter extends Adapter { subscribe: boolean = false ): Promise { if (this.states[id] === value && !subscribe) { - // Unchanged and from user not changeable Value return; } - // noinspection JSIgnoredPromiseFromCall await this.upsertStateAsync(id, common, value, ack, subscribe); } /** - * Is called when adapter shuts down - callback has to be called under any circumstances! + * This method handles the creation of devices, channels, and states as necessary. + */ + private async upsertStateAsync( + id: string, + common: Partial, + value: ioBroker.StateValue, + ack: boolean = true, + subscribe: boolean = false + ): Promise { + try { + if (this.states[id] !== undefined) { + this.states[id] = value; + await this.setStateAsync(id, value, ack); + return; + } + + const { device, channel, stateName }: { device: string; channel: string; stateName: string } = RingAdapter.getSplitIds(id); + + // Create a complete `common` object to avoid type issues + const completeCommon: ioBroker.StateCommon = { + name: "Default Name", + type: "string", + role: "state", + read: true, + write: false, + ...common, + }; + + // Create the device if it doesn't exist yet + if (device && !channel) { + await this.setObjectNotExistsAsync(device, { + type: "device", + common: { + name: device, + }, + native: {}, + }); + } + + // Create the channel if it doesn't exist yet + if (device && channel) { + await this.setObjectNotExistsAsync(`${device}.${channel}`, { + type: "channel", + common: { + name: channel, + }, + native: {}, + }); + } + + // Create the state if it doesn't exist yet + await this.setObjectNotExistsAsync(`${device}.${channel ? channel + "." : ""}${stateName}`, { + type: "state", + common: completeCommon, + native: {}, + }); + + this.states[id] = value; + await this.setStateAsync(id, value, ack); + if (subscribe) { + await this.subscribeStatesAsync(id); + } + } catch (e: any) { + this.log.warn(`Error Updating State ${id} to ${value}: ${e?.message ?? e}`); + if (e?.stack !== undefined) { + this.log.debug(`Error Stack: ${e.stack}`); + } + } + } + + /** + * Is called when the adapter is unloaded - make sure to clean up timers and intervals. */ private onUnload(callback: () => void): void { try { - // Here you must clear all timeouts or intervals that may still be active - // clearTimeout(timeout1); - // clearTimeout(timeout2); - // ... - // clearInterval(interval1); if (this.apiClient) { this.apiClient.unload(); } @@ -97,21 +155,9 @@ export class RingAdapter extends Adapter { } } - // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor. - // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`. - // /** - // * Is called if a subscribed object changes - // */ - // private onObjectChange(id: string, obj: ioBroker.Object | null | undefined): void { - // if (obj) { - // // The object was changed - // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`); - // } else { - // // The object was deleted - // this.log.info(`object ${id} deleted`); - // } - // } - + /** + * Retrieves a state value as a string from the cache or from the state object. + */ public async tryGetStringState(id: string): Promise { const cachedVal: string | number | boolean | null = this.states[id]; if (cachedVal !== undefined && cachedVal !== null) { @@ -120,34 +166,23 @@ export class RingAdapter extends Adapter { return ((await this.getStateAsync(id))?.val ?? "") + ""; } - // If you need to accept messages in your adapter, uncomment the following block and the corresponding line in the constructor. - // /** - // * Some message was sent to this instance over the message box. Used by email, pushover, text2speech, ... - // * Using this method requires "common.messagebox" property to be set to true in io-package.json - // */ - // private onMessage(obj: ioBroker.Message): void { - // if (typeof obj === "object" && obj.message) { - // if (obj.command === "send") { - // // e.g. send email or pushover or whatever - // this.log.info("send command"); - - // // Send response in callback if required - // if (obj.callback) this.sendTo(obj.from, obj.command, "Message received", obj.callback); - // } - // } - // } - + /** + * Returns the refresh token if available. + */ public async getRefreshToken(): Promise { const newTokenStateVal: string = await this.tryGetStringState("next_refresh_token"); const oldTokenStateVal: string = await this.tryGetStringState("old_user_refresh_token"); if (newTokenStateVal && oldTokenStateVal === this.config.refreshtoken) { - this.log.debug(`As the configured refresh token hasn't changed the state one will be used`); + this.log.debug(`As the configured refresh token hasn't changed, the stored one will be used`); return newTokenStateVal; } return this.config.refreshtoken; } - private async CalcSunData():Promise { + /** + * Calculates the sun data (sunrise and sunset) based on the current latitude and longitude. + */ + private async CalcSunData(): Promise { try { this.log.debug("Run CalcSunData"); if (this.latitude && this.longitude) { @@ -157,11 +192,11 @@ export class RingAdapter extends Adapter { typeof this.latitude === "string" ? parseFloat(this.latitude) : this.latitude, typeof this.longitude === "string" ? parseFloat(this.longitude) : this.longitude ); - this.sunset = sunData.night.getTime(); // night is really dark, sunset is too early - this.sunrise = sunData.nightEnd.getTime(); // same here vice versa + this.sunset = sunData.night.getTime(); + this.sunrise = sunData.nightEnd.getTime(); this.log.debug(`Sunset: ${new Date(this.sunset).toLocaleString()}, Sunrise: ${new Date(this.sunrise).toLocaleString()}`); } else { - this.log.error("Latitude or Longitude not defined in System"); + this.log.error("Latitude or Longitude not defined in the system"); } } catch (error) { const eMsg: string = `Error in CalcSunData: ${error}`; @@ -171,29 +206,15 @@ export class RingAdapter extends Adapter { } /** - * Is called when databases are connected and adapter received configuration. + * Called when the adapter is ready - initializes the API client and schedules tasks. */ private async onReady(): Promise { - // Initialize your adapter here - // The adapters config (in the instance object everything under the attribute "native") is accessible via - // this.config: this.apiClient = new RingApiClient(this); if (!this.apiClient.validateRefreshToken()) { this.terminate(`Invalid Refresh Token, please follow steps provided within Readme to generate a new one`); return; } - /* - this.log.debug(`Configured Path: "${this.config.path}"`); - const dataDir = (this.systemConfig) ? this.systemConfig.dataDir : ""; - this.log.silly(`DataDir: ${dataDir}`); - if (!this.config.path) { - this.config.path = path.join(utils.getAbsoluteDefaultDataDir(), "files", this.namespace) - this.log.debug(`New Config Path: "${this.config.path}"`); - } - await FileService.prepareFolder(this.config.path); - */ - const config_path: string[] = [this.config.path_snapshot, this.config.path_livestream]; for (const index in config_path) { this.log.debug(`Configured Path: "${config_path[index]}"`); @@ -211,18 +232,12 @@ export class RingAdapter extends Adapter { await FileService.prepareFolder(config_path[index]); } - const objectDevices: Promise = this.getDevicesAsync(); - for (const objectDevice in objectDevices) { - this.deleteDevice(objectDevice); - } - this.log.info(`Initializing Api Client`); await this.apiClient.init(); this.log.info(`Get sunset and sunrise`); await this.CalcSunData(); - // Daily schedule sometime from 00:00:20 to 00:00:40 const scheduleSeconds: number = Math.round(Math.random() * 20 + 20); this.log.info(`Daily sun parameter calculation scheduled for 00:00:${scheduleSeconds}`); schedule.scheduleJob("SunData", `${scheduleSeconds} 0 0 * * *`, async (): Promise => { @@ -232,20 +247,17 @@ export class RingAdapter extends Adapter { } /** - * Is called if a subscribed state changes + * Called when a subscribed state changes - handles user input and updates the state. */ private onStateChange(id: string, state: ioBroker.State | null | undefined): void { if (!state || !this.apiClient) { - // The state was deleted this.log.silly(`state ${id} deleted`); return; } if (state.ack) { - // As it is already ack, don't react on it (could be set by us). return; } - // The state was changed this.log.silly(`state ${id} changed: ${state.val} (ack = ${state.ack})`); const splits: string[] = id.split("."); const targetId: string = splits[2]; @@ -263,41 +275,10 @@ export class RingAdapter extends Adapter { this.log.info(message); this.log.debug(`Reason: "${reason}"`); } - - private async upsertStateAsync( - id: string, - common: Partial, - value: ioBroker.StateValue, - ack: boolean = true, - subscribe: boolean = false - ): Promise { - try { - if (this.states[id] !== undefined) { - this.states[id] = value; - await this.setStateAsync(id, value, ack); - return; - } - - const {device, channel, stateName}: { device: string; channel: string; stateName: string } = RingAdapter.getSplitIds(id); - await this.createStateAsync(device, channel, stateName, common); - this.states[id] = value; - await this.setStateAsync(id, value, ack); - if (subscribe) { - await this.subscribeStatesAsync(id); - } - } catch (e: any) { - this.log.warn(`Error Updating State ${id} to ${value}: ${e?.message ?? e}`); - if (e?.stack !== undefined) { - this.log.debug(`Error Stack: ${e.stack}`); - } - } - } } if (require.main !== module) { - // Export the constructor in compact mode module.exports = (options: Partial | undefined): RingAdapter => new RingAdapter(options); } else { - // otherwise start the instance directly - ((): RingAdapter => new RingAdapter())(); + (() => new RingAdapter())(); }