Files
2026-06-11 11:50:50 -04:00

353 lines
11 KiB
Python

"""TrueNAS binary sensor platform."""
from __future__ import annotations
from logging import getLogger
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .binary_sensor_types import (
SENSOR_SERVICES,
SENSOR_TYPES,
)
from .entity import TrueNASEntity, async_add_entities
_LOGGER = getLogger(__name__)
# ---------------------------
# async_setup_entry
# ---------------------------
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
_async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up device tracker for OpenMediaVault component."""
dispatcher = {
"TrueNASBinarySensor": TrueNASBinarySensor,
"TrueNASJailBinarySensor": TrueNASJailBinarySensor,
"TrueNASVMBinarySensor": TrueNASVMBinarySensor,
"TrueNASServiceBinarySensor": TrueNASServiceBinarySensor,
"TrueNASAppBinarySensor": TrueNASAppBinarySensor,
}
await async_add_entities(hass, config_entry, dispatcher)
# ---------------------------
# TrueNASBinarySensor
# ---------------------------
class TrueNASBinarySensor(TrueNASEntity, BinarySensorEntity):
"""Define an TrueNAS Binary Sensor."""
@property
def is_on(self) -> bool:
"""Return true if device is on."""
return self._data[self.entity_description.data_is_on]
@property
def icon(self) -> str:
"""Return the icon."""
if self.entity_description.icon_enabled:
if self._data[self.entity_description.data_is_on]:
return self.entity_description.icon_enabled
else:
return self.entity_description.icon_disabled
# ---------------------------
# TrueNASJailBinarySensor
# ---------------------------
class TrueNASJailBinarySensor(TrueNASBinarySensor):
"""Define a TrueNAS Jail Binary Sensor."""
async def start(self):
"""Start a Jail."""
tmp_jail = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"jail/id/{self._data['id']}"
)
if "state" not in tmp_jail:
_LOGGER.error(
"Jail %s (%s) invalid", self._data["comment"], self._data["id"]
)
return
if tmp_jail["state"] != "down":
_LOGGER.warning(
"Jail %s (%s) is not down", self._data["comment"], self._data["id"]
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query, "jail/start", "post", self._data["id"]
)
async def stop(self):
"""Stop a Jail."""
tmp_jail = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"jail/id/{self._data['id']}"
)
if "state" not in tmp_jail:
_LOGGER.error(
"Jail %s (%s) invalid", self._data["comment"], self._data["id"]
)
return
if tmp_jail["state"] != "up":
_LOGGER.warning(
"Jail %s (%s) is not up", self._data["comment"], self._data["id"]
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query, "jail/stop", "post", {"jail": self._data["id"]}
)
async def restart(self):
"""Restart a Jail."""
tmp_jail = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"jail/id/{self._data['id']}"
)
if "state" not in tmp_jail:
_LOGGER.error(
"Jail %s (%s) invalid", self._data["comment"], self._data["id"]
)
return
if tmp_jail["state"] != "up":
_LOGGER.warning(
"Jail %s (%s) is not up", self._data["comment"], self._data["id"]
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query, "jail/restart", "post", self._data["id"]
)
# ---------------------------
# TrueNASVMBinarySensor
# ---------------------------
class TrueNASVMBinarySensor(TrueNASBinarySensor):
"""Define a TrueNAS VM Binary Sensor."""
async def start(self, overcommit: bool = False):
"""Start a VM."""
tmp_vm = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"vm/id/{self._data['id']}"
)
if "status" not in tmp_vm:
_LOGGER.error("VM %s (%s) invalid", self._data["name"], self._data["id"])
return
if tmp_vm["status"]["state"] != "STOPPED":
_LOGGER.warning(
"VM %s (%s) is not down", self._data["name"], self._data["id"]
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query,
f"vm/id/{self._data['id']}/start",
"post",
{"overcommit": overcommit},
)
async def stop(self):
"""Stop a VM."""
tmp_vm = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"vm/id/{self._data['id']}"
)
if "status" not in tmp_vm:
_LOGGER.error("VM %s (%s) invalid", self._data["name"], self._data["id"])
return
if tmp_vm["status"]["state"] != "RUNNING":
_LOGGER.warning(
"VM %s (%s) is not up", self._data["name"], self._data["id"]
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query, f"vm/id/{self._data['id']}/stop", "post"
)
# ---------------------------
# TrueNASServiceBinarySensor
# ---------------------------
class TrueNASServiceBinarySensor(TrueNASBinarySensor):
"""Define a TrueNAS Service Binary Sensor."""
async def start(self):
"""Start a Service."""
tmp_service = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"service/id/{self._data['id']}"
)
if "state" not in tmp_service:
_LOGGER.error(
"Service %s (%s) invalid", self._data["service"], self._data["id"]
)
return
if tmp_service["state"] != "STOPPED":
_LOGGER.warning(
"Service %s (%s) is not stopped",
self._data["service"],
self._data["id"],
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query,
"service/start",
"post",
{"service": self._data["service"]},
)
await self.coordinator.async_refresh()
async def stop(self):
"""Stop a Service."""
tmp_service = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"service/id/{self._data['id']}"
)
if "state" not in tmp_service:
_LOGGER.error(
"Service %s (%s) invalid", self._data["service"], self._data["id"]
)
return
if tmp_service["state"] == "STOPPED":
_LOGGER.warning(
"Service %s (%s) is not running",
self._data["service"],
self._data["id"],
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query,
"service/stop",
"post",
{"service": self._data["service"]},
)
await self.coordinator.async_refresh()
async def restart(self):
"""Restart a Service."""
tmp_service = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"service/id/{self._data['id']}"
)
if "state" not in tmp_service:
_LOGGER.error(
"Service %s (%s) invalid", self._data["service"], self._data["id"]
)
return
if tmp_service["state"] == "STOPPED":
_LOGGER.warning(
"Service %s (%s) is not running",
self._data["service"],
self._data["id"],
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query,
"service/restart",
"post",
{"service": self._data["service"]},
)
await self.coordinator.async_refresh()
async def reload(self):
"""Reload a Service."""
tmp_service = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"service/id/{self._data['id']}"
)
if "state" not in tmp_service:
_LOGGER.error(
"Service %s (%s) invalid", self._data["service"], self._data["id"]
)
return
if tmp_service["state"] == "STOPPED":
_LOGGER.warning(
"Service %s (%s) is not running",
self._data["service"],
self._data["id"],
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query,
"service/reload",
"post",
{"service": self._data["service"]},
)
await self.coordinator.async_refresh()
# ---------------------------
# TrueNASAppsBinarySensor
# ---------------------------
class TrueNASAppBinarySensor(TrueNASBinarySensor):
"""Define a TrueNAS Applications Binary Sensor."""
async def start(self):
"""Start a VM."""
tmp_vm = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"/chart/release/id/{self._data['id']}"
)
if "status" not in tmp_vm:
_LOGGER.error("VM %s (%s) invalid", self._data["name"], self._data["id"])
return
if tmp_vm["status"] == "ACTIVE":
_LOGGER.warning(
"VM %s (%s) is not down", self._data["name"], self._data["id"]
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query,
"/chart/release/scale",
"post",
{"release_name": self._data["id"], "scale_options": {"replica_count": 1}},
)
async def stop(self):
"""Stop a VM."""
tmp_vm = await self.hass.async_add_executor_job(
self.coordinator.api.query, f"/chart/release/id/{self._data['id']}"
)
if "status" not in tmp_vm:
_LOGGER.error("VM %s (%s) invalid", self._data["name"], self._data["id"])
return
if tmp_vm["status"] != "ACTIVE":
_LOGGER.warning(
"VM %s (%s) is not up", self._data["name"], self._data["id"]
)
return
await self.hass.async_add_executor_job(
self.coordinator.api.query,
"/chart/release/scale",
"post",
{"release_name": self._data["id"], "scale_options": {"replica_count": 0}},
)