UNPKG

shelly-sdk

Version:

Shelly SDK for Node.js with Types definition

174 lines 5.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Shelly = void 0; const axios_1 = require("axios"); const settings_1 = require("./marshalling/settings"); const status_1 = require("./marshalling/status"); const nanoid_1 = require("nanoid"); const netmask_1 = require("netmask"); const SHELLY_DEFAULT_PORT = 80; const sendCommand = async (params) => { const { ip, path, port, command, value } = params; const timeout = params.timeout || 1000; let url = `http://${ip}:${port}/${path}`; if (command) { url += `?${command}=${value}`; } const response = await (0, axios_1.default)({ method: 'GET', url, headers: { 'Content-Type': 'application/json', 'x-requested-with': 'XMLHttpRequest', }, timeout, }); if (response.status === 200) { return response.data; } else { throw new Error(`HTTP ${response.status}`); } }; const updateDevice = async (params) => { const { ip, port, path, body } = params; const response = await (0, axios_1.default)({ method: 'POST', url: `http://${ip}:${port}/${path}`, headers: { 'Content-Type': 'application/json', 'x-requested-with': 'XMLHttpRequest', }, data: body, }); if (response.status === 200) { return response.data; } else { throw new Error(`HTTP ${response.status}`); } }; class Shelly { constructor(config) { this.config = Object.assign({}, { port: SHELLY_DEFAULT_PORT, id: (0, nanoid_1.nanoid)() }, config); } static async scanNetwork(baseIp, port = SHELLY_DEFAULT_PORT, timeout = 30000) { const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/; const [networkAddress, subnetMask] = baseIp.split('/'); if (!ipRegex.test(networkAddress)) { throw new Error('Invalid IP address'); } if (!subnetMask) { throw new Error('Invalid subnet mask'); } const block = new netmask_1.Netmask(baseIp); const devices = []; const scanIp = async (ip) => { try { const deviceInfo = await sendCommand({ ip, port, path: 'settings', timeout, }); if (deviceInfo.device) { const config = { name: deviceInfo.name, type: deviceInfo.device.type, id: deviceInfo.device.hostname, ip, port, }; devices.push(config); return config; } else { return undefined; } } catch (e) { return undefined; } }; const addresses = []; block.forEach((ip) => { addresses.push(ip); }); const promises = addresses.map(async (ip) => { return scanIp(ip); }); await Promise.all(promises); return devices.filter(r => r !== undefined); } static async instantiateDevices(configList) { const devices = configList.map(config => { return new Shelly(config); }); const promises = devices.map(device => { return device.init(); }); await Promise.all(promises); return devices; } async init() { await this.settings(); await this.status(); return this; } getConfig() { return this.config; } async settings() { const res = await sendCommand({ ip: this.config.ip, port: this.config.port, path: 'settings', }); this._settings = (0, settings_1.unmarshallRemoteSettings)(res); return this._settings; } async status() { const res = await sendCommand({ ip: this.config.ip, port: this.config.port, path: 'status', }); this._status = (0, status_1.unmarshallStatus)(res); return this._status; } async switchOff() { return this.switch(false); } async switchOn() { return this.switch(true); } async switch(state) { return sendCommand({ ip: this.config.ip, port: this.config.port, path: 'relay/0', command: 'turn', value: state ? 'on' : 'off', }); } async update(settings) { return updateDevice({ ip: this.config.ip, port: this.config.port, path: 'settings', body: settings, }); } toString() { return `${this.config.name} (${this.config.id})`; } serialize() { return { ...this.config, settings: this._settings, status: this._status, }; } } exports.Shelly = Shelly; //# sourceMappingURL=shelly.js.map