Initial commit: Main Gate Controller HACS integration
Tests / pytest + ruff (3.12) (push) Has been cancelled
Validate / HACS validation (push) Has been cancelled
Validate / Hassfest validation (push) Has been cancelled

This commit is contained in:
bot
2026-09-07 23:19:12 +02:00
commit 988a30cbf7
27 changed files with 2456 additions and 0 deletions
@@ -0,0 +1,86 @@
"""Sensor that reports the current state of a Main Gate Controller cycle."""
from __future__ import annotations
from typing import Any
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import MainGateConfigEntry, build_device_info
from .const import (
GATE_STATE_CLOSED,
GATE_STATE_CLOSING,
GATE_STATE_OPEN,
GATE_STATE_OPENING,
)
from .coordinator import MainGateController
async def async_setup_entry(
hass: HomeAssistant,
entry: MainGateConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the status sensor for a gate."""
controller: MainGateController = entry.runtime_data
async_add_entities([MainGateStatusSensor(controller, entry)])
_STATUS_ICONS = {
GATE_STATE_CLOSED: "mdi:gate",
GATE_STATE_OPENING: "mdi:gate-arrow-right",
GATE_STATE_OPEN: "mdi:gate-open",
GATE_STATE_CLOSING: "mdi:gate-arrow-left",
}
class MainGateStatusSensor(SensorEntity):
"""Sensor exposing the current gate state and countdown metadata."""
_attr_should_poll = False
_attr_has_entity_name = True
_attr_translation_key = "status"
_attr_device_class = SensorDeviceClass.ENUM
# Stable set of states (used by tile-card pickers / dashboards)
_attr_options: list[str] = [
GATE_STATE_CLOSED,
GATE_STATE_OPENING,
GATE_STATE_OPEN,
GATE_STATE_CLOSING,
]
def __init__(self, controller: MainGateController, entry: MainGateConfigEntry) -> None:
self._controller = controller
self._entry = entry
self._attr_unique_id = f"{entry.entry_id}_status"
self._unsub: callable = lambda: None
@property
def device_info(self) -> DeviceInfo:
return build_device_info(self._entry)
@property
def native_value(self) -> str:
return self._controller.status
@property
def extra_state_attributes(self) -> dict[str, Any]:
return self._controller.extra_state_attributes
@property
def icon(self) -> str:
return _STATUS_ICONS.get(self._controller.status, "mdi:gate")
async def async_added_to_hass(self) -> None:
self._unsub = self._controller.async_add_listener(self._async_write)
async def async_will_remove_from_hass(self) -> None:
self._unsub()
self._unsub = lambda: None
@callback
def _async_write(self) -> None:
self.async_write_ha_state()