Files
fn_nas/custom_components/fn_nas/switch.py

149 lines
5.5 KiB
Python
Raw Normal View History

2025-06-30 15:31:15 +08:00
import logging
from homeassistant.core import callback
from homeassistant.components.switch import SwitchEntity
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, DATA_UPDATE_COORDINATOR, CONF_MAC, DEVICE_ID_NAS
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities):
domain_data = hass.data[DOMAIN][config_entry.entry_id]
coordinator = domain_data[DATA_UPDATE_COORDINATOR]
entities = []
entities.append(PowerSwitch(coordinator, config_entry))
if "vms" in coordinator.data:
for vm in coordinator.data["vms"]:
entities.append(
VMSwitch(
coordinator,
vm["name"],
vm.get("title", vm["name"])
)
)
async_add_entities(entities)
class PowerSwitch(CoordinatorEntity, SwitchEntity):
def __init__(self, coordinator, config_entry):
super().__init__(coordinator)
self.config_entry = config_entry
self._attr_name = "电源"
self._attr_unique_id = "flynas_power"
self._attr_entity_category = EntityCategory.CONFIG
self._attr_device_info = {
"identifiers": {(DOMAIN, DEVICE_ID_NAS)},
"name": "飞牛NAS系统",
"manufacturer": "飞牛",
"model": "飞牛NAS"
}
self._last_status = None
@property
def is_on(self):
system_data = self.coordinator.data.get("system", {})
return system_data.get("status") == "on"
async def async_turn_on(self, **kwargs):
mac = self.config_entry.data.get(CONF_MAC)
if mac:
await self.hass.services.async_call(
'wake_on_lan',
'send_magic_packet',
{'mac': mac}
)
self.coordinator.data["system"]["status"] = "on"
self.coordinator.async_update_listeners()
self.async_write_ha_state()
else:
_LOGGER.warning("无法唤醒系统未配置MAC地址")
async def async_turn_off(self, **kwargs):
await self.coordinator.shutdown_system()
self.coordinator.data["system"]["status"] = "off"
self.coordinator.async_update_listeners()
self.async_write_ha_state()
@callback
def _handle_coordinator_update(self) -> None:
system_data = self.coordinator.data.get("system", {})
new_status = system_data.get("status", "unknown")
if self._last_status != new_status:
self.async_write_ha_state()
self._last_status = new_status
super()._handle_coordinator_update()
@property
def extra_state_attributes(self):
mac = self.config_entry.data.get(CONF_MAC, "未配置")
return {
"控制方式": "关机使用命令关机,开机使用网络唤醒",
"MAC地址": mac,
"警告": "网络唤醒需要提前配置MAC地址",
"当前状态": self.coordinator.data["system"].get("status", "未知")
}
class VMSwitch(CoordinatorEntity, SwitchEntity):
def __init__(self, coordinator, vm_name, vm_title):
super().__init__(coordinator)
self.vm_name = vm_name
self.vm_title = vm_title
self._attr_name = f"{vm_title} 电源"
self._attr_unique_id = f"flynas_vm_{vm_name}_switch"
self._attr_device_info = {
"identifiers": {(DOMAIN, f"vm_{vm_name}")},
"name": vm_title,
"via_device": (DOMAIN, DEVICE_ID_NAS)
}
self.vm_manager = coordinator.vm_manager if hasattr(coordinator, 'vm_manager') else None
@property
def is_on(self):
for vm in self.coordinator.data.get("vms", []):
if vm["name"] == self.vm_name:
return vm["state"] == "running"
return False
async def async_turn_on(self, **kwargs):
if not self.vm_manager:
_LOGGER.error("vm_manager不可用无法启动虚拟机 %s", self.vm_name)
return
try:
success = await self.vm_manager.control_vm(self.vm_name, "start")
if success:
for vm in self.coordinator.data.get("vms", []):
if vm["name"] == self.vm_name:
vm["state"] = "running"
self.async_write_ha_state()
except Exception as e:
_LOGGER.error("启动虚拟机时出错: %s", str(e), exc_info=True)
async def async_turn_off(self, **kwargs):
if not self.vm_manager:
_LOGGER.error("vm_manager不可用无法关闭虚拟机 %s", self.vm_name)
return
try:
success = await self.vm_manager.control_vm(self.vm_name, "shutdown")
if success:
for vm in self.coordinator.data.get("vms", []):
if vm["name"] == self.vm_name:
vm["state"] = "shut off"
self.async_write_ha_state()
except Exception as e:
_LOGGER.error("关闭虚拟机时出错: %s", str(e), exc_info=True)
@property
def extra_state_attributes(self):
for vm in self.coordinator.data.get("vms", []):
if vm["name"] == self.vm_name:
return {
"虚拟机ID": vm["id"],
"原始状态": vm["state"]
}
return {}