iobroker.wifilight
Advanced tools
Comparing version 1.3.5 to 2.0.0
{ | ||
"AddDevice": "Zum Hinzufügen +-Button betätigen", | ||
"Cannot find any device": "Kein neues Gerät gefunden", | ||
"Enable adapter first": "Adapter nicht aktiv. Adapter aktivieren", | ||
"Find a device": "Gerät suchen", | ||
"Please wait, looking for devices...": "Bitte warten...", | ||
"Select a device": "Geräte auswählen", | ||
"Settings": "Einstellungen", | ||
"WiFi Light": "WiFi Light Einstellungen", | ||
"devices": "Geräte-liste", | ||
"ip": "IP", | ||
"looking for device": "Suche Geräte", | ||
"name": "Bezeichnung", | ||
"on save adapter restarts with new config immediately": "Beim Speichern wird der Adapter sofort mit der neuen Konfiguration neu gestartet", | ||
"pollIntervall": "Pollintervall", | ||
"port": "Port", | ||
"type": "Typ" | ||
} | ||
"Cannot find any device": "Es kann kein Gerät gefunden werden", | ||
"Discover devices": "Geräte entdecken", | ||
"IP Address": "IP-Adresse", | ||
"Type": "Typ", | ||
"Port": "Hafen", | ||
"Poll interval (sec)": "Abfrageintervall (Sek.)" | ||
} |
{ | ||
"AddDevice": "Add #-Button to add device", | ||
"Cannot find any device": "Cannot find new devices", | ||
"Enable adapter first": "Enable adapter first", | ||
"Find a device": "Find a device", | ||
"Please wait, looking for devices...": "Please wait...", | ||
"Select a device": "Select a device", | ||
"Settings": "Settings", | ||
"WiFi Light": "WiFi Light", | ||
"devices": "Dives list", | ||
"ip": "IP", | ||
"looking for device": "Looking for devices", | ||
"name": "Name", | ||
"on save adapter restarts with new config immediately": "on save adapter restarts with new config immediately", | ||
"pollIntervall": "Poll Intervall", | ||
"port": "Port", | ||
"type": "Type" | ||
"Cannot find any device": "Cannot find any device", | ||
"Discover devices": "Discover devices", | ||
"IP Address": "IP Address", | ||
"Type": "Type", | ||
"Port": "Port", | ||
"Poll interval (sec)": "Poll interval (sec)" | ||
} |
{ | ||
"AddDevice": "Agregar #-Botón para agregar el dispositivo", | ||
"Cannot find any device": "No se puede encontrar nuevos dispositivos", | ||
"Enable adapter first": "Habilitar el adaptador de primera", | ||
"Find a device": "Encontrar un dispositivo de", | ||
"Please wait, looking for devices...": "Por favor, espere...", | ||
"Select a device": "Seleccione un dispositivo", | ||
"Settings": "Configuración", | ||
"WiFi Light": "WiFi Luz", | ||
"devices": "Lista de inmersiones", | ||
"ip": "IP", | ||
"looking for device": "Buscando dispositivos", | ||
"name": "Nombre", | ||
"on save adapter restarts with new config immediately": "en guardar adaptador se reinicia con la nueva config de inmediato", | ||
"pollIntervall": "Intervalo De Poll", | ||
"port": "Puerto", | ||
"type": "Tipo de" | ||
} | ||
"Cannot find any device": "No se puede encontrar ningún dispositivo", | ||
"Discover devices": "Descubrir dispositivos", | ||
"IP Address": "Dirección IP", | ||
"Type": "Tipo", | ||
"Port": "Puerto", | ||
"Poll interval (sec)": "Intervalo de sondeo (seg)" | ||
} |
{ | ||
"AddDevice": "Ajouter un bouton # pour ajouter un périphérique", | ||
"Cannot find any device": "Impossible de trouver de nouveaux appareils", | ||
"Enable adapter first": "Activer d'abord l'adaptateur", | ||
"Find a device": "Trouver un appareil", | ||
"Please wait, looking for devices...": "S'il vous plaît, attendez...", | ||
"Select a device": "Sélectionnez un appareil", | ||
"Settings": "Paramètres", | ||
"WiFi Light": "Lumière WiFi", | ||
"devices": "Liste des plongées", | ||
"ip": "IP", | ||
"looking for device": "À la recherche d'appareils", | ||
"name": "Nom", | ||
"on save adapter restarts with new config immediately": "sur save, l'adaptateur redémarre immédiatement avec la nouvelle configuration", | ||
"pollIntervall": "Sondage Intervall", | ||
"port": "Port", | ||
"type": "Type" | ||
} | ||
"Cannot find any device": "Impossible de trouver un appareil", | ||
"Discover devices": "Découvrir les appareils", | ||
"IP Address": "Adresse IP", | ||
"Type": "Taper", | ||
"Port": "Port", | ||
"Poll interval (sec)": "Intervalle de sondage (sec)" | ||
} |
{ | ||
"AddDevice": "Aggiungere #-Pulsante per aggiungere il dispositivo", | ||
"Cannot find any device": "Non riesce a trovare nuovi dispositivi", | ||
"Enable adapter first": "Attivare prima l'adattatore", | ||
"Find a device": "Trovare un dispositivo", | ||
"Please wait, looking for devices...": "Si prega di attendere...", | ||
"Select a device": "Selezionare un dispositivo", | ||
"Settings": "Impostazioni", | ||
"WiFi Light": "WiFi Di Luce", | ||
"devices": "Immersioni elenco", | ||
"ip": "IP", | ||
"looking for device": "Cerca dispositivi", | ||
"name": "Nome", | ||
"on save adapter restarts with new config immediately": "salva adattatore riavvia con la nuova config immediatamente", | ||
"pollIntervall": "Sondaggio Intervall", | ||
"port": "Porta", | ||
"type": "Tipo" | ||
} | ||
"Cannot find any device": "Non riesco a trovare alcun dispositivo", | ||
"Discover devices": "Scopri i dispositivi", | ||
"IP Address": "Indirizzo IP", | ||
"Type": "Tipo", | ||
"Port": "Porta", | ||
"Poll interval (sec)": "Intervallo di polling (sec)" | ||
} |
{ | ||
"AddDevice": "Voeg # -knop toe om apparaat toe te voegen", | ||
"Cannot find any device": "Kan geen nieuwe apparaten vinden", | ||
"Enable adapter first": "Schakel eerst de adapter in", | ||
"Find a device": "Zoek een apparaat", | ||
"Please wait, looking for devices...": "Even geduld aub...", | ||
"Select a device": "Selecteer een apparaat", | ||
"Settings": "instellingen", | ||
"WiFi Light": "WiFi licht", | ||
"devices": "Duiklijst", | ||
"ip": "IK P", | ||
"looking for device": "Op zoek naar apparaten", | ||
"name": "Naam", | ||
"on save adapter restarts with new config immediately": "on save adapter wordt onmiddellijk opnieuw gestart met nieuwe configuratie", | ||
"pollIntervall": "Poll Intervall", | ||
"port": "Haven", | ||
"type": "Type" | ||
} | ||
"Cannot find any device": "Kan geen enkel apparaat vinden", | ||
"Discover devices": "Ontdek apparaten", | ||
"IP Address": "IP-adres", | ||
"Type": "Type", | ||
"Port": "Haven", | ||
"Poll interval (sec)": "Poll-interval (sec)" | ||
} |
{ | ||
"AddDevice": "Dodaj #-przycisk, aby dodać urządzenie", | ||
"Cannot find any device": "Nie mogę znaleźć nowych urządzeń", | ||
"Enable adapter first": "Włączyć zasilacz pierwszy", | ||
"Find a device": "Znaleźć urządzenie", | ||
"Please wait, looking for devices...": "Proszę czekać...", | ||
"Select a device": "Wybierz urządzenie", | ||
"Settings": "Parametry", | ||
"WiFi Light": "Bezprzewodowy Światło", | ||
"devices": "Lista nurkowania ", | ||
"ip": "IZ", | ||
"looking for device": "Szukam urządzeniach", | ||
"name": "Nazwa", | ||
"on save adapter restarts with new config immediately": "zapisz ponownym uruchomieniu zasilacza z nowy konfig raz", | ||
"pollIntervall": "Interwał Sondowania ", | ||
"port": "Port", | ||
"type": "Typ" | ||
} | ||
"Cannot find any device": "Nie można znaleźć żadnego urządzenia", | ||
"Discover devices": "Odkryj urządzenia", | ||
"IP Address": "Adres IP", | ||
"Type": "Typ", | ||
"Port": "Port", | ||
"Poll interval (sec)": "Interwał sondowania (sek.)" | ||
} |
{ | ||
"AddDevice": "Adicione # -Button para adicionar dispositivo", | ||
"Cannot find any device": "Não é possível encontrar novos dispositivos", | ||
"Enable adapter first": "Ativar o adaptador primeiro", | ||
"Find a device": "Encontre um dispositivo", | ||
"Please wait, looking for devices...": "Por favor, espere...", | ||
"Select a device": "Selecione um dispositivo", | ||
"Settings": "Configurações", | ||
"WiFi Light": "WiFi Light", | ||
"devices": "Lista de mergulhos", | ||
"ip": "IP", | ||
"looking for device": "Procurando dispositivos", | ||
"name": "Nome", | ||
"on save adapter restarts with new config immediately": "ao salvar o adaptador reinicia imediatamente com a nova configuração", | ||
"pollIntervall": "Poll Intervall", | ||
"port": "Porta", | ||
"type": "Tipo" | ||
} | ||
"Cannot find any device": "Não é possível encontrar nenhum dispositivo", | ||
"Discover devices": "Descobrir dispositivos", | ||
"IP Address": "Endereço IP", | ||
"Type": "Tipo", | ||
"Port": "Porta", | ||
"Poll interval (sec)": "Intervalo de pesquisa (seg)" | ||
} |
{ | ||
"AddDevice": "Добавить # -Кнопка для добавления устройства", | ||
"Cannot find any device": "Не могу найти новые устройства", | ||
"Enable adapter first": "Сначала включите адаптер", | ||
"Find a device": "Найти устройство", | ||
"Please wait, looking for devices...": "Пожалуйста, подождите...", | ||
"Select a device": "Выберите устройство", | ||
"Settings": "Settings", | ||
"WiFi Light": "Пример", | ||
"devices": "Список погружений", | ||
"ip": "IP", | ||
"looking for device": "Ищем устройства", | ||
"name": "имя", | ||
"on save adapter restarts with new config immediately": "Сразу после сохранения настроек драйвер перезапуститься с новыми значениями", | ||
"pollIntervall": "Опрос Интервал", | ||
"port": "порт", | ||
"type": "Тип" | ||
} | ||
"Cannot find any device": "Не удалось найти ни одно устройство.", | ||
"Discover devices": "Откройте для себя устройства", | ||
"IP Address": "IP-адрес", | ||
"Type": "Тип", | ||
"Port": "Порт", | ||
"Poll interval (sec)": "Интервал опроса (сек)" | ||
} |
{ | ||
"AddDevice": "添加#-添加装置", | ||
"Cannot find any device": "无法找到新的设备", | ||
"Enable adapter first": "第一个启用适配器", | ||
"Find a device": "找到一个设备", | ||
"Please wait, looking for devices...": "请等等...", | ||
"Select a device": "选择一个设备", | ||
"Settings": "设置", | ||
"WiFi Light": "无线光", | ||
"devices": "潜列表", | ||
"ip": "IP", | ||
"looking for device": "在寻找的设备", | ||
"name": "名称", | ||
"on save adapter restarts with new config immediately": "在保存适配器重新启动与新的配置立即", | ||
"pollIntervall": "调查区间", | ||
"port": "口", | ||
"type": "类型" | ||
} | ||
"Cannot find any device": "找不到任何设备", | ||
"Discover devices": "发现设备", | ||
"IP Address": "IP 地址", | ||
"Type": "类型", | ||
"Port": "港口", | ||
"Poll interval (sec)": "轮询间隔(秒)" | ||
} |
{ | ||
"common": { | ||
"name": "wifilight", | ||
"version": "1.3.5", | ||
"version": "2.0.0", | ||
"news": { | ||
"2.0.0": { | ||
"en": "The adapter was completely refactored\nAdded compact mode\nJSON config GUI added", | ||
"de": "Der Adapter wurde komplett überarbeitet\nKompakter Modus\nJSON config GUI hinzugefügt", | ||
"ru": "Адаптер был полностью рефакторирован\nДобавить компактный режим\nJSON config GUI добавлен", | ||
"pt": "O adaptador foi completamente refactored\nAdicionado modo compacto\nJSON config GUI adicionado", | ||
"nl": "De adapter was volledig gerefactoreerd\nCompacte modus toegevoegd\nJSON config GUI toegevoegd", | ||
"fr": "L'adaptateur a été complètement refacturé\nAjout du mode compact\nJSON config GUI ajouté", | ||
"it": "L'adattatore è stato completamente rifatto\nAggiunta modalità compatta\nJSON config GUI aggiunto", | ||
"es": "El adaptador fue completamente refactorizado\nModo compacto\nJSON config GUI agregó", | ||
"pl": "Adapter został całkowicie zrefakturowany\nDodano tryb kompaktowy\nDodano GUI konfiguracyjny JSON", | ||
"uk": "Адаптер повністю рефакторований\nДодано компактний режим\nJSON config GUI додано", | ||
"zh-cn": "适配器已完全重构\n添加紧凑模式\n添加 JSON 配置图形界面" | ||
}, | ||
"1.3.5": { | ||
@@ -83,15 +96,2 @@ "en": "Formatting of the code", | ||
"zh-cn": "依赖关系已更新" | ||
}, | ||
"1.2.0": { | ||
"en": "Adapter requires node.js 18 and js-controller >= 5 now\nDependencies have been updated", | ||
"de": "Adapter benötigt node.js 18 und js-controller >= 5 jetzt\nAbhängigkeiten wurden aktualisiert", | ||
"ru": "Адаптер требует node.js 18 и js-controller >= 5 сейчас\nЗависимость обновлена", | ||
"pt": "Adapter requer node.js 18 e js-controller >= 5 agora\nAs dependências foram atualizadas", | ||
"nl": "Adapter vereist node.js 18 en js-controller Nu 5\nAfhankelijkheden zijn bijgewerkt", | ||
"fr": "Adaptateur nécessite node.js 18 et js-controller >= 5 maintenant\nLes dépendances ont été actualisées", | ||
"it": "Adattatore richiede node.js 18 e js-controller >= 5 ora\nLe dipendenze sono state aggiornate", | ||
"es": "Adaptador requiere node.js 18 y js-controller √= 5 ahora\nSe han actualizado las dependencias", | ||
"pl": "Adapter wymaga node.js 18 i sterownika js- > = 5 teraz\nZaktualizowano zależności", | ||
"uk": "Адаптер вимагає node.js 18 і js-controller >= 5 тепер\nЗалежність було оновлено", | ||
"zh-cn": "适配器需要节点.js 18和js控制器 QQ 现在5号\n依赖关系已更新" | ||
} | ||
@@ -143,2 +143,3 @@ }, | ||
"enabled": true, | ||
"compact": true, | ||
"authors": [ | ||
@@ -166,8 +167,7 @@ { | ||
"adminUI": { | ||
"config": "html" | ||
"config": "json" | ||
}, | ||
"dataSource": "push", | ||
"connectionType": "local", | ||
"tier": 2, | ||
"compact": true | ||
"tier": 2 | ||
}, | ||
@@ -174,0 +174,0 @@ "native": { |
@@ -313,3 +313,3 @@ const VARS = { | ||
const MiLightRGB = Object.assign ({}, MiLight, { | ||
const MiLightRGB = Object.assign({}, MiLight, { | ||
g: 2, | ||
@@ -316,0 +316,0 @@ dimSteps: 9, |
@@ -6,24 +6,5 @@ /** | ||
**/ | ||
let adapter = null; | ||
"use strict"; | ||
const utils = require(`@iobroker/adapter-core`); | ||
if (!Object.assign) { | ||
Object.prototype.assign = function (target) { | ||
target = target || {}; | ||
for (let i = 1; i < arguments.length; i++) { | ||
const source = arguments[i]; | ||
for (const key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
} | ||
function hasProp (obj, propString) { | ||
function hasProp(obj, propString) { | ||
if (!obj) { | ||
@@ -43,510 +24,407 @@ return false; | ||
exports.hasProp = hasProp; | ||
exports.hasProperty = hasProp; | ||
const TR = { | ||
'\u00e4': 'ae', | ||
'\u00fc': 'ue', | ||
'\u00f6': 'oe', | ||
'\u00c4': 'Ae', | ||
'\u00d6': 'Oe', | ||
'\u00dc': 'Ue', | ||
'\u00df': 'ss', | ||
' ': '_', | ||
'.': '_', | ||
}; | ||
function getLastValidProp(obj, propString) { | ||
if (!obj) { | ||
return undefined; | ||
} | ||
const ar = propString.split('.'); | ||
const len = ar.length; | ||
for (let i = 0; i < len; i++) { | ||
if (obj[ar[i]] === undefined) { | ||
return obj; | ||
} | ||
obj = obj[ar[i]]; | ||
} | ||
return obj; | ||
function normalizedName(name) { | ||
return name.replace(/[\u00e4\u00fc\u00f6\u00c4\u00d6\u00dc\u00df .]/g, $0 => TR[$0]); | ||
} | ||
exports.getLastValidProp = getLastValidProp; | ||
function getLastValidPropEx(obj, propString) { | ||
if (!obj) { | ||
return undefined; | ||
} | ||
const ar = propString.split('.'); | ||
const len = ar.length; | ||
for (let i = 0; i < len; i++) { | ||
if (obj[ar[i]] === undefined) { | ||
let ret = { obj: {}, invalidName: '', errPath: '' }; | ||
try { | ||
ret = { | ||
obj, | ||
invalidName: ar[i], | ||
errPath: ar.slice(i).join('.'), | ||
}; | ||
} catch { | ||
// ignore | ||
} | ||
return ret; | ||
} | ||
obj = obj[ar[i]]; | ||
} | ||
return { obj: {}, invalidName: '', errPath: ''}; | ||
function idWithoutNamespace(id) { | ||
return id.substr(adapter.namespace.length + 1); | ||
} | ||
exports.getLastValidPropEx = getLastValidPropEx; | ||
function getProp(obj, propString) { | ||
if (!obj) { | ||
return undefined; | ||
function valType(val) { | ||
switch (val) { | ||
//fastest way for most states | ||
case true: | ||
return true; | ||
case false: | ||
return false; | ||
case 'true': | ||
return true; | ||
case 'false': | ||
return false; | ||
case '0': | ||
return 0; | ||
case '1': | ||
return 1; | ||
case '2': | ||
return 2; | ||
case '3': | ||
return 3; | ||
case '4': | ||
return 4; | ||
case '5': | ||
return 5; | ||
case '6': | ||
return 6; | ||
case '7': | ||
return 7; | ||
case '8': | ||
return 8; | ||
case '9': | ||
return 9; | ||
} | ||
const ar = propString.split('.'); | ||
const len = ar.length; | ||
for (let i = 0; i < len; i++) { | ||
obj = obj[ar[i]]; | ||
if (obj === undefined) { | ||
return undefined; | ||
} | ||
const number = parseInt(val); | ||
if (number.toString() === val) { | ||
return number; | ||
} | ||
return obj; | ||
} | ||
exports.getProp = getProp; | ||
function safeFunction(root, path, log) { | ||
const fn = getProp(root, path); | ||
if (typeof fn === 'function') { | ||
return fn; | ||
const float = parseFloat(val); | ||
if (float.toString() === val) { | ||
return float; | ||
} | ||
if (log) { | ||
const err = getLastValidPropEx(root, path); | ||
if (typeof log !== 'function') { | ||
log = adapter.log.debug; | ||
} | ||
log(`${err.errPath} is not a function (${path})`); | ||
} | ||
return function (params, callback) { | ||
if (!arguments.length) { | ||
return; | ||
} | ||
const fn = arguments[arguments.length - 1]; | ||
if (typeof fn === 'function') { | ||
fn(new Error(`${path} is not a function`)); | ||
} | ||
}; | ||
return val; | ||
} | ||
exports.safeFunction = safeFunction; | ||
exports.getFnProp = function (root, path, log) { | ||
if (typeof log !== 'function') { | ||
log = function() {}; | ||
} | ||
return safeFunction(root, path, log); | ||
}; | ||
//////////////////////////////////////////////////////////////////////////////////// | ||
function _fullExtend(dest, from) { | ||
const props = Object.getOwnPropertyNames(from); | ||
let destination; | ||
var njs = { | ||
pasProp: hasProp, | ||
iscb: function (cb) { | ||
return typeof cb === 'function'; | ||
}, | ||
bind: function(func, that) { | ||
return function() { | ||
return func.apply(that, arguments); | ||
}; | ||
}, | ||
_fullExtend: function (dest, from) { | ||
const props = Object.getOwnPropertyNames(from); | ||
let destination; | ||
props.forEach(function (name) { | ||
if (typeof from[name] === 'object') { | ||
if (typeof dest[name] !== 'object') { | ||
dest[name] = {}; | ||
} | ||
_fullExtend(dest[name],from[name]); | ||
} else { | ||
destination = Object.getOwnPropertyDescriptor(from, name); | ||
Object.defineProperty(dest, name, destination); | ||
props.forEach(name => { | ||
if (typeof from[name] === 'object') { | ||
if (typeof dest[name] !== 'object') { | ||
dest[name] = {}; | ||
} | ||
}); | ||
}, | ||
fullExtend: function (dest, from) { | ||
_fullExtend(dest, from); | ||
return dest; | ||
}, | ||
clone: function (from) { | ||
const props = Object.getOwnPropertyNames(from); | ||
let destination; | ||
const dest = {}; | ||
props.forEach(function (name) { | ||
if (from[name] instanceof Array) { | ||
//dest[name] = new Array(from[name]); | ||
dest[name] = [].concat(from[name]); | ||
} else if (typeof from[name] === 'object') { | ||
if (typeof dest[name] !== 'object') { | ||
dest[name] = {}; | ||
} | ||
_fullExtend(dest[name],from[name]); | ||
} else { | ||
destination = Object.getOwnPropertyDescriptor(from, name); | ||
Object.defineProperty(dest, name, destination); | ||
} | ||
}); | ||
return dest; | ||
}, | ||
safeCallback: function safeCallback(callback, val1, val2) { | ||
if (njs.iscb(callback)) { | ||
callback(val1, val2); | ||
_fullExtend(dest[name],from[name]); | ||
} else { | ||
destination = Object.getOwnPropertyDescriptor(from, name); | ||
Object.defineProperty(dest, name, destination); | ||
} | ||
}, | ||
}); | ||
} | ||
forEachArrayCallback: function forEachArrayCallback (arr, readyCallback, func) { | ||
var cnt = -1, len = arr.length; | ||
function fullExtend(dest, from) { | ||
_fullExtend(dest, from); | ||
return dest; | ||
} | ||
function doit() { | ||
if (++cnt >= len) { | ||
return readyCallback && readyCallback(); | ||
} | ||
func(arr[cnt], doit); | ||
} | ||
doit(); | ||
}, | ||
function clone(from) { | ||
const props = Object.getOwnPropertyNames(from); | ||
let destination; | ||
const dest = {}; | ||
forEachCB: function (maxcnt, func, readyCallback) { | ||
var cnt = -1; | ||
function doit(ret) { | ||
if (++cnt >= maxcnt) { | ||
return njs.safeCallback(readyCallback, ret); | ||
props.forEach(function (name) { | ||
if (from[name] instanceof Array) { | ||
//dest[name] = new Array(from[name]); | ||
dest[name] = [].concat(from[name]); | ||
} else if (typeof from[name] === 'object') { | ||
if (typeof dest[name] !== 'object') { | ||
dest[name] = {}; | ||
} | ||
func(cnt, doit); | ||
_fullExtend(dest[name],from[name]); | ||
} else { | ||
destination = Object.getOwnPropertyDescriptor(from, name); | ||
Object.defineProperty(dest, name, destination); | ||
} | ||
}); | ||
return dest; | ||
} | ||
doit(-1); | ||
}, | ||
forEachSync: function (maxcnt, func, readyCallback) { | ||
var cnt = -1; | ||
function arrayToHex(ar, len) { | ||
const s = []; | ||
if (len === undefined) { | ||
len = ar.length; | ||
} | ||
for (let i = 0; i < len; i++) { | ||
s.push(ar[i].toString(16).padStart(2, '0')); | ||
} | ||
return s.join(' '); | ||
} | ||
function doit(ret) { | ||
if (++cnt >= maxcnt) { | ||
return njs.safeCallback(readyCallback, ret); | ||
} | ||
func(cnt, doit); | ||
function forEachObjSync(_objects, step, func, readyCallback) { | ||
if (typeof step === 'function') { | ||
readyCallback = func; | ||
func = step; | ||
step = 1; | ||
} | ||
let objs = []; | ||
if (!(_objects instanceof Array)) { | ||
for (const i in _objects) { | ||
objs.push(i); | ||
} | ||
} else { | ||
objs = _objects; | ||
} | ||
const pop = step === -1 ? objs.pop : objs.shift; | ||
doit(-1); | ||
}, | ||
forEachObjSync: function (objects, step, func, readyCallback) { | ||
if(typeof step === 'function') { | ||
readyCallback = func; | ||
func = step; | ||
step = 1; | ||
} | ||
var objs = []; | ||
if (!(objects instanceof Array)) { | ||
for (var i in objects) { | ||
objs.push(i); | ||
function doit(ret) { | ||
if (objs.length <= 0) { | ||
if (typeof readyCallback === 'function') { | ||
readyCallback(ret); | ||
} | ||
} else { | ||
objs = objects; | ||
} | ||
var pop = step == -1 ? objs.pop : objs.shift; | ||
function doit(ret) { | ||
if (objs.length <= 0) { | ||
return safeCallback(readyCallback, ret); | ||
} | ||
func(pop.call(objs), doit); | ||
} | ||
} | ||
doit(-1); | ||
}, | ||
doit(-1); | ||
} | ||
dcs: function (deviceName, channelName, stateName) { | ||
if (stateName === undefined) { | ||
stateName = channelName; | ||
channelName = ''; | ||
function dcs(deviceName, channelName, stateName) { | ||
if (stateName === undefined) { | ||
stateName = channelName; | ||
channelName = ''; | ||
} | ||
if (stateName[0] === '.') { | ||
return stateName.substr(1); | ||
} | ||
let ret = ''; | ||
const ar = [deviceName, channelName, stateName]; | ||
for (let i = 0; i < ar.length; i++) { | ||
const s = ar[i]; | ||
if (!ret) { | ||
ret = s; | ||
} else if (s) { | ||
ret += `.${s}`; | ||
} | ||
if (stateName[0] === '.') { | ||
return stateName.substr(1); | ||
} | ||
var ret = ''; | ||
var ar = [deviceName, channelName, stateName]; | ||
for (var i = 0; i < ar.length; i++) { | ||
var s = ar[i]; | ||
if (!ret) ret = s; | ||
else if (s) ret += '.' + s; | ||
} | ||
return ret; | ||
}, | ||
} | ||
return ret; | ||
} | ||
pattern2RegEx: function (pattern) { | ||
if (pattern != '*') { | ||
if (pattern[0] == '*' && pattern[pattern.length - 1] != '*') pattern += '$'; | ||
if (pattern[0] != '*' && pattern[pattern.length - 1] == '*') pattern = '^' + pattern; | ||
function _setObjectName(o, name) { | ||
if (!o.common) { | ||
o.common = { name }; | ||
} else { | ||
o.common.name = name; | ||
} | ||
} | ||
function val2obj(valOrObj, name) { | ||
let obj; | ||
if (valOrObj && typeof valOrObj === 'object') { | ||
obj = valOrObj || {}; | ||
} else { | ||
obj = {}; | ||
if (valOrObj !== null && valOrObj !== undefined) { | ||
obj.val = valType(valOrObj); | ||
} else { | ||
obj.val = null; | ||
} | ||
pattern = pattern.replace(/\./g, '\\.'); | ||
pattern = pattern.replace(/\*/g, '.*'); | ||
return pattern; | ||
}, | ||
} | ||
if (name && !obj?.common?.name) { | ||
_setObjectName(obj, name); | ||
} | ||
return obj; | ||
} | ||
tr: { | ||
'\u00e4': 'ae', | ||
'\u00fc': 'ue', | ||
'\u00f6': 'oe', | ||
'\u00c4': 'Ae', | ||
'\u00d6': 'Oe', | ||
'\u00dc': 'Ue', | ||
'\u00df': 'ss', | ||
' ': '_', | ||
'.': '_' | ||
}, | ||
//////////////////////////////////////////////////////////////////////////////////// | ||
normalizedName: function (name) { | ||
return name.replace(/[\u00e4\u00fc\u00f6\u00c4\u00d6\u00dc\u00df .]/g, function ($0) { | ||
return njs.tr[$0] | ||
}) | ||
}, | ||
function CDevice(_name, _devices) { | ||
let deviceName = ''; | ||
let channelName = ''; | ||
this.devices = _devices; | ||
this.list = this.devices.list; | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
idWithoutNamespace: function (id, _adapter) { | ||
if (_adapter == undefined) _adapter = adapter; | ||
return id.substr(_adapter.namespace.length+1); | ||
}, | ||
removeAllObjects: function (adapter, callback) { | ||
adapter.getStates('*', function (err, states) { | ||
var st = []; | ||
for (var i in states) { | ||
st.push(i); | ||
this.push = function (obj) { | ||
for (let i = 0; i < this.list.length; i++) { | ||
if (this.list[i]._id === obj._id) { | ||
return fullExtend(this.list[i], obj); | ||
} | ||
var s = 0; | ||
} | ||
this.list.push(obj); | ||
return obj; | ||
}; | ||
function dels() { | ||
this.setDevice = function (name, options) { | ||
channelName = ''; | ||
if (!name) { | ||
return; | ||
} | ||
deviceName = normalizedName(name); | ||
const obj = { type: 'device', _id: deviceName }; | ||
if (options) { | ||
Object.assign(obj, options); | ||
} | ||
return this.push(obj); | ||
}; | ||
if (s >= st.length) { | ||
adapter.getChannels(function (err, channels) { | ||
var c = 0; | ||
this.setDevice(_name); | ||
function delc() { | ||
if (c >= channels.length) { | ||
adapter.getDevices(function (err, devices) { | ||
var d = 0; | ||
function deld() { | ||
if (d >= devices.length) { | ||
callback(); | ||
return; | ||
} | ||
var did = devices[d++]._id; | ||
did = idWithoutNamespace(did); | ||
//adapter.delDevice(did, function(err,obj) { | ||
adapter.deleteDevice(did, function (err,obj) { | ||
deld(); | ||
}); | ||
} | ||
deld(); | ||
}); | ||
return; | ||
} | ||
adapter.deleteChannel(channels[c++]._id, function () { | ||
delc(); | ||
}); | ||
} | ||
delc(); | ||
}); | ||
return; | ||
this.setChannel = function (name, showNameOrObject) { | ||
if (name === undefined) { | ||
channelName = ''; | ||
} else { | ||
channelName = name; | ||
const id = dcs(deviceName, channelName); | ||
if (!this.devices.has(id)) { | ||
let obj; | ||
if (typeof showNameOrObject == 'object') { | ||
obj = { type: 'channel', _id: id, common: { name } }; | ||
if (showNameOrObject.common) { | ||
obj.common = showNameOrObject.common; | ||
} | ||
if (showNameOrObject.native) { | ||
obj.native = showNameOrObject.native; | ||
} | ||
} else { | ||
obj = { type: 'channel', _id: id, common: { name: showNameOrObject || name }}; | ||
} | ||
var nid = st[s++]; | ||
adapter.delState(nid, function () { | ||
adapter.delObject(nid, function() { | ||
dels(); | ||
}); | ||
}); | ||
return this.push(obj); | ||
} | ||
dels(); | ||
}); | ||
}, | ||
} | ||
}; | ||
REMOVE_ALL: function (adapter, callback) { | ||
if (callback) callback(); | ||
}, | ||
this.split = function (id, valOrObj) { | ||
const ar = (id && id[0] === '.' ? id.substr(1) : dcs(deviceName, channelName, id)) | ||
.split('.'); | ||
valtype: function (val) { | ||
switch (val) { | ||
//fastest way for most states | ||
case true: | ||
return true; | ||
case false: | ||
return false; | ||
case 'true': | ||
return true; | ||
case 'false': | ||
return false; | ||
case '0': | ||
return 0; | ||
case '1': | ||
return 1; | ||
case '2': | ||
return 2; | ||
case '3': | ||
return 3; | ||
case '4': | ||
return 4; | ||
case '5': | ||
return 5; | ||
case '6': | ||
return 6; | ||
case '7': | ||
return 7; | ||
case '8': | ||
return 8; | ||
case '9': | ||
return 9; | ||
const dName = deviceName, cName = channelName; | ||
if (ar.length === 3) { | ||
this.setDevice(ar.shift()); | ||
this.setChannel(ar.shift()); | ||
const ret = this.addEx(ar[0], valOrObj); | ||
deviceName = dName; | ||
channelName = cName; | ||
return ret; | ||
} | ||
var number = parseInt(val); | ||
if (number.toString() === val) return number; | ||
var float = parseFloat(val); | ||
if (float.toString() === val) return float; | ||
return val; | ||
}, | ||
formatValue: function (value, decimals, _format) { | ||
if (_format === undefined) _format = ".,"; | ||
if (typeof value !== "number") { | ||
value = parseFloat(value); | ||
if (ar.length === 2) { | ||
this.setChannel(ar.shift()); | ||
const ret = this.addEx(ar[0], valOrObj); | ||
deviceName = dName; | ||
channelName = cName; | ||
return ret; | ||
} | ||
var ret = isNaN(value) ? "" : value.toFixed(decimals || 0).replace(_format[0], _format[1]).replace(/\B(?=(\d{3})+(?!\d))/g, _format[0]); | ||
return (ret); | ||
} | ||
const ret = this.addEx(ar[0], valOrObj); | ||
deviceName = dName; | ||
channelName = cName; | ||
return ret; | ||
}; | ||
}; | ||
this.addEx = function (name, valOrObj) { | ||
if (valOrObj === null) { | ||
return; | ||
} | ||
if (name.includes('.')) { | ||
return this.split(name, valOrObj); | ||
} | ||
const obj = val2obj(valOrObj, name); | ||
obj._id = dcs(deviceName, channelName, name); | ||
obj.type = 'state'; | ||
return this.push(obj); | ||
}; | ||
for (var i in njs) { | ||
global[i] = njs[i]; | ||
} | ||
this.set = function (id, newObj) { | ||
const _id = dcs(deviceName, channelName, id); | ||
if (!this.devices.objects[_id]) { | ||
return this.addEx(id, newObj); | ||
} | ||
function extendGlobalNamespace() { | ||
for (var i in njs) { | ||
global[i] = njs[i]; | ||
} | ||
} | ||
const val = newObj !== null && newObj.val !== undefined ? newObj.val : newObj; | ||
var adapter; | ||
function errmsg () { | ||
console.debug('adapter not assigned, use Device.setAdapter(yourAdapter)'); | ||
} | ||
if (this.devices.objects[_id].val !== val) { | ||
this.devices.setState(_id, val, true); | ||
return true; | ||
} | ||
return false; // objects[_id]; | ||
}; | ||
if (hasProp(module, 'parent.exports.adapter')) { | ||
adapter = module.parent.exports.adapter; | ||
} else { | ||
adapter = { | ||
setState: errmsg, | ||
setObject: errmsg, | ||
setObjectNotExists: errmsg, | ||
getStates: errmsg | ||
this.getObjectEx = function (id) { | ||
id = dcs(deviceName, channelName, id); | ||
return this.devices.getObjectEx(id); | ||
}; | ||
} | ||
var objects = {}; | ||
this.getFullId = function (id) { | ||
return dcs(deviceName, channelName, id); | ||
}; | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
this.get = function(channel, id) { | ||
if (!id) { | ||
id = dcs(deviceName, channelName, channel); | ||
} else { | ||
id = dcs(deviceName, channel, id); | ||
} | ||
return this.devices.objects[id]; | ||
}; | ||
function setObject(id, obj, options, callback) { | ||
return adapter.setObject(id, obj, options, callback); | ||
} | ||
function getObject(id, options, callback) { | ||
return adapter.getObject(id, options, callback); | ||
} | ||
function setState(id, val, ack) { | ||
//ack = ack || true; | ||
if (ack === undefined) ack = true; | ||
adapter.setState(id, val, ack); | ||
} | ||
function setObjectNotExists(id, newObj, callback) { | ||
getObject(id, {}, function (err, o) { | ||
if (!o) { | ||
setObject(id, newObj, {}, callback) | ||
this.createNew = function (id, newObj) { | ||
if (this.get(id)) { | ||
return; | ||
} | ||
safeCallback(callback, "exists", o); | ||
}) | ||
this.set(id, newObj); | ||
}; | ||
this.update = function (callback) { | ||
if (this.list.length) { | ||
this.devices.update(this.list, callback); | ||
} else if (typeof callback === 'function') { | ||
callback(); | ||
} | ||
}; | ||
} | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
//////////////////////////////////////////////////////////////////////////////////// | ||
function Devices (_adapter, _callback) { | ||
if (!_adapter || !_adapter.adapterDir) { | ||
_callback = _adapter; | ||
_adapter = undefined; | ||
} | ||
var that = this; | ||
function Devices() { | ||
this.adapter = null; | ||
this.list = []; | ||
this.objects = {}; | ||
this.setAdapter = function (_adapter) { | ||
this.adapter = _adapter; | ||
adapter = _adapter; | ||
}; | ||
this.has = function (id, prop) { | ||
var b = objects.hasOwnProperty(id); | ||
if (prop === undefined) return b; | ||
return (b && objects[id] !== null && objects[id].hasOwnProperty(prop)); | ||
const b = Object.prototype.hasOwnProperty.call(this.objects, id); | ||
if (prop === undefined) { | ||
return b; | ||
} | ||
return b && this.objects[id] !== null && Object.prototype.hasOwnProperty.call(this.objects[id], prop); | ||
}; | ||
this.get = function (id) { | ||
return (objects[id]); | ||
return this.objects[id]; | ||
}; | ||
this.remove = function(id) { | ||
delete objects[id]; | ||
this.remove = function (id) { | ||
delete this.objects[id]; | ||
}; | ||
this.setraw = function (id, obj) { | ||
objects[id] = obj; | ||
this.removeWithoutNameSpace = function (id) { | ||
delete this.objects[idWithoutNamespace(id)]; | ||
}; | ||
this.getobjex = function (id) { | ||
var obj = this.get(id); | ||
if (obj || !adapter || !adapter.namespace) { | ||
this.setRaw = function (id, obj) { | ||
this.objects[id] = obj; | ||
}; | ||
this.getObjectEx = function (id) { | ||
const obj = this.get(id); | ||
if (obj || !this.adapter || !this.adapter.namespace) { | ||
return obj; | ||
} | ||
id = id.substr(adapter.namespace.length+1); | ||
return objects[id]; | ||
id = id.substr(this.adapter.namespace.length+1); | ||
return this.objects[id]; | ||
}; | ||
this._getobjex = function(id) { | ||
return this.getobjex(id) || { val: undefined }; | ||
this._getObjectEx = function(id) { | ||
return this.getObjectEx(id) || { val: undefined }; | ||
}; | ||
this.getval = function (id, _default) { | ||
var o = this.get(id); | ||
if (o && o.val !== undefined) return o.val; | ||
return _default; | ||
}; | ||
this.invalidate = function (id) { | ||
this._getobjex(id).val = undefined; | ||
this._getObjectEx(id).val = undefined; | ||
}; | ||
this.setrawval = function (id, val) { | ||
this._getobjex(id).val = val; | ||
}; | ||
this.getKeys = function (pattern) { | ||
var r = new RegExp(pattern2RegEx(pattern)); | ||
var result = []; | ||
for (var id in objects) { | ||
if (r.test(id)) result.push(id); | ||
} | ||
return result; | ||
}; | ||
this.foreach = function (pattern, callback) { | ||
var r = new RegExp(pattern2RegEx(pattern)); | ||
for (var id in objects) { | ||
if (r.test(id)) { | ||
if (callback (id, objects[id]) === false) { | ||
return { id: id, val: objects[id]}; | ||
} | ||
this.setObjectNotExists = function (id, newObj, callback) { | ||
this.adapter.getObject(id, (err, o) => { | ||
if (!o) { | ||
this.adapter.setObject(id, newObj, {}, callback); | ||
} else if (typeof callback === 'function') { | ||
callback('exists', o); | ||
} | ||
} | ||
}); | ||
}; | ||
this.createObjectNotExists = function (id, obj, callback) { | ||
var val; | ||
var newobj = { | ||
let val; | ||
const newobj = { | ||
type: 'state', | ||
@@ -569,11 +447,12 @@ common: { | ||
} | ||
setObjectNotExists(id, newobj, function(err, o) { | ||
this.setObjectNotExists(id, newobj, (err, o) => { | ||
if (!err) { | ||
//that.states[newobj._id] = newobj; | ||
objects[newobj._id] = newobj; | ||
this.objects[newobj._id] = newobj; | ||
if (val !== undefined) { | ||
that.setState(newobj._id, val, true); | ||
this.setState(newobj._id, val, true); | ||
} | ||
} | ||
safeCallback(callback, err, o); | ||
if (typeof callback === 'function') { | ||
callback(err, o); | ||
} | ||
}); | ||
@@ -583,7 +462,8 @@ }; | ||
this.setState = function (id, val, ack) { | ||
if (val !== undefined) objects[id].val = val; | ||
else val = objects[id].val; | ||
//ack = ack || true; | ||
if (ack === undefined) ack=true; | ||
setState(id, val, ack); | ||
if (val !== undefined) { | ||
this.objects[id].val = val; | ||
} else { | ||
val = this.objects[id].val; | ||
} | ||
this.adapter.setState(id, val, ack === undefined ? true : ack); | ||
}; | ||
@@ -599,51 +479,15 @@ | ||
} | ||
if (ack === undefined) ack = true; | ||
if (!that.has(id)) { | ||
that.createObjectNotExists(id, newObj, callback); | ||
} else { | ||
if (objects[id].val !== newObj.val) { | ||
that.setState(id, newObj.val, ack); | ||
} | ||
safeCallback(callback, 0); | ||
if (ack === undefined) { | ||
ack = true; | ||
} | ||
}; | ||
function val2obj(valOrObj, showName) { | ||
//if (valOrObj === null) return; | ||
//if (!valOrObj) return; | ||
if (typeof valOrObj === 'object') { | ||
var obj = valOrObj || {}; | ||
if (!this.has(id)) { | ||
this.createObjectNotExists(id, newObj, callback); | ||
} else { | ||
var obj = {}; | ||
if (valOrObj !== undefined) { | ||
obj.val = valtype(valOrObj); | ||
if (this.objects[id].val !== newObj.val) { | ||
this.setState(id, newObj.val, ack); | ||
} | ||
} | ||
if (showName && !hasProp(obj, 'common.name')) { | ||
_setobjname(obj, showName); | ||
} | ||
return obj; | ||
} | ||
this.updateAsync = function (list, callback) { | ||
if (typeof list === 'function') { | ||
callback = list; | ||
list = null; | ||
} | ||
if (!list) { | ||
list = that.list; | ||
that.list = {}; | ||
} | ||
if (!list) return callback(-1); | ||
if (Array.isArray(list)) { | ||
for (var i=0; i<list.length; i++) { | ||
var objName = Object.keys( list[i] )[ 0 ]; | ||
this.setStateEx(objName, list[i][objName]); | ||
if (typeof callback === 'function') { | ||
callback(0); | ||
} | ||
} else { | ||
for (var id in list) { | ||
this.setStateEx(id, list[id]); | ||
} | ||
} | ||
safeCallback(callback, 0); | ||
}; | ||
@@ -656,97 +500,60 @@ | ||
} | ||
if (!list || that.list === list) { | ||
//list = that.list; | ||
//that.list = []; | ||
//if (that.root.list) that.root.list = that.list; | ||
list = that.list.slice(); | ||
that.list.length = 0; | ||
if (!list || this.list === list) { | ||
list = this.list.slice(); | ||
this.list.length = 0; | ||
} | ||
if (!list || list.length == 0) return safeCallback(callback, -1); | ||
if (!list?.length) { | ||
if (typeof callback === 'function') { | ||
callback(-1); | ||
} | ||
return; | ||
} | ||
forEachObjSync(list, function (obj, doit) { | ||
that.setStateEx(obj._id, obj, true, doit); | ||
}, | ||
callback | ||
forEachObjSync( | ||
list, | ||
(obj, doit) => this.setStateEx(obj._id, obj, true, doit), | ||
callback, | ||
); | ||
}; | ||
function _setobjname(o, name) { | ||
if (o['common'] === undefined) { | ||
o['common'] = { name: name}; | ||
} else { | ||
o.common['name'] = name; | ||
} | ||
} | ||
this.setObjectName = function (id, name) { | ||
if (!objects[id] || !objects[id].common || !objects[id].common.name) { | ||
var o = {common: {name: ''} }; | ||
if (!objects[id]) { | ||
objects[id] = {}; | ||
} | ||
_setobjname(objects[id], ''); | ||
} | ||
if (objects[id].common.name !== name) { | ||
adapter.getObject(id, {}, function (err, obj) { | ||
if (err || !obj) { | ||
return; | ||
} | ||
if (obj.common.name !== name) { | ||
obj.common.name = name; | ||
adapter.setObject(id, obj); | ||
} | ||
objects[id].common.name = name; | ||
}); | ||
} | ||
}; | ||
this.readAllExistingObjects = function (callback) { | ||
adapter.getForeignStates(adapter.namespace + '.*', {}, function(err, states) { | ||
if (err || !states) return callback(-1); | ||
var namespacelen = adapter.namespace.length + 1; | ||
for (var fullId in states) { | ||
var id = fullId.substr(namespacelen), | ||
as = id.split('.'), | ||
s = as[0]; | ||
for (var i=1; i<as.length; i++) { | ||
//if (!that.has(s)) that.setraw(s, { exist: true }); | ||
//!! | ||
if (!that.has(s)) that.setraw(s, {}); | ||
s += '.' + as[i]; | ||
} | ||
that.setraw(id, { val: states[fullId] ? states[fullId].val : null}); | ||
this.adapter.getForeignStates(`${this.adapter.namespace}.*`, {}, (err, states) => { | ||
if (err || !states) { | ||
return callback(-1); | ||
} | ||
function setObjectProperty(obj, names, val) { | ||
var dot = names.indexOf('.'); | ||
if (dot > 0) { | ||
var n = names.substr(0, dot-1); | ||
if (obj[n] === undefined) { | ||
obj[n] = {}; | ||
const namespaceLen = this.adapter.namespace.length + 1; | ||
for (const fullId in states) { | ||
const id = fullId.substr(namespaceLen); | ||
const as = id.split('.'); | ||
let s = as[0]; | ||
for (let i = 1; i < as.length; i++) { | ||
if (!this.has(s)) { | ||
this.setRaw(s, {}); | ||
} | ||
setObjectProperty(obj[n], names.substr(dot+1), val); | ||
s += `.${as[i]}`; | ||
} | ||
obj[names] = val; | ||
this.setRaw(id, { val: states[fullId] ? states[fullId].val : null }); | ||
} | ||
const _objects = this.objects; | ||
function doIt(list) { | ||
for (var i = 0; i < list.length; i++) { | ||
var id = list[i]._id.substr(namespacelen); | ||
var o = {common: {name: list[i].common.name}}; | ||
if (!objects[id]) { | ||
objects[id] = {}; | ||
}; | ||
for (let i = 0; i < list.length; i++) { | ||
const id = list[i]._id.substr(namespaceLen); | ||
const o = { common: { name: list[i].common.name } }; | ||
_objects[id] = _objects[id] || {}; | ||
if (list[i].native !== undefined) { | ||
o['native'] = list[i].native; | ||
} | ||
fullExtend(objects[id], o); | ||
fullExtend(_objects[id], o); | ||
} | ||
} | ||
adapter.getDevices(function (err, devices) { | ||
!err && devices && doIt(devices); | ||
adapter.getChannels('', function (err, channels) { | ||
this.adapter.getDevices((err, _devices) => { | ||
!err && _devices && doIt(_devices); | ||
this.adapter.getChannels('', (err, channels) => { | ||
!err && channels && doIt(channels); | ||
safeCallback(callback, 0); | ||
if (typeof callback === 'function') { | ||
callback(0); | ||
} | ||
}); | ||
@@ -757,221 +564,7 @@ }); | ||
this.CDevice = function CDevice (_name, showName, list) { | ||
//if (!(this instanceof that.CDevice)) { | ||
// return new that.CDevice(_name, showName, list); | ||
//} | ||
var deviceName = '', channelName = ''; | ||
var self = this; | ||
this.list = (list === undefined) ? that.list : list; | ||
function push (obj) { | ||
for (var i=0; i<self.list.length; i++) { | ||
if (self.list[i]._id === obj._id) { | ||
return fullExtend(self.list[i], obj); | ||
} | ||
} | ||
self.list.push(obj); | ||
return obj; | ||
} | ||
this.setDevice = function (name, options) { | ||
channelName = ""; | ||
if (!name) return; | ||
deviceName = normalizedName (name); | ||
var obj = { type: 'device', _id: deviceName }; | ||
if (options) { | ||
Object.assign(obj, options); | ||
} | ||
return push(obj); | ||
}; | ||
this.setDevice(_name, showName && typeof showName == 'string' ? {common: {name: showName}} : showName); | ||
this.setObjectName = function (id, showName) { | ||
for (var i=0; i<self.list.length; i++) { | ||
if (self.list[i]._id == id) { | ||
_setobjname(self.list[i], showName); | ||
return i; | ||
} | ||
} | ||
return -1; | ||
}; | ||
this.setChannel = function (name, showNameOrObject) { | ||
if (name === undefined) channelName = ""; | ||
else { | ||
channelName = name; | ||
var id = dcs(deviceName, channelName); | ||
if (!that.has(id)) { | ||
if (typeof showNameOrObject == 'object') { | ||
var obj = {type: 'channel', _id: id, common: {name: name} }; | ||
if (showNameOrObject.common) obj.common = showNameOrObject.common; | ||
if (showNameOrObject.native) obj.native = showNameOrObject.native; | ||
} else { | ||
var obj = {type: 'channel', _id: id, common: {name: showNameOrObject || name}}; | ||
} | ||
return push(obj); | ||
} | ||
} | ||
}; | ||
this.setChannelEx = function (name, showNameOrObject) { | ||
if (name === undefined) channelName = ""; | ||
else { | ||
channelName = normalizedName(name); | ||
var id = dcs(deviceName, channelName); | ||
if (!that.has(id)) { | ||
if (typeof showNameOrObject == 'object') { | ||
var obj = {type: 'channel', _id: id, common: {name: name} }; | ||
if (showNameOrObject.common) obj.common = showNameOrObject.common; | ||
if (showNameOrObject.native) obj.native = showNameOrObject.native; | ||
} else { | ||
var obj = {type: 'channel', _id: id, common: {name: showNameOrObject || name}}; | ||
} | ||
return push(obj); | ||
} | ||
} | ||
}; | ||
function split(id, valOrObj, showName) { | ||
var ar = ((id && id[0] == '.') ? id.substr(1) : dcs(deviceName, channelName, id)).split('.'); | ||
var dName = deviceName, cName = channelName; | ||
switch(ar.length) { | ||
case 3: | ||
self.setDevice(ar.shift()); | ||
case 2: | ||
self.setChannel(ar.shift()); | ||
default: | ||
var ret = add (ar[0], valOrObj, showName); | ||
deviceName = dName; | ||
channelName = cName; | ||
return ret; | ||
} | ||
} | ||
function add (name, valOrObj, showName) { | ||
//if (valOrObj === null) return; | ||
if (valOrObj == null) return; | ||
if (name.indexOf('.') >= 0) { | ||
return split(name, valOrObj, showName); | ||
} | ||
var obj = val2obj(valOrObj, showName || name); | ||
obj._id = dcs(deviceName, channelName, name); | ||
obj.type = 'state'; | ||
return push(obj); | ||
} | ||
function __setVal(_id, newObj) { | ||
var val = newObj['val'] !== undefined ? newObj.val : newObj; | ||
if (objects[_id].val !== val) { | ||
that.setState(_id, val, true); | ||
} | ||
} | ||
this.dset = function(d,s,v,showName) { | ||
var _id = dcs(d, '', s); | ||
if (!objects[_id]) { | ||
return add ('.'+_id, v, showName); | ||
} | ||
__setVal(_id, v); | ||
}; | ||
this.rset = function (id, newObj, showName) { | ||
return this.set('.' + id, newObj, showName); | ||
}; | ||
this.set = function (id, newObj, showName) { | ||
if (newObj == undefined) return; | ||
var _id = dcs(deviceName, channelName, id); | ||
if (!objects[_id]) { | ||
return add (id, newObj, showName); | ||
} | ||
var val = newObj['val'] !== undefined ? newObj.val : newObj; | ||
if (objects[_id].val !== val) { | ||
that.setState(_id, val, true); | ||
return true; | ||
} | ||
return false; //objects[_id]; | ||
}; | ||
this.setex = function (id, newObj, showName) { | ||
if (adapter && id.substr(0, adapter.namespace.length) == adapter.namespace) { | ||
id = id.substr(adapter.namespace.length+1); | ||
} | ||
return this.set(id, newObj, showName); | ||
}; | ||
this.getobjex = function (id) { | ||
var id = dcs(deviceName, channelName, id); | ||
return that.getobjex(id); | ||
}; | ||
this._getobjex = function(id) { | ||
return this.getobjex(id) || { val: undefined }; | ||
}; | ||
this.invalidate = function (id) { | ||
this._getobjex(id).val = undefined; | ||
}; | ||
this.setraw = function (id, val) { | ||
this._getobjex(id).val = val; | ||
}; | ||
this.setName = function (name) { | ||
var id = dcs(deviceName, channelName, ''); | ||
that.setObjectName(id, name); | ||
}; | ||
this.add = this.set; | ||
this.getFullId = function (id) { | ||
return dcs(deviceName, channelName, id); | ||
}; | ||
this.get = function(channel, id) { | ||
if (id == undefined) { | ||
var _id = dcs(deviceName, channelName, channel); | ||
} else { | ||
var _id = dcs(deviceName, channel, id); | ||
} | ||
return objects[_id] | ||
}; | ||
this.createNew = function (id, newObj, showName) { | ||
if (this.get(id)) return; | ||
this.set(id, newObj, showName); | ||
}; | ||
this.setAndUpdate = function (id, newObj) { | ||
this.set(id, newObj); | ||
this.update(); | ||
}; | ||
this.setImmediately = this.setAndUpdate; | ||
this.clear = function(id) { | ||
id = exports.ns.no (id); | ||
var st = that.getobjex(id); | ||
if (st === undefined) return; | ||
switch(typeof st.val) { | ||
case 'string': st = ''; break; | ||
case 'boolean': st = false; break; | ||
case 'number': st = 0; break; | ||
default: return; | ||
} | ||
this.setAndUpdate(id, st); | ||
}; | ||
this.update = function (callback) { | ||
if (this.list.length > 0) { | ||
that.update(this.list, callback); | ||
} else { | ||
safeCallback(callback); | ||
} | ||
}; | ||
}; | ||
this.CState = this.CDevice; | ||
this.root = new this.CDevice(''); | ||
this.init = function (_adapter, callback) { | ||
this.setAdapter(_adapter); | ||
exports.ns = CNamespace(_adapter); | ||
this.readAllExistingObjects(callback); | ||
}; | ||
if (_adapter) { | ||
this.init(_adapter, _callback); | ||
} | ||
return this; | ||
@@ -982,345 +575,31 @@ } | ||
var CNamespace = function (_adapter) { | ||
if (!(this instanceof CNamespace)) { | ||
return new CNamespace(_adapter); | ||
} | ||
const devices = new Devices(); | ||
var re = new RegExp('^' + _adapter.namespace + '.|^'); // new/^adapter.0.|^/, '') | ||
var isre = new RegExp('^' + _adapter.namespace); | ||
this.no = function no (s) { | ||
return s.replace(re, ''); | ||
}; | ||
this.remove = this.no; | ||
this.is = isre.test.bind(isre); //.bind(this); | ||
this.add = function add (s) { | ||
return s.replace(re, _adapter.namespace + '.') | ||
async function changeAdapterConfig(_adapter, changeCallback) { | ||
const obj = await _adapter.getForeignObjectAsync(`system.adapter.${_adapter.namespace}`); | ||
if (obj && !obj.native) { | ||
obj.native = {}; | ||
} | ||
this.add2 = function add (s) { | ||
return s.replace(re, _adapter.namespace + (s ? '.' : '')); | ||
if (obj && changeCallback(obj.native) !== false) { | ||
await _adapter.setForeignObject(obj._id, obj); | ||
_adapter.log.info('soef.changeAdapterConfig: changed'); | ||
} | ||
}; | ||
exports.CNamespace = CNamespace; | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
function parseIntVersion(vstr) { | ||
if (!vstr || vstr=='') return 0; | ||
var ar = vstr.toString().split('.'); | ||
var iVer = 0; | ||
for (var i=0; i<ar.length; i++) { | ||
iVer *= 1000; | ||
iVer += ar[i] >> 0; | ||
} | ||
return iVer; | ||
} | ||
function nop() {} | ||
function savePrevVersion() { | ||
if(!hasProp(adapter, 'ioPack.common.version')) return; | ||
var id = 'system.adapter.' + adapter.namespace; | ||
var vid = id + '.prevVersion'; | ||
function set() { | ||
adapter.setForeignState(vid, { val: adapter.ioPack.common.version, ack: true, from: id }); | ||
} | ||
adapter.getForeignObject(vid, function(err, obj) { | ||
if (err || !obj) { | ||
adapter.setForeignObject(vid, { | ||
type: 'state', | ||
common: {name: 'version', role: "indicator.state", desc: 'version check for updates', type: 'string'}, | ||
native: {} | ||
}, function (err, obj) { | ||
set(); | ||
}); | ||
return; | ||
} | ||
set(); | ||
}); | ||
} | ||
function checkIfUpdated(doUpdateCallback, callback) { | ||
if(!adapter) return safeCallback(callback); | ||
if (!callback) callback = nop; | ||
var id = 'system.adapter.' + adapter.namespace; | ||
var vid = id + '.prevVersion'; | ||
adapter.getForeignState(vid, function(err, state) { | ||
var prevVersion = 0; | ||
var aktVersion = parseIntVersion(adapter.ioPack.common.version); | ||
prevVersion = parseIntVersion(hasProp(state, 'val') ? state.val : '0'); | ||
if (prevVersion < aktVersion) { | ||
if (typeof doUpdateCallback == 'function') { | ||
doUpdateCallback(prevVersion, aktVersion, function (err) { | ||
savePrevVersion(); | ||
callback(); | ||
}); | ||
return; | ||
} else { | ||
savePrevVersion(); | ||
} | ||
} | ||
callback(); | ||
}); | ||
} | ||
function switchToDebug(force) { | ||
if (!adapter || !adapter.log) return; | ||
if (!force && !process.env.SOEF_DEBUG) return; | ||
adapter.log.debug = console.log; | ||
adapter.log.info = console.log; | ||
adapter.log.warn = console.log; | ||
module.parent.__DEBUG__ = true; | ||
} | ||
exports.switchToDebug = switchToDebug; | ||
function _main (_adapter, options, callback ) { | ||
if (!_adapter || !_adapter.adapterDir) { | ||
options = _adapter; | ||
callback = options; | ||
_adapter = adapter; | ||
} | ||
if (typeof options == 'function') { | ||
callback = options; | ||
options = {}; | ||
} | ||
var _devices; | ||
if (options.devices) { | ||
_devices = options.devices; | ||
} else { | ||
_devices = new Devices(); | ||
global.devices = _devices; | ||
} | ||
if (!options.doNotExportAdapter) { | ||
module.parent.exports = { | ||
adapter: _adapter | ||
}; | ||
} | ||
switchToDebug(); | ||
_devices.init(_adapter, function(err) { | ||
callback(); | ||
}); | ||
}; | ||
exports.main = _main; | ||
exports.Adapter = function (_args) { | ||
var args = arguments, | ||
fns = {}; | ||
for (var i=0; i<args.length; i++) { | ||
var param = args[i]; | ||
switch (typeof param) { | ||
case 'function': | ||
fns[param.name] = param; | ||
break; | ||
case 'object': | ||
fns.options = param; | ||
break; | ||
case 'string': | ||
fns.options = fns.options || {}; | ||
fns.options.name = param; | ||
break; | ||
} | ||
} | ||
if (!fns.adapter) { | ||
fns.adapter = utils.Adapter; | ||
} | ||
var options = fns.options; | ||
if (!options.unload) { | ||
options.unload = function (callback) { | ||
try { | ||
fns.onUnload ? onUnload(calback) : callback(); | ||
} catch (e) { | ||
callback(); | ||
} | ||
}; | ||
} | ||
if (!options.stateChange && fns.onStateChange) { | ||
options.stateChange = function (id, state) { | ||
if (state && !state.ack) { | ||
///!!/////xxxxxxxxxxx////////////////////////////////////// | ||
//var _id = id.substr(fns.adapter.namespace.length+1); | ||
//_id = id.slice(fns.adapter.namespace.length+1); | ||
//if (global.devices) { | ||
// global.devices.setrawval(_id, state.val); | ||
//} | ||
///////////////////////////////////////////////////////// | ||
fns.onStateChange(id, state); | ||
} | ||
}; | ||
} | ||
if (!options.ready && fns.main) { | ||
options.ready = function () { | ||
checkIfUpdated(fns.onUpdate, function() { | ||
_main(fns.main); | ||
}); | ||
}; | ||
} | ||
if (!options.objectChange) { | ||
options.objectChange = function (id, obj) { | ||
if (id && obj == null && global.devices) { | ||
global.devices.remove(idWithoutNamespace(id)); | ||
} | ||
}; | ||
} | ||
if (!options.message && fns.onMessage) { | ||
options.message = function(obj) { | ||
if (obj) fns.onMessage(obj); | ||
}; | ||
} | ||
fns.adapter = fns.adapter(options); | ||
if (!adapter || !adapter.adapterDir) { | ||
adapter = fns.adapter; | ||
} | ||
return fns.adapter; | ||
}; | ||
function changeAdapterConfig (_adapter, changeCallback, doneCallback) { | ||
_adapter.getForeignObject(`system.adapter.${_adapter.namespace}`, function (err, obj) { | ||
if (!err && obj && !obj.native) obj['native'] = {}; | ||
if (!err && obj && changeCallback(obj.native) !== false) { | ||
_adapter.setForeignObject(obj._id, obj, {}, function (err, s_obj) { | ||
_adapter.log.info('soef.changeAdapterConfig: changed'); | ||
//_adapter.config = obj.native; //?!? nrmalisieren fehlt dann!! | ||
//_adapter.normalizeConfig ... | ||
if (doneCallback) doneCallback(err, obj); | ||
}); | ||
} | ||
}); | ||
} | ||
exports.changeAdapterConfig = changeAdapterConfig; | ||
exports.changeConfig = function changeConfig(changeCallback, doneCallback) { | ||
if (!adapter) { | ||
return false; | ||
} | ||
return changeAdapterConfig(adapter, changeCallback, doneCallback); | ||
}; | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
exports.TimeDiff = function () { | ||
if (!(this instanceof exports.TimeDiff)) return new exports.TimeDiff(); | ||
this.get = process.hrtime; | ||
this.getDif = function() { | ||
var ar = this.get(); | ||
var start = this.start[0] * 1e9 + this.start[1]; | ||
var end = ar[0] * 1e9 + ar[1]; | ||
return end - start; | ||
}; | ||
this.getMillis = function() { | ||
return this.getDif() / 1000000 >> 0; | ||
}; | ||
this.getMicros = function() { | ||
return this.getDif() / 1000 >> 0; | ||
}; | ||
this.start = function () { | ||
this.start = this.get(); | ||
}; | ||
this.start = process.hrtime(); | ||
return this; | ||
}; | ||
exports.bufferIndexOf = function (buffer, search, offset, encoding){ | ||
if (!Buffer.isBuffer(buffer)) { | ||
return -1; | ||
} | ||
if (typeof offset === 'string') { | ||
encoding = offset; | ||
offset = 0; | ||
} | ||
switch (typeof search) { | ||
case 'string': | ||
search = new Buffer(search, encoding || 'utf8'); | ||
break; | ||
case 'number': | ||
search = new Buffer([search]); | ||
break; | ||
default: | ||
if (Array.isArray(search)) { | ||
break; | ||
} | ||
if (Buffer.isBuffer(search)) { | ||
break; | ||
} | ||
return -1; | ||
} | ||
var blen = buffer.length, | ||
slen = search.length; | ||
if (slen === 0) return -1; | ||
if (!offset || typeof offset != 'number') offset = 0; | ||
else if (offset < 0) offset = buffer.length + offset; | ||
if (offset < 0) offset = 0; | ||
for (var i=offset; i < blen; i++) { | ||
if (buffer[i] != search[0]) { | ||
continue; | ||
} | ||
for (var j=1; j < slen && i + j < blen; j++) { | ||
if (buffer[i+j] != search[j]) { | ||
break; | ||
} | ||
} | ||
if (j == slen) { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
}; | ||
exports.bufferSplit = function (buffer, delimiter) { | ||
const ar = []; | ||
let start; | ||
let idx; | ||
for (start = 0, idx = 0; start < buffer.length; ) { | ||
idx = bufferIndexOf(buffer, delimiter, start); | ||
if (idx < 0) { | ||
break; | ||
} | ||
ar.push(buffer.slice(start, idx)); | ||
start = idx+delimiter.length; | ||
} | ||
if (start <= buffer.length) { | ||
ar.push(buffer.slice(start, buffer.length)); | ||
} | ||
return ar; | ||
}; | ||
exports.bufferCat = function (buffer, chunk) { | ||
if (!chunk.length) return buffer; | ||
if (buffer && buffer.length) { | ||
const newBuffer = new Buffer(chunk.length + buffer.length); | ||
buffer.copy(newBuffer); | ||
chunk.copy(newBuffer,buffer.length); | ||
return newBuffer; | ||
} | ||
return chunk; | ||
}; | ||
exports.Timer = function Timer (func, timeout, v1) { | ||
if (!(this instanceof Timer)) { | ||
return new Timer(func, timeout, v1); | ||
} | ||
function Timer(func, timeout, v1) { | ||
let timer = null; | ||
this.inhibit = false; | ||
this.enable = function (bo) { this.inhibit = (bo === false); }; | ||
this.enable = function (bo) { | ||
this.inhibit = bo === false; | ||
}; | ||
this.set = function (func, timeout, v1) { | ||
if (timer) clearTimeout(timer); | ||
if (timer) { | ||
clearTimeout(timer); | ||
} | ||
if (this.inhibit) { | ||
return; | ||
} | ||
timer = setTimeout(function () { | ||
timer = setTimeout(() => { | ||
timer = null; | ||
@@ -1339,6 +618,2 @@ func(v1); | ||
}; | ||
this.clearAndInhibit = function () { | ||
this.inhibit = true; | ||
this.clear(); | ||
}; | ||
@@ -1348,193 +623,53 @@ if (func) { | ||
} | ||
}; | ||
} | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
njs.dcs._forEach = forEachInSystemObjectView; | ||
function forEachInSystemObjectView(type, id, readyCallback, callback) { | ||
adapter.getObjectView('system', type, {startkey: `${id}.`, endkey: `${id}.\u9999`}, null, function (err, res) { | ||
if (err || !res || !res.rows) return readyCallback && readyCallback(); | ||
let i = 0; | ||
function doIt() { | ||
if (i >= res.rows.length) { | ||
return readyCallback && readyCallback(); | ||
} | ||
const o = res.rows[i++]; | ||
if (o) { | ||
callback(o, doIt, type); | ||
} else { | ||
doIt(); | ||
} | ||
} | ||
doIt(); | ||
}); | ||
} | ||
njs.dcs.delOS = delObjectAndState; | ||
function delObjectAndState(id, options, callback) { | ||
if (typeof options == 'function') { | ||
callback = options; | ||
options = null; | ||
async function forEachInSystemObjectView(type, id, callback) { | ||
const res = await adapter.getObjectViewAsync('system', type, { startkey: `${id}.`, endkey: `${id}.\u9999` }); | ||
for (let j = 0; j < res.rows.length; j++) { | ||
await callback(res.rows[j], type); | ||
} | ||
adapter.delState(id, function(err) { | ||
adapter.delObject(id, options, function (err) { | ||
return callback && callback(); | ||
}); | ||
}); | ||
} | ||
// callback first all states, then all devices and then all channels | ||
njs.dcs.forEach = forEachObjectChild; | ||
function forEachObjectChild(id, options, readyCallback, callback) { | ||
if (typeof options === 'function') { | ||
callback = readyCallback; | ||
readyCallback = options; | ||
options = null; | ||
} | ||
if (!callback) { | ||
callback = readyCallback; | ||
readyCallback = null; | ||
} | ||
if (!adapter._namespaceRegExp.test(id)) id = adapter.namespace + (id ? '.' + id : ''); | ||
function doChannels() { | ||
forEachInSystemObjectView('channel', id, readyCallback, callback); | ||
} | ||
function doDevices() { | ||
forEachInSystemObjectView('device', id, doChannels, function (o, next, type) { | ||
callback(o, function() { | ||
next(); //forEachObjectChild(o.id, options, callback, next); | ||
}, type); | ||
}); | ||
} | ||
forEachInSystemObjectView('state', id, doDevices, callback); | ||
}; | ||
// callback first all devices, then all channels and then all states | ||
njs.dcs.forEach2 = forEachObjectChild2; | ||
function forEachObjectChild2(id, options, readyCallback, callback) { | ||
if (typeof options === 'function') { | ||
callback = readyCallback; | ||
readyCallback = options; | ||
options = null; | ||
} | ||
if (!callback) { | ||
callback = readyCallback; | ||
readyCallback = null; | ||
} | ||
if (!adapter._namespaceRegExp.test(id)) id = adapter.namespace + (id ? `.${id}` : ''); | ||
function doStates() { | ||
forEachInSystemObjectView('state', id, readyCallback, callback); | ||
} | ||
function doChannels() { | ||
forEachInSystemObjectView('channel', id, doStates, callback); | ||
} | ||
forEachInSystemObjectView('device', id, doChannels, callback); | ||
async function delObjectAndState(id) { | ||
await adapter.delStateAsync(id); | ||
await adapter.delObject(id); | ||
} | ||
njs.dcs.del = delObjectWithStates; | ||
function delObjectWithStates (id, options, callback) { | ||
if (typeof options === 'function') { | ||
callback = options; | ||
options = undefined; | ||
// collect first all states, then all devices and then all channels | ||
async function forEachObjectChild(id, callback) { | ||
if (!adapter._namespaceRegExp.test(id)) { | ||
id = adapter.namespace + (id ? `.${id}` : ''); | ||
} | ||
// if (!adapter._namespaceRegExp.test(id)) id = adapter.namespace + '.' + id; | ||
exports.ns.add(id); | ||
delObjectAndState(id, options, function (err) { | ||
forEachObjectChild(id, callback, function (o, next, type) { | ||
delObjectAndState(o.id, options, next); | ||
devices.remove(idWithoutNamespace(o.id)); | ||
}); | ||
}); | ||
} | ||
njs.dcs.delall = function (callback) { | ||
var options = null; | ||
forEachObjectChild('', callback, function(o, next, type) { | ||
delObjectAndState(o.id, options, next); | ||
}); | ||
}; | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
function toHex (val) { | ||
return `0${val.toString(16)}`.substr(-2); | ||
await forEachInSystemObjectView('state', id, callback); | ||
await forEachInSystemObjectView('device', id, callback); | ||
await forEachInSystemObjectView('channel', id, callback); | ||
} | ||
exports.toHex = toHex; | ||
function arrayToHex(ar, len) { | ||
let s = ''; | ||
if (len === undefined) { | ||
len = ar.length; | ||
async function delObjectWithStates(id) { | ||
if (!id.startsWith(`${adapter.namespace}.`)) { | ||
id = `${adapter.namespace}.${id}`; | ||
} | ||
for (let i=0; i<len; i++) { | ||
s += `${toHex(ar[i])} `; | ||
} | ||
return s; | ||
} | ||
exports.arrayToHex = arrayToHex; | ||
function extendArray () { | ||
require('array-ext'); | ||
} | ||
exports.extendArray = extendArray; | ||
await adapter.delStateAsync(id); | ||
await adapter.delObject(id); | ||
function extendNumber() { | ||
Number.prototype.toHex = function () { | ||
return `0${this.toString(16)}`.substr(-2); | ||
}; | ||
await forEachObjectChild(id, async o => { | ||
devices.remove(idWithoutNamespace(o.id)); | ||
await delObjectAndState(o.id); | ||
}); | ||
} | ||
exports.extendNumber = extendNumber; | ||
exports.extendAll = function () { | ||
extendArray (); | ||
extendNumber(); | ||
}; | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
var log = function (fmt, args) { | ||
adapter.log.info(exports.sprintf.apply (null, arguments)); | ||
module.exports = { | ||
Timer, | ||
arrayToHex, | ||
changeAdapterConfig, | ||
clone, | ||
delObjectWithStates, | ||
devices, | ||
fullExtend, | ||
CDevice, | ||
}; | ||
log.error = function (fmt, args) { | ||
adapter.log.error(exports.sprintf.apply (null, arguments)); | ||
}; | ||
log.info = function (fmt, args) { | ||
adapter.log.info(exports.sprintf.apply (null, arguments)); | ||
}; | ||
log.debug = function (fmt, args) { | ||
if (adapter.common.loglevel !== 'debug') { | ||
log.debug = function() {}; | ||
return; | ||
} | ||
log.debug = function (fmt, args) { | ||
adapter.log.debug(exports.sprintf.apply (null, arguments)); | ||
}; | ||
adapter.log.debug(exports.sprintf.apply (null, arguments)); | ||
}; | ||
log.warn = function (fmt, args) { | ||
adapter.log.warn(exports.sprintf.apply (null, arguments)); | ||
}; | ||
exports.log = log; | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
exports.Devices = Devices; | ||
exports.njs = njs; | ||
exports.extendGlobalNamespace = extendGlobalNamespace; | ||
try { | ||
const _sprintf = require('sprintf-js'); | ||
exports.sprintf = _sprintf.sprintf; | ||
exports.vsprintf = _sprintf.vsprintf; | ||
} catch(e) { | ||
exports.sprintf = function(fs) { | ||
return `sprintf-js not loaded ${fs}`; | ||
}; | ||
exports.vsprintf = exports.sprintf; | ||
} | ||
424
main.js
const net = require('node:net'); | ||
const utils = require(`@iobroker/adapter-core`); | ||
const discovery = require('./lib/discovery'); | ||
const { rgb2hsv, roundRGB, ct2rgb, hsv2rgb } = require('./lib/colors'); | ||
const soef = require('./lib/dontBeSoSoef'); | ||
const { | ||
Timer, | ||
arrayToHex, | ||
changeAdapterConfig, | ||
clone, | ||
delObjectWithStates, | ||
devices, | ||
fullExtend, | ||
CDevice, | ||
} = require('./lib/dontBeSoSoef'); | ||
@@ -10,16 +21,23 @@ //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
const debug = false; | ||
const commands = require('./lib/devices'); | ||
let adapter = null; | ||
function _fullExtendEx(dest, from) { | ||
const props = Object.getOwnPropertyNames(from); | ||
let destination; | ||
function savePrevVersion() { | ||
if (!adapter?.ioPack?.common?.version) { | ||
return; | ||
} | ||
const id = `system.adapter.${adapter.namespace}`; | ||
const vid = `${id}.prevVersion`; | ||
props.forEach(name => { | ||
if (typeof from[name] === 'object') { | ||
if (typeof dest[name] !== 'object') { | ||
dest[name] = {}; | ||
} | ||
_fullExtendEx(dest[name],from[name]); | ||
adapter.getForeignObject(vid, (err, obj) => { | ||
if (err || !obj) { | ||
adapter.setForeignObject(vid, { | ||
type: 'state', | ||
common: { name: 'version', role: 'indicator.state', desc: 'version check for updates', type: 'string' }, | ||
native: {} | ||
}, () => { | ||
adapter.setForeignState(vid, { val: adapter.ioPack.common.version, ack: true, from: id }); | ||
}); | ||
} else { | ||
destination = Object.getOwnPropertyDescriptor(from, name); | ||
Object.defineProperty(dest, name, destination); | ||
adapter.setForeignState(vid, { val: adapter.ioPack.common.version, ack: true, from: id }); | ||
} | ||
@@ -29,52 +47,39 @@ }); | ||
function fullExtendEx(dest, from) { | ||
_fullExtendEx(dest, from); | ||
return dest; | ||
function parseIntVersion(versionString) { | ||
if (!versionString) { | ||
return 0; | ||
} | ||
const ar = versionString.toString().split('.'); | ||
let iVer = 0; | ||
for (let i = 0; i < ar.length; i++) { | ||
iVer *= 1000; | ||
iVer += ar[i] >> 0; | ||
} | ||
return iVer; | ||
} | ||
function cloneEx(from) { | ||
const props = Object.getOwnPropertyNames(from); | ||
let destination; | ||
const dest = {}; | ||
function checkIfUpdated(callback) { | ||
if (!adapter) { | ||
if (typeof callback === 'function') { | ||
callback(); | ||
} | ||
return; | ||
} | ||
props.forEach(function (name) { | ||
if (from[name] instanceof Array) { | ||
//dest[name] = new Array(from[name]); | ||
dest[name] = [].concat(from[name]); | ||
} else if (typeof from[name] === 'object') { | ||
if (typeof dest[name] !== 'object') { | ||
dest[name] = {}; | ||
} | ||
_fullExtendEx(dest[name],from[name]); | ||
} else { | ||
destination = Object.getOwnPropertyDescriptor(from, name); | ||
Object.defineProperty(dest, name, destination); | ||
const id = `system.adapter.${adapter.namespace}`; | ||
const vid = `${id}.prevVersion`; | ||
adapter.getForeignState(vid, (err, state)=> { | ||
const aktVersion = parseIntVersion(adapter.ioPack.common.version); | ||
const prevVersion = parseIntVersion(state ? state.val || '0' : '0'); | ||
if (prevVersion < aktVersion) { | ||
savePrevVersion(); | ||
} | ||
if (typeof callback === 'function') { | ||
callback(); | ||
} | ||
}); | ||
return dest; | ||
} | ||
function arrayToHexEx(ar, len) { | ||
const s = []; | ||
if (len === undefined) { | ||
len = ar.length; | ||
} | ||
for (let i = 0; i < len; i++) { | ||
s.push(ar[i].toString(16).padStart(2, '0')); | ||
} | ||
return s.join(' '); | ||
} | ||
soef.extendAll(); | ||
const adapter = soef.Adapter( | ||
main, | ||
onStateChange, | ||
onMessage, | ||
onUnload, | ||
{ name: 'wifilight' }, | ||
); | ||
function fromDeviceName(name) { | ||
return cmds.knownDeviceNames[name] || cmds.knownDeviceNames[name.toUpperCase()]; | ||
return commands.knownDeviceNames[name] || commands.knownDeviceNames[name.toUpperCase()]; | ||
} | ||
@@ -88,51 +93,83 @@ | ||
} | ||
switch (obj.command) { | ||
case 'discovery': | ||
discovery.scanForAllDevices( | ||
entry => { | ||
const ret = !adapter.config.devices.some(e => e.ip === entry.ip); | ||
if (ret) { | ||
const dev = fromDeviceName(entry.name); | ||
entry.type = dev ? dev.type : ''; | ||
entry.port = dev?.port ? dev.port : 5577; | ||
entry.pollIntervall = 30; | ||
if (obj.command === 'discovery') { | ||
discovery.scanForAllDevices( | ||
entry => { | ||
const ret = !adapter.config.devices.some(e => e.ip === entry.ip); | ||
if (ret) { | ||
const dev = fromDeviceName(entry.name); | ||
entry.type = dev ? dev.type : ''; | ||
entry.port = dev?.port ? dev.port : 5577; | ||
entry.pollIntervall = 30; | ||
} | ||
return ret; | ||
}, | ||
result => { | ||
if (obj.callback) { | ||
adapter.sendTo(obj.from, obj.command, JSON.stringify(result), obj.callback); | ||
} | ||
}, | ||
); | ||
} else if (obj.command === 'discoveryJson' && obj.callback) { | ||
// extract devices | ||
let _devices; | ||
try { | ||
if (typeof obj.message === 'string') { | ||
_devices = JSON.parse(obj.message); | ||
} else { | ||
_devices = obj.message?.devices || []; | ||
} | ||
} catch { | ||
// ignore | ||
} | ||
_devices = _devices || []; | ||
discovery.scanForAllDevices( | ||
entry => { | ||
const ret = _devices.find(e => e.ip === entry.ip); | ||
if (!ret) { | ||
const dev = fromDeviceName(entry.name); | ||
entry.type = dev ? dev.type : ''; | ||
entry.port = dev?.port ? dev.port : 5577; | ||
entry.pollIntervall = 30; | ||
return true; | ||
} | ||
// device already exists | ||
return false; | ||
}, | ||
result => { | ||
let found = false; | ||
result.forEach(e => { | ||
if (!_devices.find(d => d.ip === e.ip)) { | ||
_devices.push(e); | ||
found = true; | ||
} | ||
return ret; | ||
}, | ||
result => { | ||
if (obj.callback) { | ||
adapter.sendTo(obj.from, obj.command, JSON.stringify(result), obj.callback); | ||
} | ||
}); | ||
if (found) { | ||
adapter.sendTo(obj.from, obj.command, { native: { devices: _devices }}, obj.callback); | ||
} else { | ||
adapter.sendTo(obj.from, obj.command, { error: 'Cannot find any device' }, obj.callback); | ||
} | ||
); | ||
return true; | ||
default: | ||
adapter.log.warn(`Unknown command: ${obj.command}`); | ||
break; | ||
}, | ||
); | ||
} else { | ||
adapter.log.warn(`Unknown command: ${obj.command}`); | ||
} | ||
if (obj.callback) { | ||
adapter.sendTo(obj.from, obj.command, obj.message, obj.callback); | ||
} | ||
return true; | ||
} | ||
function onUnload(callback) { | ||
Object.keys(wifi).forEach(v => { | ||
wifi[v].close(); | ||
delete wifi[v]; | ||
adapter.log.debug(`unload: ${v}`); | ||
}); | ||
try { | ||
Object.keys(wifi).forEach(v => { | ||
wifi[v].close(); | ||
delete wifi[v]; | ||
adapter.log.debug(`unload: ${v}`); | ||
}); | ||
} catch { | ||
// ignore | ||
} | ||
callback && callback(); | ||
} | ||
// process.on('exit', function() { | ||
// if (adapter &&adapter.log) adapter.log.info('on process exit'); | ||
// console.log('on process exit'); | ||
// }); | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
const cmds = require('./lib/devices'); | ||
const usedStateNames = { | ||
@@ -186,4 +223,6 @@ online: { n: 'reachable', g: 1, val: false, common: { write: false, type: 'boolean', role: 'indicator.reachable' }}, | ||
function onStateChange(id, state) { | ||
if (!state || state.ack) { | ||
return; | ||
} | ||
const ar = id.split('.'); | ||
// const dcs = adapter.idToDCS(id); | ||
let deviceName = ar[2]; | ||
@@ -207,2 +246,15 @@ let channelName = ''; | ||
function startAdapter() { | ||
adapter = utils.Adapter({ | ||
name: 'wifilight', | ||
message: obj => onMessage(obj), | ||
objectChange: (id, obj) => id && !obj && devices?.removeWithoutNameSpace(id), | ||
ready: () => checkIfUpdated(() => devices.init(adapter, () => main())), | ||
stateChange: (id, state) => onStateChange(id, state), | ||
unload: (callback) => onUnload(callback), | ||
}); | ||
return adapter; | ||
} | ||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
@@ -214,6 +266,7 @@ class WifiLight { | ||
} | ||
this.zone = undefined; | ||
this.config = config; | ||
this.isOnline = false; | ||
this.cmds = cmds[config.type]; | ||
this.prgTimer = soef.Timer(); | ||
this.cmds = commands[config.type]; | ||
this.prgTimer = new Timer(); | ||
} | ||
@@ -235,7 +288,7 @@ | ||
this.createDevice((/* err */) => { | ||
this.setOnline(false); | ||
if (this.cmds.onlyConnectOnWrite) { | ||
this.USE_SOCKET_ONCE = true; | ||
this.setOnline('on demand'); | ||
this.setOnline(null); | ||
} else { | ||
this.setOnline(false); | ||
} | ||
@@ -257,3 +310,3 @@ this.queue = []; | ||
createDevice(cb) { | ||
this.dev = new devices.CDevice(0, ''); | ||
this.dev = new CDevice(0, devices); | ||
this.dev.setDevice(this.config.ip, { | ||
@@ -269,2 +322,3 @@ common: { | ||
}); | ||
if (this.zone !== undefined) { | ||
@@ -284,3 +338,3 @@ this.dev.setChannel(this.zone.toString(), ['All Zones', 'Zone 1', 'Zone 2', 'Zone 3', 'Zone 4'][this.zone]); | ||
} | ||
// eslint-ignore-next-line | ||
// eslint-disable-next-line no-bitwise | ||
if (st.g & this.cmds.g) { | ||
@@ -290,2 +344,3 @@ this.dev.createNew(st.n, st); | ||
} | ||
devices.update(cb); | ||
@@ -295,3 +350,3 @@ } | ||
onStateChange(channel, stateName, val) { | ||
let transitionTime = this.getval(channel, usedStateNames.transition.n, 0); | ||
let transitionTime = this.getValue(channel, usedStateNames.transition.n, 0); | ||
this.clearQueue(); | ||
@@ -347,3 +402,3 @@ let co; | ||
let ar = val.split(' '); | ||
if (!ar || ar.lengt < 2) { | ||
if (!ar || ar.length < 2) { | ||
ar = val.split(','); | ||
@@ -356,5 +411,4 @@ } | ||
} else { | ||
speed = this.getval(channel, usedStateNames.progSpeed.n, 30); | ||
speed = this.getValue(channel, usedStateNames.progSpeed.n, 30); | ||
} | ||
// if (this.cmds._setProgNo) _setProgNo(this, channel, val >> 0); else | ||
this.addToQueue(channel, this.cmds.progNo, val >> 0, speed); | ||
@@ -418,3 +472,3 @@ break; | ||
} | ||
const o = fullExtendEx(this.getRGBStates(channel), colors); | ||
const o = fullExtend(this.getRGBStates(channel), colors); | ||
adapter.log.debug(JSON.stringify(o)); | ||
@@ -492,3 +546,3 @@ if (o.x !== undefined) { | ||
reconnect(cb, timeout) { | ||
if (cb && typeof cb != 'function') { | ||
if (cb && typeof cb !== 'function') { | ||
timeout = cb; | ||
@@ -521,8 +575,10 @@ cb = undefined; | ||
const ts = debug ? `(${Math.round((Date.now() - this.ts) / 1000)} sec) ` : ''; | ||
this.log(`onClose ${ts}hasError=${hasError} client=${this.client}`); | ||
this.log(`onClose ${ts}hasError=${hasError} client=${this.config.ip}:${this.config.port}`); | ||
}); | ||
this.client.on('error', error => { | ||
const ts = debug ? `(${Math.round((Date.now() - this.ts) / 1000)} sec) ` : ''; | ||
this.log(`onError: ${ts}${error.code !== undefined ? error.code : ''} ${error.message}`); | ||
switch (error.errno) { //error.code | ||
switch (error.code) { //error.code | ||
case 'ECONNRESET': | ||
@@ -536,2 +592,3 @@ case 'ETIMEDOUT': | ||
}); | ||
this.client.connect(this.config.port, this.config.ip, () => { | ||
@@ -541,3 +598,5 @@ this.log(`${this.config.ip} connected`); | ||
this.runUpdateTimer(); | ||
adapter.log.debug('self.client.connect: connected'); | ||
if (typeof cb == 'function') { | ||
@@ -582,5 +641,5 @@ cb(); | ||
getval(channel, state, def) { | ||
getValue(channel, state, def) { | ||
const o = this.dev.get(channel, state); | ||
if (o && o.val !== undefined) { | ||
if (o?.val !== undefined) { | ||
return o.val; | ||
@@ -598,2 +657,8 @@ } | ||
} | ||
if (this.writeTimer) { | ||
clearTimeout(this.writeTimer); | ||
this.writeTimer = null; | ||
} | ||
if (this.onTimerObject) { | ||
@@ -621,3 +686,4 @@ clearTimeout(this.onTimerObject); | ||
this.isOnline = val; | ||
if ((this.cmds.g & usedStateNames.online.g) === 0) { | ||
// eslint-disable-next-line no-bitwise | ||
if (!(this.cmds.g & usedStateNames.online.g)) { | ||
return; | ||
@@ -659,3 +725,3 @@ } | ||
//this.log('writing: ' + buf.toString('hex').match(/.{2}/g).join(' ')); | ||
this.log(`write: ${arrayToHexEx(buf)}`); | ||
this.log(`write: ${arrayToHex(buf)}`); | ||
if (!this.isOnline /*&& !this.USE_SOCKET_ONCE*/) { | ||
@@ -687,3 +753,3 @@ this.reconnect(() => this._write(buf, cb), 0); | ||
for (let i = 0; i < args[idx].length; i++) { | ||
cmd[i] = args[idx][i] < 0 && args[idx][i] !== cmds.VARS.separator && args[idx][i] !== cmds.VARS.sepNoDelay ? args[j++] : args[idx][i]; | ||
cmd[i] = args[idx][i] < 0 && args[idx][i] !== commands.VARS.separator && args[idx][i] !== commands.VARS.sepNoDelay ? args[j++] : args[idx][i]; | ||
} | ||
@@ -703,6 +769,6 @@ } else { | ||
switch (c) { | ||
case cmds.VARS.separator: | ||
case commands.VARS.separator: | ||
sep = 1; | ||
break; | ||
case cmds.VARS.sepNoDelay: | ||
case commands.VARS.sepNoDelay: | ||
sep = 2; | ||
@@ -789,3 +855,3 @@ break; | ||
const steps = maxSteps; | ||
const delay = parseInt(transitionTime * 100 / maxSteps); | ||
const delay = Math.round(transitionTime * 100 / maxSteps); | ||
@@ -821,6 +887,2 @@ for (let i = 0; i < steps; i++) { | ||
temperature(channel, temp, transitionTime) { | ||
return this.ct(channel, temp, transitionTime); | ||
} | ||
getRGBStates(/* channel */) { | ||
@@ -861,5 +923,7 @@ return { | ||
onData(data) { | ||
this.setOnline(true); | ||
if (adapter.common.loglevel === 'debug') { | ||
adapter.log.debug(`raw data length: ${data.length}`); | ||
adapter.log.debug(`raw data: ${arrayToHexEx(data)}`); | ||
adapter.log.debug(`raw data: ${arrayToHex(data)}`); | ||
} | ||
@@ -882,3 +946,3 @@ const newPos = this.dataBuffer.pos + data.length; | ||
const [lengthRead, states] = this.cmds.decodeResponse(this.dataBuffer); | ||
this.log(`onData: raw: ${arrayToHexEx(this.dataBuffer, lengthRead)}`); | ||
this.log(`onData: raw: ${arrayToHex(this.dataBuffer, lengthRead)}`); | ||
this.dataBuffer.copyWithin(0, lengthRead, this.dataBuffer.pos); | ||
@@ -892,3 +956,2 @@ this.dataBuffer.pos -= lengthRead; | ||
if (this.states) { | ||
//set(usedStateNames.status.n, this.states.power); | ||
this.dev.set(usedStateNames.on.n, this.states.on); | ||
@@ -902,5 +965,6 @@ this.dev.set(usedStateNames.red.n, this.states.red); | ||
this.dev.set(usedStateNames.white.n, this.states.white); | ||
let rgb = `#${this.states.red.toHex()}${this.states.green.toHex()}${this.states.blue.toHex()}`; | ||
let rgb = `#${this.states.red.toString(16).padStart(2, '0')}${this.states.green.toString(16).padStart(2, '0')}${this.states.blue.toString(16).padStart(2, '0')}`; | ||
if (this.states.white !== undefined) { | ||
rgb += this.states.white.toHex(); | ||
rgb += this.states.white.toString(16).padStart(2, '0'); | ||
} | ||
@@ -924,7 +988,7 @@ this.dev.set(usedStateNames.rgb.n, rgb); | ||
this.zone = zone; | ||
this.cmds = cloneEx(this.cmds); | ||
this.cmds = clone(this.cmds); | ||
this.cmds.setZone(this.zone); | ||
this.states = { on: 0, red: 0, green: 0, blue: 0, white: 0 }; | ||
this.writeTimer = soef.Timer(); | ||
this.isOnline = 'on demand'; | ||
this.writeTimer = null; | ||
this.isOnline = null; | ||
} | ||
@@ -945,3 +1009,3 @@ | ||
}); | ||
this.client.on('message', (/* data, rinfo */) => {}); | ||
this.client.on('message', (/* data, rInfo */) => {}); | ||
this.client.on('error', (/* error */) => {}); | ||
@@ -955,3 +1019,6 @@ this.client.on('close', (/* error */) => { | ||
this.client.send(data, 0, data.length, this.config.port, this.config.ip, (/* error, bytes */) => { | ||
this.writeTimer.set(() => this?.client?.close(), 2000); | ||
this.writeTimer = setTimeout(() => { | ||
this.writeTimer = null; | ||
this?.client?.close(); | ||
}, 2000); | ||
cb && cb(); | ||
@@ -982,14 +1049,14 @@ }); | ||
pair(channel) { | ||
for (let i = 0; i < 3; i++) { | ||
this.addToQueue(channel, this.pair, { delay: 1000 }); | ||
} | ||
} | ||
// pair(channel) { | ||
// for (let i = 0; i < 3; i++) { | ||
// this.addToQueue(channel, this.pair, { delay: 1000 }); | ||
// } | ||
// } | ||
// | ||
// unPair(channel) { | ||
// for (let i = 0; i < 15; i++) { | ||
// this.addToQueue(channel, this.unPair, { delay: 200 }); | ||
// } | ||
// } | ||
unPair(channel) { | ||
for (let i = 0; i < 15; i++) { | ||
this.addToQueue(channel, this.unPair, { delay: 200 }); | ||
} | ||
} | ||
onStateChange(channel, stateName, val) { | ||
@@ -1003,3 +1070,3 @@ switch (stateName) { | ||
} | ||
// const bri = this.getval(channel, 'bri'); | ||
// const bri = this.getValue(channel, 'bri'); | ||
let cmd = this.cmds._white(10).cc(this.cmds.on); | ||
@@ -1013,3 +1080,3 @@ while (val--) { | ||
default: | ||
WifiLight.prototype.onStateChange.call(this, channel, stateName, val); | ||
super.onStateChange(channel, stateName, val); | ||
break; | ||
@@ -1020,20 +1087,21 @@ } | ||
function checkDeletedDevices(cb) { | ||
adapter.getDevices((err, res) => { | ||
if (err || !res || res.length <= 0) { | ||
return cb && cb(); | ||
async function checkDeletedDevices() { | ||
const res = await adapter.getDevicesAsync(); | ||
if (!res?.length) { | ||
return; | ||
} | ||
const reIp = /[^0-9]/g; | ||
const toDelete = []; | ||
res.forEach(obj => { | ||
const ar = obj._id.split('.'); | ||
const ip = ar[2].replace(reIp, '.'); | ||
const found = adapter.config.devices.find(v => v.ip === ip); | ||
if (!found) { | ||
toDelete.push(obj._id); | ||
} | ||
const reIp = /[^0-9]/g; | ||
const toDelete = []; | ||
res.forEach(obj => { | ||
const ar = obj._id.split('.'); | ||
const ip = ar[2].replace(reIp, '.'); | ||
const found = adapter.config.devices.find(v => v.ip === ip); // xxxx | ||
if (!found) { | ||
toDelete.push(obj._id); | ||
} | ||
}); | ||
}); | ||
toDelete.forEachCallback((next, id) => dcs.del(id, next), cb); | ||
}); | ||
for (let i = 0; i < toDelete.length; i++) { | ||
await delObjectWithStates(toDelete[i]); | ||
} | ||
} | ||
@@ -1043,3 +1111,3 @@ | ||
function normalizeConfig(config) { | ||
async function normalizeConfig(config) { | ||
let changed = false; | ||
@@ -1054,7 +1122,7 @@ const types = []; | ||
} | ||
const c = cmds[d.type]; | ||
const c = commands[d.type]; | ||
if (!c) { | ||
let err = `config.device.type "${d.type}" (${d.name}) is not a known device type. Skipping this device!`; | ||
if (!types.length) Object.keys(cmds).forEach(n => { | ||
if (typeof cmds[n] === 'object' && cmds[n].on) { | ||
if (!types.length) Object.keys(commands).forEach(n => { | ||
if (typeof commands[n] === 'object' && commands[n].on) { | ||
types.push(n); | ||
@@ -1079,30 +1147,26 @@ } | ||
d.port = parseInt(d.port) || (c && c.port ? c.port : dev && dev.port ? dev.port : 5577); | ||
Object.keys(d).forEach(key => { | ||
changed = changed || d[key] !== old[key]; | ||
}); | ||
Object.keys(d).forEach(key => | ||
changed = changed || d[key] !== old[key]); | ||
}); | ||
if (changed) { | ||
soef.changeAdapterConfig(adapter, conf => conf.devices = config.devices); | ||
await changeAdapterConfig(adapter, conf => conf.devices = config.devices); | ||
} | ||
} | ||
function main() { | ||
async function main() { | ||
if (!adapter.config.devices) { | ||
return; | ||
} | ||
checkDeletedDevices((/* err */) => {}); | ||
normalizeConfig(adapter.config); | ||
await checkDeletedDevices(); | ||
await normalizeConfig(adapter.config); | ||
const miLight = []; | ||
for (let i = 0; i < adapter.config.devices.length; i++) { | ||
if (adapter.config.devices[i].type === 'MiLight') { | ||
for (let zone = 0; zone <= 4; zone++) { | ||
miLight[zone] = new MiLight(adapter.config.devices[i], zone); | ||
miLight[zone].run(() => { | ||
}); | ||
const device = new MiLight(adapter.config.devices[i], zone); | ||
device.run(); | ||
} | ||
} else { | ||
const wifiLight = new WifiLight(adapter.config.devices[i]); | ||
wifiLight.run(() => {}); | ||
wifiLight.run(); | ||
} | ||
@@ -1114,1 +1178,9 @@ } | ||
} | ||
// If started as allInOne mode => return function to create instance | ||
if (module.parent) { | ||
module.exports = startAdapter; | ||
} else { | ||
// or start the instance directly | ||
startAdapter(); | ||
} |
{ | ||
"name": "iobroker.wifilight", | ||
"version": "1.3.5", | ||
"version": "2.0.0", | ||
"description": "WiFi Light Adapter", | ||
@@ -26,5 +26,2 @@ "author": { | ||
}, | ||
"optionalDependencies": { | ||
"mdns-discovery": "^0.2.6" | ||
}, | ||
"engines": { | ||
@@ -35,5 +32,3 @@ "node": ">=18" | ||
"netmask": "^2.0.2", | ||
"@iobroker/adapter-core": "^3.1.6", | ||
"sprintf-js": "^1.1.3", | ||
"array-ext": "^0.1.5" | ||
"@iobroker/adapter-core": "^3.1.6" | ||
}, | ||
@@ -62,6 +57,3 @@ "devDependencies": { | ||
"prettier": "^3.3.3", | ||
"proxyquire": "^2.1.3", | ||
"sinon": "^18.0.0", | ||
"sinon-chai": "^3.7.0", | ||
"typescript": "~5.5.4" | ||
"proxyquire": "^2.1.3" | ||
}, | ||
@@ -73,3 +65,2 @@ "main": "main.js", | ||
"lib/", | ||
"www/", | ||
"io-package.json", | ||
@@ -76,0 +67,0 @@ "LICENSE", |
@@ -54,2 +54,7 @@ ![Logo](admin/wifilight.png) | ||
--> | ||
### 2.0.0 (2024-09-05) | ||
* (bluefox) The adapter was completely refactored | ||
* (bluefox) Added compact mode | ||
* (bluefox) JSON config GUI added | ||
### 1.3.5 (2024-09-04) | ||
@@ -56,0 +61,0 @@ * (bluefox) Formatting of the code |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
2
22
24
124
1
120988
2446
- Removedarray-ext@^0.1.5
- Removedsprintf-js@^1.1.3
- Removedarray-ext@0.1.5(transitive)
- Removeddebug@2.2.0(transitive)
- Removeddgram@1.0.1(transitive)
- Removeddns-packet@1.3.4(transitive)
- Removedip@1.1.9(transitive)
- Removedmdns-discovery@0.2.6(transitive)
- Removedms@0.7.1(transitive)
- Removedsafe-buffer@5.2.1(transitive)
- Removedsprintf-js@1.1.3(transitive)