feat: Strom, Leistung und Strombudget
Zeigt strip.current_ma und strip.power_w aus system/info als Sensoren und macht max_milliamps aus system/settings ueber ein Zahlenfeld einstellbar. Schreiben liest wie bei sACN zurueck statt den geschriebenen Wert anzunehmen.
This commit is contained in:
@@ -115,6 +115,10 @@ class NinstripClient:
|
||||
"""sACN-Einstellungen aendern. Weggelassene Felder behalten ihren Wert."""
|
||||
await self._request("PUT", "system/settings", {"type": "sacn", **fields})
|
||||
|
||||
async def set_strip(self, **fields: Any) -> None:
|
||||
"""Strip-Einstellungen aendern. Weggelassene Felder behalten ihren Wert."""
|
||||
await self._request("PUT", "system/settings", {"type": "strip", **fields})
|
||||
|
||||
async def reboot(self) -> None:
|
||||
await self._request("PUT", "system/command", {"command": {"type": "reboot"}})
|
||||
|
||||
|
||||
@@ -183,6 +183,29 @@ class NinstripCoordinator(DataUpdateCoordinator[NinstripData]):
|
||||
)
|
||||
)
|
||||
|
||||
async def async_set_strip(self, **fields: Any) -> None:
|
||||
"""Strip-Einstellungen schreiben und die Antwort des Geraets uebernehmen.
|
||||
|
||||
Gleiches Muster wie async_set_sacn: das Geraet antwortet nur mit
|
||||
{"status": "ok"}, also wird zurueckgelesen statt angenommen.
|
||||
"""
|
||||
|
||||
async def schreiben_und_lesen(client: NinstripClient) -> dict[str, Any]:
|
||||
await client.set_strip(**fields)
|
||||
return await client.get_settings()
|
||||
|
||||
settings = await self.async_call(schreiben_und_lesen)
|
||||
self._consecutive_poll_failures = 0
|
||||
self.async_set_updated_data(
|
||||
NinstripData(
|
||||
self.data.state,
|
||||
self.data.info,
|
||||
self.data.presets,
|
||||
self.data.segments,
|
||||
settings,
|
||||
)
|
||||
)
|
||||
|
||||
async def async_set_all_segments(self, **fields: Any) -> None:
|
||||
"""Schreibt dieselben Felder in JEDES Segment und liest zurueck.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ from homeassistant.components.number import (
|
||||
NumberEntityDescription,
|
||||
NumberMode,
|
||||
)
|
||||
from homeassistant.const import EntityCategory, UnitOfTime
|
||||
from homeassistant.const import EntityCategory, UnitOfElectricCurrent, UnitOfTime
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
@@ -60,6 +60,7 @@ async def async_setup_entry(
|
||||
entitaeten: list[NumberEntity] = [NinstripZeit(coordinator, d) for d in ZEITEN]
|
||||
entitaeten.append(NinstripSacnUniverse(coordinator))
|
||||
entitaeten.append(NinstripSacnStartSlot(coordinator))
|
||||
entitaeten.append(NinstripStrombudget(coordinator))
|
||||
async_add_entities(entitaeten)
|
||||
|
||||
|
||||
@@ -141,3 +142,28 @@ class NinstripSacnStartSlot(NinstripSacnEntity, NumberEntity):
|
||||
|
||||
async def async_set_native_value(self, value: float) -> None:
|
||||
await self.coordinator.async_set_sacn(start_slot=int(value))
|
||||
|
||||
|
||||
class NinstripStrombudget(NinstripEntity, NumberEntity):
|
||||
"""Was das Netzteil hergibt. Die Firmware regelt daran."""
|
||||
|
||||
_attr_entity_category = EntityCategory.CONFIG
|
||||
_attr_translation_key = "max_milliamps"
|
||||
_attr_native_min_value = 100
|
||||
# Die Firmware nimmt fuer das Budget hoechstens 65535 mA an (uint16).
|
||||
_attr_native_max_value = 65535
|
||||
_attr_native_step = 100
|
||||
_attr_mode = NumberMode.BOX
|
||||
_attr_native_unit_of_measurement = UnitOfElectricCurrent.MILLIAMPERE
|
||||
|
||||
def __init__(self, coordinator: NinstripCoordinator) -> None:
|
||||
super().__init__(coordinator, "max_milliamps")
|
||||
|
||||
@property
|
||||
def native_value(self) -> float | None:
|
||||
strip = self.coordinator.data.settings.get("strip")
|
||||
wert = strip.get("max_milliamps") if isinstance(strip, dict) else None
|
||||
return float(wert) if isinstance(wert, (int, float)) else None
|
||||
|
||||
async def async_set_native_value(self, value: float) -> None:
|
||||
await self.coordinator.async_set_strip(max_milliamps=int(value))
|
||||
|
||||
@@ -16,7 +16,9 @@ from homeassistant.components.sensor import (
|
||||
from homeassistant.const import (
|
||||
SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
|
||||
EntityCategory,
|
||||
UnitOfElectricCurrent,
|
||||
UnitOfInformation,
|
||||
UnitOfPower,
|
||||
UnitOfTime,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
@@ -98,6 +100,27 @@ SENSORS: tuple[NinstripSensorDescription, ...] = (
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value=lambda d: _strip(d, "power_scale"),
|
||||
),
|
||||
# 0 mA heisst entweder "zieht gerade nichts" oder "misst gar nicht" -
|
||||
# aeltere Firmware ohne Shunt meldet ebenfalls 0. Von aussen nicht zu
|
||||
# unterscheiden, und keine Heuristik dagegen: Schwaeche der Geraete-API.
|
||||
NinstripSensorDescription(
|
||||
key="current",
|
||||
translation_key="current",
|
||||
device_class=SensorDeviceClass.CURRENT,
|
||||
native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value=lambda d: _strip(d, "current_ma"),
|
||||
),
|
||||
NinstripSensorDescription(
|
||||
key="power",
|
||||
translation_key="power",
|
||||
device_class=SensorDeviceClass.POWER,
|
||||
native_unit_of_measurement=UnitOfPower.WATT,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
value=lambda d: _strip(d, "power_w"),
|
||||
),
|
||||
# Was bei der letzten Aktualisierung schiefging - leer, solange nichts
|
||||
# schiefging. Aus der Ferne der einzige Hinweis darauf.
|
||||
NinstripSensorDescription(
|
||||
|
||||
@@ -105,6 +105,12 @@
|
||||
"power_scale": {
|
||||
"name": "Leistungsbegrenzung"
|
||||
},
|
||||
"current": {
|
||||
"name": "Strom"
|
||||
},
|
||||
"power": {
|
||||
"name": "Leistung"
|
||||
},
|
||||
"last_ota_error": {
|
||||
"name": "Letzter Update-Fehler"
|
||||
},
|
||||
@@ -135,6 +141,9 @@
|
||||
},
|
||||
"transition_default": {
|
||||
"name": "Übergangszeit (Vorgabe)"
|
||||
},
|
||||
"max_milliamps": {
|
||||
"name": "Strombudget"
|
||||
}
|
||||
},
|
||||
"binary_sensor": {
|
||||
|
||||
@@ -105,6 +105,12 @@
|
||||
"power_scale": {
|
||||
"name": "Leistungsbegrenzung"
|
||||
},
|
||||
"current": {
|
||||
"name": "Strom"
|
||||
},
|
||||
"power": {
|
||||
"name": "Leistung"
|
||||
},
|
||||
"last_ota_error": {
|
||||
"name": "Letzter Update-Fehler"
|
||||
},
|
||||
@@ -135,6 +141,9 @@
|
||||
},
|
||||
"transition_default": {
|
||||
"name": "Übergangszeit (Vorgabe)"
|
||||
},
|
||||
"max_milliamps": {
|
||||
"name": "Strombudget"
|
||||
}
|
||||
},
|
||||
"binary_sensor": {
|
||||
|
||||
@@ -105,6 +105,12 @@
|
||||
"power_scale": {
|
||||
"name": "Power limiting"
|
||||
},
|
||||
"current": {
|
||||
"name": "Current"
|
||||
},
|
||||
"power": {
|
||||
"name": "Power"
|
||||
},
|
||||
"last_ota_error": {
|
||||
"name": "Last update error"
|
||||
},
|
||||
@@ -135,6 +141,9 @@
|
||||
},
|
||||
"transition_default": {
|
||||
"name": "Default transition time"
|
||||
},
|
||||
"max_milliamps": {
|
||||
"name": "Current budget"
|
||||
}
|
||||
},
|
||||
"binary_sensor": {
|
||||
|
||||
Reference in New Issue
Block a user