Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

iobroker.device-watcher

Package Overview
Dependencies
Maintainers
1
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

iobroker.device-watcher - npm Package Compare versions

Comparing version 0.1.2 to 0.2.0

3

admin/i18n/de/translations.json

@@ -67,3 +67,4 @@ {

"If you like to have for every Adapter an own folder with own data": "Wenn Sie möchten, haben Sie für jeden Adapter einen eigenen Ordner mit eigenen Daten",
"Please choose": "Bitte auswählen"
"Please choose": "Bitte auswählen",
"Create own folders for each adapter": "Erstellen Sie für jeden Adapter eigene Ordner"
}

@@ -64,5 +64,5 @@ {

"Choose your notification services":"Choose your notification services",
"Create own folders for each adapter !!Doesn't work yet!!":"Create own folders for each adapter !!Doesn't work yet!!",
"If you like to have for every Adapter an own folder with own data":"If you like to have for every Adapter an own folder with own data",
"Please choose":"Please choose"
"Please choose":"Please choose",
"Create own folders for each adapter":"Create own folders for each adapter"
}

@@ -77,3 +77,4 @@ {

"If you like to have for every Adapter an own folder with own data": "Si desea tener para cada adaptador una carpeta propia con datos propios",
"Please choose": "Por favor elige"
"Please choose": "Por favor elige",
"Create own folders for each adapter": "Crear carpetas propias para cada adaptador"
}

@@ -77,3 +77,4 @@ {

"If you like to have for every Adapter an own folder with own data": "Si vous souhaitez avoir pour chaque adaptateur un dossier avec ses propres données",
"Please choose": "Choisissez s'il vous plaît"
"Please choose": "Choisissez s'il vous plaît",
"Create own folders for each adapter": "Créez vos propres dossiers pour chaque adaptateur"
}

@@ -77,3 +77,4 @@ {

"If you like to have for every Adapter an own folder with own data": "Se ti piace avere per ogni Adapter una propria cartella con i propri dati",
"Please choose": "Si prega di scegliere"
"Please choose": "Si prega di scegliere",
"Create own folders for each adapter": "Crea cartelle personalizzate per ogni adattatore"
}

@@ -77,3 +77,4 @@ {

"If you like to have for every Adapter an own folder with own data": "Als je voor elke Adapter een eigen map met eigen gegevens wilt hebben",
"Please choose": "Gelieve te kiezen"
"Please choose": "Gelieve te kiezen",
"Create own folders for each adapter": "Maak eigen mappen voor elke adapter"
}

@@ -77,3 +77,4 @@ {

"If you like to have for every Adapter an own folder with own data": "Jeśli chcesz mieć dla każdego adaptera własny folder z własnymi danymi",
"Please choose": "Proszę wybrać"
"Please choose": "Proszę wybrać",
"Create own folders for each adapter": "Utwórz własne foldery dla każdego adaptera"
}

@@ -77,3 +77,4 @@ {

"If you like to have for every Adapter an own folder with own data": "Se você gosta de ter para cada adaptador uma pasta própria com dados próprios",
"Please choose": "Por favor escolha"
"Please choose": "Por favor escolha",
"Create own folders for each adapter": "Crie pastas próprias para cada adaptador"
}

@@ -77,3 +77,4 @@ {

"If you like to have for every Adapter an own folder with own data": "Если вы хотите иметь для каждого адаптера собственную папку с собственными данными",
"Please choose": "Пожалуйста, выберите"
"Please choose": "Пожалуйста, выберите",
"Create own folders for each adapter": "Создайте свои папки для каждого адаптера"
}

@@ -77,3 +77,4 @@ {

"If you like to have for every Adapter an own folder with own data": "如果您希望每个适配器都有一个包含自己数据的文件夹",
"Please choose": "请选择"
"Please choose": "请选择",
"Create own folders for each adapter": "为每个适配器创建自己的文件夹"
}

@@ -561,3 +561,3 @@ {

"lg": 4,
"label": "Create own folders for each adapter !!Doesn't work yet!!",
"label": "Create own folders for each adapter",
"help": "If you like to have for every Adapter an own folder with own data"

@@ -564,0 +564,0 @@ },

{
"common": {
"name": "device-watcher",
"version": "0.1.2",
"version": "0.2.0",
"news": {
"0.2.0": {
"en": "- added function to create data of each adapter",
"de": "- zusätzliche funktion zur erstellung von daten jedes adapters",
"ru": "- добавлена функция для создания данных каждого адаптера",
"pt": "- função adicionada para criar dados de cada adaptador",
"nl": "- vertaling:",
"fr": "- fonction ajoutée pour créer des données de chaque adaptateur",
"it": "- funzione aggiunta per creare dati di ogni adattatore",
"es": "- función agregada para crear datos de cada adaptador",
"pl": "- dodanie funkcji do tworzenia danych każdego adaptera",
"zh-cn": "- 创造每一适应者的数据的附加职能"
},
"0.1.2": {
"en": "- improved overview of admin ui\n- added option in admin ui to create own folders for each adapter (!!not working yet!!)",
"de": "- verbesserte übersicht von admin ui\n- zusätzliche option in admin ui, um eigene ordner für jeden adapter zu erstellen!(noch nicht funktionieren!)",
"ru": "- улучшенный обзор админ ui\n- добавлена опция в админ ui для создания собственных папок для каждого адаптера !( еще не работает!)",
"pt": "- visão geral melhorada de admin ui\n- opção adicionada no admin ui para criar pastas próprias para cada adaptador! (não funciona ainda!)",
"nl": "- verbeterde overzicht van administratie\n- toegevoegd optie in administratie om eigen vouwen te creëren voor elke adapter",
"fr": "- aperçu amélioré de admin ui\n- option ajoutée dans admin ui pour créer ses propres dossiers pour chaque adaptateur !(pas encore!)",
"it": "- una migliore panoramica di admin ui\n- opzione aggiunta in admin ui per creare proprie cartelle per ogni adattatore! (non funziona ancora!)",
"es": "- mejor descripción de admin ui\n- opción agregada en admin ui para crear carpetas propias para cada adaptador !(no funciona todavía!)",
"pl": "admin ui – poprawiony przegląd admin ui\n- dodanie opcji w admin ui w celu stworzenia własnych folderów dla każdego adaptatora ! (nie pracuje jeszcze!)",
"zh-cn": "- 改进对专注的概述\n- 增加专注的备选办法,为每个适应者创造自己的手"
"en": "- improved overview of admin ui\n- added option in admin ui to create own folders for each adapter (!!not working yet!!)",
"de": "- verbesserte übersicht von admin ui\n- zusätzliche option in admin ui, um eigene ordner für jeden adapter zu erstellen!(noch nicht funktionieren!)",
"ru": "- улучшенный обзор админ ui\n- добавлена опция в админ ui для создания собственных папок для каждого адаптера !( еще не работает!)",
"pt": "- visão geral melhorada de admin ui\n- opção adicionada no admin ui para criar pastas próprias para cada adaptador! (não funciona ainda!)",
"nl": "- verbeterde overzicht van administratie\n- toegevoegd optie in administratie om eigen vouwen te creëren voor elke adapter",
"fr": "- aperçu amélioré de admin ui\n- option ajoutée dans admin ui pour créer ses propres dossiers pour chaque adaptateur !(pas encore!)",
"it": "- una migliore panoramica di admin ui\n- opzione aggiunta in admin ui per creare proprie cartelle per ogni adattatore! (non funziona ancora!)",
"es": "- mejor descripción de admin ui\n- opción agregada en admin ui para crear carpetas propias para cada adaptador !(no funciona todavía!)",
"pl": "admin ui – poprawiony przegląd admin ui\n- dodanie opcji w admin ui w celu stworzenia własnych folderów dla każdego adaptatora ! (nie pracuje jeszcze!)",
"zh-cn": "- 改进对专注的概述\n- 增加专注的备选办法,为每个适应者创造自己的手"
},

@@ -175,2 +187,3 @@ "0.1.1": {

"listOnlyBattery": false,
"createOwnFolder": false,
"checkSendOfflineMsg": false,

@@ -177,0 +190,0 @@ "checkSendBatteryMsg": false,

@@ -47,5 +47,5 @@ /* jshint -W097 */

//**** This Datapoints are only for the dev ****//
test: {'Selektor':'0_userdata.*.UNREACH', 'adapter':'homematic', 'rssiState':'.RSSI_DEVICE', 'battery':'.OPERATING_VOLTAGE', 'reach':'.UNREACH'},
test2: {'Selektor':'0_userdata.*.alive', 'adapter':'esphome', 'rssiState': '.Wifi_RSSI', 'battery':'none', 'reach':'.alive', 'isLowBat':'none', 'id':'.name'},
test3: {'Selektor':'0_userdata.*.link_quality', 'adapter':'zigbee', 'battery':'.battery', 'reach':'available', 'isLowBat':'none'},
test: {'Selektor':'0_userdata.*.UNREACH', 'adapter':'homematic', 'rssiState':'.RSSI_DEVICE', 'battery':'.OPERATING_VOLTAGE', 'reach':'.UNREACH', 'isLowBat':'.LOW_BAT'},
test2: {'Selektor':'0_userdata.*.alive', 'adapter':'test2', 'rssiState': '.Wifi_RSSI', 'battery':'none', 'reach':'.alive', 'isLowBat':'none', 'id':'.name'},
test3: {'Selektor':'0_userdata.*.link_quality', 'adapter':'test3', 'battery':'.battery', 'reach':'available', 'isLowBat':'none'},
//**** End of Dev Datapoints ****//

@@ -149,3 +149,3 @@ alexa2: {

'Selektor':'switchbot-ble.*.rssi',
'adapter':'switchbot ble',
'adapter':'switchbotBle',
'battery':'.battery',

@@ -192,3 +192,4 @@ 'reach':'none',

await this.main();
await this.sendNotifications();
if (this.config.checkSendOfflineMsg) await this.sendOfflineNotifications();
if (this.config.checkSendBatteryMsg) await this.sendBatteryNotifications();
await this.writeDatapoints();

@@ -222,2 +223,45 @@ this.log.debug('all done, exiting');

//Notification services
async sendPushover(text) {
await this.sendToAsync(this.config.instancePushover, 'send', {
message: text,
title: this.config.titlePushover,
device: this.config.devicePushover,
priority: this.config.prioPushover
});
}
async sendTelegram(text) {
await this.sendToAsync(this.config.instanceTelegram, 'send', {
text: text,
user: this.config.deviceTelegram,
chatId: this.config.chatIdTelegram
});
}
async sendWhatsapp(text) {
await this.sendToAsync(this.config.instanceWhatsapp, 'send', {
text: text,
phone: this.config.phoneWhatsapp
});
}
async sendEmail(text) {
await this.sendToAsync(this.config.instanceEmail, 'send', {
sendTo: this.config.sendToEmail,
text: text,
subject: this.config.subjectEmail
});
}
async sendJarvis(text) {
await this.setForeignStateAsync(`${this.config.instanceJarvis}.addNotification`, text);
}
async sendLovelace(text) {
await this.setForeignStateAsync(`${this.config.instanceLovelace}.notifications.add`, text);
}
//create datapoints for each adapter

@@ -335,201 +379,138 @@ async createDPsForEachAdapter(adptName) {

async main() {
this.log.debug(`Function started: ${this.main.name}`);
async createData(i) {
const devices = await this.getForeignStatesAsync(this.arrDev[i].Selektor);
const deviceAdapterName = await this.capitalize(this.arrDev[i].adapter);
const myBlacklist = this.config.tableBlacklist;
this.supAdapter = {
alexa2: this.config.alexa2Devices,
esphome: this.config.esphomeDevices,
zigbee: this.config.zigbeeDevices,
ble: this.config.bleDevices,
sonoff: this.config.sonoffDevices,
shelly: this.config.shellyDevices,
homematic: this.config.homematicDevices,
deconz: this.config.deconzDevices,
zwave: this.config.zwaveDevices,
dect: this.config.dectDevices,
hue: this.config.hueDevices,
hueExt: this.config.hueExtDevices,
nukiExt: this.config.nukiExtDevices,
ping: this.config.pingDevices,
switchbotBle: this.config.switchbotBleDevices,
sonos: this.config.sonosDevices,
mihome: this.config.mihomeDevices,
mihomeGW: this.config.mihomeDevices,
test: false, // Only for Developer
test2: false, // Only for Developer
test3: false // Only for Developer
};
for(const [id] of Object.entries(this.arrApart)) {
const idAdapter = this.supAdapter[id];
if (idAdapter) {
this.arrDev.push(this.arrApart[id]);
this.adapterSelected.push(await this.capitalize(id));
/*try {
await this.createDPsForEachAdapter(id);
this.log.debug(`Created datapoints for ${await this.capitalize(id)}`);
} catch (e) {
this.log.warn(`Error at creating datapoints for each adapter: ${e}`);
}*/
}
/*---------- Loop for blacklist ----------*/
for(const i in myBlacklist){
this.blacklistArr.push(myBlacklist[i].device);
this.log.debug(`Found items on the blacklist: ${this.blacklistArr}`);
}
//Check if one Adapter is selected.
if (this.adapterSelected.length >= 1) {
this.log.info(`Number of selected adapters: ${this.adapterSelected.length}. Loading data from: ${(this.adapterSelected).join(', ')} ...`);
} else {
this.log.warn(`No adapter selected. Please check the instance configuration!`);
}
/*---------- Start of second main loop ----------*/
for(const [id] of Object.entries(devices)) {
if (!this.blacklistArr.includes(id)) {
this.log.debug(JSON.stringify(this.arrDev));
const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
/*=============================================
= Start of main loop =
=============================================*/
for (let i = 0; i < this.arrDev.length; i++) {
const devices = await this.getForeignStatesAsync(this.arrDev[i].Selektor);
const deviceAdapterName = await this.capitalize(this.arrDev[i].adapter);
const myBlacklist = this.config.tableBlacklist;
//Get device name
const deviceObject = await this.getForeignObjectAsync(currDeviceString);
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
let deviceName;
/*---------- Loop for blacklist ----------*/
for(const i in myBlacklist){
this.blacklistArr.push(myBlacklist[i].device);
this.log.debug(`Found items on the blacklist: ${this.blacklistArr}`);
}
if (deviceObject && typeof deviceObject === 'object') {
deviceName = deviceObject.common.name;
}
/*---------- Start of second main loop ----------*/
for(const [id] of Object.entries(devices)) {
if (!this.blacklistArr.includes(id)) {
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
if (this.arrDev[i].adapter === 'hue extended') {
deviceName = shortDeviceObject.common.name;
}
}
const currDeviceString = id.slice(0, (id.lastIndexOf('.') + 1) - 1);
const shortCurrDeviceString = currDeviceString.slice(0, (currDeviceString.lastIndexOf('.') + 1) - 1);
//Get ID for Switchbot and ESPHome Devices
switch (this.arrDev[i].adapter) {
case 'switchbot ble':
case 'esphome':
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
break;
}
//Get device name
const deviceObject = await this.getForeignObjectAsync(currDeviceString);
const shortDeviceObject = await this.getForeignObjectAsync(shortCurrDeviceString);
let deviceName;
// 1. Get link quality
let deviceQualityState;
let linkQuality;
if (deviceObject && typeof deviceObject === 'object') {
deviceName = deviceObject.common.name;
}
switch (this.arrDev[i].adapter) {
case 'homematic':
case 'sonoff':
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiState);
break;
default:
deviceQualityState = await this.getForeignStateAsync(id);
}
if (shortDeviceObject && typeof shortDeviceObject === 'object') {
if (this.arrDev[i].adapter === 'hue extended') {
deviceName = shortDeviceObject.common.name;
if ((deviceQualityState) && (typeof deviceQualityState.val === 'number')){
if (this.config.trueState) {
linkQuality = deviceQualityState.val;
} else {
if (deviceQualityState.val < 0) {
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
} else if ((deviceQualityState.val) >= 0) {
linkQuality = parseFloat((100/255 * deviceQualityState.val).toFixed(0)) + '%';
}
}
this.linkQualityDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Link_quality: linkQuality
}
);
} else {
// no linkQuality available for powered devices
linkQuality = ' - ';
}
//Get ID for Switchbot and ESPHome Devices
switch (this.arrDev[i].adapter) {
case 'switchbot ble':
case 'esphome':
deviceName = await this.getInitValue(currDeviceString + this.arrDev[i].id);
break;
}
// 1b. Count how many devices with link Quality
this.linkQualityCount = this.linkQualityDevices.length;
// 1. Get link quality
let deviceQualityState;
let linkQuality;
// 2. When was the last contact to the device?
let lastContactString;
switch (this.arrDev[i].adapter) {
case 'homematic':
case 'sonoff':
deviceQualityState = await this.getForeignStateAsync(currDeviceString + this.arrDev[i].rssiState);
break;
default:
deviceQualityState = await this.getForeignStateAsync(id);
}
const deviceMainSelector = await this.getForeignStateAsync(id);
let deviceState = 'Online';
if (deviceMainSelector) {
try {
const time = new Date();
const lastContact = Math.round((time.getTime() - deviceMainSelector.ts) / 1000 / 60);
const lastStateChange = Math.round((time.getTime() - deviceMainSelector.lc) / 1000 / 60);
const deviceUnreachState = await this.getInitValue(currDeviceString + this.arrDev[i].reach);
if ((deviceQualityState) && (typeof deviceQualityState.val === 'number')){
if (this.config.trueState) {
linkQuality = deviceQualityState.val;
} else {
if (deviceQualityState.val < 0) {
linkQuality = Math.min(Math.max(2 * (deviceQualityState.val + 100), 0), 100) + '%';
} else if ((deviceQualityState.val) >= 0) {
linkQuality = parseFloat((100/255 * deviceQualityState.val).toFixed(0)) + '%';
const getLastContact = async () => {
lastContactString = this.formatDate(new Date((deviceMainSelector.ts)), 'hh:mm') + ' Uhr';
if (Math.round(lastContact) > 100) {
lastContactString = Math.round(lastContact/60) + ' Stunden';
}
}
this.linkQualityDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Link_quality: linkQuality
if (Math.round(lastContact/60) > 48) {
lastContactString = Math.round(lastContact/60/24) + ' Tagen';
}
);
} else {
// no linkQuality available for powered devices
linkQuality = ' - ';
}
return lastContactString;
};
// 1b. Count how many devices with link Quality
this.linkQualityCount = this.linkQualityDevices.length;
const getLastStateChange = async () => {
lastContactString = this.formatDate(new Date((deviceMainSelector.lc)), 'hh:mm') + ' Uhr';
if (Math.round(lastStateChange) > 100) {
lastContactString = Math.round(lastStateChange/60) + ' Stunden';
}
if (Math.round(lastStateChange/60) > 48) {
lastContactString = Math.round(lastStateChange/60/24) + ' Tagen';
}
return lastContactString;
};
// 2. When was the last contact to the device?
let lastContactString;
const deviceMainSelector = await this.getForeignStateAsync(id);
let deviceState = 'Online';
if (deviceMainSelector) {
try {
const time = new Date();
const lastContact = Math.round((time.getTime() - deviceMainSelector.ts) / 1000 / 60);
const lastStateChange = Math.round((time.getTime() - deviceMainSelector.lc) / 1000 / 60);
const deviceUnreachState = await this.getInitValue(currDeviceString + this.arrDev[i].reach);
const getLastContact = async () => {
lastContactString = this.formatDate(new Date((deviceMainSelector.ts)), 'hh:mm') + ' Uhr';
if (Math.round(lastContact) > 100) {
lastContactString = Math.round(lastContact/60) + ' Stunden';
// 2b. wenn seit X Minuten kein Kontakt mehr besteht, nimm Gerät in Liste auf
//Rechne auf Tage um, wenn mehr als 48 Stunden seit letztem Kontakt vergangen sind
//lastContactString = Math.round(lastContact) + ' Minuten';
switch (this.arrDev[i].adapter) {
case 'ping':
//State changed
if (!deviceUnreachState) {
await getLastStateChange();
} else {
await getLastContact();
}
if (Math.round(lastContact/60) > 48) {
lastContactString = Math.round(lastContact/60/24) + ' Tagen';
}
return lastContactString;
};
break;
const getLastStateChange = async () => {
lastContactString = this.formatDate(new Date((deviceMainSelector.lc)), 'hh:mm') + ' Uhr';
if (Math.round(lastStateChange) > 100) {
lastContactString = Math.round(lastStateChange/60) + ' Stunden';
}
if (Math.round(lastStateChange/60) > 48) {
lastContactString = Math.round(lastStateChange/60/24) + ' Tagen';
}
return lastContactString;
};
default:
await getLastContact();
break;
}
// 2b. wenn seit X Minuten kein Kontakt mehr besteht, nimm Gerät in Liste auf
//Rechne auf Tage um, wenn mehr als 48 Stunden seit letztem Kontakt vergangen sind
//lastContactString = Math.round(lastContact) + ' Minuten';
switch (this.arrDev[i].adapter) {
case 'ping':
//State changed
switch (this.arrDev[i].adapter) {
case 'alexa2':
if (this.config.alexa2MaxMinutes === -1) {
if (!deviceUnreachState) {
await getLastStateChange();
} else {
await getLastContact();
}
break;
default:
await getLastContact();
break;
}
switch (this.arrDev[i].adapter) {
case 'alexa2':
if (this.config.alexa2MaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
}
} else if (lastContact > this.config.alexa2MaxMinutes) {
deviceState = 'Offline'; //set online state to offline

@@ -544,16 +525,16 @@ this.offlineDevices.push(

}
break;
case 'ble':
if (this.config.bleMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.alexa2MaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.bleMaxMinutes) {
);
}
break;
case 'ble':
if (this.config.bleMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -568,16 +549,16 @@ this.offlineDevices.push(

}
break;
case 'deconz':
if (this.config.deconzMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.bleMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.deconzMaxMinutes) {
);
}
break;
case 'deconz':
if (this.config.deconzMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -592,16 +573,16 @@ this.offlineDevices.push(

}
break;
case 'esphome':
if (this.config.esphomeMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.deconzMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.esphomeMaxMinutes) {
);
}
break;
case 'esphome':
if (this.config.esphomeMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -616,16 +597,16 @@ this.offlineDevices.push(

}
break;
case 'fritzDect':
if (this.config.fritzdectMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.esphomeMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.fritzdectMaxMinutes) {
);
}
break;
case 'fritzDect':
if (this.config.fritzdectMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -640,16 +621,16 @@ this.offlineDevices.push(

}
break;
case 'homematic':
if (this.config.homematicMaxMinutes === -1) {
if (deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.fritzdectMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.homematicMaxMinutes) {
);
}
break;
case 'homematic':
if (this.config.homematicMaxMinutes === -1) {
if (deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -664,16 +645,16 @@ this.offlineDevices.push(

}
break;
case 'hue':
if (this.config.hueMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.homematicMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.hueMaxMinutes) {
);
}
break;
case 'hue':
if (this.config.hueMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -688,16 +669,16 @@ this.offlineDevices.push(

}
break;
case 'hue extended':
if (this.config.hueextMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.hueMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.hueextMaxMinutes) {
);
}
break;
case 'hue extended':
if (this.config.hueextMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -712,16 +693,16 @@ this.offlineDevices.push(

}
break;
case 'miHome':
if (this.config.mihomeMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.hueextMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.mihomeMaxMinutes) {
);
}
break;
case 'miHome':
if (this.config.mihomeMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -736,16 +717,16 @@ this.offlineDevices.push(

}
break;
case 'nuki_extended':
if (this.config.nukiextendMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.mihomeMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.nukiextendMaxMinutes) {
);
}
break;
case 'nuki_extended':
if (this.config.nukiextendMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -760,16 +741,16 @@ this.offlineDevices.push(

}
break;
case 'ping':
if (this.config.pingMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.nukiextendMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if ((lastStateChange > this.config.pingMaxMinutes) && (!deviceUnreachState)) {
);
}
break;
case 'ping':
if (this.config.pingMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -784,16 +765,16 @@ this.offlineDevices.push(

}
break;
case 'shelly':
if (this.config.shellyMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if ((lastStateChange > this.config.pingMaxMinutes) && (!deviceUnreachState)) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.shellyMaxMinutes) {
);
}
break;
case 'shelly':
if (this.config.shellyMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -808,16 +789,16 @@ this.offlineDevices.push(

}
break;
case 'sonoff':
if (this.config.sonoffMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.shellyMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.sonoffMaxMinutes) {
);
}
break;
case 'sonoff':
if (this.config.sonoffMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -832,16 +813,16 @@ this.offlineDevices.push(

}
break;
case 'sonos':
if (this.config.sonosMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.sonoffMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.sonosMaxMinutes) {
);
}
break;
case 'sonos':
if (this.config.sonosMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -856,16 +837,16 @@ this.offlineDevices.push(

}
break;
case 'switchbot ble':
if (this.config.switchbotMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.sonosMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.switchbotMaxMinutes) {
);
}
break;
case 'switchbot ble':
if (this.config.switchbotMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -880,16 +861,16 @@ this.offlineDevices.push(

}
break;
case 'zigbee':
if (this.config.zigbeeMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.switchbotMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.zigbeeMaxMinutes) {
);
}
break;
case 'zigbee':
if (this.config.zigbeeMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -904,16 +885,16 @@ this.offlineDevices.push(

}
break;
case 'zwave':
if (this.config.zwaveMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
);
} else if (lastContact > this.config.zigbeeMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Last_contact: lastContactString
}
} else if (lastContact > this.config.zwaveMaxMinutes) {
);
}
break;
case 'zwave':
if (this.config.zwaveMaxMinutes === -1) {
if (!deviceUnreachState) {
deviceState = 'Offline'; //set online state to offline

@@ -928,47 +909,9 @@ this.offlineDevices.push(

}
break;
}
} catch (e) {
this.log.error(`(03) Error while getting timestate ${e}`);
}
}
// 2c. Count how many devcies are offline
this.offlineDevicesCount = this.offlineDevices.length;
// 3. Get battery states
const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
let batteryHealth;
if ((!deviceBatteryState) && (!shortDeviceBatteryState)) {
batteryHealth = ' - ';
} else {
switch (this.arrDev[i].adapter) {
case 'homematic':
if (deviceBatteryState === 0) {
batteryHealth = ' - ';
} else {
batteryHealth = deviceBatteryState + 'V';
}
this.batteryPowered.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Battery: batteryHealth
}
);
break;
case 'hue extended':
if (shortDeviceBatteryState) {
batteryHealth = shortDeviceBatteryState + '%';
this.batteryPowered.push(
} else if (lastContact > this.config.zwaveMaxMinutes) {
deviceState = 'Offline'; //set online state to offline
this.offlineDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Battery: batteryHealth
Last_contact: lastContactString
}

@@ -978,26 +921,31 @@ );

break;
default:
batteryHealth = (deviceBatteryState) + '%';
this.batteryPowered.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Battery: batteryHealth
}
);
}
} catch (e) {
this.log.error(`(03) Error while getting timestate ${e}`);
}
}
// 3b. Count how many devices are with battery
this.batteryPoweredCount = this.batteryPowered.length;
// 3c. Count how many devices are with low battery
const batteryWarningMin = this.config.minWarnBatterie;
const deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
const deviceLowBatStateHM = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
// 2c. Count how many devcies are offline
this.offlineDevicesCount = this.offlineDevices.length;
if (this.arrDev[i].isLowBat === 'none') {
if (deviceBatteryState && (deviceBatteryState < batteryWarningMin)) {
this.batteryLowPowered.push(
// 3. Get battery states
const deviceBatteryState = await this.getInitValue(currDeviceString + this.arrDev[i].battery);
const shortDeviceBatteryState = await this.getInitValue(shortCurrDeviceString + this.arrDev[i].battery);
let batteryHealth;
if ((!deviceBatteryState) && (!shortDeviceBatteryState)) {
batteryHealth = ' - ';
} else {
switch (this.arrDev[i].adapter) {
case 'homematic':
if (deviceBatteryState === 0) {
batteryHealth = ' - ';
} else {
batteryHealth = deviceBatteryState + 'V';
}
this.batteryPowered.push(
{

@@ -1009,6 +957,18 @@ Device: deviceName,

);
}
} else {
if (deviceLowBatState || deviceLowBatStateHM) {
this.batteryLowPowered.push(
break;
case 'hue extended':
if (shortDeviceBatteryState) {
batteryHealth = shortDeviceBatteryState + '%';
this.batteryPowered.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Battery: batteryHealth
}
);
}
break;
default:
batteryHealth = (deviceBatteryState) + '%';
this.batteryPowered.push(
{

@@ -1020,23 +980,42 @@ Device: deviceName,

);
}
}
}
// 3d. Count how many devices are with low battery
this.lowBatteryPoweredCount = this.batteryLowPowered.length;
// 3b. Count how many devices are with battery
this.batteryPoweredCount = this.batteryPowered.length;
// 4. Add all devices in the list
if (this.config.listOnlyBattery) {
if (deviceBatteryState !== null || shortDeviceBatteryState !== null) {
this.listAllDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Battery: batteryHealth,
Link_quality: linkQuality,
Last_contact: lastContactString,
Status: deviceState
}
);
}
} else if (!this.config.listOnlyBattery) {
// 3c. Count how many devices are with low battery
const batteryWarningMin = this.config.minWarnBatterie;
const deviceLowBatState = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat);
const deviceLowBatStateHM = await this.getInitValue(currDeviceString + this.arrDev[i].isLowBat2);
if (this.arrDev[i].isLowBat === 'none') {
if (deviceBatteryState && (deviceBatteryState < batteryWarningMin)) {
this.batteryLowPowered.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Battery: batteryHealth
}
);
}
} else {
if (deviceLowBatState || deviceLowBatStateHM) {
this.batteryLowPowered.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Battery: batteryHealth
}
);
}
}
// 3d. Count how many devices are with low battery
this.lowBatteryPoweredCount = this.batteryLowPowered.length;
// 4. Add all devices in the list
if (this.config.listOnlyBattery) {
if (deviceBatteryState !== null || shortDeviceBatteryState !== null) {
this.listAllDevices.push(

@@ -1053,169 +1032,220 @@ {

}
} else if (!this.config.listOnlyBattery) {
this.listAllDevices.push(
{
Device: deviceName,
Adapter: deviceAdapterName,
Battery: batteryHealth,
Link_quality: linkQuality,
Last_contact: lastContactString,
Status: deviceState
}
);
}
// 4a. Count how many devices are exists
this.deviceCounter = this.listAllDevices.length;
}
} //<--End of second loop
} //<---End of main loop
// 4a. Count how many devices are exists
this.deviceCounter = this.listAllDevices.length;
}
} //<--End of second loop
}
this.log.debug(`Function finished: ${this.main.name}`);
} //<--End of main function
async createDataForEachAdpt(adptName) {
this.log.debug(`Function started: ${this.createDataForEachAdpt.name}`);
await this.resetVars();
async sendNotifications() {
/*=============================================
= Notifications =
=============================================*/
this.log.debug(`Start the function: ${this.sendNotifications.name}`);
for (let i = 0; i < this.arrDev.length; i++) {
const pushover = {
instance: this.config.instancePushover,
title: this.config.titlePushover,
device: this.config.devicePushover,
prio: this.config.prioPushover
if (this.arrDev[i].adapter.includes(adptName)) {
await this.createData(i);
}
};
const telegram = {
instance: this.config.instanceTelegram,
user: this.config.deviceTelegram,
chatId: this.config.chatIdTelegram
};
const whatsapp = {
instance: this.config.instanceWhatsapp,
phone: this.config.phoneWhatsapp
};
const email = {
instance: this.config.instanceEmail,
subject: this.config.subjectEmail,
sendTo: this.config.sendToEmail
}
await this.writeDatapoints(adptName);
};
const jarvis = {
instance: this.config.instanceJarvis,
title: this.config.titleJarvis
this.log.debug(`Function finished: ${this.createDataForEachAdpt.name}`);
}
};
const lovelace = {
instance: this.config.instanceLovelace,
title: this.config.titleLovelace
async createDataOfAll() {
this.log.debug(`Function started: ${this.createDataOfAll.name}`);
await this.resetVars();
};
for (let i = 0; i < this.arrDev.length; i++) {
const choosedDays = {
monday: this.config.checkMonday,
tuesday: this.config.checkTuesday,
wednesday: this.config.checkWednesday,
thursday: this.config.checkThursday,
friday: this.config.checkFriday,
saturday: this.config.checkSaturday,
sunday: this.config.checkSunday,
};
await this.createData(i);
const sendPushover = async (text) => {
await this.sendToAsync(pushover.instance, 'send', {
message: text,
title: pushover.title,
device: pushover.device,
priority: pushover.prio
});
};
}
await this.writeDatapoints();
const sendTelegram = async (text) => {
await this.sendToAsync(telegram.instance, 'send', {
text: text,
user: telegram.user,
chatId: telegram.chatId
});
};
this.log.debug(`Function finished: ${this.createDataOfAll.name}`);
}
const sendWhatsapp = async (text) => {
await this.sendToAsync(whatsapp.instance, 'send', {
text: text,
phone: whatsapp.phone
});
};
async resetVars() {
// arrays
this.offlineDevices = [],
this.linkQualityDevices = [];
this.batteryPowered = [];
this.batteryLowPowered = [];
this.listAllDevices = [];
const sendEmail = async (text) => {
await this.sendToAsync(email.instance, 'send', {
sendTo: email.sendTo,
text: text,
subject: email.subject
});
};
// counts
this.offlineDevicesCount = 0;
this.deviceCounter = 0;
this.linkQualityCount = 0;
this.batteryPoweredCount = 0;
this.lowBatteryPoweredCount = 0;
const sendJarvis = async (text) => {
await this.setForeignStateAsync(`${jarvis.instance}.addNotification`, text);
};
this.deviceReachable = '';
}
const sendLovelace = async (text) => {
await this.setForeignStateAsync(`${lovelace.instance}.notifications.add`, text);
async main() {
this.log.debug(`Function started: ${this.main.name}`);
this.supAdapter = {
alexa2: this.config.alexa2Devices,
esphome: this.config.esphomeDevices,
zigbee: this.config.zigbeeDevices,
ble: this.config.bleDevices,
sonoff: this.config.sonoffDevices,
shelly: this.config.shellyDevices,
homematic: this.config.homematicDevices,
deconz: this.config.deconzDevices,
zwave: this.config.zwaveDevices,
dect: this.config.dectDevices,
hue: this.config.hueDevices,
hueExt: this.config.hueExtDevices,
nukiExt: this.config.nukiExtDevices,
ping: this.config.pingDevices,
switchbotBle: this.config.switchbotBleDevices,
sonos: this.config.sonosDevices,
mihome: this.config.mihomeDevices,
mihomeGW: this.config.mihomeDevices,
test: false, // Only for Developer
test2: false, // Only for Developer
test3: false // Only for Developer
};
/*---------- oflline notification ----------*/
if(this.config.checkSendOfflineMsg) {
try {
let msg = '';
const offlineDevicesCountOld = await this.getOwnInitValue('offlineCount');
for(const [id] of Object.entries(this.arrApart)) {
if (this.supAdapter[id]) {
this.arrDev.push(this.arrApart[id]);
this.adapterSelected.push(await this.capitalize(id));
this.log.debug(JSON.stringify(this.arrDev));
if ((this.offlineDevicesCount != offlineDevicesCountOld)) {
if (this.offlineDevicesCount == 1) { // make singular if it is only one device
msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
} else if (this.offlineDevicesCount >= 2) { //make plural if it is more than one device
msg = `Folgende ${this.offlineDevicesCount} Geräte sind seit einiger Zeit nicht erreichbar: \n`;
//create and fill datapoints for each adapter if selected
if (this.config.createOwnFolder) {
try {
await this.createDPsForEachAdapter(id);
this.log.debug(`Created datapoints for ${await this.capitalize(id)}`);
await this.createDataForEachAdpt(id);
this.log.debug(`Created and filled data for each adapter`);
} catch (e) {
this.log.warn(`Error at creating/filling datapoints for each adapter: ${e}`);
return;
}
}
}
}
for (const id of this.offlineDevices) {
msg = `${msg} \n ${id['Device']} (${id['Last_contact']})`;
//Check if an Adapter is selected.
if (this.adapterSelected.length >= 1) {
this.log.info(`Number of selected adapters: ${this.adapterSelected.length}. Loading data from: ${(this.adapterSelected).join(', ')} ...`);
} else {
this.log.warn(`No adapter selected. Please check the instance configuration!`);
return;
}
/*=============================================
= Start of main loop =
=============================================*/
try {
await this.createDataOfAll();
this.log.debug(`Created and filled data for all adapters`);
} catch (e) {
this.log.warn(`Error at creating/filling datapoints for all adapters: ${e}`);
return;
}
this.log.debug(`Function finished: ${this.main.name}`);
} //<--End of main function
async sendOfflineNotifications() {
/*=============================================
= send offline notification =
=============================================*/
this.log.debug(`Start the function: ${this.sendOfflineNotifications.name}`);
try {
let msg = '';
const offlineDevicesCountOld = await this.getOwnInitValue('offlineCount');
if ((this.offlineDevicesCount != offlineDevicesCountOld)) {
if (this.offlineDevicesCount == 1) { // make singular if it is only one device
msg = 'Folgendes Gerät ist seit einiger Zeit nicht erreichbar: \n';
} else if (this.offlineDevicesCount >= 2) { //make plural if it is more than one device
msg = `Folgende ${this.offlineDevicesCount} Geräte sind seit einiger Zeit nicht erreichbar: \n`;
}
for (const id of this.offlineDevices) {
msg = `${msg} \n ${id['Device']} (${id['Last_contact']})`;
}
this.log.info(msg);
await this.setStateAsync('lastNotification', msg, true);
if (this.config.instancePushover) {
try {
await this.sendPushover(msg);
} catch (e) {
this.log.warn (`Getting error at sending pushover notification ${e}`);
}
this.log.info(msg);
await this.setStateAsync('lastNotification', msg, true);
if (pushover.instance) {
try {
await sendPushover(msg);
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
if (this.config.instanceTelegram) {
try {
await this.sendTelegram(msg);
} catch (e) {
this.log.warn (`Getting error at sending telegram notification ${e}`);
}
if (telegram.instance) {
try {
await sendTelegram(msg);
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
if (this.config.instanceWhatsapp) {
try {
await this.sendWhatsapp(msg);
} catch (e) {
this.log.warn (`Getting error at sending whatsapp notification ${e}`);
}
if (whatsapp.instance) {
try {
await sendWhatsapp(msg);
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
if (this.config.instanceEmail) {
try {
await this.sendEmail(msg);
} catch (e) {
this.log.warn (`Getting error at sending email notification ${e}`);
}
if (email.instance) {
try {
await sendEmail(msg);
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
if (this.config.instanceJarvis) {
try {
await this.sendJarvis('{"title":"'+ this.config.titleJarvis +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + this.offlineDevicesCount + ' Geräte sind nicht erreichbar","display": "drawer"}');
} catch (e) {
this.log.warn (`Getting error at sending jarvis notification ${e}`);
}
if (jarvis.instance) {
try {
await sendJarvis('{"title":"'+ jarvis.title +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + this.offlineDevicesCount + ' Geräte sind nicht erreichbar","display": "drawer"}');
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
if (this.config.instanceLovelace) {
try {
await this.sendLovelace('{"message":" ' + this.offlineDevicesCount + ' Geräte sind nicht erreichbar", "title":"'+ this.config.titleLovelace +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}');
} catch (e) {
this.log.warn (`Getting error at sending lovelace notification ${e}`);
}
if (lovelace.instance) {
try {
await sendLovelace('{"message":" ' + this.offlineDevicesCount + ' Geräte sind nicht erreichbar", "title":"'+ lovelace.title +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}');
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
}
} catch (e) {
this.log.debug(`Getting error at sending offline notification ${e}`);
}
}//<--End of offline notification
} catch (e) {
this.log.debug(`Getting error at sending offline notification ${e}`);
}
this.log.debug(`Finished the function: ${this.sendOfflineNotifications.name}`);
}//<--End of offline notification
/*---------- Low battery Notification ----------*/
async sendBatteryNotifications() {
/*=============================================
= send low battery notification =
=============================================*/
this.log.debug(`Start the function: ${this.sendBatteryNotifications.name}`);
const now = new Date();

@@ -1226,2 +1256,12 @@ const today = now.getDay();

const choosedDays = {
monday: this.config.checkMonday,
tuesday: this.config.checkTuesday,
wednesday: this.config.checkWednesday,
thursday: this.config.checkThursday,
friday: this.config.checkFriday,
saturday: this.config.checkSaturday,
sunday: this.config.checkSunday,
};
if (choosedDays.monday) checkDays.push(1);

@@ -1235,4 +1275,3 @@ if (choosedDays.tuesday) checkDays.push(2);

if (this.config.checkSendBatteryMsg) this.log.debug(JSON.stringify(checkDays));
//Check if the message should be send today
checkDays.forEach(object => {

@@ -1244,97 +1283,105 @@ if((object >= 0) && today == object){

if (this.config.checkSendBatteryMsg) {
try {
const lastBatteryNotifyIndicator = await this.getOwnInitValue('info.lastBatteryNotification');
const batteryWarningMin = this.config.minWarnBatterie;
//Check first if a day is selected
if (checkDays.length >= 1) {
this.log.debug(`Number of selected days: ${checkDays.length}. Send Message on: ${(checkDays).join(', ')} ...`);
} else {
this.log.warn(`No days selected. Please check the instance configuration!`);
return;
}
if (now.getHours() < 11) {await this.setStateAsync('info.lastBatteryNotification', false, true);} //Nur einmal abfragen
if ((now.getHours() > 11) && (!lastBatteryNotifyIndicator) && (checkToday != undefined)){
let batteryMinCount = 0;
let infotext = '';
try {
for (const id of this.batteryPowered) {
if (id['Battery']) {
const batteryValue = parseFloat(id['Battery'].replace('%', ''));
if ((batteryValue < batteryWarningMin) && (id['Adapter'] != 'Homematic')) {
infotext = infotext + '\n' + id['Device'] + ' ' + ' (' + id['Battery'] + ')'.split(', ');
++batteryMinCount;
}
//Check if the message for low battery was already sent today
const lastBatteryNotifyIndicator = await this.getOwnInitValue('info.lastBatteryNotification');
if (now.getHours() < 11) {await this.setStateAsync('info.lastBatteryNotification', false, true);} //set indicator for send message first to 'false' later after sending to 'true'
if ((now.getHours() > 11) && (!lastBatteryNotifyIndicator) && (checkToday != undefined)){
let infotext = '';
for (const id of this.batteryLowPowered) {
infotext = infotext + '\n' + id['Device'] + ' (' + id['Battery'] + ')'.split(', ');
}
if (this.lowBatteryPoweredCount > 0) {
this.log.info(`Niedrige Batteriezustände: ${infotext}`);
await this.setStateAsync('lastNotification', infotext, true);
if (this.config.instancePushover) {
try {
await this.sendPushover(`Niedrige Batteriezustände: ${infotext}`);
} catch (e) {
this.log.warn (`Getting error at sending pushover notification ${e}`);
}
}
if (batteryMinCount > 0) {
this.log.info(`Batteriezustände: ${infotext}`);
await this.setStateAsync('lastNotification', infotext, true);
if (pushover.instance) {
try {
await sendPushover(`Batteriezustände: ${infotext}`);
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
if (this.config.instanceTelegram) {
try {
await this.sendTelegram(`Niedrige Batteriezustände: ${infotext}`);
} catch (e) {
this.log.warn (`Getting error at sending telegram notification ${e}`);
}
if (telegram.instance) {
try {
await sendTelegram(`Batteriezustände: ${infotext}`);
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
if (this.config.instanceWhatsapp) {
try {
await this.sendWhatsapp(`Niedrige Batteriezustände: ${infotext}`);
} catch (e) {
this.log.warn (`Getting error at sending whatsapp notification ${e}`);
}
if (whatsapp.instance) {
try {
await sendWhatsapp(`Batteriezustände: ${infotext}`);
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
if (this.config.instanceEmail) {
try {
await this.sendEmail(`Niedrige Batteriezustände: ${infotext}`);
} catch (e) {
this.log.warn (`Getting error at sending email notification ${e}`);
}
if (email.instance) {
try {
await sendEmail(`Batteriezustände: ${infotext}`);
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
if (this.config.instanceJarvis) {
try {
await this.sendJarvis('{"title":"'+ this.config.titleJarvis +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + this.lowBatteryPoweredCount + ' Geräte mit schwacher Batterie","display": "drawer"}');
} catch (e) {
this.log.warn (`Getting error at sending jarvis notification ${e}`);
}
if (jarvis.instance) {
try {
await sendJarvis('{"title":"'+ jarvis.title +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')","message":" ' + batteryMinCount + ' Geräte mit schwacher Batterie","display": "drawer"}');
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
if (this.config.instanceLovelace) {
try {
await this.sendLovelace('{"message":" ' + this.lowBatteryPoweredCount + ' Geräte mit schwacher Batterie", "title":"'+ this.config.titleLovelace +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}');
} catch (e) {
this.log.warn (`Getting error at sending lovelace notification ${e}`);
}
if (lovelace.instance) {
try {
await sendLovelace('{"message":" ' + batteryMinCount + ' Geräte mit schwacher Batterie", "title":"'+ lovelace.title +' (' + this.formatDate(new Date(), 'DD.MM.YYYY - hh:mm:ss') + ')"}');
} catch (e) {
this.log.warn (`Getting error at sending notification ${e}`);
}
}
}
await this.setStateAsync('info.lastBatteryNotification', true, true);
}
await this.setStateAsync('info.lastBatteryNotification', true, true);
}
} catch (e) {
this.log.debug(`Getting error at sending battery notification ${e}`);
}
}//<--End of battery notification
this.log.debug(`Function finished: ${this.sendNotifications.name}`);
}
/*===== End of Section notifications ======*/
} catch (e) {
this.log.debug(`Getting error at sending battery notification ${e}`);
}
this.log.debug(`Finished the function: ${this.sendBatteryNotifications.name}`);
}//<--End of battery notification
async writeDatapoints() {
async writeDatapoints(adptName) {
/*=============================================
= Write Datapoints =
=============================================*/
this.log.debug(`Start the function: ${this.writeDatapoints.name}`);
try {
await this.setStateAsync('offlineCount', {val: this.offlineDevicesCount, ack: true});
await this.setStateAsync('countAll', {val: this.deviceCounter, ack: true});
await this.setStateAsync('batteryCount', {val: this.batteryPoweredCount, ack: true});
await this.setStateAsync('lowBatteryCount', {val: this.lowBatteryPoweredCount, ack: true});
let dpSubFolder;
if (adptName) { //write the datapoints in subfolders with the adaptername otherwise write the dP's in the root folder
dpSubFolder = adptName + '.';
} else {
dpSubFolder = '';}
await this.setStateAsync(`${dpSubFolder}offlineCount`, {val: this.offlineDevicesCount, ack: true});
await this.setStateAsync(`${dpSubFolder}countAll`, {val: this.deviceCounter, ack: true});
await this.setStateAsync(`${dpSubFolder}batteryCount`, {val: this.batteryPoweredCount, ack: true});
await this.setStateAsync(`${dpSubFolder}lowBatteryCount`, {val: this.lowBatteryPoweredCount, ack: true});
if (this.deviceCounter == 0) {
this.listAllDevices = [{Device: '--keine--', Adapter: '', Battery: '', Last_contact: '', Link_quality: ''}]; //JSON-Info Gesamtliste mit Info je Gerät
await this.setStateAsync('listAll', {val: JSON.stringify(this.listAllDevices), ack: true});
await this.setStateAsync(`${dpSubFolder}listAll`, {val: JSON.stringify(this.listAllDevices), ack: true});
} else {
await this.setStateAsync('listAll', {val: JSON.stringify(this.listAllDevices), ack: true});
await this.setStateAsync(`${dpSubFolder}listAll`, {val: JSON.stringify(this.listAllDevices), ack: true});
}

@@ -1345,5 +1392,5 @@

await this.setStateAsync('linkQualityList', {val: JSON.stringify(this.linkQualityDevices), ack: true});
await this.setStateAsync(`${dpSubFolder}linkQualityList`, {val: JSON.stringify(this.linkQualityDevices), ack: true});
} else {
await this.setStateAsync('linkQualityList', {val: JSON.stringify(this.linkQualityDevices), ack: true});
await this.setStateAsync(`${dpSubFolder}linkQualityList`, {val: JSON.stringify(this.linkQualityDevices), ack: true});
}

@@ -1355,5 +1402,5 @@

await this.setStateAsync('offlineList', {val: JSON.stringify(this.offlineDevices), ack: true});
await this.setStateAsync(`${dpSubFolder}offlineList`, {val: JSON.stringify(this.offlineDevices), ack: true});
} else {
await this.setStateAsync('offlineList', {val: JSON.stringify(this.offlineDevices), ack: true});
await this.setStateAsync(`${dpSubFolder}offlineList`, {val: JSON.stringify(this.offlineDevices), ack: true});
}

@@ -1364,5 +1411,5 @@

await this.setStateAsync('batteryList', {val: JSON.stringify(this.batteryPowered), ack: true});
await this.setStateAsync(`${dpSubFolder}batteryList`, {val: JSON.stringify(this.batteryPowered), ack: true});
} else {
await this.setStateAsync('batteryList', {val: JSON.stringify(this.batteryPowered), ack: true});
await this.setStateAsync(`${dpSubFolder}batteryList`, {val: JSON.stringify(this.batteryPowered), ack: true});
}

@@ -1373,5 +1420,5 @@

await this.setStateAsync('lowBatteryList', {val: JSON.stringify(this.batteryLowPowered), ack: true});
await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {val: JSON.stringify(this.batteryLowPowered), ack: true});
} else {
await this.setStateAsync('lowBatteryList', {val: JSON.stringify(this.batteryLowPowered), ack: true});
await this.setStateAsync(`${dpSubFolder}lowBatteryList`, {val: JSON.stringify(this.batteryLowPowered), ack: true});
}

@@ -1387,6 +1434,6 @@

this.log.debug(`Function finished: ${this.writeDatapoints.name}`);
}
/*===== End of writing Datapoints ======*/
}//<--End of writing Datapoints
onUnload(callback) {

@@ -1393,0 +1440,0 @@ try {

{
"name": "iobroker.device-watcher",
"version": "0.1.2",
"version": "0.2.0",
"description": "Watchdog for wireless devices",

@@ -5,0 +5,0 @@ "author": "Christian Behrends <mail@christian-behrends.de>",

@@ -10,3 +10,3 @@ ![Logo](admin/device-watcher.png)

![GitHub commit activity](https://img.shields.io/github/commit-activity/m/ciddi89/ioBroker.device-watcher)
![GitHub commits since tagged version (branch)](https://img.shields.io/github/commits-since/ciddi89/ioBroker.device-watcher/v0.1.2)
![GitHub commits since tagged version (branch)](https://img.shields.io/github/commits-since/ciddi89/ioBroker.device-watcher/v0.2.0)
![GitHub last commit](https://img.shields.io/github/last-commit/ciddi89/ioBroker.device-watcher)

@@ -78,2 +78,5 @@ ![GitHub issues](https://img.shields.io/github/issues/ciddi89/ioBroker.device-watcher)

-->
### 0.2.0 (2022-07-24)
- added function to create data of each adapter
### 0.1.2 (2022-07-22)

@@ -80,0 +83,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc