123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- #!/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('/<name>', 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()
|