Skip to content

Commit

Permalink
Add sensors
Browse files Browse the repository at this point in the history
  • Loading branch information
Andre0512 committed Oct 15, 2023
1 parent a194403 commit 336d950
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 9 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Telekom Speedport Integration for Home Assistant based on [speedport-api](https:
- Track presence of connected devices
- Turn on/off wifi (guest/office/normal)
- Reconnect, reboot, wps on
- Sensors (IP-Addresses, Upload/Download, Connection, ...)

## Installation
#### Installing via HACS
Expand All @@ -30,3 +31,10 @@ Telekom Speedport Integration for Home Assistant based on [speedport-api](https:
* Speedport Smart 4

So far I can only confirm that it works with my router 🙂

## Support
If you find this project helpful and would like to support its development, you can buy me a coffee! ☕

[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/andre0512)

Don't forget to star the repository if you found it useful! ⭐
8 changes: 7 additions & 1 deletion custom_components/speedport/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@

from .const import DOMAIN

PLATFORMS: list[Platform] = [Platform.BUTTON, Platform.DEVICE_TRACKER, Platform.SWITCH]
PLATFORMS: list[Platform] = [
Platform.BUTTON,
Platform.DEVICE_TRACKER,
Platform.SWITCH,
Platform.BINARY_SENSOR,
Platform.SENSOR,
]


async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
Expand Down
57 changes: 57 additions & 0 deletions custom_components/speedport/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import logging

from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from speedport import Speedport

from .const import DOMAIN
from .device import SpeedportEntity

_LOGGER = logging.getLogger(__name__)

BINARY_SENSORS: tuple[BinarySensorEntityDescription, ...] = (
BinarySensorEntityDescription(
key="onlinestatus",
name="Connection",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
),
BinarySensorEntityDescription(
key="dsl_link_status",
name="DSL-Connection",
device_class=BinarySensorDeviceClass.PLUG,
),
)


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up entry."""
speedport: Speedport = hass.data[DOMAIN][entry.entry_id]

entities = [
SpeedportBinarySensor(hass, speedport, description)
for description in BINARY_SENSORS
]

async_add_entities(entities)


class SpeedportBinarySensor(SpeedportEntity, BinarySensorEntity):
entity_description: BinarySensorEntityDescription

@property
def is_on(self) -> bool | None:
"""Return true if the binary sensor is on."""
return self._speedport.get(self.entity_description.key) == "online"

def available(self) -> bool:
if self._speedport.get(self.entity_description.key) is None:
return False
return super().available
4 changes: 0 additions & 4 deletions custom_components/speedport/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from homeassistant.components.button import ButtonDeviceClass, ButtonEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import HomeAssistantType
from speedport import Speedport
Expand All @@ -29,7 +28,6 @@ async def async_setup_entry(

class SpeedportReconnectButton(ButtonEntity, SpeedportEntity):
_attr_device_class = ButtonDeviceClass.RESTART
_attr_entity_category = EntityCategory.CONFIG

def __init__(self, hass: HomeAssistantType, speedport: Speedport) -> None:
"""Initialize the button entity."""
Expand All @@ -45,7 +43,6 @@ async def async_press(self) -> None:

class SpeedportRebootButton(ButtonEntity, SpeedportEntity):
_attr_device_class = ButtonDeviceClass.RESTART
_attr_entity_category = EntityCategory.CONFIG

def __init__(self, hass: HomeAssistantType, speedport: Speedport) -> None:
"""Initialize the button entity."""
Expand All @@ -61,7 +58,6 @@ async def async_press(self) -> None:

class SpeedportWPSButton(ButtonEntity, SpeedportEntity):
_attr_device_class = ButtonDeviceClass.IDENTIFY
_attr_entity_category = EntityCategory.CONFIG

def __init__(self, hass: HomeAssistantType, speedport: Speedport) -> None:
"""Initialize the button entity."""
Expand Down
14 changes: 11 additions & 3 deletions custom_components/speedport/device.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import asyncio
import logging
from datetime import timedelta

Expand Down Expand Up @@ -25,21 +26,28 @@ def __init__(self, hass: HomeAssistantType, device: Speedport):
name=device.device_name,
update_interval=timedelta(seconds=UPDATE_INTERVAL),
)
self._device = device
self._speedport: Speedport = device

async def _async_update_data(self) -> None:
return await self._device.update_status()
await asyncio.gather(
*[self._speedport.update_status(), self._speedport.update_ip_data()]
)


class SpeedportEntity(CoordinatorEntity[SpeedportCoordinator]):
_attr_has_entity_name = True

def __init__(self, hass: HomeAssistantType, speedport: Speedport) -> None:
def __init__(
self, hass: HomeAssistantType, speedport: Speedport, description=None
) -> None:
coordinator = get_coordinator(hass, speedport)
super().__init__(coordinator)

self._coordinator = coordinator
self._speedport: Speedport = speedport
if description is not None:
self.entity_description = description
self._attr_unique_id = f"speedport_{description.key}"

@property
def device_info(self) -> DeviceInfo:
Expand Down
101 changes: 101 additions & 0 deletions custom_components/speedport/sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
from datetime import datetime

import pytz
from homeassistant.components.sensor import (
SensorEntityDescription,
SensorDeviceClass,
SensorStateClass,
SensorEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
EntityCategory,
UnitOfDataRate,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from speedport import Speedport

from custom_components.speedport import DOMAIN
from custom_components.speedport.device import SpeedportEntity

SENSORS: tuple[SensorEntityDescription, ...] = (
SensorEntityDescription(
key="public_ip_v4",
name="IPv4",
icon="mdi:earth",
),
SensorEntityDescription(
key="public_ip_v6",
name="IPv6",
icon="mdi:earth",
),
SensorEntityDescription(
key="inet_uptime",
name="Internet Uptime",
device_class=SensorDeviceClass.TIMESTAMP,
),
SensorEntityDescription(
key="inet_upload",
name="Upload",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDataRate.KILOBITS_PER_SECOND,
device_class=SensorDeviceClass.DATA_RATE,
icon="mdi:upload",
),
SensorEntityDescription(
key="inet_download",
name="Download",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfDataRate.KILOBITS_PER_SECOND,
device_class=SensorDeviceClass.DATA_RATE,
icon="mdi:download",
),
SensorEntityDescription(
key="dsl_upstream",
name="DSL-Link Upstream",
native_unit_of_measurement=UnitOfDataRate.KILOBITS_PER_SECOND,
device_class=SensorDeviceClass.DATA_RATE,
icon="mdi:upload",
),
SensorEntityDescription(
key="dsl_downstream",
name="DSL-Link Downstream",
native_unit_of_measurement=UnitOfDataRate.KILOBITS_PER_SECOND,
device_class=SensorDeviceClass.DATA_RATE,
icon="mdi:download",
),
)


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up entry."""
speedport: Speedport = hass.data[DOMAIN][entry.entry_id]

entities = [
SpeedportBinarySensor(hass, speedport, description) for description in SENSORS
]

async_add_entities(entities)


class SpeedportBinarySensor(SpeedportEntity, SensorEntity):
entity_description: SensorEntityDescription

@property
def native_value(self) -> StateType:
"""Return the value reported by the sensor."""
if (data := self._speedport.get(self.entity_description.key)) is None:
return None
if self.entity_description.device_class == SensorDeviceClass.TIMESTAMP:
date = datetime.strptime(data, "%Y-%m-%d %H:%M:%S")
return pytz.timezone("Europe/Berlin").localize(date)
return data

def available(self) -> bool:
if self._speedport.get(self.entity_description.key) is None:
return False
return super().available
3 changes: 2 additions & 1 deletion custom_components/speedport/switch.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import asyncio
import logging
from typing import Any

Expand All @@ -22,7 +23,7 @@ async def async_setup_entry(
"""Set up entry."""

speedport: Speedport = hass.data[DOMAIN][entry.entry_id]
await speedport.update_status()
await asyncio.gather(*[speedport.update_status(), speedport.update_ip_data()])
async_add_entities(
[
SpeedportWifiSwitch(hass, speedport),
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
speedport-api==0.5.2
homeassistant~=2023.10
pytz~=2023.3

0 comments on commit 336d950

Please sign in to comment.