コード例 #1
0
 def handle_message(self, msgobj):
     global devices
     global process_list
     cmd = msgobj.get("cmd")
     if not cmd:
         print(shgutil.current_time(), "指令未找到",
               json.dumps(msgobj, ensure_ascii=False))
         error_msg = self.para_factory.log(
             "指令未找到: " + json.dumps(msgobj, ensure_ascii=False), 2)
         self.pipeline.putTask(json.dumps(error_msg, ensure_ascii=False))
         return False
     handler = self.switchDic.get(cmd)
     if not handler:
         print(shgutil.current_time(), "指令不支持")
         error_msg = self.para_factory.log("指令不支持")
         self.pipeline.putTask(json.dumps(error_msg, ensure_ascii=False))
         return False
     try:
         ret = handler(msgobj)
         print(shgutil.current_time(), "消息 %s 处理结果 %s" % (cmd, ret))
         return ret
     except Exception as err:
         print(shgutil.current_time(), "指令处理异常", err)
         traceback.print_exc()
         error_msg = self.para_factory.log("指令处理异常: " + str(err))
         self.pipeline.putTask(json.dumps(error_msg, ensure_ascii=False))
         return False
コード例 #2
0
def on_connect(mqttClient, obj, flags, rc):
    mqttClient.connected = True  # 设置连接标志
    print(shgutil.current_time(), "云端" if mqttClient.insType == 1 else "本地",
          "mqtt连接已建立")
    if mqttClient.subscribeList and len(mqttClient.subscribeList) > 0:
        for topic in mqttClient.subscribeList:
            if topic:
                mqttClient.subscribe(topic, 0)
                print(shgutil.current_time(),
                      "云端" if mqttClient.insType == 1 else "本地", "mqtt提交订阅",
                      topic)
    # 发送上线通知
    online_para = para_factory_local.online()
    content = json.dumps(online_para, ensure_ascii=False)
    mqttClient.send(content)
コード例 #3
0
def init_mqtt_cloud():
    global config_data
    global mqtt_client_to_cloud
    global send_pipeline_thread
    global para_factory
    # 云端的mqtt, 默认以websocket协议连接
    #config_data["mqtt"]["topicLocal"] = str(uuid.uuid1())
    mqttConfig = config_data["mqtt"]
    mqtt_client_to_cloud = mqttclient.MqttClient(
        mqttConfig["host"],
        mqttConfig["port"],
        mqttConfig["username"],
        mqttConfig["password"],
        mqttConfig["topicServer"],
        insType=1,
        subscribeList=[mqttConfig["topicLocal"]],
        para_factory=para_factory)
    # 启动mqtt连接, 并设置服务下线的遗嘱消息
    willMsg = json.dumps(para_factory.will_msg, ensure_ascii=False)
    mqtt_client_to_cloud.start(on_message_from_server, willMsg)
    # 启动消息发送流水线线程
    send_pipeline_thread = mqttpipe.SendPipeLineThread(config_data,
                                                       mqtt_client_to_cloud)
    send_pipeline_thread.setDaemon(True)
    send_pipeline_thread.start()
    print(shgutil.current_time(), "发送线程已启动")
    # 发送推送服务启动通知
    online_msg = para_factory.online()
    send_pipeline_thread.putTask(json.dumps(online_msg, ensure_ascii=False))
コード例 #4
0
def main():
    global config_data
    global mqtt_client_to_cloud
    global pid
    global send_pipeline_thread
    global heartbeat_thread
    global status_thread
    global msg_handler
    global para_factory
    global udp_server
    # sys.excepthook = shgutil.globalExceptHook
    print(shgutil.current_time(),
          "版权所属: 飞牛智能科技(南京)有限公司, www.fcow-it.com, 2018~2019")
    pid = os.getpid()
    print(shgutil.current_time(), "进程号: ", pid)
    # Reading config from file
    print(shgutil.current_time(), "读取配置")
    config_data = shgutil.read_config()
    config_data["running"] = True
    config_data["cwd"] = os.path.abspath('.')
    config_data["vcwd"] = os.path.abspath('.')
    # 初始化参数工厂
    para_factory = parafactory.ParaFactory(config_data)
    # 连接云端mqtt服务器
    print(shgutil.current_time(), "开始建立通信信道")
    init_mqtt_cloud()
    print(shgutil.current_time(), "通信信道连接结束")
    # 初始化消息处理对象
    msg_handler = msghandler.MsgHandler(config_data, send_pipeline_thread,
                                        para_factory)
    # 启动心跳线程
    heartbeat_thread = mqttpipe.MqttHeartbeatThread(config_data,
                                                    send_pipeline_thread,
                                                    para_factory,
                                                    mqtt_client_to_cloud)
    heartbeat_thread.setDaemon(True)
    heartbeat_thread.start()
    print(shgutil.current_time(), "心跳线程已启动")
    # 启动状态线程
    status_thread = mqttpipe.DeviceStatusReportThread(config_data,
                                                      send_pipeline_thread,
                                                      para_factory,
                                                      mqtt_client_to_cloud)
    status_thread.setDaemon(True)
    status_thread.start()
    print(shgutil.current_time(), "状态报告线程已启动")
    # 使用一个UDP server来阻塞主线程
    print(shgutil.current_time(), "阻塞主线程")
    host, port = "localhost", 50000
    udp_server = socketserver.UDPServer((host, port), shgutil.MyTCPHandler)
    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    udp_server.serve_forever()
    config_data["running"] = False
    # close mqtt
    mqtt_client_to_cloud.stop()
コード例 #5
0
def on_message_from_server(client, obj, msg):
    global msg_handler
    global config_data
    if not msg_handler:
        return False
    msgstr = str(msg.payload, encoding='utf-8')
    print(shgutil.current_time(), "云端mqtt接收: ", msgstr)
    # 过滤非法消息
    try:
        msgobj = json.loads(msgstr, encoding="utf-8")
        if msgobj["data"]["cmd"] == constants.EXIT:
            print(shgutil.current_time(), "退出指令")
            config_data["running"] = False
            sys.exit(0)
            shgutil.kill_proc_force(pid)
            return True
        return msg_handler.handle_message(msgobj)
    except Exception as err:
        print(shgutil.current_time(), "云端mqtt分析异常", err)
        traceback.print_exc()
        return False
コード例 #6
0
def do_cmd_one(cmd, config_data, pipeline, para_factory):
    print(shgutil.current_time(), "执行: ", cmd)
    process = subprocess.Popen(cmd,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.STDOUT,
                               bufsize=1,
                               env=os.environ,
                               shell=True,
                               cwd=config_data["vcwd"])
    while config_data["running"] and process.poll() is None:
        line = process.stdout.readline()
        if line == b'':
            if process.poll() is not None:
                break
        content = str(line, encoding="utf-8")
        print(shgutil.current_time(), content)
        if not cmd.startswith("cd "):
            log_msg = para_factory.log(content, 0)
            pipeline.putTask(json.dumps(log_msg, ensure_ascii=False))
    output = process.communicate()
    if output:
        content = str(output[0], encoding="utf-8")
        print(shgutil.current_time(), content)
        if not cmd.startswith("cd "):
            log_msg = para_factory.log(content, 0)
            pipeline.putTask(json.dumps(log_msg, ensure_ascii=False))
    if cmd.startswith("cd "):
        target_dir = cmd[3:]
        if target_dir != ".":
            if target_dir == "..":
                target_dir = os.path.abspath(
                    os.path.join(config_data["vcwd"], ".."))
            if not os.path.exists(target_dir):
                target_dir = config_data["vcwd"] + "/" + target_dir
            config_data["vcwd"] = target_dir
            shgutil.write_config(config_data)
        log_msg = para_factory.log(config_data["vcwd"], 0)
        pipeline.putTask(json.dumps(log_msg, ensure_ascii=False))
    print(shgutil.current_time(), "指令执行结束")
    return True
コード例 #7
0
 def do_cmd(self, msgobj, alone=True, restart=False):
     print(shgutil.current_time(), "执行指令")
     try:
         cmd = msgobj.get("data").get("cmd")
         if not cmd:
             print(shgutil.current_time(), "指令缺失")
             error_msg = self.para_factory.log("指令缺失", 2)
             self.pipeline.putTask(json.dumps(error_msg,
                                              ensure_ascii=False))
             return False
         if cmd in unsupport_cmds:
             print(shgutil.current_time(), "指令不支持")
             error_msg = self.para_factory.log("指令不支持: ", 2)
             self.pipeline.putTask(json.dumps(error_msg,
                                              ensure_ascii=False))
             return False
         # 执行
         if not os.path.exists(self.config_data["vcwd"]):
             self.config_data["vcwd"] = os.getcwd()
         if cmd.startswith("../"):
             pdir = os.path.abspath(
                 os.path.join(self.config_data["vcwd"], "..")) + "/"
             cmd = cmd.replace("../", pdir)
         elif cmd.startswith("./"):
             cmd = cmd.replace("../", self.config_data["vcwd"] + "/")
         # 创建线程02,指定参数,注意逗号不要少,否则不是一个tuple
         thread_02 = Thread(target=do_cmd_one,
                            args=(cmd, self.config_data, self.pipeline,
                                  self.para_factory))
         thread_02.setDaemon(True)
         thread_02.start()
         return True
     except Exception as err:
         print(shgutil.current_time(), "执行指令异常", err)
         traceback.print_exc()
         error_msg = self.para_factory.log("执行指令异常: " + str(err), 2)
         self.pipeline.putTask(json.dumps(error_msg, ensure_ascii=False))
         return False
コード例 #8
0
 def run(self):
     print(shgutil.current_time(), "状态报告线程启动")
     while self.config_data.get("running"):
         # 睡眠3秒
         itv = self.config_data["statusReportInterval"]
         if not itv or itv < 1:
             itv = 1
         print(shgutil.current_time(), "等待", itv)
         time.sleep(itv)
         # 发送报告
         try:
             if self.config_data.get("reportStatus"):
                 status_info = self.para_factory.report_status()
                 status_info_string = json.dumps(status_info,
                                                 ensure_ascii=False)
                 self.pipeline.putTask(status_info_string)
             else:
                 print(shgutil.current_time(), "配置不发送状态")
         except Exception as err:
             print(shgutil.current_time(), "状态报告线程异常: ", err)
             traceback.print_exc()
             time.sleep(1)
     print(shgutil.current_time(), "状态报告线程退出")
コード例 #9
0
 def run(self):
     print(shgutil.current_time(), "心跳线程启动")
     heartbeat_para = self.para_factory.heartbeat()
     while self.config_data.get("running"):
         # 睡眠10秒
         itv = self.config_data["heartbeatInterval"]
         if not itv or itv < 1:
             itv = 1
         time.sleep(itv)
         # 发送心跳
         try:
             if self.config_data.get("heartbeat"):
                 heartbeat_para["data"]["n"] = parafactory.get_counter()
                 heartbeat_string = json.dumps(heartbeat_para,
                                               ensure_ascii=False)
                 self.pipeline.putTask(heartbeat_string)
             if self.config_data.get("debug"):
                 print(shgutil.current_time(), "消息队列长度: ",
                       self.pipeline.qsize())
         except Exception as err:
             print(shgutil.current_time(), "心跳线程异常: ", err)
             traceback.print_exc()
     print(shgutil.current_time(), "心跳线程退出")
コード例 #10
0
 def send(self, content, topic=None, qos=1, retain=False):
     if not content:
         return None
     #if not self.mqttClient.connected:
     #    print(shgutil.current_time(), "mqtt无发送, 发送任务取消")
     try:
         if topic is None:
             self.mqttClient.publish(self.serverTopic, content, qos, retain)
         else:
             self.mqttClient.publish(topic, content, qos, retain)
         return True
     except Exception as err:
         print(shgutil.current_time(), "mqtt发送异常1", err)
     return False
コード例 #11
0
 def run(self):
     print(shgutil.current_time(), "发送线程启动")
     while self.config_data.get("running"):
         # 睡眠20毫秒
         time.sleep(0.02)
         if self.sendQueue.empty():
             continue
         if not self.mclient:
             continue
         if not self.mclient.connected():
             continue
         try:
             # 取出一个发送任务
             task = self.sendQueue.get()
             # 执行发送
             if task:
                 self.mclient.send(task[1], task[0],
                                   self.config_data["mqtt"]["qosSend"])
                 if self.config_data.get("debug"):
                     print(shgutil.current_time(), "[DEBUG]发送任务", task[1])
         except Exception as err:
             print(shgutil.current_time(), "发送异常: ", err)
             traceback.print_exc()
     print(shgutil.current_time(), "发送线程退出")
コード例 #12
0
                                                      para_factory,
                                                      mqtt_client_to_cloud)
    status_thread.setDaemon(True)
    status_thread.start()
    print(shgutil.current_time(), "状态报告线程已启动")
    # 使用一个UDP server来阻塞主线程
    print(shgutil.current_time(), "阻塞主线程")
    host, port = "localhost", 50000
    udp_server = socketserver.UDPServer((host, port), shgutil.MyTCPHandler)
    # Activate the server; this will keep running until you
    # interrupt the program with Ctrl-C
    udp_server.serve_forever()
    config_data["running"] = False
    # close mqtt
    mqtt_client_to_cloud.stop()


# 执行main函数
if __name__ == '__main__':
    try:
        main()
    except Exception as err:
        print(shgutil.current_time(), "[主]执行异常, 系统退出", err)
        traceback.print_exc()
        try:
            config_data["running"] = False
            udp_server.shutdown()
            mqtt_client_to_cloud.stop()
        finally:
            sys.exit(-255)
コード例 #13
0
def on_disconnect(mqttClient, userdata, rc):
    mqttClient.connected = False  # 设置连接标志
    print(shgutil.current_time(), "云端" if mqttClient.insType == 1 else "本地",
          "mqtt连接断开!")
コード例 #14
0
def on_log(mqttClient, obj, level, string):
    print(shgutil.current_time(), "云端" if mqttClient.insType == 1 else "本地",
          "mqtt日志", string)
コード例 #15
0
def on_subscribe(mqttClient, obj, mid, granted_qos):
    print(shgutil.current_time(), "云端" if mqttClient.insType == 1 else "本地",
          "订阅成功")
コード例 #16
0
def on_publish(mqttClient, obj, mid):
    print(shgutil.current_time(), "云端" if mqttClient.insType == 1 else "本地",
          "发送成功")
コード例 #17
0
def on_message(mqttClient, obj, msg):
    print(shgutil.current_time(), "云端" if mqttClient.insType == 1 else "本地",
          "mqtt接收: ", str(msg.payload, encoding='utf-8'))