Use instance attributes in minecraft_server (#75157)

* Remove minecraft_server from mypy ignore list

* Use new entity naming style
This commit is contained in:
epenet 2022-07-14 18:06:33 +02:00 committed by GitHub
parent 89985b93fb
commit 1725948d4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 89 deletions

View File

@ -1,21 +1,22 @@
"""The Minecraft Server integration.""" """The Minecraft Server integration."""
from __future__ import annotations from __future__ import annotations
from collections.abc import Mapping
from datetime import datetime, timedelta from datetime import datetime, timedelta
import logging import logging
from typing import Any
from mcstatus.server import MinecraftServer as MCStatus from mcstatus.server import MinecraftServer as MCStatus
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, Platform from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, Platform
from homeassistant.core import HomeAssistant, callback from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, async_dispatcher_connect,
async_dispatcher_send, async_dispatcher_send,
) )
from homeassistant.helpers.entity import DeviceInfo, Entity from homeassistant.helpers.entity import DeviceInfo, Entity
from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.typing import ConfigType
from . import helpers from . import helpers
from .const import DOMAIN, MANUFACTURER, SCAN_INTERVAL, SIGNAL_NAME_PREFIX from .const import DOMAIN, MANUFACTURER, SCAN_INTERVAL, SIGNAL_NAME_PREFIX
@ -30,6 +31,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
domain_data = hass.data.setdefault(DOMAIN, {}) domain_data = hass.data.setdefault(DOMAIN, {})
# Create and store server instance. # Create and store server instance.
assert entry.unique_id
unique_id = entry.unique_id unique_id = entry.unique_id
_LOGGER.debug( _LOGGER.debug(
"Creating server instance for '%s' (%s)", "Creating server instance for '%s' (%s)",
@ -71,7 +73,7 @@ class MinecraftServer:
_MAX_RETRIES_STATUS = 3 _MAX_RETRIES_STATUS = 3
def __init__( def __init__(
self, hass: HomeAssistant, unique_id: str, config_data: ConfigType self, hass: HomeAssistant, unique_id: str, config_data: Mapping[str, Any]
) -> None: ) -> None:
"""Initialize server instance.""" """Initialize server instance."""
self._hass = hass self._hass = hass
@ -94,14 +96,14 @@ class MinecraftServer:
self.latency_time = None self.latency_time = None
self.players_online = None self.players_online = None
self.players_max = None self.players_max = None
self.players_list = None self.players_list: list[str] | None = None
self.motd = None self.motd = None
# Dispatcher signal name # Dispatcher signal name
self.signal_name = f"{SIGNAL_NAME_PREFIX}_{self.unique_id}" self.signal_name = f"{SIGNAL_NAME_PREFIX}_{self.unique_id}"
# Callback for stopping periodic update. # Callback for stopping periodic update.
self._stop_periodic_update = None self._stop_periodic_update: CALLBACK_TYPE | None = None
def start_periodic_update(self) -> None: def start_periodic_update(self) -> None:
"""Start periodic execution of update method.""" """Start periodic execution of update method."""
@ -111,7 +113,8 @@ class MinecraftServer:
def stop_periodic_update(self) -> None: def stop_periodic_update(self) -> None:
"""Stop periodic execution of update method.""" """Stop periodic execution of update method."""
self._stop_periodic_update() if self._stop_periodic_update:
self._stop_periodic_update()
async def async_check_connection(self) -> None: async def async_check_connection(self) -> None:
"""Check server connection using a 'status' request and store connection status.""" """Check server connection using a 'status' request and store connection status."""
@ -219,14 +222,21 @@ class MinecraftServer:
class MinecraftServerEntity(Entity): class MinecraftServerEntity(Entity):
"""Representation of a Minecraft Server base entity.""" """Representation of a Minecraft Server base entity."""
_attr_has_entity_name = True
_attr_should_poll = False
def __init__( def __init__(
self, server: MinecraftServer, type_name: str, icon: str, device_class: str self,
server: MinecraftServer,
type_name: str,
icon: str,
device_class: str | None,
) -> None: ) -> None:
"""Initialize base entity.""" """Initialize base entity."""
self._server = server self._server = server
self._name = f"{server.name} {type_name}" self._attr_name = type_name
self._icon = icon self._attr_icon = icon
self._unique_id = f"{self._server.unique_id}-{type_name}" self._attr_unique_id = f"{self._server.unique_id}-{type_name}"
self._attr_device_info = DeviceInfo( self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, self._server.unique_id)}, identifiers={(DOMAIN, self._server.unique_id)},
manufacturer=MANUFACTURER, manufacturer=MANUFACTURER,
@ -234,34 +244,9 @@ class MinecraftServerEntity(Entity):
name=self._server.name, name=self._server.name,
sw_version=self._server.protocol_version, sw_version=self._server.protocol_version,
) )
self._device_class = device_class self._attr_device_class = device_class
self._extra_state_attributes = None self._extra_state_attributes = None
self._disconnect_dispatcher = None self._disconnect_dispatcher: CALLBACK_TYPE | None = None
@property
def name(self) -> str:
"""Return name."""
return self._name
@property
def unique_id(self) -> str:
"""Return unique ID."""
return self._unique_id
@property
def device_class(self) -> str:
"""Return device class."""
return self._device_class
@property
def icon(self) -> str:
"""Return icon."""
return self._icon
@property
def should_poll(self) -> bool:
"""Disable polling."""
return False
async def async_update(self) -> None: async def async_update(self) -> None:
"""Fetch data from the server.""" """Fetch data from the server."""
@ -275,7 +260,8 @@ class MinecraftServerEntity(Entity):
async def async_will_remove_from_hass(self) -> None: async def async_will_remove_from_hass(self) -> None:
"""Disconnect dispatcher before removal.""" """Disconnect dispatcher before removal."""
self._disconnect_dispatcher() if self._disconnect_dispatcher:
self._disconnect_dispatcher()
@callback @callback
def _update_callback(self) -> None: def _update_callback(self) -> None:

View File

@ -37,13 +37,8 @@ class MinecraftServerStatusBinarySensor(MinecraftServerEntity, BinarySensorEntit
icon=ICON_STATUS, icon=ICON_STATUS,
device_class=BinarySensorDeviceClass.CONNECTIVITY, device_class=BinarySensorDeviceClass.CONNECTIVITY,
) )
self._is_on = False self._attr_is_on = False
@property
def is_on(self) -> bool:
"""Return binary state."""
return self._is_on
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update status.""" """Update status."""
self._is_on = self._server.online self._attr_is_on = self._server.online

View File

@ -11,7 +11,9 @@ from homeassistant.core import HomeAssistant
from .const import SRV_RECORD_PREFIX from .const import SRV_RECORD_PREFIX
async def async_check_srv_record(hass: HomeAssistant, host: str) -> dict[str, Any]: async def async_check_srv_record(
hass: HomeAssistant, host: str
) -> dict[str, Any] | None:
"""Check if the given host is a valid Minecraft SRV record.""" """Check if the given host is a valid Minecraft SRV record."""
# Check if 'host' is a valid SRV record. # Check if 'host' is a valid SRV record.
return_value = None return_value = None

View File

@ -1,8 +1,6 @@
"""The Minecraft Server sensor platform.""" """The Minecraft Server sensor platform."""
from __future__ import annotations from __future__ import annotations
from typing import Any
from homeassistant.components.sensor import SensorEntity from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import TIME_MILLISECONDS from homeassistant.const import TIME_MILLISECONDS
@ -62,30 +60,19 @@ class MinecraftServerSensorEntity(MinecraftServerEntity, SensorEntity):
self, self,
server: MinecraftServer, server: MinecraftServer,
type_name: str, type_name: str,
icon: str = None, icon: str,
unit: str = None, unit: str | None,
device_class: str = None, device_class: str | None = None,
) -> None: ) -> None:
"""Initialize sensor base entity.""" """Initialize sensor base entity."""
super().__init__(server, type_name, icon, device_class) super().__init__(server, type_name, icon, device_class)
self._state = None self._attr_native_unit_of_measurement = unit
self._unit = unit
@property @property
def available(self) -> bool: def available(self) -> bool:
"""Return sensor availability.""" """Return sensor availability."""
return self._server.online return self._server.online
@property
def native_value(self) -> Any:
"""Return sensor state."""
return self._state
@property
def native_unit_of_measurement(self) -> str:
"""Return sensor measurement unit."""
return self._unit
class MinecraftServerVersionSensor(MinecraftServerSensorEntity): class MinecraftServerVersionSensor(MinecraftServerSensorEntity):
"""Representation of a Minecraft Server version sensor.""" """Representation of a Minecraft Server version sensor."""
@ -98,7 +85,7 @@ class MinecraftServerVersionSensor(MinecraftServerSensorEntity):
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update version.""" """Update version."""
self._state = self._server.version self._attr_native_value = self._server.version
class MinecraftServerProtocolVersionSensor(MinecraftServerSensorEntity): class MinecraftServerProtocolVersionSensor(MinecraftServerSensorEntity):
@ -115,7 +102,7 @@ class MinecraftServerProtocolVersionSensor(MinecraftServerSensorEntity):
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update protocol version.""" """Update protocol version."""
self._state = self._server.protocol_version self._attr_native_value = self._server.protocol_version
class MinecraftServerLatencyTimeSensor(MinecraftServerSensorEntity): class MinecraftServerLatencyTimeSensor(MinecraftServerSensorEntity):
@ -132,7 +119,7 @@ class MinecraftServerLatencyTimeSensor(MinecraftServerSensorEntity):
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update latency time.""" """Update latency time."""
self._state = self._server.latency_time self._attr_native_value = self._server.latency_time
class MinecraftServerPlayersOnlineSensor(MinecraftServerSensorEntity): class MinecraftServerPlayersOnlineSensor(MinecraftServerSensorEntity):
@ -149,20 +136,15 @@ class MinecraftServerPlayersOnlineSensor(MinecraftServerSensorEntity):
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update online players state and device state attributes.""" """Update online players state and device state attributes."""
self._state = self._server.players_online self._attr_native_value = self._server.players_online
extra_state_attributes = None extra_state_attributes = {}
players_list = self._server.players_list players_list = self._server.players_list
if players_list is not None and len(players_list) != 0: if players_list is not None and len(players_list) != 0:
extra_state_attributes = {ATTR_PLAYERS_LIST: self._server.players_list} extra_state_attributes[ATTR_PLAYERS_LIST] = self._server.players_list
self._extra_state_attributes = extra_state_attributes self._attr_extra_state_attributes = extra_state_attributes
@property
def extra_state_attributes(self) -> dict[str, Any]:
"""Return players list in device state attributes."""
return self._extra_state_attributes
class MinecraftServerPlayersMaxSensor(MinecraftServerSensorEntity): class MinecraftServerPlayersMaxSensor(MinecraftServerSensorEntity):
@ -179,7 +161,7 @@ class MinecraftServerPlayersMaxSensor(MinecraftServerSensorEntity):
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update maximum number of players.""" """Update maximum number of players."""
self._state = self._server.players_max self._attr_native_value = self._server.players_max
class MinecraftServerMOTDSensor(MinecraftServerSensorEntity): class MinecraftServerMOTDSensor(MinecraftServerSensorEntity):
@ -196,4 +178,4 @@ class MinecraftServerMOTDSensor(MinecraftServerSensorEntity):
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update MOTD.""" """Update MOTD."""
self._state = self._server.motd self._attr_native_value = self._server.motd

View File

@ -2665,15 +2665,6 @@ ignore_errors = true
[mypy-homeassistant.components.evohome] [mypy-homeassistant.components.evohome]
ignore_errors = true ignore_errors = true
[mypy-homeassistant.components.minecraft_server]
ignore_errors = true
[mypy-homeassistant.components.minecraft_server.helpers]
ignore_errors = true
[mypy-homeassistant.components.minecraft_server.sensor]
ignore_errors = true
[mypy-homeassistant.components.sonos] [mypy-homeassistant.components.sonos]
ignore_errors = true ignore_errors = true

View File

@ -19,9 +19,6 @@ IGNORED_MODULES: Final[list[str]] = [
"homeassistant.components.cloud.client", "homeassistant.components.cloud.client",
"homeassistant.components.cloud.http_api", "homeassistant.components.cloud.http_api",
"homeassistant.components.evohome", "homeassistant.components.evohome",
"homeassistant.components.minecraft_server",
"homeassistant.components.minecraft_server.helpers",
"homeassistant.components.minecraft_server.sensor",
"homeassistant.components.sonos", "homeassistant.components.sonos",
"homeassistant.components.sonos.alarms", "homeassistant.components.sonos.alarms",
"homeassistant.components.sonos.binary_sensor", "homeassistant.components.sonos.binary_sensor",