UNPKG

node-red-contrib-mysensors

Version:

Mysensors related nodes, for decoding / encoding mysensors serial protocol and MQTT topic, and wrapping arbitrary messages into mysensors compatible messages

117 lines (94 loc) 3.79 kB
/* eslint-disable @typescript-eslint/no-unused-vars */ import type { NodeContextData } from 'node-red'; import {IStorage, INodeData, ISensorData} from './storage-interface'; type Nodes = { [key in number]: INodeData } export class NoderedStorage implements IStorage { constructor( private context: NodeContextData | undefined, private storageKey: string, private store = 'default' ) { } private async getNodes(): Promise<Nodes> { const data = await this.context?.get(this.storageKey, this.store); return (data || {}) as Nodes; } private async setNode(nodeId: number, data: Partial<INodeData>): Promise<void> { const nodes = await this.getNodes(); const node = nodes?.[nodeId] || { batteryLevel: -1, nodeId: nodeId, label: '', lastHeard: new Date(), lastRestart: new Date(), parentId: -1, sensors: [], sketchName: '', sketchVersion: '', used: 1, }; nodes[nodeId] = { ...node, ...data }; return this.context?.set(this.storageKey, nodes, this.store); } private async setChild(nodeId: number, childId: number, data: Partial<ISensorData>) { const children = (await this.getNodes())?.[nodeId]?.sensors; if (!children) { // We do not have parent node, so do _not_ try to set any child sensor information return; } const child = children.find((item) => item.childId === childId) || { childId, description: '', lastHeard: new Date(), nodeId: nodeId, sType: 0, }; const newSensors = children.filter((item) => item.childId !== childId).concat([{ ...child, ...data, }]); this.setNode(nodeId, {sensors: newSensors}); } public async nodeHeard(nodeId: number): Promise<void> { await this.setNode(nodeId, {lastHeard: new Date()}); } public async sketchName(nodeId: number, name: string): Promise<void> { await this.setNode(nodeId, { sketchName: name}); } public async sketchVersion(nodeId: number, version: string): Promise<void> { await this.setNode(nodeId, {sketchVersion: version}); } public async getNodeList(): Promise<INodeData[]> { return Object.values(await this.getNodes()).filter((item) => item.used); } public async getFreeNodeId(): Promise<number | undefined> { const freeNode = Object.values(await this.getNodes()).find((item) => !item.used); return freeNode?.nodeId; } public async setParent(nodeId: number, last: number): Promise<void> { await this.setNode(nodeId, {parentId: last}); } public async setBatteryLevel(nodeId: number, batterylevel: number): Promise<void> { await this.setNode(nodeId, {batteryLevel: batterylevel}); } /** child nodes, dummy implementation for now */ public async getChild(nodeId: number, childId: number): Promise<ISensorData | undefined> { const nodes = await this.getNodes(); return nodes[nodeId]?.sensors?.find((item) => item.childId === childId) || { childId, nodeId, description: '', lastHeard: new Date(), sType: 0 }; } public async childHeard(nodeId: number, childId: number): Promise<void> { return this.setChild(nodeId, childId, {lastHeard:new Date()}); } public async child(_nodeId: number, _childId: number, _type: number, _description: string): Promise<void> { await this.setChild(_nodeId, _childId, {sType: _type, description:_description}); } }