quality_server.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. #!/usr/bin/python37
  2. # coding: utf-8
  3. """
  4. @version: 1.0
  5. @software: PyCharm
  6. @file: quality_server.py
  7. @time: 2024/9/10 12:18
  8. """
  9. import threading
  10. from sched import scheduler
  11. import numpy as np
  12. import pandas as pd
  13. import os
  14. import time
  15. import json
  16. import pickle
  17. import configparser
  18. from decimal import Decimal
  19. from PIL import ImageFile
  20. ImageFile.LOAD_TRUNCATED_IMAGES = True
  21. import Flask_water_server
  22. from flask import Flask, request, jsonify
  23. from flask_cors import CORS
  24. from gevent import pywsgi, monkey
  25. monkey.patch_all()
  26. import logging
  27. np.set_printoptions(threshold = 1000000000, linewidth=1245)
  28. class Logger:
  29. def __init__(self,loggername, logpath, filename):
  30. self.logger = logging.getLogger(loggername)
  31. self.logger.setLevel(logging.INFO)
  32. log_path = logpath # 指定文件输出路径,logs是个文件夹,要加上/
  33. logname = log_path + filename
  34. self.fh = logging.FileHandler(logname, encoding = 'utf-8')
  35. self.fh.setLevel(logging.INFO)
  36. self.ch = logging.StreamHandler()
  37. self.ch.setLevel(logging.INFO)
  38. formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
  39. self.fh.setFormatter(formatter)
  40. self.ch.setFormatter(formatter)
  41. self.logger.addHandler(self.fh)
  42. self.logger.addHandler(self.ch)
  43. def get_log(self):
  44. return self.logger
  45. def get_fh(self):
  46. return self.fh
  47. def log_clear(self):
  48. self.logger.handlers.clear()
  49. class Tool:
  50. def set_precision(num, digit):
  51. precision_str = '{:.%d' % (digit) + 'f}'
  52. dec_val = precision_str.format(Decimal(num))
  53. return float(dec_val)
  54. def mean_absolute_percentage_error(y_true, y_pred):
  55. y_true, y_pred = np.array(y_true), np.array(y_pred)
  56. return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
  57. def month_of_year(ts):
  58. # ts = str(ts)
  59. t = time.strptime(ts, "%Y-%m-%d %H:%M")
  60. tm_mon = t.tm_mon
  61. return tm_mon
  62. def day_of_month(ts):
  63. # ts = str(ts)
  64. t = time.strptime(ts, "%Y-%m-%d %H:%M")
  65. tm_mday = t.tm_mday
  66. return tm_mday
  67. def hour_of_day(ts):
  68. t = time.strptime(ts, "%Y-%m-%d %H:%M")
  69. tm_hour = t.tm_hour
  70. return tm_hour
  71. def min_of_hour(ts):
  72. t = time.strptime(ts, "%Y-%m-%d %H:%M")
  73. tm_min = t.tm_min
  74. return tm_min
  75. def five_min_of_hour(ts):
  76. t = time.strptime(ts, "%d/%m/%Y %H:%M:%S")
  77. tm_min = t.tm_min
  78. if tm_min % 5 == 0:
  79. return 1
  80. else:
  81. return 0
  82. def day_of_week(ts):
  83. t = time.strptime(ts, "%Y-%m-%d %H:%M")
  84. tm_day = t.tm_wday
  85. return tm_day
  86. def week_of_year(day):
  87. week = int((day - 1) / 7) + 1
  88. return week
  89. def time_str(str):
  90. return str[:-3]
  91. def time_format(ts):
  92. t = time.strptime(ts, "%d/%m/%Y %H:%M")
  93. tm_year = t.tm_year
  94. tm_month = t.tm_mon
  95. tm_day = t.tm_mday
  96. tm_hour = t.tm_hour
  97. tm_min = t.tm_min
  98. return '%s-%s-%s %s:%s' %(tm_year, tm_month, tm_day, tm_hour, tm_min)
  99. def map_season(month):
  100. # print(month)
  101. month = int(month)
  102. if month >= 12 or month <= 2:
  103. value = 1
  104. if month >= 3 and month <= 5:
  105. value = 2
  106. if month >= 6 and month <= 8:
  107. value = 3
  108. else:
  109. value = 4
  110. return value
  111. def map_weather(stat):
  112. # print(month)
  113. if stat =='晴':
  114. value = 1
  115. if stat =='阴':
  116. value = 2
  117. if stat =='小雨':
  118. value = 3
  119. if stat =='中雨':
  120. value = 4
  121. if stat =='大雨':
  122. value = 5
  123. if stat =='暴雨':
  124. value = 6
  125. if stat =='阵雨':
  126. value = 7
  127. if stat =='多云':
  128. value = 8
  129. else:
  130. value = 9
  131. return value
  132. def map_turbidity(turbidity):
  133. turbidity = int(turbidity)
  134. if turbidity >= 0 and turbidity < 10:
  135. value = 1
  136. if turbidity >= 10 and turbidity <20:
  137. value = 2
  138. if turbidity >= 20 and turbidity < 50:
  139. value = 3
  140. else:
  141. value = 4
  142. return value
  143. def mean_absolute_percentage_error(y_true, y_pred):
  144. y_true, y_pred = np.array(y_true), np.array(y_pred)
  145. return np.mean(np.abs((y_true - y_pred) / y_true)) * 100
  146. def model_load(path, id):
  147. path_id = ''.join([path, id, '.pk'])
  148. with open(path_id, 'rb') as f:
  149. obj = pickle.load(f)
  150. return obj
  151. def dose_cal(in_flow, nh4, coef):
  152. dose_value = in_flow * (4.58 * (nh4 * coef - 6) + 1.15 * 1.8 * (1 + 2.17)) / 1000 / 38 / 0.5 * 100 + 160
  153. return dose_value/4
  154. class TN_model:
  155. def __init__(self, clf):
  156. self.clf = clf
  157. def mypredict(self, jsonData):
  158. try:
  159. # data = json.loads(jsonData)
  160. data = jsonData
  161. in_flow = float(data['lfgawqyq_plc3_Tag17'])
  162. in_tn = float(data['lfgawqyq_plc3_Tag22'])
  163. except Exception as e:
  164. logger.get_log().info("传入的json串不正确\n")
  165. fe_tn = [in_flow, in_tn]
  166. fe_tn = np.array(fe_tn).reshape(1, -1)
  167. src_columns = ['in_flow', 'in_tn']
  168. result = self.clf.predict(pd.DataFrame(fe_tn, columns=src_columns))
  169. r = float(result[0])
  170. r = Tool.set_precision(r, 3)
  171. if r<0:
  172. r=0
  173. return r
  174. class COD_model:
  175. def __init__(self, clf):
  176. self.clf = clf
  177. def mypredict(self, jsonData):
  178. try:
  179. # data = json.loads(jsonData)
  180. data = jsonData
  181. in_flow = float(data['lfgawqyq_plc3_Tag17'])
  182. in_cod = float(data['lfgawqyq_plc3_Tag20'])
  183. except Exception as e:
  184. logger.get_log().info("传入的json串不正确\n")
  185. fe_cod = [in_flow, in_cod]
  186. fe_cod = np.array(fe_cod).reshape(1, -1)
  187. src_columns = ['in_flow','in_cod']
  188. result = self.clf.predict(pd.DataFrame(fe_cod, columns=src_columns))
  189. r = float(result[0])
  190. r = Tool.set_precision(r, 3)
  191. if r<0:
  192. r=0
  193. return r
  194. app = Flask(__name__)
  195. @app.route('/<name>', methods=['POST'])
  196. def predict(name):
  197. paths = ['water_quality']
  198. ip = request.remote_addr
  199. data = request.get_json()
  200. data_json = data
  201. # data_json = json.dumps(data)
  202. logger.get_log().info('receive from %s = %s ' % (ip, data))
  203. if str(name) in paths:
  204. model_path = ""
  205. obj_cod = Tool.model_load(model_path, cod_model)
  206. obj_tn = Tool.model_load(model_path, tn_model)
  207. result_cod = obj_cod.mypredict(data_json)
  208. result_tn = obj_tn.mypredict(data_json)
  209. in_flow = data_json['lfgawqyq_plc3_Tag17']
  210. in_tn = data_json['lfgawqyq_plc3_Tag22']
  211. in_cod = data_json['lfgawqyq_plc3_Tag20']
  212. n1_nh4 = data_json['lfgawqyq_plc10_Tag50']
  213. n2_nh4 = data_json['lfgawqyq_plc10_Tag52']
  214. s1_nh4 = data_json['lfgawqyq_plc10_Tag51']
  215. s2_nh4 = data_json['lfgawqyq_plc10_Tag53']
  216. out_tn = data_json['lfgawqyq_plc10_Tag45']
  217. out_cod = data_json['lfgawqyq_plc10_Tag43']
  218. n1_dose = Tool.dose_cal(in_flow, n1_nh4, 0.9)
  219. n2_dose = Tool.dose_cal(in_flow, n2_nh4, 0.95)
  220. s1_dose = Tool.dose_cal(in_flow, s1_nh4, 0.9)
  221. s2_dose = Tool.dose_cal(in_flow, s2_nh4, 0.95)
  222. result=[Tool.set_precision(n1_dose, 3), Tool.set_precision(n2_dose, 3),
  223. Tool.set_precision(3, s1_dose), Tool.set_precision(s2_dose, 3),
  224. Tool.set_precision(result_cod, 3), Tool.set_precision(result_tn, 3)]
  225. logger.get_log().info('return to %s = %s\n ' % (ip, result))
  226. return jsonify(result)
  227. @app.route('/update_water_quality')
  228. def calc():
  229. data = Flask_water_server.calc_water_quality()
  230. print('calculate water quality')
  231. return data,200
  232. @app.route('/')
  233. def home():
  234. return 'Hello, World!'
  235. if __name__ == "__main__":
  236. cf = configparser.ConfigParser()
  237. parent_dir = os.path.dirname(os.path.abspath(__file__))
  238. cf.read("config.ini")
  239. server_port = cf.get("config", "port")
  240. cod_model = cf.get("config", "cod_model")
  241. tn_model = cf.get("config", "tn_model")
  242. logpath = cf.get("config", "logpath")
  243. logname = cf.get("config", "filename")
  244. logger = Logger(__name__, logpath, logname)
  245. logger.get_log().info("服务启动\n")
  246. pywsgi.WSGIServer(('0.0.0.0', int(server_port)), app).serve_forever()