Merge branch 'master' into master
This commit is contained in:
@@ -28,7 +28,7 @@ jobs:
|
||||
steps:
|
||||
- uses: ioBroker/testing-action-check@v1
|
||||
with:
|
||||
node-version: '22.x'
|
||||
node-version: '24.x'
|
||||
lint: true
|
||||
|
||||
adapter-tests:
|
||||
@@ -67,6 +67,6 @@ jobs:
|
||||
steps:
|
||||
- uses: ioBroker/testing-action-deploy@v1
|
||||
with:
|
||||
node-version: '22.x'
|
||||
node-version: '24.x'
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
build: true
|
||||
|
||||
@@ -109,6 +109,7 @@ Please check it https://www.smarthomejetzt.de/mit-iobroker-auf-eine-home-assista
|
||||
### **WORK IN PROGRESS**
|
||||
* (@klein0r) Use /core/ instead of /api/ when connecting to supervisor directly (e.g. in ha app)
|
||||
* (@klein0r) Use ENV var SUPERVISOR_TOKEN as fallback for password
|
||||
* (@GermanBluefox) Tried to keep the custom settings of the objects when updating them with new data from HASS
|
||||
|
||||
### 2.0.3 (2026-04-02)
|
||||
* (@GermanBluefox) Adapter was updated and migrated to TypeScript
|
||||
|
||||
+10
-25
@@ -131,19 +131,16 @@
|
||||
"adminUI": {
|
||||
"config": "json"
|
||||
},
|
||||
"license": "MIT",
|
||||
"licenseInformation": {
|
||||
"type": "free",
|
||||
"license": "MIT"
|
||||
},
|
||||
"extIcon": "https://raw.githubusercontent.com/ioBroker/ioBroker.hass/master/admin/hass.png",
|
||||
"keywords": [
|
||||
"HASS",
|
||||
"Home",
|
||||
"assistant"
|
||||
],
|
||||
"keywords": ["HASS", "Home", "assistant"],
|
||||
"readme": "https://github.com/ioBroker/ioBroker.hass/blob/master/README.md",
|
||||
"loglevel": "info",
|
||||
"type": "iot-systems",
|
||||
"authors": [
|
||||
"bluefox <dogafox@gmail.com>"
|
||||
],
|
||||
"authors": ["bluefox <dogafox@gmail.com>"],
|
||||
"dependencies": [
|
||||
{
|
||||
"js-controller": ">=6.0.11"
|
||||
@@ -166,10 +163,7 @@
|
||||
{
|
||||
"condition": {
|
||||
"operand": "and",
|
||||
"rules": [
|
||||
"oldVersion<1.1.0",
|
||||
"newVersion>=1.1.0"
|
||||
]
|
||||
"rules": ["oldVersion<1.1.0", "newVersion>=1.1.0"]
|
||||
},
|
||||
"title": {
|
||||
"en": "Re-enter the password after Update!",
|
||||
@@ -198,18 +192,12 @@
|
||||
"uk": "Після встановлення цього оновлення пароль/токен, який використовується для доступу до встановлення HASS, потрібно повторно ввести в налаштуваннях екземпляра!"
|
||||
},
|
||||
"level": "warn",
|
||||
"buttons": [
|
||||
"agree",
|
||||
"cancel"
|
||||
]
|
||||
"buttons": ["agree", "cancel"]
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"operand": "and",
|
||||
"rules": [
|
||||
"oldVersion<1.2.0",
|
||||
"newVersion>=1.2.0"
|
||||
]
|
||||
"rules": ["oldVersion<1.2.0", "newVersion>=1.2.0"]
|
||||
},
|
||||
"title": {
|
||||
"en": "Important notice!",
|
||||
@@ -238,10 +226,7 @@
|
||||
"uk": "Нова версія 1.2.x потенційно змінить назви об’єктів, якщо в атрибутах об’єктів використовувалися спеціальні символи, такі як «.», «-» або пробіли! За потреби видаліть старі об’єкти вручну."
|
||||
},
|
||||
"level": "warn",
|
||||
"buttons": [
|
||||
"agree",
|
||||
"cancel"
|
||||
]
|
||||
"buttons": ["agree", "cancel"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Generated
+9
-10
@@ -21,8 +21,7 @@
|
||||
"@iobroker/eslint-config": "^2.2.0",
|
||||
"@iobroker/legacy-testing": "^2.0.2",
|
||||
"@iobroker/testing": "^5.2.2",
|
||||
"@types/ws": "^8.18.1",
|
||||
"mocha": "^11.7.5"
|
||||
"@types/ws": "^8.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@alcalzone/esbuild-register": {
|
||||
@@ -2641,12 +2640,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz",
|
||||
"integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==",
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz",
|
||||
"integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.11",
|
||||
"follow-redirects": "^1.16.0",
|
||||
"form-data": "^4.0.5",
|
||||
"proxy-from-env": "^2.1.0"
|
||||
}
|
||||
@@ -10042,12 +10041,12 @@
|
||||
}
|
||||
},
|
||||
"axios": {
|
||||
"version": "1.15.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz",
|
||||
"integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==",
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz",
|
||||
"integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"follow-redirects": "^1.15.11",
|
||||
"follow-redirects": "^1.16.0",
|
||||
"form-data": "^4.0.5",
|
||||
"proxy-from-env": "^2.1.0"
|
||||
}
|
||||
|
||||
+1
-2
@@ -37,8 +37,7 @@
|
||||
"@iobroker/eslint-config": "^2.2.0",
|
||||
"@iobroker/legacy-testing": "^2.0.2",
|
||||
"@iobroker/testing": "^5.2.2",
|
||||
"@types/ws": "^8.18.1",
|
||||
"mocha": "^11.7.5"
|
||||
"@types/ws": "^8.18.1"
|
||||
},
|
||||
"main": "build/main.js",
|
||||
"files": [
|
||||
|
||||
+28
-3
@@ -403,26 +403,51 @@ class HassAdapter extends Adapter {
|
||||
|
||||
private async deleteStaleObjects(expectedObjects: Set<string>): Promise<number> {
|
||||
const objectsToDelete: string[] = [];
|
||||
let knownCount = 0;
|
||||
for (const id in this.hassObjects) {
|
||||
if (
|
||||
Object.prototype.hasOwnProperty.call(this.hassObjects, id) &&
|
||||
id.startsWith(`${this.namespace}.entities.`) &&
|
||||
!expectedObjects.has(id)
|
||||
id.startsWith(`${this.namespace}.entities.`)
|
||||
) {
|
||||
knownCount++;
|
||||
if (!expectedObjects.has(id)) {
|
||||
objectsToDelete.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity guard: if HASS returned a drastically smaller entity set than what we
|
||||
// know (e.g. mid-startup after a restart), assume the data is incomplete and
|
||||
// skip deletion. The next sync will retry.
|
||||
if (knownCount > 10 && objectsToDelete.length > knownCount / 2) {
|
||||
this.log.warn(
|
||||
`Skipping deletion of ${objectsToDelete.length}/${knownCount} stale objects — HASS likely returned an incomplete state list. Will retry on next sync.`,
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
let deletedCount = 0;
|
||||
for (const id of objectsToDelete) {
|
||||
try {
|
||||
// Never auto-delete objects that hold user configuration like
|
||||
// common.custom (history/influxdb/sql adapter settings) — losing
|
||||
// those silently on a transient HASS hiccup would force the user
|
||||
// to recreate them. See issue #165.
|
||||
const existing = await this.getForeignObjectAsync(id);
|
||||
const custom = (existing?.common as { custom?: Record<string, unknown> } | undefined)?.custom;
|
||||
if (custom && Object.keys(custom).length) {
|
||||
this.log.debug(`Keeping "${id}" despite being stale: object holds custom adapter configuration`);
|
||||
continue;
|
||||
}
|
||||
await this.delObjectAsync(id);
|
||||
delete this.hassObjects[id];
|
||||
deletedCount++;
|
||||
} catch (err) {
|
||||
this.log.error(`Error deleting object ${id}: ${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
return objectsToDelete.length;
|
||||
return deletedCount;
|
||||
}
|
||||
|
||||
private async parseStates(entities: HassEntity[], services: HassServices): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user