Coverage for src/unit_cooler/webui/webapi/cooler_stat.py: 92%

37 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-07-23 14:35 +0000

1#!/usr/bin/env python3 

2""" 

3冷却システムを作業状況を WebUI に渡します。 

4 

5Usage: 

6 cooler_stat.py [-c CONFIG] [-D] 

7 

8Options: 

9 -c CONFIG : CONFIG を設定ファイルとして読み込んで実行します。 [default: config.yaml] 

10 -D : デバッグモードで動作します。 

11""" 

12 

13import logging 

14import os 

15 

16import flask 

17import my_lib.flask_util 

18import my_lib.sensor_data 

19import my_lib.webapp.config 

20 

21import unit_cooler.controller.engine 

22import unit_cooler.controller.sensor 

23 

24blueprint = flask.Blueprint("cooler-stat", __name__) 

25 

26api_base_url = None 

27 

28 

29def init(api_base_url_): 

30 global api_base_url # noqa: PLW0603 

31 

32 api_base_url = api_base_url_ 

33 

34 

35def watering(config, day_before): 

36 day_offset = 7 if os.environ.get("DUMMY_MODE", "false") == "true" else 0 

37 

38 amount = my_lib.sensor_data.get_day_sum( 

39 config["controller"]["influxdb"], 

40 config["controller"]["watering"]["measure"], 

41 config["controller"]["watering"]["hostname"], 

42 "flow", 

43 1, 

44 day_before, 

45 day_offset, 

46 ) 

47 

48 return { 

49 "amount": amount, 

50 "price": amount * config["controller"]["watering"]["unit_price"] / 1000.0, 

51 } 

52 

53 

54def watering_list(config): 

55 return [watering(config, i) for i in range(10)] 

56 

57 

58def get_last_message(message_queue): 

59 # NOTE: 現在の実際の制御モードを取得する。 

60 while not message_queue.empty(): 

61 get_last_message.last_message = message_queue.get() 

62 return get_last_message.last_message 

63 

64 

65get_last_message.last_message = None 

66 

67 

68def get_stats(config, message_queue): 

69 # NOTE: データを受け渡すのは面倒なので、直接計算してしまう 

70 sense_data = unit_cooler.controller.sensor.get_sense_data(config) 

71 mode = unit_cooler.controller.engine.judge_cooling_mode(config, sense_data) 

72 

73 return { 

74 "watering": watering_list(config), 

75 "sensor": mode["sense_data"], 

76 "mode": get_last_message(message_queue), 

77 "cooler_status": mode["cooler_status"], 

78 "outdoor_status": mode["outdoor_status"], 

79 } 

80 

81 

82@blueprint.route("/api/stat", methods=["GET"]) 

83@my_lib.flask_util.support_jsonp 

84def api_get_stats(): 

85 try: 

86 config = flask.current_app.config["CONFIG"] 

87 message_queue = flask.current_app.config["MESSAGE_QUEUE"] 

88 

89 return flask.jsonify(get_stats(config, message_queue)) 

90 except Exception as e: 

91 logging.exception("Error in api_get_stats") 

92 return flask.jsonify({"error": str(e)}), 500 

93 

94 

95if __name__ == "__main__": 

96 # TEST Code 

97 import docopt 

98 import my_lib.config 

99 import my_lib.logger 

100 import my_lib.pretty 

101 

102 args = docopt.docopt(__doc__) 

103 

104 config_file = args["-c"] 

105 debug_mode = args["-D"] 

106 

107 my_lib.logger.init("test", level=logging.DEBUG if debug_mode else logging.INFO) 

108 

109 config = my_lib.config.load(config_file) 

110 

111 logging.info(my_lib.pretty.format(watering_list(config)))