Skip to content

Commit

Permalink
Refactor Numbers for 2021.12+ (#254)
Browse files Browse the repository at this point in the history
* update numbers for 2012.12+

* fix numbers definition

* fix test reference

* Add restore after restart

* Add RestoreEntity import

* Fix error

* Update test_charge_point.py

fix typo

* Update test_charge_point.py

fix imports

* Update const.py

Co-authored-by: lbbrhzn <[email protected]>
  • Loading branch information
drc38 and lbbrhzn authored Dec 22, 2021
1 parent 45025bc commit 4597bbd
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 69 deletions.
18 changes: 0 additions & 18 deletions custom_components/ocpp/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@
CONF_CSID = "csid"
CONF_HOST = ha.CONF_HOST
CONF_ICON = ha.CONF_ICON
CONF_INITIAL = input_number.CONF_INITIAL
CONF_MAX = input_number.CONF_MAX
CONF_MIN = input_number.CONF_MIN
CONF_METER_INTERVAL = "meter_interval"
CONF_MODE = ha.CONF_MODE
CONF_MONITORED_VARIABLES = ha.CONF_MONITORED_VARIABLES
Expand All @@ -32,8 +29,6 @@
DEFAULT_METER_INTERVAL = 60
DOMAIN = "ocpp"
ICON = "mdi:ev-station"
MODE_SLIDER = input_number.MODE_SLIDER
MODE_BOX = input_number.MODE_BOX
SLEEP_TIME = 60

# Platforms
Expand Down Expand Up @@ -97,19 +92,6 @@

SWITCHES = [SWITCH_CHARGE, SWITCH_AVAILABILITY]

# Input number definitions
NUMBER_MAX_CURRENT = {
CONF_NAME: "Maximum_Current",
CONF_ICON: ICON,
CONF_MIN: 0,
CONF_MAX: 32,
CONF_STEP: 1,
CONF_INITIAL: 32,
CONF_MODE: MODE_SLIDER,
CONF_UNIT_OF_MEASUREMENT: "A",
}
NUMBERS = [NUMBER_MAX_CURRENT]

# Where a HA unit does not exist use Ocpp unit
UNITS_OCCP_TO_HA = {
UnitOfMeasure.wh: ha.ENERGY_WATT_HOUR,
Expand Down
118 changes: 71 additions & 47 deletions custom_components/ocpp/number.py
Original file line number Diff line number Diff line change
@@ -1,60 +1,97 @@
"""Number platform for ocpp."""
from homeassistant.components.input_number import InputNumber
from homeassistant.components.number import NumberEntity
from __future__ import annotations

from dataclasses import dataclass
from typing import Final

from homeassistant.components.number import (
DOMAIN as NUMBER_DOMAIN,
NumberEntity,
NumberEntityDescription,
)
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.restore_state import RestoreEntity
import voluptuous as vol

from .api import CentralSystem
from .const import (
CONF_CPID,
CONF_INITIAL,
CONF_MAX,
CONF_MIN,
CONF_STEP,
DEFAULT_CPID,
DOMAIN,
NUMBERS,
)
from .const import CONF_CPID, DEFAULT_CPID, DOMAIN, ICON
from .enums import Profiles


@dataclass
class OcppNumberDescription(NumberEntityDescription):
"""Class to describe a Number entity."""

initial_value: float | None = None
# can be removed when dev branch released
max_value: float | None = None
min_value: float | None = None
step: float | None = None


NUMBERS: Final = [
OcppNumberDescription(
key="maximum_current",
name="Maximum_Current",
icon=ICON,
initial_value=32,
min_value=0,
max_value=32,
step=1,
),
]


async def async_setup_entry(hass, entry, async_add_devices):
"""Configure the number platform."""
central_system = hass.data[DOMAIN][entry.entry_id]
cp_id = entry.data.get(CONF_CPID, DEFAULT_CPID)

entities = []

for cfg in NUMBERS:
entities.append(Number(central_system, cp_id, cfg))
for ent in NUMBERS:
entities.append(OcppNumber(central_system, cp_id, ent))

async_add_devices(entities, False)


class Number(InputNumber, NumberEntity):
class OcppNumber(NumberEntity, RestoreEntity):
"""Individual slider for setting charge rate."""

def __init__(self, central_system: CentralSystem, cp_id: str, config: dict):
entity_description: OcppNumberDescription

def __init__(
self,
central_system: CentralSystem,
cp_id: str,
description: OcppNumberDescription,
):
"""Initialize a Number instance."""
super().__init__(config)
self.cp_id = cp_id
self.central_system = central_system
self.id = ".".join(["number", self.cp_id, config["name"]])
self._name = ".".join([self.cp_id, config["name"]])
self.entity_id = "number." + "_".join([self.cp_id, config["name"]])
self._attr_max_value: float = config[CONF_MAX]
self._attr_min_value: float = config[CONF_MIN]
self._attr_step: float = config[CONF_STEP]
self._attr_value: float = config[CONF_INITIAL]

@property
def unique_id(self):
"""Return the unique id of this entity."""
return self.id

@property
def name(self):
"""Return the name of this entity."""
return self._name
self.entity_description = description
self._attr_unique_id = ".".join(
[NUMBER_DOMAIN, self.cp_id, self.entity_description.key]
)
self._name = ".".join([self.cp_id, self.entity_description.name])
self.entity_id = (
NUMBER_DOMAIN + "." + "_".join([self.cp_id, self.entity_description.key])
)
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, self.cp_id)},
via_device=(DOMAIN, self.central_system.id),
)
self._attr_value = self.entity_description.initial_value
# can be removed when dev branch released
self._attr_max_value = self.entity_description.max_value
self._attr_min_value = self.entity_description.min_value
self._attr_step = self.entity_description.step

async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await self.async_base_added_to_hass()
if state := await self.async_get_last_state():
self._attr_value = state.state

@property
def available(self) -> bool:
Expand All @@ -65,19 +102,6 @@ def available(self) -> bool:
return False
return self.central_system.get_available(self.cp_id) # type: ignore [no-any-return]

@property
def state(self):
"""Return the state of the component."""
return self._attr_value

@property
def device_info(self):
"""Return device information."""
return {
"identifiers": {(DOMAIN, self.cp_id)},
"via_device": (DOMAIN, self.central_system.id),
}

async def async_set_value(self, value):
"""Set new value."""
num_value = float(value)
Expand Down
7 changes: 3 additions & 4 deletions tests/test_charge_point.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

from custom_components.ocpp import async_setup_entry, async_unload_entry
from custom_components.ocpp.button import BUTTONS
from custom_components.ocpp.const import DOMAIN as OCPP_DOMAIN, NUMBERS
from custom_components.ocpp.const import DOMAIN as OCPP_DOMAIN
from custom_components.ocpp.enums import ConfigurationKey, HAChargerServices as csvcs
from custom_components.ocpp.number import NUMBERS
from custom_components.ocpp.switch import SWITCHES
from ocpp.routing import on
from ocpp.v16 import ChargePoint as cpclass, call, call_result
Expand Down Expand Up @@ -117,9 +118,7 @@ async def test_services(hass, socket_enabled):
"set_value",
service_data={"value": "10"},
blocking=True,
target={
ATTR_ENTITY_ID: f"{NUMBER_DOMAIN}.test_cpid_{number['name'].lower()}"
},
target={ATTR_ENTITY_ID: f"{NUMBER_DOMAIN}.test_cpid_{number.key}"},
)
assert result

Expand Down

0 comments on commit 4597bbd

Please sign in to comment.