ha.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. from flask import Blueprint, jsonify, request
  2. from hardware.ha_devices_module import (
  3. turn_on_entrance_lights, turn_off_entrance_lights,
  4. turn_on_exhibition_spotlight, turn_off_exhibition_spotlight,
  5. turn_on_exhibition_ceiling_lights, turn_off_exhibition_ceiling_lights, set_exhibition_ceiling_light_level,
  6. turn_on_exhibition_desktop_switch, turn_off_exhibition_desktop_switch,
  7. turn_on_exhibition_3d_fan, turn_off_exhibition_3d_fan,
  8. turn_on_exhibition_stand_light_strip, turn_off_exhibition_stand_light_strip,
  9. turn_on_all, turn_off_all,
  10. ha_device_controller
  11. )
  12. from utils.logger_config import logger
  13. from api.utils import login_required
  14. import threading
  15. import concurrent.futures
  16. ha_bp = Blueprint('ha', __name__)
  17. @ha_bp.route('/api/ha/entrance_lights/turn_on', methods=['POST'])
  18. @login_required
  19. def turn_on_entrance_lights_api():
  20. """打开一楼大门玄关顶灯"""
  21. try:
  22. def task():
  23. try:
  24. turn_on_entrance_lights()
  25. except Exception as e:
  26. logger.error(f"异步打开一楼大门玄关顶灯异常: {str(e)}")
  27. threading.Thread(target=task).start()
  28. return jsonify({
  29. "success": True,
  30. "message": "已发送打开一楼大门玄关顶灯指令 - 异步执行"
  31. })
  32. except Exception as e:
  33. logger.error(f"打开一楼大门玄关顶灯异常: {str(e)}")
  34. return jsonify({
  35. "success": False,
  36. "message": f"打开一楼大门玄关顶灯失败: {str(e)}"
  37. }), 500
  38. @ha_bp.route('/api/ha/entrance_lights/turn_off', methods=['POST'])
  39. @login_required
  40. def turn_off_entrance_lights_api():
  41. """关闭一楼大门玄关顶灯"""
  42. try:
  43. def task():
  44. try:
  45. turn_off_entrance_lights()
  46. except Exception as e:
  47. logger.error(f"异步关闭一楼大门玄关顶灯异常: {str(e)}")
  48. threading.Thread(target=task).start()
  49. return jsonify({
  50. "success": True,
  51. "message": "已发送关闭一楼大门玄关顶灯指令 - 异步执行"
  52. })
  53. except Exception as e:
  54. logger.error(f"关闭一楼大门玄关顶灯异常: {str(e)}")
  55. return jsonify({
  56. "success": False,
  57. "message": f"关闭一楼大门玄关顶灯失败: {str(e)}"
  58. }), 500
  59. @ha_bp.route('/api/ha/exhibition_spotlight/turn_on', methods=['POST'])
  60. @login_required
  61. def turn_on_exhibition_spotlight_api():
  62. """打开一楼大门玄关射灯"""
  63. try:
  64. def task():
  65. try:
  66. turn_on_exhibition_spotlight()
  67. except Exception as e:
  68. logger.error(f"异步打开一楼大门玄关射灯异常: {str(e)}")
  69. threading.Thread(target=task).start()
  70. return jsonify({
  71. "success": True,
  72. "message": "已发送打开一楼大门玄关射灯指令 - 异步执行"
  73. })
  74. except Exception as e:
  75. logger.error(f"打开一楼大门玄关射灯异常: {str(e)}")
  76. return jsonify({
  77. "success": False,
  78. "message": f"打开一楼大门玄关射灯失败: {str(e)}"
  79. }), 500
  80. @ha_bp.route('/api/ha/exhibition_spotlight/turn_off', methods=['POST'])
  81. @login_required
  82. def turn_off_exhibition_spotlight_api():
  83. """关闭一楼大门玄关射灯"""
  84. try:
  85. def task():
  86. try:
  87. turn_off_exhibition_spotlight()
  88. except Exception as e:
  89. logger.error(f"异步关闭一楼大门玄关射灯异常: {str(e)}")
  90. threading.Thread(target=task).start()
  91. return jsonify({
  92. "success": True,
  93. "message": "已发送关闭一楼大门玄关射灯指令 - 异步执行"
  94. })
  95. except Exception as e:
  96. logger.error(f"关闭一楼大门玄关射灯异常: {str(e)}")
  97. return jsonify({
  98. "success": False,
  99. "message": f"关闭一楼大门玄关射灯失败: {str(e)}"
  100. }), 500
  101. @ha_bp.route('/api/ha/exhibition_ceiling_lights/turn_on', methods=['POST'])
  102. @login_required
  103. def turn_on_exhibition_ceiling_lights_api():
  104. """打开一楼展厅顶灯"""
  105. try:
  106. def task():
  107. try:
  108. turn_on_exhibition_ceiling_lights()
  109. except Exception as e:
  110. logger.error(f"异步打开一楼展厅顶灯异常: {str(e)}")
  111. threading.Thread(target=task).start()
  112. return jsonify({
  113. "success": True,
  114. "message": "已发送打开一楼展厅顶灯指令 - 异步执行"
  115. })
  116. except Exception as e:
  117. logger.error(f"打开一楼展厅顶灯异常: {str(e)}")
  118. return jsonify({
  119. "success": False,
  120. "message": f"打开一楼展厅顶灯失败: {str(e)}"
  121. }), 500
  122. @ha_bp.route('/api/ha/exhibition_ceiling_lights/turn_off', methods=['POST'])
  123. @login_required
  124. def turn_off_exhibition_ceiling_lights_api():
  125. """关闭一楼展厅顶灯"""
  126. try:
  127. def task():
  128. try:
  129. turn_off_exhibition_ceiling_lights()
  130. except Exception as e:
  131. logger.error(f"异步关闭一楼展厅顶灯异常: {str(e)}")
  132. threading.Thread(target=task).start()
  133. return jsonify({
  134. "success": True,
  135. "message": "已发送关闭一楼展厅顶灯指令 - 异步执行"
  136. })
  137. except Exception as e:
  138. logger.error(f"关闭一楼展厅顶灯异常: {str(e)}")
  139. return jsonify({
  140. "success": False,
  141. "message": f"关闭一楼展厅顶灯失败: {str(e)}"
  142. }), 500
  143. @ha_bp.route('/api/ha/exhibition_ceiling_lights/set_level', methods=['POST'])
  144. @login_required
  145. def set_exhibition_ceiling_light_level_api():
  146. """设置一楼展厅顶灯等级 (0-3)"""
  147. try:
  148. data = request.get_json()
  149. if not data or 'level' not in data:
  150. return jsonify({"success": False, "message": "缺少参数 level"}), 400
  151. level = data['level']
  152. def task():
  153. try:
  154. set_exhibition_ceiling_light_level(level)
  155. except Exception as e:
  156. logger.error(f"异步设置一楼展厅顶灯等级异常: {str(e)}")
  157. threading.Thread(target=task).start()
  158. return jsonify({
  159. "success": True,
  160. "message": f"已发送设置一楼展厅顶灯等级指令 ({level}) - 异步执行"
  161. })
  162. except Exception as e:
  163. logger.error(f"设置一楼展厅顶灯等级异常: {str(e)}")
  164. return jsonify({
  165. "success": False,
  166. "message": f"设置一楼展厅顶灯等级失败: {str(e)}"
  167. }), 500
  168. @ha_bp.route('/api/ha/exhibition_desktop_switch/turn_on', methods=['POST'])
  169. @login_required
  170. def turn_on_exhibition_desktop_switch_api():
  171. """打开展厅桌面的灯座总开关"""
  172. try:
  173. def task():
  174. try:
  175. turn_on_exhibition_desktop_switch()
  176. except Exception as e:
  177. logger.error(f"异步打开展厅桌面的灯座总开关异常: {str(e)}")
  178. threading.Thread(target=task).start()
  179. return jsonify({
  180. "success": True,
  181. "message": "已发送打开展厅桌面的灯座总开关指令 - 异步执行"
  182. })
  183. except Exception as e:
  184. logger.error(f"打开展厅桌面的灯座总开关异常: {str(e)}")
  185. return jsonify({
  186. "success": False,
  187. "message": f"打开展厅桌面的灯座总开关失败: {str(e)}"
  188. }), 500
  189. @ha_bp.route('/api/ha/exhibition_desktop_switch/turn_off', methods=['POST'])
  190. @login_required
  191. def turn_off_exhibition_desktop_switch_api():
  192. """关闭展厅桌面的灯座总开关"""
  193. try:
  194. def task():
  195. try:
  196. turn_off_exhibition_desktop_switch()
  197. except Exception as e:
  198. logger.error(f"异步关闭展厅桌面的灯座总开关异常: {str(e)}")
  199. threading.Thread(target=task).start()
  200. return jsonify({
  201. "success": True,
  202. "message": "已发送关闭展厅桌面的灯座总开关指令 - 异步执行"
  203. })
  204. except Exception as e:
  205. logger.error(f"关闭展厅桌面的灯座总开关异常: {str(e)}")
  206. return jsonify({
  207. "success": False,
  208. "message": f"关闭展厅桌面的灯座总开关失败: {str(e)}"
  209. }), 500
  210. @ha_bp.route('/api/ha/exhibition_3d_fan/turn_on', methods=['POST'])
  211. @login_required
  212. def turn_on_exhibition_3d_fan_api():
  213. """打开展厅桌面3D风扇投影"""
  214. try:
  215. def task():
  216. try:
  217. turn_on_exhibition_3d_fan()
  218. except Exception as e:
  219. logger.error(f"异步打开展厅桌面3D风扇投影异常: {str(e)}")
  220. threading.Thread(target=task).start()
  221. return jsonify({
  222. "success": True,
  223. "message": "已发送打开展厅桌面3D风扇投影指令 - 异步执行"
  224. })
  225. except Exception as e:
  226. logger.error(f"打开展厅桌面3D风扇投影异常: {str(e)}")
  227. return jsonify({
  228. "success": False,
  229. "message": f"打开展厅桌面3D风扇投影失败: {str(e)}"
  230. }), 500
  231. @ha_bp.route('/api/ha/exhibition_3d_fan/turn_off', methods=['POST'])
  232. @login_required
  233. def turn_off_exhibition_3d_fan_api():
  234. """关闭展厅桌面3D风扇投影"""
  235. try:
  236. def task():
  237. try:
  238. turn_off_exhibition_3d_fan()
  239. except Exception as e:
  240. logger.error(f"异步关闭展厅桌面3D风扇投影异常: {str(e)}")
  241. threading.Thread(target=task).start()
  242. return jsonify({
  243. "success": True,
  244. "message": "已发送关闭展厅桌面3D风扇投影指令 - 异步执行"
  245. })
  246. except Exception as e:
  247. logger.error(f"关闭展厅桌面3D风扇投影异常: {str(e)}")
  248. return jsonify({
  249. "success": False,
  250. "message": f"关闭展厅桌面3D风扇投影失败: {str(e)}"
  251. }), 500
  252. @ha_bp.route('/api/ha/exhibition_stand_light_strip/turn_on', methods=['POST'])
  253. @login_required
  254. def turn_on_exhibition_stand_light_strip_api():
  255. """打开展台桌子灯带"""
  256. try:
  257. def task():
  258. try:
  259. turn_on_exhibition_stand_light_strip()
  260. except Exception as e:
  261. logger.error(f"异步打开展台桌子灯带异常: {str(e)}")
  262. threading.Thread(target=task).start()
  263. return jsonify({
  264. "success": True,
  265. "message": "已发送打开展台桌子灯带指令 - 异步执行"
  266. })
  267. except Exception as e:
  268. logger.error(f"打开展台桌子灯带异常: {str(e)}")
  269. return jsonify({
  270. "success": False,
  271. "message": f"打开展台桌子灯带失败: {str(e)}"
  272. }), 500
  273. @ha_bp.route('/api/ha/exhibition_stand_light_strip/turn_off', methods=['POST'])
  274. @login_required
  275. def turn_off_exhibition_stand_light_strip_api():
  276. """关闭展台桌子灯带"""
  277. try:
  278. def task():
  279. try:
  280. turn_off_exhibition_stand_light_strip()
  281. except Exception as e:
  282. logger.error(f"异步关闭展台桌子灯带异常: {str(e)}")
  283. threading.Thread(target=task).start()
  284. return jsonify({
  285. "success": True,
  286. "message": "已发送关闭展台桌子灯带指令 - 异步执行"
  287. })
  288. except Exception as e:
  289. logger.error(f"关闭展台桌子灯带异常: {str(e)}")
  290. return jsonify({
  291. "success": False,
  292. "message": f"关闭展台桌子灯带失败: {str(e)}"
  293. }), 500
  294. @ha_bp.route('/api/ha/turn_on_all', methods=['POST'])
  295. @login_required
  296. def ha_turn_on_all_api():
  297. """打开所有HA设备"""
  298. try:
  299. def task():
  300. try:
  301. turn_on_all()
  302. except Exception as e:
  303. logger.error(f"异步打开所有HA设备异常: {str(e)}")
  304. threading.Thread(target=task).start()
  305. return jsonify({
  306. "success": True,
  307. "message": "已发送打开所有HA设备指令 - 异步执行"
  308. })
  309. except Exception as e:
  310. logger.error(f"打开所有HA设备异常: {str(e)}")
  311. return jsonify({
  312. "success": False,
  313. "message": f"打开所有HA设备失败: {str(e)}"
  314. }), 500
  315. @ha_bp.route('/api/ha/turn_off_all', methods=['POST'])
  316. @login_required
  317. def ha_turn_off_all_api():
  318. """关闭所有HA设备"""
  319. try:
  320. def task():
  321. try:
  322. turn_off_all()
  323. except Exception as e:
  324. logger.error(f"异步关闭所有HA设备异常: {str(e)}")
  325. threading.Thread(target=task).start()
  326. return jsonify({
  327. "success": True,
  328. "message": "已发送关闭所有HA设备指令 - 异步执行"
  329. })
  330. except Exception as e:
  331. logger.error(f"关闭所有HA设备异常: {str(e)}")
  332. return jsonify({
  333. "success": False,
  334. "message": f"关闭所有HA设备失败: {str(e)}"
  335. }), 500
  336. from application.self_check_service import check_ha_status
  337. @ha_bp.route('/api/ha/self_check', methods=['POST'])
  338. @login_required
  339. def self_check_api():
  340. """
  341. HA设备自检
  342. 检查所有配置的HA设备是否可用(通过调用 HA API 获取状态)
  343. """
  344. try:
  345. results = check_ha_status()
  346. # 检查是否有错误返回
  347. if results and "error" in results[0]:
  348. return jsonify({
  349. "success": False,
  350. "message": results[0]["error"],
  351. "data": []
  352. }), 500
  353. return jsonify({
  354. "success": True,
  355. "message": "HA设备自检完成",
  356. "data": results
  357. })
  358. except Exception as e:
  359. logger.error(f"HA设备自检异常: {str(e)}")
  360. return jsonify({
  361. "success": False,
  362. "message": f"HA设备自检失败: {str(e)}"
  363. }), 500