Skip to content

Commit

Permalink
feat: number.py for configurable integer items
Browse files Browse the repository at this point in the history
- Zero Export power as first configurable item
  • Loading branch information
davidrapan committed Jul 17, 2024
1 parent b23482e commit 175936d
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 23 deletions.
2 changes: 1 addition & 1 deletion custom_components/solarman/const.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import timedelta as td

DOMAIN = "solarman"
PLATFORMS: list[str] = ["sensor", "switch"]
PLATFORMS: list[str] = ["sensor", "switch", "number"]

IP_BROADCAST = "<broadcast>"
IP_ANY = "0.0.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,16 @@ parameters:
registers: [0x0067]
icon: "mdi:battery"

- name: "Zero Export"
attribute:
- name: "Zero Export power"
class: "power"
state_class: "measurement"
uom: "W"
scale: 1
rule: 1
registers: [0x0068]
configurable:
min: 0
max: 500
icon: "mdi:transmission-tower-import"

- name: "Battery Equalization Cycle"
Expand Down Expand Up @@ -1273,7 +1275,6 @@ parameters:
rule: 4
registers: [0x0271, 0x02B2]
icon: "mdi:transmission-tower"
attributes: ["Zero Export"]

- group: Inverter
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,16 @@ parameters:
registers: [0x0067]
icon: "mdi:battery"

- name: "Zero Export Power"
- name: "Zero Export power"
class: "power"
state_class: "measurement"
uom: "W"
scale: 1
rule: 1
registers: [0x0068]
configurable:
min: 0
max: 500
icon: "mdi:transmission-tower-import"

- name: "Battery Equalization Cycle"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,14 +201,16 @@ parameters:
registers: [0x0067]
icon: "mdi:battery"

- name: "Zero Export"
attribute:
- name: "Zero Export power"
class: "power"
state_class: "measurement"
uom: "W"
scale: 1
rule: 1
registers: [0x0068]
configurable:
min: 0
max: 500
icon: "mdi:transmission-tower-import"

- name: "Battery Equalization Cycle"
Expand Down Expand Up @@ -1290,7 +1292,6 @@ parameters:
rule: 4
registers: [0x0271, 0x02B2]
icon: "mdi:transmission-tower"
attributes: ["Zero Export"]

# Grid - The inverted power is S16bit (low 16 bits) + S16bit (high 16 bits)
- name: "Grid Power ∇"
Expand All @@ -1304,7 +1305,6 @@ parameters:
inverted: True
registers: [0x0271, 0x02B2]
icon: "mdi:transmission-tower"
attributes: ["Zero Export"]

- group: Inverter
items:
Expand Down
84 changes: 84 additions & 0 deletions custom_components/solarman/number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from __future__ import annotations

import logging
import asyncio
import voluptuous as vol

from functools import cached_property, partial

from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.const import CONF_NAME, STATE_OFF, STATE_ON, EntityCategory
from homeassistant.components.number import NumberEntity, NumberDeviceClass, NumberEntityDescription
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import *
from .common import *
from .services import *
from .sensor import SolarmanSensor

_LOGGER = logging.getLogger(__name__)

_PLATFORM = get_current_file_name(__name__)

def _create_sensor(coordinator, sensor):
try:
entity = SolarmanNumberEntity(coordinator, sensor)

entity.update()

return entity
except BaseException as e:
_LOGGER.error(f"Configuring {sensor} failed. [{format_exception(e)}]")
raise

async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry, async_add_entities: AddEntitiesCallback) -> bool:
_LOGGER.debug(f"async_setup_entry: {config.options}")
coordinator = hass.data[DOMAIN][config.entry_id]

sensors = coordinator.inverter.get_sensors()

# Add entities.
#
_LOGGER.debug(f"async_setup: async_add_entities")

async_add_entities(_create_sensor(coordinator, sensor) for sensor in sensors if "configurable" in sensor)
#if ("class" in sensor and sensor["class"] == _PLATFORM)
return True

async def async_unload_entry(hass: HomeAssistant, config: ConfigEntry) -> bool:
_LOGGER.debug(f"async_unload_entry: {config.options}")
return True

class SolarmanNumberEntity(SolarmanSensor, NumberEntity):
def __init__(self, coordinator, sensor):
SolarmanSensor.__init__(self, coordinator, sensor, 0)
# Set The Category of the entity.
self._attr_entity_category = EntityCategory.CONFIG

registers = sensor["registers"]
registers_length = len(registers)
if registers_length > 0:
self.register = sensor["registers"][0]
if registers_length > 1:
_LOGGER.warning(f"SolarmanNumberEntity.__init__: Contains more than 1 register!")

configurable = sensor["configurable"]
if "min" in configurable:
self._attr_native_min_value = configurable["min"]
if "max" in configurable:
self._attr_native_max_value = configurable["max"]

@property
def native_value(self) -> float:
"""Return the state of the setting entity."""
return self._attr_state

async def async_set_native_value(self, value: float) -> None:
"""Update the setting."""
int_value = int(value)
await self.coordinator.inverter.service_write_multiple_holding_registers(self.register, [int_value,])
self._attr_state = int_value
self.async_write_ha_state()
#await self.entity_description.update_fn(self.coordinator., int(value))
#await self.coordinator.async_request_refresh()
2 changes: 1 addition & 1 deletion custom_components/solarman/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry, async_add_
#
_LOGGER.debug(f"async_setup: async_add_entities")

async_add_entities(_create_sensor(coordinator, sensor, battery_nominal_voltage, battery_life_cycle_rating) for sensor in sensors if (not "class" in sensor or not sensor["class"] in PLATFORMS))
async_add_entities(_create_sensor(coordinator, sensor, battery_nominal_voltage, battery_life_cycle_rating) for sensor in sensors if ((not "class" in sensor or not sensor["class"] in PLATFORMS) and not "configurable" in sensor))
return True

async def async_unload_entry(hass: HomeAssistant, config: ConfigEntry) -> bool:
Expand Down
16 changes: 3 additions & 13 deletions custom_components/solarman/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,15 @@

from functools import cached_property, partial

from homeassistant.components.template.sensor import SensorTemplate
from homeassistant.components.template.sensor import TriggerSensorEntity
from homeassistant.components.switch import SwitchEntity, SwitchDeviceClass, SwitchEntityDescription
from homeassistant.helpers.template import Template

from homeassistant.core import HomeAssistant, callback
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME, EntityCategory, STATE_OFF, STATE_ON
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo, format_mac
from homeassistant.helpers.entity import Entity, ToggleEntity
from homeassistant.core import HomeAssistant, callback
from homeassistant.const import CONF_NAME, STATE_OFF, STATE_ON, EntityCategory
from homeassistant.components.switch import SwitchEntity, SwitchDeviceClass, SwitchEntityDescription
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import *
from .common import *
from .services import *
from .api import Inverter
from .coordinator import InverterCoordinator
from .entity import SolarmanCoordinatorEntity, SolarmanBaseEntity, SolarmanEntity
from .sensor import SolarmanSensor

_LOGGER = logging.getLogger(__name__)
Expand Down

0 comments on commit 175936d

Please sign in to comment.