Files
ha-ninstrip/custom_components/ninstrip/translations/en.json
T
Michael Sauer 2c77b2d325 feat: update-Entitaet fuer die Firmware und das Testgeruest
Aufgebaut wie ha-ninlight: die Abbilder liegen unter ninstrip_firmware im
Konfigurationsverzeichnis, Home Assistant liefert sie selbst unter einer
einmaligen Adresse aus, und zwar genau die Bytes, die vorher geprueft
wurden. Dazu firmware.py (Anhaenger, Versionsreihenfolge, WLAN-Pruefung,
Katalog), http.py, urls.py und shared.py.

Drei Unterschiede zu ninlight, alle aus der Firmware heraus:

* Verglichen wird device_type - die Platine -, nicht product. Letzteres ist
  bei allen Platinen 'ninstrip'; die Abbilder unterscheiden sich aber hart,
  die K1Y invertiert das Datensignal und die KL-RGBC3 nicht. Firmware ohne
  dieses Feld bekommt gar kein Angebot.
* Die WLAN-Pruefung sucht die SSID unverpackt: ein ESP32-Abbild ist nicht
  gzip-verpackt wie das des W600. An einem mit sdkconfig.local gebauten
  Abbild gegengeprueft - die SSID steht genau einmal NUL-gerahmt drin.
* Der Fehlerschluessel heisst device_url_too_long statt lamp_url_too_long.

Dazu das Testgeruest, das es hier bisher gar nicht gab: 204 Tests in
tests_unit/ (ohne HA-Instanz) und tests/ (mit), Abdeckung 97 %, dazu
scripts/check.sh als Ersatz fuer die fehlende CI. Die Nutzdaten in
tests_unit/samples.py sind an der Stehlampe abgefragt.

Beim Gegenpruefen per Mutation fiel auf, dass die Platinenpruefung
unmittelbar vor dem Senden ungeprueft war - der Test dazu ist jetzt da und
faellt, wenn man die Pruefung entfernt.
2026-09-22 23:10:07 +02:00

160 lines
4.6 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"config": {
"step": {
"user": {
"title": "Add ninstrip",
"description": "Host and API token of the device. A factory-new or factory-reset device uses the default token, which is prefilled. If you set your own, enter it here.",
"data": {
"host": "Host",
"token": "API token"
}
},
"discovery_confirm": {
"title": "ninstrip found",
"description": "{name} at {host}. Please enter the API token.",
"data": {
"token": "API token"
}
},
"reauth_confirm": {
"title": "Renew token",
"description": "The device at {host} rejects the stored token. After a factory reset the default token applies again.",
"data": {
"token": "API token"
}
}
},
"error": {
"cannot_connect": "Device unreachable",
"invalid_auth": "Token rejected",
"not_ninstrip": "No ninstrip answering there",
"unknown": "Unexpected error"
},
"abort": {
"already_configured": "This device is already configured",
"reauth_successful": "Token renewed"
}
},
"options": {
"step": {
"init": {
"title": "Settings",
"data": {
"scan_interval": "Polling interval (seconds)",
"device_base_url": "Address devices use to reach Home Assistant"
},
"data_description": {
"device_base_url": "Only needed for firmware updates if devices cannot reach Home Assistant's internal URL over plain http, e.g. http://192.168.1.50:8123"
}
}
},
"error": {
"invalid_base_url": "Must be a plain http:// address with host and optional port, without path.",
"base_url_too_long": "Address too long – the device accepts at most 255 characters for the whole firmware URL."
}
},
"entity": {
"select": {
"preset": {
"name": "Scene"
},
"sacn_on_timeout": {
"name": "sACN on stream end",
"state": {
"release": "Return to previous image",
"hold": "Hold last image"
}
}
},
"button": {
"restart": {
"name": "Restart"
}
},
"sensor": {
"rssi": {
"name": "Wi-Fi signal"
},
"uptime": {
"name": "Uptime"
},
"free_heap": {
"name": "Free memory"
},
"power_scale": {
"name": "Power limiting"
}
},
"switch": {
"sacn_enabled": {
"name": "sACN receiver"
}
},
"number": {
"sacn_universe": {
"name": "sACN universe"
},
"sacn_start_slot": {
"name": "sACN start slot"
}
},
"binary_sensor": {
"sacn_active": {
"name": "sACN active"
},
"sacn_multicast": {
"name": "sACN multicast joined"
}
},
"update": {
"firmware": {
"name": "Firmware"
}
}
},
"exceptions": {
"auth_failed": {
"message": "The device rejected the token."
},
"device_busy": {
"message": "The device is busy - an update is probably running."
},
"request_failed": {
"message": "The device rejected the request: {message}"
},
"cannot_connect": {
"message": "The device is unreachable."
},
"update_busy": {
"message": "An update is already running on the device."
},
"no_update": {
"message": "No firmware update is available."
},
"no_http_url": {
"message": "Devices can only reach Home Assistant over plain http. Set the address in the integration options."
},
"device_url_too_long": {
"message": "The firmware URL is longer than the 255 characters the device accepts."
},
"image_invalid": {
"message": "The firmware file changed or is no longer valid."
},
"wifi_guard": {
"message": "This firmware does not contain the Wi-Fi credentials for {ssid}; the device would lose its network connection."
},
"update_failed": {
"message": "The update failed: {reason}"
},
"update_timeout": {
"message": "The device did not report the new firmware within 12 minutes."
}
},
"issues": {
"wifi_guard": {
"title": "Firmware for {name} not offered",
"description": "The firmware folder contains {version} for {device_type}, but without Wi-Fi credentials for {ssid}. The device only knows its Wi-Fi from its firmware and would lose its network connection after this update, so the update is not offered. A device that was put on the network through onboarding instead gets the update without this reservation."
}
}
}