UNPKG

@zigasebenik/node-red-zte-sms

Version:

A Node-RED node to send sms messages using ZTE modem.

127 lines (111 loc) 3.58 kB
const Modem = require('@zigasebenik/zte-sms'); class Q { constructor() { this._items = []; } enqueue(item) { this._items.push(item); } dequeue() { return this._items.shift(); } get size() { return this._items.length; } } class Queue extends Q { constructor() { super(); this._pendingPromise = false; } enqueue(action) { return new Promise((resolve, reject) => { super.enqueue({ action, resolve, reject }); this.dequeue(); }); } async dequeue() { if (this._pendingPromise) { return false }; let item = super.dequeue(); if (!item) { return false }; try { this._pendingPromise = true; let payload = await item.action(this); this._pendingPromise = false; item.resolve(payload); } catch (error) { this._pendingPromise = false; item.reject(error); } finally { this.dequeue(); } return true; } } module.exports = function(RED) { function ZteModemNode(config) { RED.nodes.createNode(this, config); this.config = config; this.modemCapacity = null; this.observedNodes = new Set([]); this.queue = new Queue(); const modem = new Modem({ modemIP: config.modemIP, modemPassword: this.credentials.modemPassword }); const node = this; const getCapacityInfo = async function () { try { node.modemCapacity = await modem.getSmsCapacityInfo(); setNodeSuccessStatus(); return node.modemCapacity; } catch (error) { node.observedNodes.forEach((n) => { n.status({ fill: 'red', shape: 'dot', text: `Can't get modem capacity` }); }); } } const setNodeSuccessStatus = function () { const used = Number.parseInt(node.modemCapacity.sms_nvused_total, 10); const total = Number.parseInt(node.modemCapacity.sms_nv_total, 10); node.observedNodes.forEach((n) => { if (!n.isError) { n.status({ fill: 'green', shape: 'dot', text: `Modem capacity: ${used}/${total}` }); } }); } this.getAllSms = function (n) { return node.queue.enqueue(async () => { n.status({ fill: 'blue', shape: 'dot', text: 'Checking ...' }); await getCapacityInfo(); return await modem.getAllSms(); }) } this.sendSms = function (n, phoneNumber, smsMessage) { return node.queue.enqueue(async () => { n.status({ fill: 'blue', shape: 'dot', text: 'Sending ...' }); const sms = await modem.sendSms(phoneNumber, smsMessage) await getCapacityInfo(); return sms; }); } this.deleteSms = function (n, smsId) { return node.queue.enqueue(async () => { n.status({ fill: 'blue', shape: 'dot', text: 'Deleting ...' }); await modem.deleteSms(smsId) await getCapacityInfo(); }); } this.markSmsAsRead = function (n, smsId) { return node.queue.enqueue(async () => { n.status({ fill: 'blue', shape: 'dot', text: 'Marking as read ...' }); await modem.setSmsAsRead(smsId) await getCapacityInfo(); }); } setImmediate(() => { node.config._users?.forEach((uId) => { const node = RED.nodes.getNode(uId); node && this.observedNodes.add(node); }); getCapacityInfo(); }); } RED.nodes.registerType("zte-modem", ZteModemNode, { credentials: { modemPassword: { type: "password" }, } }); }