#!/usr/bin/python37 # coding: utf-8 """ @version: 1.0 @software: PyCharm @file: quality_server.py @time: 2024/9/10 12:18 """ import threading from sched import scheduler import numpy as np import pandas as pd import os import time import json import pickle import configparser from decimal import Decimal from PIL import ImageFile ImageFile.LOAD_TRUNCATED_IMAGES = True import Flask_water_server from flask import Flask, request, jsonify from flask_cors import CORS from gevent import pywsgi, monkey monkey.patch_all() import logging np.set_printoptions(threshold = 1000000000, linewidth=1245) class Logger: def __init__(self,loggername, logpath, filename): self.logger = logging.getLogger(loggername) self.logger.setLevel(logging.INFO) log_path = logpath # 指定文件输出路径,logs是个文件夹,要加上/ logname = log_path + filename self.fh = logging.FileHandler(logname, encoding = 'utf-8') self.fh.setLevel(logging.INFO) self.ch = logging.StreamHandler() self.ch.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s') self.fh.setFormatter(formatter) self.ch.setFormatter(formatter) self.logger.addHandler(self.fh) self.logger.addHandler(self.ch) def get_log(self): return self.logger def get_fh(self): return self.fh def log_clear(self): self.logger.handlers.clear() class Tool: def set_precision(num, digit): precision_str = '{:.%d' % (digit) + 'f}' dec_val = precision_str.format(Decimal(num)) return float(dec_val) def mean_absolute_percentage_error(y_true, y_pred): y_true, y_pred = np.array(y_true), np.array(y_pred) return np.mean(np.abs((y_true - y_pred) / y_true)) * 100 def month_of_year(ts): # ts = str(ts) t = time.strptime(ts, "%Y-%m-%d %H:%M") tm_mon = t.tm_mon return tm_mon def day_of_month(ts): # ts = str(ts) t = time.strptime(ts, "%Y-%m-%d %H:%M") tm_mday = t.tm_mday return tm_mday def hour_of_day(ts): t = time.strptime(ts, "%Y-%m-%d %H:%M") tm_hour = t.tm_hour return tm_hour def min_of_hour(ts): t = time.strptime(ts, "%Y-%m-%d %H:%M") tm_min = t.tm_min return tm_min def five_min_of_hour(ts): t = time.strptime(ts, "%d/%m/%Y %H:%M:%S") tm_min = t.tm_min if tm_min % 5 == 0: return 1 else: return 0 def day_of_week(ts): t = time.strptime(ts, "%Y-%m-%d %H:%M") tm_day = t.tm_wday return tm_day def week_of_year(day): week = int((day - 1) / 7) + 1 return week def time_str(str): return str[:-3] def time_format(ts): t = time.strptime(ts, "%d/%m/%Y %H:%M") tm_year = t.tm_year tm_month = t.tm_mon tm_day = t.tm_mday tm_hour = t.tm_hour tm_min = t.tm_min return '%s-%s-%s %s:%s' %(tm_year, tm_month, tm_day, tm_hour, tm_min) def map_season(month): # print(month) month = int(month) if month >= 12 or month <= 2: value = 1 if month >= 3 and month <= 5: value = 2 if month >= 6 and month <= 8: value = 3 else: value = 4 return value def map_weather(stat): # print(month) if stat =='晴': value = 1 if stat =='阴': value = 2 if stat =='小雨': value = 3 if stat =='中雨': value = 4 if stat =='大雨': value = 5 if stat =='暴雨': value = 6 if stat =='阵雨': value = 7 if stat =='多云': value = 8 else: value = 9 return value def map_turbidity(turbidity): turbidity = int(turbidity) if turbidity >= 0 and turbidity < 10: value = 1 if turbidity >= 10 and turbidity <20: value = 2 if turbidity >= 20 and turbidity < 50: value = 3 else: value = 4 return value def mean_absolute_percentage_error(y_true, y_pred): y_true, y_pred = np.array(y_true), np.array(y_pred) return np.mean(np.abs((y_true - y_pred) / y_true)) * 100 def model_load(path, id): path_id = ''.join([path, id, '.pk']) with open(path_id, 'rb') as f: obj = pickle.load(f) return obj def dose_cal(in_flow, nh4, coef): dose_value = in_flow * (4.58 * (nh4 * coef - 6) + 1.15 * 1.8 * (1 + 2.17)) / 1000 / 38 / 0.5 * 100 + 160 return dose_value/4 class TN_model: def __init__(self, clf): self.clf = clf def mypredict(self, jsonData): try: # data = json.loads(jsonData) data = jsonData in_flow = float(data['lfgawqyq_plc3_Tag17']) in_tn = float(data['lfgawqyq_plc3_Tag22']) except Exception as e: logger.get_log().info("传入的json串不正确\n") fe_tn = [in_flow, in_tn] fe_tn = np.array(fe_tn).reshape(1, -1) src_columns = ['in_flow', 'in_tn'] result = self.clf.predict(pd.DataFrame(fe_tn, columns=src_columns)) r = float(result[0]) r = Tool.set_precision(r, 3) if r<0: r=0 return r class COD_model: def __init__(self, clf): self.clf = clf def mypredict(self, jsonData): try: # data = json.loads(jsonData) data = jsonData in_flow = float(data['lfgawqyq_plc3_Tag17']) in_cod = float(data['lfgawqyq_plc3_Tag20']) except Exception as e: logger.get_log().info("传入的json串不正确\n") fe_cod = [in_flow, in_cod] fe_cod = np.array(fe_cod).reshape(1, -1) src_columns = ['in_flow','in_cod'] result = self.clf.predict(pd.DataFrame(fe_cod, columns=src_columns)) r = float(result[0]) r = Tool.set_precision(r, 3) if r<0: r=0 return r app = Flask(__name__) @app.route('/', methods=['POST']) def predict(name): paths = ['water_quality'] ip = request.remote_addr data = request.get_json() data_json = data # data_json = json.dumps(data) logger.get_log().info('receive from %s = %s ' % (ip, data)) if str(name) in paths: model_path = "" obj_cod = Tool.model_load(model_path, cod_model) obj_tn = Tool.model_load(model_path, tn_model) result_cod = obj_cod.mypredict(data_json) result_tn = obj_tn.mypredict(data_json) in_flow = data_json['lfgawqyq_plc3_Tag17'] in_tn = data_json['lfgawqyq_plc3_Tag22'] in_cod = data_json['lfgawqyq_plc3_Tag20'] n1_nh4 = data_json['lfgawqyq_plc10_Tag50'] n2_nh4 = data_json['lfgawqyq_plc10_Tag52'] s1_nh4 = data_json['lfgawqyq_plc10_Tag51'] s2_nh4 = data_json['lfgawqyq_plc10_Tag53'] out_tn = data_json['lfgawqyq_plc10_Tag45'] out_cod = data_json['lfgawqyq_plc10_Tag43'] n1_dose = Tool.dose_cal(in_flow, n1_nh4, 0.9) n2_dose = Tool.dose_cal(in_flow, n2_nh4, 0.95) s1_dose = Tool.dose_cal(in_flow, s1_nh4, 0.9) s2_dose = Tool.dose_cal(in_flow, s2_nh4, 0.95) result=[Tool.set_precision(n1_dose, 3), Tool.set_precision(n2_dose, 3), Tool.set_precision(3, s1_dose), Tool.set_precision(s2_dose, 3), Tool.set_precision(result_cod, 3), Tool.set_precision(result_tn, 3)] logger.get_log().info('return to %s = %s\n ' % (ip, result)) return jsonify(result) @app.route('/update_water_quality') def calc(): data = Flask_water_server.calc_water_quality() print('calculate water quality') return data,200 @app.route('/') def home(): return 'Hello, World!' if __name__ == "__main__": cf = configparser.ConfigParser() parent_dir = os.path.dirname(os.path.abspath(__file__)) cf.read("config.ini") server_port = cf.get("config", "port") cod_model = cf.get("config", "cod_model") tn_model = cf.get("config", "tn_model") logpath = cf.get("config", "logpath") logname = cf.get("config", "filename") logger = Logger(__name__, logpath, logname) logger.get_log().info("服务启动\n") pywsgi.WSGIServer(('0.0.0.0', int(server_port)), app).serve_forever()