From 70f8bfbd4f569d58b7959179a5fd3239c59f7cb9 Mon Sep 17 00:00:00 2001
From: Philipp Danner <philipp@danner-web.de>
Date: Sun, 22 Dec 2019 19:46:53 +0100
Subject: [PATCH] Update Integration of Keba charging station (#30125)

* fixed parsing of current to float in service set_current

* Added optional name in the config file in order to get a better entety naming (easier to find)

* fix parsing of all parameters to service calls

* addressed code review comments + updated pypi dependency

* config name imported from cont.py + minor naming changes to be more clear about the meaning of a sensor

* removed name in config again, use product name gathered from the charging station instead

* implemented suggested changes

* changed variable naming as requested
---
 homeassistant/components/keba/__init__.py     | 19 +++++---
 .../components/keba/binary_sensor.py          | 23 +++++----
 homeassistant/components/keba/lock.py         | 11 +++--
 homeassistant/components/keba/manifest.json   |  2 +-
 homeassistant/components/keba/sensor.py       | 47 +++++++++++++++----
 requirements_all.txt                          |  2 +-
 6 files changed, 72 insertions(+), 32 deletions(-)

diff --git a/homeassistant/components/keba/__init__.py b/homeassistant/components/keba/__init__.py
index 830ebe7ffab..a261311be76 100644
--- a/homeassistant/components/keba/__init__.py
+++ b/homeassistant/components/keba/__init__.py
@@ -112,7 +112,8 @@ class KebaHandler(KebaKeContact):
         self._update_listeners = []
         self._hass = hass
         self.rfid = rfid
-        self.device_name = "keba_wallbox_"
+        self.device_name = "keba"  # correct device name will be set in setup()
+        self.device_id = "keba_wallbox_"  # correct device id will be set in setup()
 
         # Ensure at least MAX_POLLING_INTERVAL seconds delay
         self._refresh_interval = max(MAX_POLLING_INTERVAL, refresh_interval)
@@ -147,8 +148,12 @@ class KebaHandler(KebaKeContact):
 
         # Request initial values and extract serial number
         await self.request_data()
-        if self.get_value("Serial") is not None:
-            self.device_name = f"keba_wallbox_{self.get_value('Serial')}"
+        if (
+            self.get_value("Serial") is not None
+            and self.get_value("Product") is not None
+        ):
+            self.device_id = f"keba_wallbox_{self.get_value('Serial')}"
+            self.device_name = self.get_value("Product")
             return True
 
         return False
@@ -179,7 +184,7 @@ class KebaHandler(KebaKeContact):
         """Set energy target in async way."""
         try:
             energy = param["energy"]
-            await self.set_energy(energy)
+            await self.set_energy(float(energy))
             self._set_fast_polling()
         except (KeyError, ValueError) as ex:
             _LOGGER.warning("Energy value is not correct. %s", ex)
@@ -188,7 +193,7 @@ class KebaHandler(KebaKeContact):
         """Set current maximum in async way."""
         try:
             current = param["current"]
-            await self.set_current(current)
+            await self.set_current(float(current))
             # No fast polling as this function might be called regularly
         except (KeyError, ValueError) as ex:
             _LOGGER.warning("Current value is not correct. %s", ex)
@@ -216,10 +221,10 @@ class KebaHandler(KebaKeContact):
     async def async_set_failsafe(self, param=None):
         """Set failsafe mode in async way."""
         try:
-            timout = param[CONF_FS_TIMEOUT]
+            timeout = param[CONF_FS_TIMEOUT]
             fallback = param[CONF_FS_FALLBACK]
             persist = param[CONF_FS_PERSIST]
-            await self.set_failsafe(timout, fallback, persist)
+            await self.set_failsafe(int(timeout), float(fallback), bool(persist))
             self._set_fast_polling()
         except (KeyError, ValueError) as ex:
             _LOGGER.warning(
diff --git a/homeassistant/components/keba/binary_sensor.py b/homeassistant/components/keba/binary_sensor.py
index ac7326cc92e..5cced416bc3 100644
--- a/homeassistant/components/keba/binary_sensor.py
+++ b/homeassistant/components/keba/binary_sensor.py
@@ -22,10 +22,16 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
     keba = hass.data[DOMAIN]
 
     sensors = [
-        KebaBinarySensor(keba, "Online", "Wallbox", DEVICE_CLASS_CONNECTIVITY),
-        KebaBinarySensor(keba, "Plug", "Plug", DEVICE_CLASS_PLUG),
-        KebaBinarySensor(keba, "State", "Charging state", DEVICE_CLASS_POWER),
-        KebaBinarySensor(keba, "Tmo FS", "Failsafe Mode", DEVICE_CLASS_SAFETY),
+        KebaBinarySensor(
+            keba, "Online", "Status", "device_state", DEVICE_CLASS_CONNECTIVITY
+        ),
+        KebaBinarySensor(keba, "Plug", "Plug", "plug_state", DEVICE_CLASS_PLUG),
+        KebaBinarySensor(
+            keba, "State", "Charging State", "charging_state", DEVICE_CLASS_POWER
+        ),
+        KebaBinarySensor(
+            keba, "Tmo FS", "Failsafe Mode", "failsafe_mode_state", DEVICE_CLASS_SAFETY
+        ),
     ]
     async_add_entities(sensors)
 
@@ -33,11 +39,12 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
 class KebaBinarySensor(BinarySensorDevice):
     """Representation of a binary sensor of a KEBA charging station."""
 
-    def __init__(self, keba, key, sensor_name, device_class):
+    def __init__(self, keba, key, name, entity_type, device_class):
         """Initialize the KEBA Sensor."""
         self._key = key
         self._keba = keba
-        self._name = sensor_name
+        self._name = name
+        self._entity_type = entity_type
         self._device_class = device_class
         self._is_on = None
         self._attributes = {}
@@ -50,12 +57,12 @@ class KebaBinarySensor(BinarySensorDevice):
     @property
     def unique_id(self):
         """Return the unique ID of the binary sensor."""
-        return f"{self._keba.device_name}_{self._name}"
+        return f"{self._keba.device_id}_{self._entity_type}"
 
     @property
     def name(self):
         """Return the name of the device."""
-        return self._name
+        return f"{self._keba.device_name} {self._name}"
 
     @property
     def device_class(self):
diff --git a/homeassistant/components/keba/lock.py b/homeassistant/components/keba/lock.py
index 3a65e44cd6f..f69fbdddf20 100644
--- a/homeassistant/components/keba/lock.py
+++ b/homeassistant/components/keba/lock.py
@@ -15,17 +15,18 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
 
     keba = hass.data[DOMAIN]
 
-    sensors = [KebaLock(keba, "Authentication")]
+    sensors = [KebaLock(keba, "Authentication", "authentication")]
     async_add_entities(sensors)
 
 
 class KebaLock(LockDevice):
     """The entity class for KEBA charging stations switch."""
 
-    def __init__(self, keba, name):
+    def __init__(self, keba, name, entity_type):
         """Initialize the KEBA switch."""
         self._keba = keba
         self._name = name
+        self._entity_type = entity_type
         self._state = True
 
     @property
@@ -35,13 +36,13 @@ class KebaLock(LockDevice):
 
     @property
     def unique_id(self):
-        """Return the unique ID of the binary sensor."""
-        return f"{self._keba.device_name}_{self._name}"
+        """Return the unique ID of the lock."""
+        return f"{self._keba.device_id}_{self._entity_type}"
 
     @property
     def name(self):
         """Return the name of the device."""
-        return self._name
+        return f"{self._keba.device_name} {self._name}"
 
     @property
     def is_locked(self):
diff --git a/homeassistant/components/keba/manifest.json b/homeassistant/components/keba/manifest.json
index 422a79cd0be..0f3d21fc783 100644
--- a/homeassistant/components/keba/manifest.json
+++ b/homeassistant/components/keba/manifest.json
@@ -2,7 +2,7 @@
   "domain": "keba",
   "name": "Keba Charging Station",
   "documentation": "https://www.home-assistant.io/integrations/keba",
-  "requirements": ["keba-kecontact==0.2.0"],
+  "requirements": ["keba-kecontact==1.0.0"],
   "dependencies": [],
   "codeowners": [
     "@dannerph"
diff --git a/homeassistant/components/keba/sensor.py b/homeassistant/components/keba/sensor.py
index dfa04f95c65..d9e6118ff32 100644
--- a/homeassistant/components/keba/sensor.py
+++ b/homeassistant/components/keba/sensor.py
@@ -17,15 +17,40 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
     keba = hass.data[DOMAIN]
 
     sensors = [
-        KebaSensor(keba, "Curr user", "Max current", "mdi:flash", "A"),
+        KebaSensor(keba, "Curr user", "Max Current", "max_current", "mdi:flash", "A"),
         KebaSensor(
-            keba, "Setenergy", "Energy target", "mdi:gauge", ENERGY_KILO_WATT_HOUR
+            keba,
+            "Setenergy",
+            "Energy Target",
+            "energy_target",
+            "mdi:gauge",
+            ENERGY_KILO_WATT_HOUR,
         ),
-        KebaSensor(keba, "P", "Charging power", "mdi:flash", "kW", DEVICE_CLASS_POWER),
         KebaSensor(
-            keba, "E pres", "Session energy", "mdi:gauge", ENERGY_KILO_WATT_HOUR
+            keba,
+            "P",
+            "Charging Power",
+            "charging_power",
+            "mdi:flash",
+            "kW",
+            DEVICE_CLASS_POWER,
+        ),
+        KebaSensor(
+            keba,
+            "E pres",
+            "Session Energy",
+            "session_energy",
+            "mdi:gauge",
+            ENERGY_KILO_WATT_HOUR,
+        ),
+        KebaSensor(
+            keba,
+            "E total",
+            "Total Energy",
+            "total_energy",
+            "mdi:gauge",
+            ENERGY_KILO_WATT_HOUR,
         ),
-        KebaSensor(keba, "E total", "Total Energy", "mdi:gauge", ENERGY_KILO_WATT_HOUR),
     ]
     async_add_entities(sensors)
 
@@ -33,14 +58,16 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
 class KebaSensor(Entity):
     """The entity class for KEBA charging stations sensors."""
 
-    def __init__(self, keba, key, name, icon, unit, device_class=None):
+    def __init__(self, keba, key, name, entity_type, icon, unit, device_class=None):
         """Initialize the KEBA Sensor."""
-        self._key = key
         self._keba = keba
+        self._key = key
         self._name = name
-        self._device_class = device_class
+        self._entity_type = entity_type
         self._icon = icon
         self._unit = unit
+        self._device_class = device_class
+
         self._state = None
         self._attributes = {}
 
@@ -52,12 +79,12 @@ class KebaSensor(Entity):
     @property
     def unique_id(self):
         """Return the unique ID of the binary sensor."""
-        return f"{self._keba.device_name}_{self._name}"
+        return f"{self._keba.device_id}_{self._entity_type}"
 
     @property
     def name(self):
         """Return the name of the device."""
-        return self._name
+        return f"{self._keba.device_name} {self._name}"
 
     @property
     def device_class(self):
diff --git a/requirements_all.txt b/requirements_all.txt
index 6919b103117..831933c70b1 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -738,7 +738,7 @@ jsonrpc-websocket==0.6
 kaiterra-async-client==0.0.2
 
 # homeassistant.components.keba
-keba-kecontact==0.2.0
+keba-kecontact==1.0.0
 
 # homeassistant.scripts.keyring
 keyring==20.0.0
-- 
GitLab