Skip to content

Commit

Permalink
Admin notification for available firmware updates
Browse files Browse the repository at this point in the history
  • Loading branch information
klein0r committed Mar 12, 2024
1 parent 15ffa13 commit 4890368
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ execute
### **WORK IN PROGRESS**

* (klein0r) Added Shelly Plus 0-10V
* (klein0r) Admin notification for available firmware updates

### 6.8.0 (2024-02-17)

Expand Down
65 changes: 65 additions & 0 deletions io-package.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,71 @@
}
]
},
"notifications": [
{
"scope": "shelly",
"name": {
"en": "Shelly",
"de": "Shelly",
"ru": "Shelly",
"pt": "Shelly",
"nl": "Shelly",
"fr": "Shelly",
"it": "Shelly",
"es": "Shelly",
"pl": "Shelly",
"uk": "Shelly",
"zh-cn": "Shelly"
},
"description": {
"en": "These notifications represent news of connected devices.",
"de": "Diese Benachrichtigungen stellen Neuigkeiten über angeschlossene Geräte dar.",
"ru": "Эти уведомления представляют собой новости о подключенных устройствах.",
"pt": "Essas notificações representam notícias de dispositivos conectados.",
"nl": "Deze meldingen vertegenwoordigen nieuws van aangesloten apparaten.",
"fr": "Ces notifications représentent des nouvelles d'appareils connectés.",
"it": "Queste notifiche rappresentano notizie di dispositivi collegati.",
"es": "Estas notificaciones representan noticias de dispositivos conectados.",
"pl": "Powiadomienia te stanowią wiadomości o podłączonych urządzeniach.",
"uk": "Ці повідомлення представляють новини підключених пристроїв.",
"zh-cn": "这些通知代表了连接设备的消息."
},
"categories": [
{
"category": "deviceUpdates",
"name": {
"en": "Firmware update available",
"de": "Firmware-Update verfügbar",
"ru": "Доступное обновление прошивки",
"pt": "Atualização de firmware disponível",
"nl": "Firmware-update beschikbaar",
"fr": "Mise à jour du firmware disponible",
"it": "Aggiornamento firmware disponibile",
"es": "Actualización de firmware disponible",
"pl": "Dostępna aktualizacja oprogramowania firmowego",
"uk": "Оновлення прошивки",
"zh-cn": "可更新的固件"
},
"severity": "notify",
"description": {
"en": "New firmware update is available for your devices.",
"de": "Neues Firmware-Update ist für deine Geräte verfügbar.",
"ru": "Новое обновление прошивки доступно для ваших устройств.",
"pt": "Nova atualização de firmware está disponível para seus dispositivos.",
"nl": "Nieuwe firmware update is beschikbaar voor uw apparaten.",
"fr": "Une nouvelle mise à jour firmware est disponible pour vos appareils.",
"it": "Nuovo aggiornamento firmware è disponibile per i tuoi dispositivi.",
"es": "Nueva actualización de firmware está disponible para sus dispositivos.",
"pl": "Dla Państwa urządzeń dostępna jest nowa aktualizacja oprogramowania firmowego.",
"uk": "Нові оновлення прошивки доступні для ваших пристроїв.",
"zh-cn": "您的设备有新的固件更新 ."
},
"regex": [],
"limit": 1
}
]
}
],
"protectedNative": [
"mqttusername",
"mqttpassword",
Expand Down
62 changes: 55 additions & 7 deletions main.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use strict';

const utils = require('@iobroker/adapter-core');
// @ts-ignore
const objectHelper = require('@apollon/iobroker-tools').objectHelper; // Common adapter utils
const protocolMqtt = require('./lib/protocol/mqtt');
const protocolCoap = require('./lib/protocol/coap');
const adapterName = require('./package.json').name.split('.').pop();
// @ts-ignore
const tcpPing = require('tcp-ping');
const EventEmitter = require('events').EventEmitter;

Expand Down Expand Up @@ -81,6 +83,9 @@ class Shelly extends utils.Adapter {

// Wait 10 seconds for devices to connect
this.setTimeout(() => this.autoFirmwareUpdate(), 10 * 1000);
} else {
// Wait 10 seconds for devices to connect
this.setTimeout(() => this.firmwareNotify(), 10 * 1000);
}
} catch (err) {
this.log.error(`[onReady] Startup error: ${err}`);
Expand Down Expand Up @@ -173,17 +178,14 @@ class Shelly extends utils.Adapter {

try {
const deviceIds = await this.getAllDeviceIds();
for (const d in deviceIds) {
const deviceId = deviceIds[d];

const idHostname = `${deviceId}.hostname`;

const stateHostaname = await this.getStateAsync(idHostname);
for (const deviceId of deviceIds) {
const stateHostaname = await this.getStateAsync(`${deviceId}.hostname`);
const valHostname = stateHostaname ? stateHostaname.val : undefined;

if (valHostname) {
this.log.debug(`[onlineCheck] Checking ${deviceId} on ${valHostname}:${valPort}`);

// @ts-ignore
tcpPing.probe(valHostname, valPort, (error, isAlive) =>
this.deviceStatusUpdate(deviceId, isAlive));
}
Expand Down Expand Up @@ -287,7 +289,42 @@ class Shelly extends utils.Adapter {
this.firmwareUpdateTimeout = this.setTimeout(() => {
this.firmwareUpdateTimeout = null;
this.autoFirmwareUpdate();
}, 15 * 60 * 1000); // Restart firmware update in 60 Seconds
}, 15 * 60 * 1000); // Restart firmware update in 15 minutes
}
}

async firmwareNotify() {
if (this.isUnloaded) return;
if (!this.config.autoupdate) {
this.log.debug(`[firmwareNotify] Starting firmware check on every device`);

const availableUpdates = [];

try {
const deviceIds = await this.getAllDeviceIds();
for (const deviceId of deviceIds) {
const stateFirmware = await this.getStateAsync(`${deviceId}.firmware`);
const hasNewFirmware = stateFirmware && stateFirmware.ack ? stateFirmware.val : false;

if (hasNewFirmware) {
const deviceObj = await this.getObjectAsync(deviceId);

availableUpdates.push(`${deviceObj?.common.name} (${deviceId})`);
}
}
} catch (e) {
this.log.error(e.toString());
}

if (availableUpdates.length > 0) {
// @ts-ignore
this.registerNotification('shelly', 'deviceUpdates', availableUpdates.join('\n'));
}

this.firmwareUpdateTimeout = this.setTimeout(() => {
this.firmwareUpdateTimeout = null;
this.firmwareNotify();
}, 15 * 60 * 1000); // Restart firmware check in 15 minutes
}
}

Expand Down Expand Up @@ -348,28 +385,39 @@ class Shelly extends utils.Adapter {

async migrateConfig() {
const native = {};
// @ts-ignore
if (this.config?.http_username) {
// @ts-ignore
native.httpusername = this.config.http_username;
native.http_username = '';
}
// @ts-ignore
if (this.config?.http_password) {
// @ts-ignore
native.httppassword = this.config.http_password;
native.http_password = '';
}
// @ts-ignore
if (this.config?.user) {
// @ts-ignore
native.mqttusername = this.config.user;
native.user = '';
}
// @ts-ignore
if (this.config?.password) {
// @ts-ignore
native.mqttpassword = this.config.password;
native.password = '';
}
// @ts-ignore
if (this.config?.keys) {
// @ts-ignore
native.blacklist = this.config.keys.map(b => { return { id: b.blacklist }; });
native.keys = null;
}

if (this.config) {
// @ts-ignore
this.config.polltime = parseInt(this.config?.polltime, 10);
}

Expand Down

0 comments on commit 4890368

Please sign in to comment.