From 1b17c83095333a5365a9f55f3f53ec10167d0a00 Mon Sep 17 00:00:00 2001 From: Paul Annekov Date: Mon, 26 Sep 2022 04:49:55 +0300 Subject: [PATCH] More details about SMS modem (#75694) --- homeassistant/components/sms/const.py | 63 --------------- homeassistant/components/sms/gateway.py | 40 +++++++++- homeassistant/components/sms/sensor.py | 100 ++++++++++++++++++------ 3 files changed, 115 insertions(+), 88 deletions(-) diff --git a/homeassistant/components/sms/const.py b/homeassistant/components/sms/const.py index d055894f402..5c7a2ce86a4 100644 --- a/homeassistant/components/sms/const.py +++ b/homeassistant/components/sms/const.py @@ -1,9 +1,4 @@ """Constants for sms Component.""" -from typing import Final - -from homeassistant.components.sensor import SensorDeviceClass, SensorEntityDescription -from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS -from homeassistant.helpers.entity import EntityCategory DOMAIN = "sms" SMS_GATEWAY = "SMS_GATEWAY" @@ -38,61 +33,3 @@ DEFAULT_BAUD_SPEEDS = [ {"value": "76800", "label": "76800"}, {"value": "115200", "label": "115200"}, ] - -SIGNAL_SENSORS: Final[dict[str, SensorEntityDescription]] = { - "SignalStrength": SensorEntityDescription( - key="SignalStrength", - name="Signal Strength", - device_class=SensorDeviceClass.SIGNAL_STRENGTH, - entity_category=EntityCategory.DIAGNOSTIC, - native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS, - entity_registry_enabled_default=False, - ), - "SignalPercent": SensorEntityDescription( - key="SignalPercent", - icon="mdi:signal-cellular-3", - name="Signal Percent", - native_unit_of_measurement=PERCENTAGE, - entity_registry_enabled_default=True, - ), - "BitErrorRate": SensorEntityDescription( - key="BitErrorRate", - name="Bit Error Rate", - entity_category=EntityCategory.DIAGNOSTIC, - native_unit_of_measurement=PERCENTAGE, - entity_registry_enabled_default=False, - ), -} - -NETWORK_SENSORS: Final[dict[str, SensorEntityDescription]] = { - "NetworkName": SensorEntityDescription( - key="NetworkName", - name="Network Name", - entity_category=EntityCategory.DIAGNOSTIC, - entity_registry_enabled_default=False, - ), - "State": SensorEntityDescription( - key="State", - name="Network Status", - entity_registry_enabled_default=True, - ), - "NetworkCode": SensorEntityDescription( - key="NetworkCode", - name="GSM network code", - entity_category=EntityCategory.DIAGNOSTIC, - entity_registry_enabled_default=False, - ), - "CID": SensorEntityDescription( - key="CID", - name="Cell ID", - icon="mdi:radio-tower", - entity_category=EntityCategory.DIAGNOSTIC, - entity_registry_enabled_default=False, - ), - "LAC": SensorEntityDescription( - key="LAC", - name="Local Area Code", - entity_category=EntityCategory.DIAGNOSTIC, - entity_registry_enabled_default=False, - ), -} diff --git a/homeassistant/components/sms/gateway.py b/homeassistant/components/sms/gateway.py index 7a2f095abd1..36ada5421e0 100644 --- a/homeassistant/components/sms/gateway.py +++ b/homeassistant/components/sms/gateway.py @@ -21,10 +21,16 @@ class Gateway: self._worker.configure(config) self._hass = hass self._first_pull = True + self.manufacturer = None + self.model = None + self.firmware = None async def init_async(self): - """Initialize the sms gateway asynchronously.""" + """Initialize the sms gateway asynchronously. This method is also called in config flow to verify connection.""" await self._worker.init_async() + self.manufacturer = await self.get_manufacturer_async() + self.model = await self.get_model_async() + self.firmware = await self.get_firmware_async() def sms_pull(self, state_machine): """Pull device. @@ -156,7 +162,37 @@ class Gateway: async def get_network_info_async(self): """Get the current network info of the modem.""" - return await self._worker.get_network_info_async() + network_info = await self._worker.get_network_info_async() + # Looks like there is a bug and it's empty for any modem https://github.com/gammu/python-gammu/issues/31, so try workaround + if not network_info["NetworkName"]: + network_info["NetworkName"] = gammu.GSMNetworks.get( + network_info["NetworkCode"] + ) + return network_info + + async def get_manufacturer_async(self): + """Get the manufacturer of the modem.""" + return await self._worker.get_manufacturer_async() + + async def get_model_async(self): + """Get the model of the modem.""" + model = await self._worker.get_model_async() + if not model or not model[0]: + return + display = model[0] # Identification model + if model[1]: # Real model + display = f"{display} ({model[1]})" + return display + + async def get_firmware_async(self): + """Get the firmware information of the modem.""" + firmware = await self._worker.get_firmware_async() + if not firmware or not firmware[0]: + return + display = firmware[0] # Version + if firmware[1]: # Date + display = f"{display} ({firmware[1]})" + return display async def terminate_async(self): """Terminate modem connection.""" diff --git a/homeassistant/components/sms/sensor.py b/homeassistant/components/sms/sensor.py index de20a5b5d0f..f276b9a9e9e 100644 --- a/homeassistant/components/sms/sensor.py +++ b/homeassistant/components/sms/sensor.py @@ -1,19 +1,78 @@ """Support for SMS dongle sensor.""" -from homeassistant.components.sensor import SensorEntity +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntity, + SensorEntityDescription, + SensorStateClass, +) from homeassistant.config_entries import ConfigEntry +from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity import DeviceInfo +from homeassistant.helpers.entity import DeviceInfo, EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import ( - DOMAIN, - GATEWAY, - NETWORK_COORDINATOR, - NETWORK_SENSORS, - SIGNAL_COORDINATOR, - SIGNAL_SENSORS, - SMS_GATEWAY, +from .const import DOMAIN, GATEWAY, NETWORK_COORDINATOR, SIGNAL_COORDINATOR, SMS_GATEWAY + +SIGNAL_SENSORS = ( + SensorEntityDescription( + key="SignalStrength", + name="Signal Strength", + device_class=SensorDeviceClass.SIGNAL_STRENGTH, + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS, + entity_registry_enabled_default=False, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="SignalPercent", + icon="mdi:signal-cellular-3", + name="Signal Percent", + native_unit_of_measurement=PERCENTAGE, + entity_registry_enabled_default=True, + state_class=SensorStateClass.MEASUREMENT, + ), + SensorEntityDescription( + key="BitErrorRate", + name="Bit Error Rate", + entity_category=EntityCategory.DIAGNOSTIC, + native_unit_of_measurement=PERCENTAGE, + entity_registry_enabled_default=False, + state_class=SensorStateClass.MEASUREMENT, + ), +) + +NETWORK_SENSORS = ( + SensorEntityDescription( + key="NetworkName", + name="Network Name", + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + SensorEntityDescription( + key="State", + name="Network Status", + entity_registry_enabled_default=True, + ), + SensorEntityDescription( + key="NetworkCode", + name="GSM network code", + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + SensorEntityDescription( + key="CID", + name="Cell ID", + icon="mdi:radio-tower", + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), + SensorEntityDescription( + key="LAC", + name="Local Area Code", + entity_category=EntityCategory.DIAGNOSTIC, + entity_registry_enabled_default=False, + ), ) @@ -29,21 +88,13 @@ async def async_setup_entry( gateway = sms_data[GATEWAY] unique_id = str(await gateway.get_imei_async()) entities = [] - for description in SIGNAL_SENSORS.values(): + for description in SIGNAL_SENSORS: entities.append( - DeviceSensor( - signal_coordinator, - description, - unique_id, - ) + DeviceSensor(signal_coordinator, description, unique_id, gateway) ) - for description in NETWORK_SENSORS.values(): + for description in NETWORK_SENSORS: entities.append( - DeviceSensor( - network_coordinator, - description, - unique_id, - ) + DeviceSensor(network_coordinator, description, unique_id, gateway) ) async_add_entities(entities, True) @@ -51,12 +102,15 @@ async def async_setup_entry( class DeviceSensor(CoordinatorEntity, SensorEntity): """Implementation of a device sensor.""" - def __init__(self, coordinator, description, unique_id): + def __init__(self, coordinator, description, unique_id, gateway): """Initialize the device sensor.""" super().__init__(coordinator) self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, unique_id)}, name="SMS Gateway", + manufacturer=gateway.manufacturer, + model=gateway.model, + sw_version=gateway.firmware, ) self._attr_unique_id = f"{unique_id}_{description.key}" self.entity_description = description