mitvs_module.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import yaml
  2. import requests
  3. import os
  4. import json
  5. from utils.logger_config import logger
  6. class MiTVController:
  7. def __init__(self, kodi_config_path='kodi_config_prod.yaml', ha_config_path='ha_config_prod.yaml'):
  8. self.kodi_config_path = kodi_config_path
  9. self.ha_config_path = ha_config_path
  10. self.kodi_config = self._load_config(self.kodi_config_path)
  11. self.ha_config_full = self._load_config(self.ha_config_path)
  12. self.ha_config = self.ha_config_full.get('home_assistant', {})
  13. self.base_url = self.ha_config.get('url', '').rstrip('/')
  14. self.token = self.ha_config.get('token', '')
  15. self.headers = {
  16. "Authorization": f"Bearer {self.token}",
  17. "Content-Type": "application/json",
  18. }
  19. self.kodi_servers = self.kodi_config.get('kodi_servers', [])
  20. def _load_config(self, path):
  21. if not os.path.exists(path):
  22. logger.error(f"配置文件不存在: {path}")
  23. return {}
  24. try:
  25. with open(path, 'r', encoding='utf-8') as f:
  26. return yaml.safe_load(f) or {}
  27. except Exception as e:
  28. logger.error(f"加载配置文件失败 {path}: {e}")
  29. return {}
  30. def _call_ha_service(self, entity_id, service="press", domain="button"):
  31. if not self.base_url or not self.token:
  32. logger.error("Home Assistant 配置缺失 (url or token)")
  33. return False
  34. if not entity_id:
  35. logger.warning("未配置 entity_id")
  36. return False
  37. url = f"{self.base_url}/api/services/{domain}/{service}"
  38. payload = {"entity_id": entity_id}
  39. logger.info(f"准备调用HA接口: URL={url}, Entity={entity_id}")
  40. try:
  41. response = requests.post(url, headers=self.headers, json=payload, timeout=5)
  42. if response.status_code in [200, 201]:
  43. logger.info(f"HA调用成功: {entity_id} -> {domain}.{service}, 响应: {response.text}")
  44. return True
  45. else:
  46. logger.error(f"HA调用失败: {response.status_code} - {response.text}")
  47. return False
  48. except Exception as e:
  49. logger.error(f"HA请求异常: {e}")
  50. return False
  51. def turn_on_display(self, kodi_id):
  52. """唤醒指定ID的电视"""
  53. server = next((s for s in self.kodi_servers if s.get('id') == kodi_id), None)
  54. if not server:
  55. logger.error(f"未找到ID为 {kodi_id} 的Kodi服务器配置")
  56. return False
  57. entity_id = server.get('ha_turn_on_entity_id')
  58. if not entity_id:
  59. logger.error(f"Kodi ID {kodi_id} 未配置唤醒实例ID (ha_turn_on_entity_id)")
  60. return False
  61. # 智能调用,不强制指定service,让 _call_ha_service 判断
  62. return self._call_ha_service(entity_id)
  63. def turn_off_display(self, kodi_id):
  64. """息屏指定ID的电视"""
  65. server = next((s for s in self.kodi_servers if s.get('id') == kodi_id), None)
  66. if not server:
  67. logger.error(f"未找到ID为 {kodi_id} 的Kodi服务器配置")
  68. return False
  69. entity_id = server.get('ha_turn_off_entity_id')
  70. if not entity_id:
  71. logger.error(f"Kodi ID {kodi_id} 未配置息屏实例ID (ha_turn_off_entity_id)")
  72. return False
  73. # 智能调用,不强制指定service
  74. return self._call_ha_service(entity_id)
  75. def turn_on_all_displays(self):
  76. """唤醒所有电视"""
  77. success_count = 0
  78. for server in self.kodi_servers:
  79. if self.turn_on_display(server.get('id')):
  80. success_count += 1
  81. return success_count > 0
  82. def turn_off_all_displays(self):
  83. """息屏所有电视"""
  84. success_count = 0
  85. for server in self.kodi_servers:
  86. if self.turn_off_display(server.get('id')):
  87. success_count += 1
  88. return success_count > 0
  89. # 单例实例
  90. mitv_controller = MiTVController()
  91. def turn_on_display(kodi_id):
  92. return mitv_controller.turn_on_display(kodi_id)
  93. def turn_off_display(kodi_id):
  94. return mitv_controller.turn_off_display(kodi_id)
  95. def turn_on_all_displays():
  96. return mitv_controller.turn_on_all_displays()
  97. def turn_off_all_displays():
  98. return mitv_controller.turn_off_all_displays()