From 0bdbeb9cf74b36411aff007bc6e9fc12d032fb3d Mon Sep 17 00:00:00 2001
From: xyj <10908227994@qq.com>
Date: Mon, 22 Jan 2024 18:01:03 +0800
Subject: [PATCH] first
---
.idea/inspectionProfiles/Project_Default.xml | 33 +++
.../inspectionProfiles/profiles_settings.xml | 6 +
.idea/misc.xml | 7 +
.idea/modules.xml | 8 +
.idea/vcs.xml | 6 +
.idea/workspace.xml | 237 ++++++++++++++++++
.idea/xumu_iot.iml | 12 +
MQTT.py | 86 +++++++
bash/start_push_stream.sh | 2 +
bash/stop_push_stream.sh | 2 +
bash/stream.sh | 3 +
conf/common/mqtt.conf | 10 +
conf/common/push_stream.conf | 9 +
conf/device/device.conf | 10 +
conf/example/supervisord.conf | 40 +++
conf/tmp/device_name | 1 +
config.py | 44 ++++
git_push.sh | 5 +
git_update.sh | 9 +
requirements.txt | 2 +
tool.py | 92 +++++++
21 files changed, 624 insertions(+)
create mode 100644 .idea/inspectionProfiles/Project_Default.xml
create mode 100644 .idea/inspectionProfiles/profiles_settings.xml
create mode 100644 .idea/misc.xml
create mode 100644 .idea/modules.xml
create mode 100644 .idea/vcs.xml
create mode 100644 .idea/workspace.xml
create mode 100644 .idea/xumu_iot.iml
create mode 100644 MQTT.py
create mode 100755 bash/start_push_stream.sh
create mode 100755 bash/stop_push_stream.sh
create mode 100644 bash/stream.sh
create mode 100644 conf/common/mqtt.conf
create mode 100644 conf/common/push_stream.conf
create mode 100644 conf/device/device.conf
create mode 100644 conf/example/supervisord.conf
create mode 100644 conf/tmp/device_name
create mode 100644 config.py
create mode 100755 git_push.sh
create mode 100755 git_update.sh
create mode 100644 requirements.txt
create mode 100755 tool.py
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..53670f4
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..b9b36bf
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..90821fa
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..257c4a7
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,237 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ "associatedIndex": 3
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1702028845497
+
+
+ 1702028845497
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/xumu_iot.iml b/.idea/xumu_iot.iml
new file mode 100644
index 0000000..9e256bc
--- /dev/null
+++ b/.idea/xumu_iot.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MQTT.py b/MQTT.py
new file mode 100644
index 0000000..b28ea7a
--- /dev/null
+++ b/MQTT.py
@@ -0,0 +1,86 @@
+import time
+
+import paho.mqtt.client as mqtt
+
+from tool import *
+
+from config import broker, port, subscribe_topic, username, password, info_topic
+
+
+def valid(msg, client):
+ origin_data = json.loads(msg.payload.decode('utf-8'))
+ if 'msg' not in origin_data:
+ client.publish(info_topic, payload=publish_payload(code=404, msg="msg must be supplied"), qos=0)
+ return False
+ return True
+
+
+class MQTTClient:
+ def __init__(self, broker, port, topic, username, password):
+ self.broker = broker
+ self.port = port
+ self.topic = topic
+ self.username = username
+ self.password = password
+ # 千万不要指定client_id 不然死翘翘
+ self.client = mqtt.Client(client_id=subscribe_topic)
+ self.client.username_pw_set(self.username, self.password)
+ self.client.on_connect = self.on_connect
+ self.client.on_message = self.on_message
+
+ def on_connect(self, client, userdata, flags, rc):
+ if rc == 0:
+ self.client.subscribe(self.topic)
+ client.publish(info_topic, payload=publish_payload(code=200, msg='成功订阅' + self.topic),
+ qos=0)
+ # 关闭摄像机电
+ subprocess.Popen(['sudo /usr/bin/python close_led.py'], shell=True)
+ # 关闭LED灯
+ subprocess.Popen(['sudo /usr/bin/python close_blue_led.py'], shell=True)
+
+ def on_message(self, client, userdata, msg):
+ if not valid(msg, client):
+ return
+ try:
+ origin_data = json.loads(msg.payload.decode('utf-8'))
+ data = origin_data["msg"]
+ if data == "push_stream":
+ # 启动推流视频
+ push_stream(client)
+ elif data == "close_stream":
+ # 关闭推流视频
+ close_stream(client)
+ elif data == "exec":
+ # 执行命令
+ exec_sh(msg, client)
+ elif data == "update":
+ # git更新项目和配置文件
+ update(client)
+ elif data == "reload":
+ # 重启配置
+ reload(client)
+ elif data == "status":
+ # 查看运行状态
+ get_status(client)
+ else:
+ # 错误类型
+ client.publish(info_topic, payload=publish_payload(code=404, msg='No Such Msg Type'), qos=0)
+ except Exception as e:
+ pass
+
+ def start(self):
+ self.client.connect(self.broker, self.port)
+
+
+if __name__ == '__main__':
+ # MQTT客户端
+ MQTT = MQTTClient(broker, port, subscribe_topic, username, password)
+ # 循环连接
+ while True:
+ try:
+ MQTT.start()
+ # 阻塞监听
+ MQTT.client.loop_forever()
+ except Exception as e:
+ # 异常等待时间在进行连接
+ time.sleep(30)
diff --git a/bash/start_push_stream.sh b/bash/start_push_stream.sh
new file mode 100755
index 0000000..6b949e7
--- /dev/null
+++ b/bash/start_push_stream.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+supervisorctl start push_stream
diff --git a/bash/stop_push_stream.sh b/bash/stop_push_stream.sh
new file mode 100755
index 0000000..855eaeb
--- /dev/null
+++ b/bash/stop_push_stream.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+supervisorctl stop push_stream
diff --git a/bash/stream.sh b/bash/stream.sh
new file mode 100644
index 0000000..d39990b
--- /dev/null
+++ b/bash/stream.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+device_name=`cat /home/pi/device_name`
+/usr/bin/ffmpeg -rtsp_transport tcp -re -i "rtsp://admin:lihai123@192.168.0.123:554/cam/realmonitor?channel=1&subtype=0" -c copy -f rtsp -rtsp_transport tcp rtsp://47.108.186.87:554/live/$device_name
\ No newline at end of file
diff --git a/conf/common/mqtt.conf b/conf/common/mqtt.conf
new file mode 100644
index 0000000..29c3fb0
--- /dev/null
+++ b/conf/common/mqtt.conf
@@ -0,0 +1,10 @@
+[program:__mqtt__]
+directory=/home/pi/lot_manager
+command=/usr/bin/python MQTT.py
+user=pi
+autostart=true
+autorestart=true
+redirect_stderr=true
+stopsignal=TERM
+stopasgroup=True
+priority=1
diff --git a/conf/common/push_stream.conf b/conf/common/push_stream.conf
new file mode 100644
index 0000000..78c3fb2
--- /dev/null
+++ b/conf/common/push_stream.conf
@@ -0,0 +1,9 @@
+[program:push_stream]
+directory=/home/pi/lot_manager/bash
+command=/usr/bin/bash stream.sh
+user=pi
+autostart=true
+autorestart=true
+redirect_stderr=true
+stopsignal=TERM
+stopasgroup=True
\ No newline at end of file
diff --git a/conf/device/device.conf b/conf/device/device.conf
new file mode 100644
index 0000000..ba4a17a
--- /dev/null
+++ b/conf/device/device.conf
@@ -0,0 +1,10 @@
+# 设备1-32G
+# 编号
+[xumu_camera_1]
+# 订阅的控制主题,必须和系统设置的相同
+subscribe_topic=xumu_camera_1
+# 发布消息的主题
+publish_topic=camera_1
+info_topic=info_xumu_camera_1
+username=lihai_lot_land1
+password=lihai_lot_land1
\ No newline at end of file
diff --git a/conf/example/supervisord.conf b/conf/example/supervisord.conf
new file mode 100644
index 0000000..71e1528
--- /dev/null
+++ b/conf/example/supervisord.conf
@@ -0,0 +1,40 @@
+; supervisor config file
+
+[unix_http_server]
+file=/var/run/supervisor.sock ; (the path to the socket file)
+chmod=0777 ; sockef file mode (default 0700)
+
+[supervisord]
+logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
+pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
+childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
+user=root
+; the below section must remain in the config file for RPC
+; (supervisorctl/web interface) to work, additional interfaces may be
+; added by defining them in separate rpcinterface: sections
+[rpcinterface:supervisor]
+supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
+
+[supervisorctl]
+serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
+user=pi
+; The [include] section can just contain the "files" setting. This
+; setting can list multiple files (separated by whitespace or
+; newlines). It can also contain wildcards. The filenames are
+; interpreted as relative to this file. Included files *cannot*
+; include files themselves.
+[inet_http_server]
+host = 127.0.0.1
+port = 9001
+[program:__mqtt__]
+directory=/home/pi/lot_manager
+command=/usr/bin/python MQTT.py
+user=pi
+autostart=true
+autorestart=true
+redirect_stderr=true
+stopsignal=TERM
+stopasgroup=True
+priority=1
+[include]
+files = /home/pi/lot_manager/conf/common/*.conf
diff --git a/conf/tmp/device_name b/conf/tmp/device_name
new file mode 100644
index 0000000..97bae99
--- /dev/null
+++ b/conf/tmp/device_name
@@ -0,0 +1 @@
+xumu_camera_1
\ No newline at end of file
diff --git a/config.py b/config.py
new file mode 100644
index 0000000..bc77ef9
--- /dev/null
+++ b/config.py
@@ -0,0 +1,44 @@
+import configparser
+
+import subprocess
+
+try:
+ p = subprocess.Popen(['cat /home/pi/device_name'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ # 设备名称,必须要有
+ device_name = out.decode('utf-8').strip()
+
+ # 读取配置
+ config = configparser.ConfigParser()
+ # 读取公共配置
+ config.read('conf/main/common.conf')
+ # 域名
+ broker = config.get("broker", "host")
+ # 端口,这里必须是int类型
+ port = config.getint("broker", "port")
+ # 录像地址
+ post_record_list_url = config.get("record", "post_record_list_url")
+ post_record_url = config.get("record", "post_record_url")
+
+ # 读取设备配置
+ config.read('conf/device/device.conf')
+ # 订阅的主题
+ subscribe_topic = config.get(device_name, "subscribe_topic")
+ # 发布数据的主题
+ publish_topic = config.get(device_name, "publish_topic")
+ # 发布信息的主题
+ info_topic = config.get(device_name, "info_topic")
+ # 用户
+ username = config.get(device_name, "username")
+ # 密码
+ password = config.get(device_name, "password")
+
+ # 特殊配置
+ config.read('conf/zhanguan/topic.conf')
+ zhanguan_device_name = config.get("device", "name")
+
+ # tool配置
+ mp4_path = '/home/pi/mp4'
+except Exception as e:
+ # print(e)
+ pass
diff --git a/git_push.sh b/git_push.sh
new file mode 100755
index 0000000..0799741
--- /dev/null
+++ b/git_push.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+set -e
+git add .
+git commit -m 'update'
+git push -f origin master
diff --git a/git_update.sh b/git_update.sh
new file mode 100755
index 0000000..762d4da
--- /dev/null
+++ b/git_update.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+set -e
+# git更新
+git pull origin master --force
+# 配置文件复制到supervisor管理
+# cp -r conf/common/*.conf /etc/supervisor/conf.d/
+# 更新配置文件
+supervisorctl reread
+supervisorctl update
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..e185e44
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,2 @@
+paho-mqtt~=1.6.1
+requests~=2.31.0
\ No newline at end of file
diff --git a/tool.py b/tool.py
new file mode 100755
index 0000000..85a9476
--- /dev/null
+++ b/tool.py
@@ -0,0 +1,92 @@
+import json
+import os
+import subprocess
+import threading
+
+import requests
+
+from config import mp4_path, post_record_list_url, post_record_url, info_topic
+
+
+# 统一返回
+def publish_payload(code, msg):
+ return json.dumps({
+ "code": code,
+ "msg": msg
+ }, ensure_ascii=False)
+
+
+def exception_handler(func):
+ def wrapper(*args, **kwargs):
+ try:
+ return func(*args, **kwargs)
+ except Exception as e:
+ print(f"函数{func.__name__}中发生了异常:{e}")
+
+ return wrapper
+
+
+def push_stream(client):
+ p = subprocess.Popen(['/bin/bash /home/pi/lot_manager/bash/start_push_stream.sh'],
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ output = out.decode('utf-8').strip()
+ client.publish(info_topic, payload=publish_payload(200, output), qos=0)
+
+
+def close_stream(client):
+ p = subprocess.Popen(['/bin/bash /home/pi/lot_manager/bash/stop_push_stream.sh'],
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ output = out.decode('utf-8').strip()
+ client.publish(info_topic, payload=publish_payload(code=200, msg=output), qos=0)
+
+
+def exec_sh(msg, client):
+ origin_data = json.loads(msg.payload.decode('utf-8'))
+ if 'data' not in origin_data:
+ client.publish(info_topic, payload=publish_payload(code=404, msg='data must be supplied'), qos=0)
+ return
+ cmd = origin_data["data"]
+ if cmd in ["supervisorctl stop __mqtt__",
+ "supervisorctl restart __mqtt__",
+ "supervisorctl stop all"]:
+ return
+ if cmd == "supervisorctl reload":
+ client.publish(info_topic, payload=publish_payload(code=200, msg='reloading'), qos=0)
+ subprocess.Popen([cmd], shell=True)
+ return
+ p = subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ output = out.decode('utf-8').strip()
+ client.publish(info_topic, payload=publish_payload(code=200, msg=output), qos=0)
+
+
+def get_status(client):
+ p = subprocess.Popen(['supervisorctl status'],
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ output = out.decode('utf-8').strip()
+ client.publish(info_topic, payload=publish_payload(code=200, msg=output), qos=0)
+
+
+def update(client):
+ p = subprocess.Popen(['/bin/bash /home/pi/lot_manager/git_update.sh'],
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ out, err = p.communicate()
+ output = out.decode('utf-8').strip()
+ client.publish(info_topic, payload=publish_payload(code=200, msg=output),
+ qos=0)
+
+
+def reload(client):
+ client.publish(info_topic, payload=publish_payload(200, "reloading"), qos=0)
+ subprocess.Popen(['supervisorctl reload'], shell=True)