# !flask/bin/python import threading from threading import Thread from flask import Flask, jsonify, request from flask_socketio import SocketIO, emit, send # from gevent import pywsgi # from threading import Thread import os import sys import eventlet import time from utils.Tool import logger, config, traceback, PLC_Tool import service.DetectService as detect app = Flask(__name__) app.config['SECRET_KEY'] = 'VMiddleware' app.config['PROPAGATE_EXCEPTIONS'] = False app.config['JSON_AS_ASCII'] = False socketio = SocketIO(app) eventlet.monkey_patch() def responseMsg(code: int, msg: str, data): if code in [500, 412]: logger.error(msg) elif code == 417: logger.error("%s date:%s" % (msg, str(data))) elif code == 200: logger.info(msg) return jsonify({'code': code, 'msg': msg, "data": data}), 200 def restart_program(): time.sleep(2) logger.info("Restarting program...") python = sys.executable os.execl(python, python, *sys.argv) @app.errorhandler(404) def handle_not_found_error(error): return responseMsg(404, '请查阅接口文档,使用正确地址', {}), 404 @app.route('/') def hello(): # put application's code here return responseMsg(404, '请查阅接口文档,使用正确地址', {}), 404 @app.route('/api/report_open', methods=['POST']) def report_open(): try: requestData = request.json pound_no = requestData.get('pound_no', None) total_number_carriage = requestData.get('total_number_carriage', 0) pre_load = requestData.get('pre_load', []) # if pound_no is None: # return responseMsg(412, 'no pound_no', {}) # if not isinstance(pound_no, str): # return responseMsg(412, "pound_no should be a string", {}) # if pound_no != "": # return responseMsg(412, 'no pound_no', {}) # if isinstance(pound_no, str) and not pound_no.isdigit(): # return responseMsg(412, "pound_no should be a int and 0 < track <= 2", {}) # if not (0 < int(pound_no) <= 2): # return responseMsg(412, "pound_no should be a int and 0 < track <= 2", {}) code, msg, results = detect.report_open(pound_no, total_number_carriage, pre_load) return responseMsg(code, "开启PLC报表成功" if code == 200 else msg, results) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 @app.route('/api/report_close', methods=['POST']) def report_close(): try: requestData = request.json pound_no = requestData.get('pound_no', None) total_number_carriage = requestData.get('total_number_carriage', 0) code, msg, results = detect.report_close(pound_no, total_number_carriage) return responseMsg(code, "关闭PLC报表成功" if code == 200 else msg, results) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 @app.route('/api/read_config', methods=['GET']) def read_config(): try: return responseMsg(200, "读取成功", config.getConfig()) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 @app.route('/api/update_config', methods=['POST']) def update_config(): try: requestData = request.json option = requestData.get('option', "") value = requestData.get('value', "") msg = config.updateConfig(option, value) if msg != "": return responseMsg(412, msg, {}) return responseMsg(200, "修改配置项 {%s: %s} 成功!" % (option, value), {}) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 @app.route('/api/restart_VMiddleware', methods=['GET']) def restart_VMiddleware(): try: t = threading.Thread(target=restart_program) t.start() return responseMsg(200, "程序重启...", {}) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 @app.route('/test/write/tags', methods=['POST']) def write_tag(): plc = None try: requestData = request.json plcIp = requestData.get("plc_ip", None) plcSlot = requestData.get("slot", None) plcTags = requestData.get("tags", None) if plcIp is None: return responseMsg(412, 'no plc_ip', {}) # 412 没有传输plc_ip,直接返回 if plcSlot is None: return responseMsg(412, 'no slot', {}) # 412 没有传输slot,直接返回 if not isinstance(plcTags, dict): return responseMsg(412, 'tags格式异常', {}) # 412 没有按格式传输tags,直接返回 tags = list(zip(plcTags.keys(), plcTags.values())) if len(tags) == 0: return responseMsg(412, 'no tags', {}) # 412 没有传输tags,直接返回 if isinstance(plcSlot, str) and not plcSlot.isdigit(): plcSlot = 0 plc = PLC_Tool(plcIp, plcSlot) success, msg, results = plc.batch_write_tag(tags) if not success: return responseMsg(412, msg, {}) else: if success > 1: return responseMsg(417, msg, results) else: return responseMsg(200, "【测试功能】修改PLC标签值成功", results) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 finally: if plc is not None: plc.close() @app.route('/test/read/tags', methods=['GET']) def get_tag(): plc = None try: plcIp = request.args.get('plcIp', None) plcSlot = request.args.get('plcSlot', None) tag = request.args.get('tags', None) if plcIp is None: return responseMsg(412, 'no plc_ip', {}) # 412 没有传输plc_ip,直接返回 if plcSlot is None: return responseMsg(412, 'no slot', {}) # 412 没有传输slot,直接返回 if not tag.startswith('[') or not tag.endswith(']'): return responseMsg(412, 'tags格式异常', {}) # 412 没有按格式传输tags,直接返回 tags = (tag[1:-1].replace(' ', '')).split(',') if len(tags) < 1: return responseMsg(412, 'no tags', {}) # 412 没有传输tags,直接返回 if isinstance(plcSlot, str) and not plcSlot.isdigit(): plcSlot = 0 plc = PLC_Tool(plcIp, plcSlot) success, msg, results = plc.get_tags(tags) if not success: return responseMsg(412, msg, {}) else: return responseMsg(200, "【测试功能】读取PLC标签值成功", results) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 finally: if plc is not None: plc.close() @app.route('/test/get_token', methods=['GET']) def get_web_authorization(): try: code, msg, results = detect.get_web_token() return responseMsg(code, "【测试功能】获取token成功" if code == 200 else msg, results) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 @app.route('/test/upload_pinch_coal', methods=['POST']) def upload_pinch_coal(): try: requestData = request.json carriage_order = requestData.get("carriage_order", 0) pinch_coal = requestData.get("pinch_coal", -1) pound_no = requestData.get("pound_no", "") code, msg, results = detect.upload_pinch_coal(carriage_order, pinch_coal, pound_no) return responseMsg(code, "【测试功能】上传掐煤量成功" if code == 200 else msg, results) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 @app.route('/test/upload_gross_weight', methods=['POST']) def upload_gross_weight(): try: requestData = request.json carriage_order = requestData.get("carriage_order", 0) gross_weight = requestData.get("gross_weight", -1) pound_no = requestData.get("pound_no", "") code, msg, results = detect.upload_gross_weight(carriage_order, gross_weight, pound_no) return responseMsg(code, "【测试功能】上传装车毛重成功" if code == 200 else msg, results) except Exception as e: logger.error(traceback.format_exc()) return responseMsg(500, str(e), {}) # 500 内部错误。 @socketio.on('connect') def ws_connect(): print('Client connected') send('You are connected!', broadcast=True) @socketio.on('disconnect') def ws_disconnect(): print('Client disconnected') @socketio.on('message') def handle_message(msg): print('Received message: ' + msg) emit('message', "此接口已失效", broadcast=True) return # plc = PLC_Tool(config.ip_address, config.slot) # if msg == "open_report": # success, msg, results = plc.batch_write_tag( # [("JZ_B_WRITE[24].19", 1), ("AI.Car_festival2", 77), ("AI.load[1]", 77)]) # if not success: # emit('message', msg, broadcast=True) # else: # if success > 1: # logger.warn("%s result: %s" % (msg, str(results))) # emit('message', msg, broadcast=True) # else: # emit('message', "ok", broadcast=True) # elif msg == "close_report": # success, msg, results = plc.batch_write_tag( # [("JZ_B_WRITE[24].19", 0), ("AI.Car_festival2", 0), ("AI.load[1]", 0)]) # if not success: # return responseMsg(412, msg, {}) # else: # if success > 1: # logger.warn("%s result: %s" % (msg, str(results))) # emit('message', msg, broadcast=True) # else: # emit('message', "ok", broadcast=True) # else: # emit('message', msg, broadcast=True) @socketio.on('json') def handle_json(json): print('received json: ' + str(json)) # def read_plc_thread(): # socketio.detectService.interval_read_PLC_up_web() # # # def web_thread(): # socketio.run(app, host='0.0.0.0', port=config.serverPort, debug=False) def runWebSocket(): socketio.run(app, host='0.0.0.0', port=config.server_port, debug=False) def runReadPLC(): while True: try: detect.interval_read_PLC_up_web() except Exception as e: logger.error("数据 读取&上传 异常:%s", traceback.print_exc()) continue def writePLC_heartbeat(): while True: try: detect.writePLC_heartbeat() except Exception as e: logger.error("心跳(PLC时间读取)数据 读取&上传 异常:%s", traceback.print_exc()) continue finally: time.sleep(30) if __name__ == '__main__': # --- 运行方式一 --- # t = Thread(target=read_plc_thread) # t.daemon = True # t.start() # # server = pywsgi.WSGIServer(('0.0.0.0', serverPort), app) # server.serve_forever() # --- 运行方式二 --- pool = eventlet.GreenPool() pool.spawn_n(runWebSocket) pool.spawn_n(runReadPLC) pool.spawn_n(writePLC_heartbeat) pool.waitall()