More details about SMS modem (#75694)
This commit is contained in:
parent
92612c9fe3
commit
1b17c83095
3 changed files with 115 additions and 88 deletions
|
@ -1,9 +1,4 @@
|
||||||
"""Constants for sms Component."""
|
"""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"
|
DOMAIN = "sms"
|
||||||
SMS_GATEWAY = "SMS_GATEWAY"
|
SMS_GATEWAY = "SMS_GATEWAY"
|
||||||
|
@ -38,61 +33,3 @@ DEFAULT_BAUD_SPEEDS = [
|
||||||
{"value": "76800", "label": "76800"},
|
{"value": "76800", "label": "76800"},
|
||||||
{"value": "115200", "label": "115200"},
|
{"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,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
|
@ -21,10 +21,16 @@ class Gateway:
|
||||||
self._worker.configure(config)
|
self._worker.configure(config)
|
||||||
self._hass = hass
|
self._hass = hass
|
||||||
self._first_pull = True
|
self._first_pull = True
|
||||||
|
self.manufacturer = None
|
||||||
|
self.model = None
|
||||||
|
self.firmware = None
|
||||||
|
|
||||||
async def init_async(self):
|
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()
|
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):
|
def sms_pull(self, state_machine):
|
||||||
"""Pull device.
|
"""Pull device.
|
||||||
|
@ -156,7 +162,37 @@ class Gateway:
|
||||||
|
|
||||||
async def get_network_info_async(self):
|
async def get_network_info_async(self):
|
||||||
"""Get the current network info of the modem."""
|
"""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):
|
async def terminate_async(self):
|
||||||
"""Terminate modem connection."""
|
"""Terminate modem connection."""
|
||||||
|
|
|
@ -1,19 +1,78 @@
|
||||||
"""Support for SMS dongle sensor."""
|
"""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.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import PERCENTAGE, SIGNAL_STRENGTH_DECIBELS
|
||||||
from homeassistant.core import HomeAssistant
|
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.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
|
|
||||||
from .const import (
|
from .const import DOMAIN, GATEWAY, NETWORK_COORDINATOR, SIGNAL_COORDINATOR, SMS_GATEWAY
|
||||||
DOMAIN,
|
|
||||||
GATEWAY,
|
SIGNAL_SENSORS = (
|
||||||
NETWORK_COORDINATOR,
|
SensorEntityDescription(
|
||||||
NETWORK_SENSORS,
|
key="SignalStrength",
|
||||||
SIGNAL_COORDINATOR,
|
name="Signal Strength",
|
||||||
SIGNAL_SENSORS,
|
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
|
||||||
SMS_GATEWAY,
|
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]
|
gateway = sms_data[GATEWAY]
|
||||||
unique_id = str(await gateway.get_imei_async())
|
unique_id = str(await gateway.get_imei_async())
|
||||||
entities = []
|
entities = []
|
||||||
for description in SIGNAL_SENSORS.values():
|
for description in SIGNAL_SENSORS:
|
||||||
entities.append(
|
entities.append(
|
||||||
DeviceSensor(
|
DeviceSensor(signal_coordinator, description, unique_id, gateway)
|
||||||
signal_coordinator,
|
|
||||||
description,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
for description in NETWORK_SENSORS.values():
|
for description in NETWORK_SENSORS:
|
||||||
entities.append(
|
entities.append(
|
||||||
DeviceSensor(
|
DeviceSensor(network_coordinator, description, unique_id, gateway)
|
||||||
network_coordinator,
|
|
||||||
description,
|
|
||||||
unique_id,
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
async_add_entities(entities, True)
|
async_add_entities(entities, True)
|
||||||
|
|
||||||
|
@ -51,12 +102,15 @@ async def async_setup_entry(
|
||||||
class DeviceSensor(CoordinatorEntity, SensorEntity):
|
class DeviceSensor(CoordinatorEntity, SensorEntity):
|
||||||
"""Implementation of a device sensor."""
|
"""Implementation of a device sensor."""
|
||||||
|
|
||||||
def __init__(self, coordinator, description, unique_id):
|
def __init__(self, coordinator, description, unique_id, gateway):
|
||||||
"""Initialize the device sensor."""
|
"""Initialize the device sensor."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, unique_id)},
|
identifiers={(DOMAIN, unique_id)},
|
||||||
name="SMS Gateway",
|
name="SMS Gateway",
|
||||||
|
manufacturer=gateway.manufacturer,
|
||||||
|
model=gateway.model,
|
||||||
|
sw_version=gateway.firmware,
|
||||||
)
|
)
|
||||||
self._attr_unique_id = f"{unique_id}_{description.key}"
|
self._attr_unique_id = f"{unique_id}_{description.key}"
|
||||||
self.entity_description = description
|
self.entity_description = description
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue