add udp and manager
This commit is contained in:
40
README.md
40
README.md
@@ -14,7 +14,8 @@ upc_resent/
|
|||||||
│ ├── crond_tcp.py.tpl # TCP保活检查模板
|
│ ├── crond_tcp.py.tpl # TCP保活检查模板
|
||||||
│ ├── crond_udp.py.tpl # UDP保活检查模板
|
│ ├── crond_udp.py.tpl # UDP保活检查模板
|
||||||
│ ├── sender_tcp.py.tpl # TCP发送模块模板
|
│ ├── sender_tcp.py.tpl # TCP发送模块模板
|
||||||
│ └── sender_udp.py.tpl # UDP发送模块模板
|
│ ├── sender_udp.py.tpl # UDP发送模块模板
|
||||||
|
│ └── control.sh.tpl # 控制脚本模板
|
||||||
├── scripts/
|
├── scripts/
|
||||||
│ └── generate.py # 代码生成器
|
│ └── generate.py # 代码生成器
|
||||||
├── bin/ # 生成的监听服务文件(自动生成)
|
├── bin/ # 生成的监听服务文件(自动生成)
|
||||||
@@ -23,7 +24,7 @@ upc_resent/
|
|||||||
│ └── {device_id}.py # 各设备监听服务
|
│ └── {device_id}.py # 各设备监听服务
|
||||||
├── crond/ # 生成的保活检查文件(自动生成)
|
├── crond/ # 生成的保活检查文件(自动生成)
|
||||||
├── log/ # 日志目录
|
├── log/ # 日志目录
|
||||||
├── start.sh # 启动脚本(自动生成)
|
├── control.sh # 服务控制脚本(自动生成)
|
||||||
├── crontab.txt # 定时任务配置(自动生成)
|
├── crontab.txt # 定时任务配置(自动生成)
|
||||||
└── cutlog.sh # 日志清理脚本
|
└── cutlog.sh # 日志清理脚本
|
||||||
```
|
```
|
||||||
@@ -77,8 +78,17 @@ python3 scripts/generate.py
|
|||||||
### 3. 部署与启动
|
### 3. 部署与启动
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# 查看服务状态
|
||||||
|
./control.sh status
|
||||||
|
|
||||||
# 启动所有服务
|
# 启动所有服务
|
||||||
./start.sh
|
./control.sh start
|
||||||
|
|
||||||
|
# 停止所有服务
|
||||||
|
./control.sh stop
|
||||||
|
|
||||||
|
# 重启所有服务
|
||||||
|
./control.sh restart
|
||||||
|
|
||||||
# 配置定时任务(保活)
|
# 配置定时任务(保活)
|
||||||
crontab crontab.txt
|
crontab crontab.txt
|
||||||
@@ -273,6 +283,26 @@ python3 scripts/generate.py
|
|||||||
python3 scripts/generate.py --help
|
python3 scripts/generate.py --help
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 服务控制脚本
|
||||||
|
|
||||||
|
`control.sh` 提供以下命令:
|
||||||
|
|
||||||
|
| 命令 | 说明 |
|
||||||
|
|-----|------|
|
||||||
|
| `start` | 启动所有服务 |
|
||||||
|
| `stop` | 停止所有服务 |
|
||||||
|
| `restart` | 重启所有服务 |
|
||||||
|
| `status` | 查看服务运行状态 |
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./control.sh status
|
||||||
|
./control.sh start
|
||||||
|
./control.sh stop
|
||||||
|
./control.sh restart
|
||||||
|
```
|
||||||
|
|
||||||
## 日志文件
|
## 日志文件
|
||||||
|
|
||||||
| 文件 | 说明 |
|
| 文件 | 说明 |
|
||||||
@@ -284,7 +314,7 @@ python3 scripts/generate.py --help
|
|||||||
|
|
||||||
## 注意事项
|
## 注意事项
|
||||||
|
|
||||||
1. **不要直接修改** `bin/` 和 `crond/` 下的文件,这些文件是自动生成的,重新生成时会覆盖。
|
1. **不要直接修改** `bin/`、`crond/` 和 `control.sh`,这些文件是自动生成的,重新生成时会覆盖。
|
||||||
|
|
||||||
2. **修改配置后必须重新运行** `python3 scripts/generate.py` 才能生效。
|
2. **修改配置后必须重新运行** `python3 scripts/generate.py` 才能生效。
|
||||||
|
|
||||||
@@ -293,3 +323,5 @@ python3 scripts/generate.py --help
|
|||||||
4. UDP 是无连接协议,设备可能不会返回响应,这是正常现象。
|
4. UDP 是无连接协议,设备可能不会返回响应,这是正常现象。
|
||||||
|
|
||||||
5. 部署到生产环境前,请将 `base_dir` 修改为实际的部署路径(如 `/opt/upc_resent`)。
|
5. 部署到生产环境前,请将 `base_dir` 修改为实际的部署路径(如 `/opt/upc_resent`)。
|
||||||
|
|
||||||
|
6. 控制脚本使用 `pgrep` 来查找进程,确保系统中没有同名脚本冲突。
|
||||||
|
|||||||
@@ -1,126 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import sys
|
|
||||||
# reload(sys) 和 sys.setdefaultencoding('utf-8') 在 Python 3 中不再需要
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
#======修改以下参数======
|
|
||||||
TmsServerIp='192.168.8.9' #TMS服务器IP,用于绑定服务,等待外部指令
|
|
||||||
TmsPor='10129' #TMS服务器端口,用于绑定服务,等待外部指令
|
|
||||||
upc_dev_ip="192.168.8.125" #自动化控制设备IP
|
|
||||||
upc_dev_port="502" #自动化控制设备端口
|
|
||||||
# 注意:Senderfile 指向的 sender.py 脚本也需要是 Python 3 版本!
|
|
||||||
Senderfile='/opt/upc_resent/bin/sender.py' #发送程序位置
|
|
||||||
Logfile='/opt/upc_resent/log/192.168.8.125.log' #日志文件位置
|
|
||||||
pythonpath="/usr/bin/python3" # Python 3 执行文件的位置,可在操作系统中使用which python3命令获取
|
|
||||||
#========================
|
|
||||||
|
|
||||||
BUFSIZE = 1024
|
|
||||||
|
|
||||||
# 配置日志,只执行一次
|
|
||||||
logging.basicConfig(filename=Logfile,filemode="a", level=logging.DEBUG)
|
|
||||||
ISOTIMEFORMAT='%Y-%m-%d %X'
|
|
||||||
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
try:
|
|
||||||
sock.bind((TmsServerIp, int(TmsPor))) #启动TMS本地服务,等待外部设备发送指令
|
|
||||||
sock.listen(500)
|
|
||||||
except OSError as e: # 在 Python 3 中使用 OSError 替代 socket.error
|
|
||||||
logstr="!!!!!ERROR!!!!!"+time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) )+" 无法绑定端口 %s:%s - %s" % (TmsServerIp, TmsPor, e)
|
|
||||||
logging.error(logstr)
|
|
||||||
print(logstr) # Python 3 print 函数
|
|
||||||
sys.exit(1) # 绑定失败则退出
|
|
||||||
|
|
||||||
logging.info("服务启动,监听 %s:%s" % (TmsServerIp, TmsPor))
|
|
||||||
|
|
||||||
while True:
|
|
||||||
connection,address = sock.accept()
|
|
||||||
try:
|
|
||||||
connection.settimeout(5) #GDC系统长连接
|
|
||||||
# 接收到的数据是 bytes,需要解码成 str 进行比较
|
|
||||||
buf_bytes = connection.recv(BUFSIZE)
|
|
||||||
buf = buf_bytes.decode('utf-8').strip() # 解码成 str 并移除空白符
|
|
||||||
|
|
||||||
operation = "nodata" # 默认值,如果没有匹配的命令
|
|
||||||
|
|
||||||
datetime_str=time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) )
|
|
||||||
logstr="==="+datetime_str+"收到客户端"+ address[0]+":"+str(address[1])+"发送的指令: '" +str(buf)+"'"
|
|
||||||
logging.info(logstr)
|
|
||||||
|
|
||||||
# 根据接收到的外部命令,映射到单个内部操作指令
|
|
||||||
if buf == 'open':
|
|
||||||
operation = 'openall4'
|
|
||||||
elif buf == 'close':
|
|
||||||
operation = 'closeall4'
|
|
||||||
elif buf == 'open1':
|
|
||||||
operation = 'open1'
|
|
||||||
elif buf == 'close1':
|
|
||||||
operation = 'close1'
|
|
||||||
elif buf == 'open2':
|
|
||||||
operation = 'open2'
|
|
||||||
elif buf == 'close2':
|
|
||||||
operation = 'close2'
|
|
||||||
elif buf == 'open3':
|
|
||||||
operation = 'open3'
|
|
||||||
elif buf == 'close3':
|
|
||||||
operation = 'close3'
|
|
||||||
elif buf == 'open4':
|
|
||||||
operation = 'open4'
|
|
||||||
elif buf == 'close4':
|
|
||||||
operation = 'close4'
|
|
||||||
elif buf == 'open5': # 新增 5-8 路的命令映射
|
|
||||||
operation = 'open5'
|
|
||||||
elif buf == 'close5':
|
|
||||||
operation = 'close5'
|
|
||||||
elif buf == 'open6':
|
|
||||||
operation = 'open6'
|
|
||||||
elif buf == 'close6':
|
|
||||||
operation = 'close6'
|
|
||||||
elif buf == 'open7':
|
|
||||||
operation = 'open7'
|
|
||||||
elif buf == 'close7':
|
|
||||||
operation = 'close7'
|
|
||||||
elif buf == 'open8':
|
|
||||||
operation = 'open8'
|
|
||||||
elif buf == 'close8':
|
|
||||||
operation = 'close8'
|
|
||||||
elif buf == 'guanggao-guan': # 外部命令 'guanggao-guan' 映射到 'closeall4' (全关)
|
|
||||||
operation = 'closeall4'
|
|
||||||
# else: operation 保持为 "nodata"
|
|
||||||
|
|
||||||
if operation == "nodata":
|
|
||||||
logstr="==="+datetime_str+" 未知指令: '" +str(buf)+"'"
|
|
||||||
logging.warning(logstr)
|
|
||||||
print(logstr) # Python 3 print 函数
|
|
||||||
# 给客户端一个反馈,需要编码成 bytes
|
|
||||||
connection.send(('Unknown command: %s' % buf).encode('utf-8'))
|
|
||||||
else:
|
|
||||||
logstr="==="+datetime_str+" 映射到内部指令: '" +str(operation)+"'"
|
|
||||||
logging.info(logstr)
|
|
||||||
# 直接执行一次外部脚本
|
|
||||||
os_command=str(pythonpath)+" " +Senderfile+ " " + str(upc_dev_ip)+" "+str(upc_dev_port)+" "+str(operation)+" "+str(Logfile)
|
|
||||||
logging.info("执行外部命令: %s" % os_command)
|
|
||||||
os.system(os_command) # 执行发送指令的脚本
|
|
||||||
# 成功处理后给客户端反馈,需要编码成 bytes
|
|
||||||
connection.send(('Command %s processed as %s' % (buf, operation)).encode('utf-8'))
|
|
||||||
except socket.timeout:
|
|
||||||
datetime_str=time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) )
|
|
||||||
logstr="==="+datetime_str+" 客户端连接超时: "+ address[0]+":"+str(address[1])+"==="
|
|
||||||
logging.warning(logstr)
|
|
||||||
print('time out') # Python 3 print 函数
|
|
||||||
except Exception as e: # 捕获其他可能的异常
|
|
||||||
datetime_str=time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) )
|
|
||||||
logstr="==="+datetime_str+" 处理客户端 "+ address[0]+":"+str(address[1])+" 请求时发生错误: "+str(e)+"==="
|
|
||||||
logging.error(logstr, exc_info=True) # 记录异常详情
|
|
||||||
print("Error processing request:", e) # Python 3 print 函数
|
|
||||||
# 给客户端一个错误反馈,需要编码成 bytes
|
|
||||||
connection.send(('Error processing command: %s' % str(e)).encode('utf-8'))
|
|
||||||
finally:
|
|
||||||
connection.close() # 确保每次连接都被关闭
|
|
||||||
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import sys
|
|
||||||
# reload(sys) 和 sys.setdefaultencoding('utf-8') 在 Python 3 中不再需要
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
#======修改以下参数======
|
|
||||||
TmsServerIp='192.168.8.9' #TMS服务器IP,用于绑定服务,等待外部指令
|
|
||||||
TmsPor='10079' #TMS服务器端口,用于绑定服务,等待外部指令
|
|
||||||
upc_dev_ip="192.168.8.73" #自动化控制设备IP
|
|
||||||
upc_dev_port="502" #自动化控制设备端口
|
|
||||||
# 注意:Senderfile 指向的 sender.py 脚本也需要是 Python 3 版本!
|
|
||||||
Senderfile='/opt/upc_resent/bin/sender.py' #发送程序位置
|
|
||||||
Logfile='/opt/upc_resent/log/192.168.8.73.log' #日志文件位置
|
|
||||||
pythonpath="/usr/bin/python3" # Python 3 执行文件的位置,可在操作系统中使用which python3命令获取
|
|
||||||
#========================
|
|
||||||
|
|
||||||
BUFSIZE = 1024
|
|
||||||
|
|
||||||
# 配置日志,只执行一次
|
|
||||||
logging.basicConfig(filename=Logfile,filemode="a", level=logging.DEBUG)
|
|
||||||
ISOTIMEFORMAT='%Y-%m-%d %X'
|
|
||||||
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
try:
|
|
||||||
sock.bind((TmsServerIp, int(TmsPor))) #启动TMS本地服务,等待外部设备发送指令
|
|
||||||
sock.listen(500)
|
|
||||||
except OSError as e: # 在 Python 3 中使用 OSError 替代 socket.error
|
|
||||||
logstr="!!!!!ERROR!!!!!"+time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) )+" 无法绑定端口 %s:%s - %s" % (TmsServerIp, TmsPor, e)
|
|
||||||
logging.error(logstr)
|
|
||||||
print(logstr) # Python 3 print 函数
|
|
||||||
sys.exit(1) # 绑定失败则退出
|
|
||||||
|
|
||||||
logging.info("服务启动,监听 %s:%s" % (TmsServerIp, TmsPor))
|
|
||||||
|
|
||||||
while True:
|
|
||||||
connection,address = sock.accept()
|
|
||||||
try:
|
|
||||||
connection.settimeout(5) #GDC系统长连接
|
|
||||||
# 接收到的数据是 bytes,需要解码成 str 进行比较
|
|
||||||
buf_bytes = connection.recv(BUFSIZE)
|
|
||||||
buf = buf_bytes.decode('utf-8').strip() # 解码成 str 并移除空白符
|
|
||||||
|
|
||||||
operation = "nodata" # 默认值,如果没有匹配的命令
|
|
||||||
|
|
||||||
datetime_str=time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) )
|
|
||||||
logstr="==="+datetime_str+"收到客户端"+ address[0]+":"+str(address[1])+"发送的指令: '" +str(buf)+"'"
|
|
||||||
logging.info(logstr)
|
|
||||||
|
|
||||||
# 根据接收到的外部命令,映射到单个内部操作指令
|
|
||||||
if buf == 'open':
|
|
||||||
operation = 'openall4'
|
|
||||||
elif buf == 'close':
|
|
||||||
operation = 'closeall4'
|
|
||||||
elif buf == 'open1':
|
|
||||||
operation = 'open1'
|
|
||||||
elif buf == 'close1':
|
|
||||||
operation = 'close1'
|
|
||||||
elif buf == 'open2':
|
|
||||||
operation = 'open2'
|
|
||||||
elif buf == 'close2':
|
|
||||||
operation = 'close2'
|
|
||||||
elif buf == 'open3':
|
|
||||||
operation = 'open3'
|
|
||||||
elif buf == 'close3':
|
|
||||||
operation = 'close3'
|
|
||||||
elif buf == 'open4':
|
|
||||||
operation = 'open4'
|
|
||||||
elif buf == 'close4':
|
|
||||||
operation = 'close4'
|
|
||||||
elif buf == 'open5': # 新增 5-8 路的命令映射
|
|
||||||
operation = 'open5'
|
|
||||||
elif buf == 'close5':
|
|
||||||
operation = 'close5'
|
|
||||||
elif buf == 'open6':
|
|
||||||
operation = 'open6'
|
|
||||||
elif buf == 'close6':
|
|
||||||
operation = 'close6'
|
|
||||||
elif buf == 'open7':
|
|
||||||
operation = 'open7'
|
|
||||||
elif buf == 'close7':
|
|
||||||
operation = 'close7'
|
|
||||||
elif buf == 'open8':
|
|
||||||
operation = 'open8'
|
|
||||||
elif buf == 'close8':
|
|
||||||
operation = 'close8'
|
|
||||||
elif buf == 'guanggao-guan': # 外部命令 'guanggao-guan' 映射到 'closeall4' (全关)
|
|
||||||
operation = 'closeall4'
|
|
||||||
# else: operation 保持为 "nodata"
|
|
||||||
|
|
||||||
if operation == "nodata":
|
|
||||||
logstr="==="+datetime_str+" 未知指令: '" +str(buf)+"'"
|
|
||||||
logging.warning(logstr)
|
|
||||||
print(logstr) # Python 3 print 函数
|
|
||||||
# 给客户端一个反馈,需要编码成 bytes
|
|
||||||
connection.send(('Unknown command: %s' % buf).encode('utf-8'))
|
|
||||||
else:
|
|
||||||
logstr="==="+datetime_str+" 映射到内部指令: '" +str(operation)+"'"
|
|
||||||
logging.info(logstr)
|
|
||||||
# 直接执行一次外部脚本
|
|
||||||
os_command=str(pythonpath)+" " +Senderfile+ " " + str(upc_dev_ip)+" "+str(upc_dev_port)+" "+str(operation)+" "+str(Logfile)
|
|
||||||
logging.info("执行外部命令: %s" % os_command)
|
|
||||||
os.system(os_command) # 执行发送指令的脚本
|
|
||||||
# 成功处理后给客户端反馈,需要编码成 bytes
|
|
||||||
connection.send(('Command %s processed as %s' % (buf, operation)).encode('utf-8'))
|
|
||||||
except socket.timeout:
|
|
||||||
datetime_str=time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) )
|
|
||||||
logstr="==="+datetime_str+" 客户端连接超时: "+ address[0]+":"+str(address[1])+"==="
|
|
||||||
logging.warning(logstr)
|
|
||||||
print('time out') # Python 3 print 函数
|
|
||||||
except Exception as e: # 捕获其他可能的异常
|
|
||||||
datetime_str=time.strftime( ISOTIMEFORMAT, time.localtime( time.time() ) )
|
|
||||||
logstr="==="+datetime_str+" 处理客户端 "+ address[0]+":"+str(address[1])+" 请求时发生错误: "+str(e)+"==="
|
|
||||||
logging.error(logstr, exc_info=True) # 记录异常详情
|
|
||||||
print("Error processing request:", e) # Python 3 print 函数
|
|
||||||
# 给客户端一个错误反馈,需要编码成 bytes
|
|
||||||
connection.send(('Error processing command: %s' % str(e)).encode('utf-8'))
|
|
||||||
finally:
|
|
||||||
connection.close() # 确保每次连接都被关闭
|
|
||||||
|
|
||||||
124
bin/dev1.py
124
bin/dev1.py
@@ -1,124 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
|
||||||
# Device: 设备73-TCP (dev1)
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# ====== 配置参数(从配置文件读取)======
|
|
||||||
TMS_SERVER_IP = '192.168.8.9'
|
|
||||||
TMS_PORT = 10079
|
|
||||||
UPC_DEV_IP = '192.168.8.73'
|
|
||||||
UPC_DEV_PORT = '502'
|
|
||||||
SENDER_FILE = '/home/smart/pythonPJ/upc_resent/bin/sender_tcp.py'
|
|
||||||
LOG_FILE = '/home/smart/pythonPJ/upc_resent/log/dev1.log'
|
|
||||||
PYTHON_PATH = '/usr/bin/python3'
|
|
||||||
DEVICE_ID = 'dev1'
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
BUFSIZE = 1024
|
|
||||||
|
|
||||||
# 配置日志
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
# 命令映射表
|
|
||||||
COMMAND_MAPPINGS = {
|
|
||||||
"open": "openall4",
|
|
||||||
"close": "closeall4",
|
|
||||||
"guanggao-guan": "closeall4",
|
|
||||||
"open1": "open1",
|
|
||||||
"close1": "close1",
|
|
||||||
"open2": "open2",
|
|
||||||
"close2": "close2",
|
|
||||||
"open3": "open3",
|
|
||||||
"close3": "close3",
|
|
||||||
"open4": "open4",
|
|
||||||
"close4": "close4",
|
|
||||||
"open5": "open5",
|
|
||||||
"close5": "close5",
|
|
||||||
"open6": "open6",
|
|
||||||
"close6": "close6",
|
|
||||||
"open7": "open7",
|
|
||||||
"close7": "close7",
|
|
||||||
"open8": "open8",
|
|
||||||
"close8": "close8",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def process_command(buf):
|
|
||||||
"""处理接收到的命令,返回对应的操作指令"""
|
|
||||||
buf = buf.strip()
|
|
||||||
if buf in COMMAND_MAPPINGS:
|
|
||||||
return COMMAND_MAPPINGS[buf]
|
|
||||||
return "nodata"
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
try:
|
|
||||||
sock.bind((TMS_SERVER_IP, int(TMS_PORT)))
|
|
||||||
sock.listen(500)
|
|
||||||
except OSError as e:
|
|
||||||
logstr = "!!!!!ERROR!!!!!" + time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) + \
|
|
||||||
" 无法绑定端口 %s:%s - %s" % (TMS_SERVER_IP, TMS_PORT, e)
|
|
||||||
logging.error(logstr)
|
|
||||||
print(logstr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
logging.info("服务启动,监听 %s:%s" % (TMS_SERVER_IP, TMS_PORT))
|
|
||||||
print(f"[{DEVICE_ID}] 服务启动,监听 {TMS_SERVER_IP}:{TMS_PORT}")
|
|
||||||
|
|
||||||
while True:
|
|
||||||
connection, address = sock.accept()
|
|
||||||
try:
|
|
||||||
connection.settimeout(5)
|
|
||||||
buf_bytes = connection.recv(BUFSIZE)
|
|
||||||
buf = buf_bytes.decode('utf-8').strip()
|
|
||||||
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = "===" + datetime_str + " 收到客户端 " + address[0] + ":" + str(address[1]) + \
|
|
||||||
" 发送的指令: '" + str(buf) + "'"
|
|
||||||
logging.info(logstr)
|
|
||||||
print(logstr)
|
|
||||||
|
|
||||||
operation = process_command(buf)
|
|
||||||
|
|
||||||
if operation == "nodata":
|
|
||||||
logstr = "===" + datetime_str + " 未知指令: '" + str(buf) + "'"
|
|
||||||
logging.warning(logstr)
|
|
||||||
print(logstr)
|
|
||||||
connection.send(('Unknown command: %s' % buf).encode('utf-8'))
|
|
||||||
else:
|
|
||||||
logstr = "===" + datetime_str + " 映射到内部指令: '" + str(operation) + "'"
|
|
||||||
logging.info(logstr)
|
|
||||||
print(logstr)
|
|
||||||
|
|
||||||
os_command = str(PYTHON_PATH) + " " + SENDER_FILE + " " + \
|
|
||||||
str(UPC_DEV_IP) + " " + str(UPC_DEV_PORT) + " " + \
|
|
||||||
str(operation) + " " + str(LOG_FILE)
|
|
||||||
logging.info("执行外部命令: %s" % os_command)
|
|
||||||
os.system(os_command)
|
|
||||||
connection.send(('Command %s processed as %s' % (buf, operation)).encode('utf-8'))
|
|
||||||
except socket.timeout:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = "===" + datetime_str + " 客户端连接超时: " + address[0] + ":" + str(address[1]) + "==="
|
|
||||||
logging.warning(logstr)
|
|
||||||
print('time out')
|
|
||||||
except Exception as e:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = "===" + datetime_str + " 处理客户端 " + address[0] + ":" + str(address[1]) + \
|
|
||||||
" 请求时发生错误: " + str(e) + "==="
|
|
||||||
logging.error(logstr, exc_info=True)
|
|
||||||
print("Error processing request:", e)
|
|
||||||
connection.send(('Error processing command: %s' % str(e)).encode('utf-8'))
|
|
||||||
finally:
|
|
||||||
connection.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
124
bin/dev2.py
124
bin/dev2.py
@@ -1,124 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
|
||||||
# Device: 设备125-TCP (dev2)
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# ====== 配置参数(从配置文件读取)======
|
|
||||||
TMS_SERVER_IP = '192.168.8.9'
|
|
||||||
TMS_PORT = 10129
|
|
||||||
UPC_DEV_IP = '192.168.8.125'
|
|
||||||
UPC_DEV_PORT = '502'
|
|
||||||
SENDER_FILE = '/home/smart/pythonPJ/upc_resent/bin/sender_tcp.py'
|
|
||||||
LOG_FILE = '/home/smart/pythonPJ/upc_resent/log/dev2.log'
|
|
||||||
PYTHON_PATH = '/usr/bin/python3'
|
|
||||||
DEVICE_ID = 'dev2'
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
BUFSIZE = 1024
|
|
||||||
|
|
||||||
# 配置日志
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
# 命令映射表
|
|
||||||
COMMAND_MAPPINGS = {
|
|
||||||
"open": "openall4",
|
|
||||||
"close": "closeall4",
|
|
||||||
"guanggao-guan": "closeall4",
|
|
||||||
"open1": "open1",
|
|
||||||
"close1": "close1",
|
|
||||||
"open2": "open2",
|
|
||||||
"close2": "close2",
|
|
||||||
"open3": "open3",
|
|
||||||
"close3": "close3",
|
|
||||||
"open4": "open4",
|
|
||||||
"close4": "close4",
|
|
||||||
"open5": "open5",
|
|
||||||
"close5": "close5",
|
|
||||||
"open6": "open6",
|
|
||||||
"close6": "close6",
|
|
||||||
"open7": "open7",
|
|
||||||
"close7": "close7",
|
|
||||||
"open8": "open8",
|
|
||||||
"close8": "close8",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def process_command(buf):
|
|
||||||
"""处理接收到的命令,返回对应的操作指令"""
|
|
||||||
buf = buf.strip()
|
|
||||||
if buf in COMMAND_MAPPINGS:
|
|
||||||
return COMMAND_MAPPINGS[buf]
|
|
||||||
return "nodata"
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
try:
|
|
||||||
sock.bind((TMS_SERVER_IP, int(TMS_PORT)))
|
|
||||||
sock.listen(500)
|
|
||||||
except OSError as e:
|
|
||||||
logstr = "!!!!!ERROR!!!!!" + time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) + \
|
|
||||||
" 无法绑定端口 %s:%s - %s" % (TMS_SERVER_IP, TMS_PORT, e)
|
|
||||||
logging.error(logstr)
|
|
||||||
print(logstr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
logging.info("服务启动,监听 %s:%s" % (TMS_SERVER_IP, TMS_PORT))
|
|
||||||
print(f"[{DEVICE_ID}] 服务启动,监听 {TMS_SERVER_IP}:{TMS_PORT}")
|
|
||||||
|
|
||||||
while True:
|
|
||||||
connection, address = sock.accept()
|
|
||||||
try:
|
|
||||||
connection.settimeout(5)
|
|
||||||
buf_bytes = connection.recv(BUFSIZE)
|
|
||||||
buf = buf_bytes.decode('utf-8').strip()
|
|
||||||
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = "===" + datetime_str + " 收到客户端 " + address[0] + ":" + str(address[1]) + \
|
|
||||||
" 发送的指令: '" + str(buf) + "'"
|
|
||||||
logging.info(logstr)
|
|
||||||
print(logstr)
|
|
||||||
|
|
||||||
operation = process_command(buf)
|
|
||||||
|
|
||||||
if operation == "nodata":
|
|
||||||
logstr = "===" + datetime_str + " 未知指令: '" + str(buf) + "'"
|
|
||||||
logging.warning(logstr)
|
|
||||||
print(logstr)
|
|
||||||
connection.send(('Unknown command: %s' % buf).encode('utf-8'))
|
|
||||||
else:
|
|
||||||
logstr = "===" + datetime_str + " 映射到内部指令: '" + str(operation) + "'"
|
|
||||||
logging.info(logstr)
|
|
||||||
print(logstr)
|
|
||||||
|
|
||||||
os_command = str(PYTHON_PATH) + " " + SENDER_FILE + " " + \
|
|
||||||
str(UPC_DEV_IP) + " " + str(UPC_DEV_PORT) + " " + \
|
|
||||||
str(operation) + " " + str(LOG_FILE)
|
|
||||||
logging.info("执行外部命令: %s" % os_command)
|
|
||||||
os.system(os_command)
|
|
||||||
connection.send(('Command %s processed as %s' % (buf, operation)).encode('utf-8'))
|
|
||||||
except socket.timeout:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = "===" + datetime_str + " 客户端连接超时: " + address[0] + ":" + str(address[1]) + "==="
|
|
||||||
logging.warning(logstr)
|
|
||||||
print('time out')
|
|
||||||
except Exception as e:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = "===" + datetime_str + " 处理客户端 " + address[0] + ":" + str(address[1]) + \
|
|
||||||
" 请求时发生错误: " + str(e) + "==="
|
|
||||||
logging.error(logstr, exc_info=True)
|
|
||||||
print("Error processing request:", e)
|
|
||||||
connection.send(('Error processing command: %s' % str(e)).encode('utf-8'))
|
|
||||||
finally:
|
|
||||||
connection.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
118
bin/dev3.py
118
bin/dev3.py
@@ -1,118 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
|
||||||
# Device: 设备UDP示例 (dev3) - UDP Protocol
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# ====== 配置参数(从配置文件读取)======
|
|
||||||
TMS_SERVER_IP = '192.168.8.9'
|
|
||||||
TMS_PORT = 10080
|
|
||||||
UPC_DEV_IP = '192.168.8.200'
|
|
||||||
UPC_DEV_PORT = 502
|
|
||||||
SENDER_FILE = '/home/smart/pythonPJ/upc_resent/bin/sender_udp.py'
|
|
||||||
LOG_FILE = '/home/smart/pythonPJ/upc_resent/log/dev3.log'
|
|
||||||
PYTHON_PATH = '/usr/bin/python3'
|
|
||||||
DEVICE_ID = 'dev3'
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
BUFSIZE = 1024
|
|
||||||
|
|
||||||
# 配置日志
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
# 命令映射表
|
|
||||||
COMMAND_MAPPINGS = {
|
|
||||||
"open": "openall4",
|
|
||||||
"close": "closeall4",
|
|
||||||
"guanggao-guan": "closeall4",
|
|
||||||
"open1": "open1",
|
|
||||||
"close1": "close1",
|
|
||||||
"open2": "open2",
|
|
||||||
"close2": "close2",
|
|
||||||
"open3": "open3",
|
|
||||||
"close3": "close3",
|
|
||||||
"open4": "open4",
|
|
||||||
"close4": "close4",
|
|
||||||
"open5": "open5",
|
|
||||||
"close5": "close5",
|
|
||||||
"open6": "open6",
|
|
||||||
"close6": "close6",
|
|
||||||
"open7": "open7",
|
|
||||||
"close7": "close7",
|
|
||||||
"open8": "open8",
|
|
||||||
"close8": "close8",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def process_command(buf):
|
|
||||||
"""处理接收到的命令,返回对应的操作指令"""
|
|
||||||
buf = buf.strip()
|
|
||||||
if buf in COMMAND_MAPPINGS:
|
|
||||||
return COMMAND_MAPPINGS[buf]
|
|
||||||
return "nodata"
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# 创建 UDP socket
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
try:
|
|
||||||
sock.bind((TMS_SERVER_IP, int(TMS_PORT)))
|
|
||||||
except OSError as e:
|
|
||||||
logstr = "!!!!!ERROR!!!!!" + time.strftime(ISOTIMEFORMAT, time.localtime(time.time())) + \
|
|
||||||
" 无法绑定UDP端口 %s:%s - %s" % (TMS_SERVER_IP, TMS_PORT, e)
|
|
||||||
logging.error(logstr)
|
|
||||||
print(logstr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
logging.info("UDP服务启动,监听 %s:%s" % (TMS_SERVER_IP, TMS_PORT))
|
|
||||||
print(f"[{DEVICE_ID}] UDP服务启动,监听 {TMS_SERVER_IP}:{TMS_PORT}")
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
# UDP 使用 recvfrom 接收数据,同时获取客户端地址
|
|
||||||
buf_bytes, client_addr = sock.recvfrom(BUFSIZE)
|
|
||||||
buf = buf_bytes.decode('utf-8').strip()
|
|
||||||
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = "===" + datetime_str + " 收到UDP客户端 " + client_addr[0] + ":" + str(client_addr[1]) + \
|
|
||||||
" 发送的指令: '" + str(buf) + "'"
|
|
||||||
logging.info(logstr)
|
|
||||||
print(logstr)
|
|
||||||
|
|
||||||
operation = process_command(buf)
|
|
||||||
|
|
||||||
if operation == "nodata":
|
|
||||||
logstr = "===" + datetime_str + " 未知指令: '" + str(buf) + "'"
|
|
||||||
logging.warning(logstr)
|
|
||||||
print(logstr)
|
|
||||||
# 发送UDP响应
|
|
||||||
sock.sendto(('Unknown command: %s' % buf).encode('utf-8'), client_addr)
|
|
||||||
else:
|
|
||||||
logstr = "===" + datetime_str + " 映射到内部指令: '" + str(operation) + "'"
|
|
||||||
logging.info(logstr)
|
|
||||||
print(logstr)
|
|
||||||
|
|
||||||
# 执行发送指令的脚本
|
|
||||||
os_command = str(PYTHON_PATH) + " " + SENDER_FILE + " " + \
|
|
||||||
str(UPC_DEV_IP) + " " + str(UPC_DEV_PORT) + " " + \
|
|
||||||
str(operation) + " " + str(LOG_FILE)
|
|
||||||
logging.info("执行外部命令: %s" % os_command)
|
|
||||||
os.system(os_command)
|
|
||||||
|
|
||||||
# 发送UDP响应
|
|
||||||
sock.sendto(('Command %s processed as %s' % (buf, operation)).encode('utf-8'), client_addr)
|
|
||||||
except Exception as e:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = "===" + datetime_str + " 处理UDP请求时发生错误: " + str(e) + "==="
|
|
||||||
logging.error(logstr, exc_info=True)
|
|
||||||
print("Error processing UDP request:", e)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
140
bin/sender.py
140
bin/sender.py
@@ -1,140 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import telnetlib
|
|
||||||
|
|
||||||
|
|
||||||
def tcp_command_send(upc_addr, upc_command, data):
|
|
||||||
"""负责发送数据和接收一次响应"""
|
|
||||||
timeout = 2
|
|
||||||
socket.setdefaulttimeout(timeout)
|
|
||||||
try:
|
|
||||||
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
logging.debug(f"尝试连接到 {upc_addr[0]}:{upc_addr[1]}...")
|
|
||||||
client.connect(upc_addr)
|
|
||||||
logging.debug(f"成功连接到 {upc_addr[0]}:{upc_addr[1]}。")
|
|
||||||
|
|
||||||
logging.info(f"正在发送命令 '{upc_command}' 到 {upc_addr}: {data!r} (原始字节)")
|
|
||||||
client.send(data)
|
|
||||||
logging.debug(f"数据发送完成。")
|
|
||||||
|
|
||||||
recv_buffer_size = 1024
|
|
||||||
response_bytes = b''
|
|
||||||
try:
|
|
||||||
logging.debug(f"尝试从 {upc_addr} 接收响应数据...")
|
|
||||||
response_bytes = client.recv(recv_buffer_size)
|
|
||||||
if response_bytes:
|
|
||||||
logging.info(f"从 {upc_addr} 收到原始响应字节: {response_bytes!r}")
|
|
||||||
try:
|
|
||||||
response_str = response_bytes.decode('utf-8', errors='ignore')
|
|
||||||
logging.info(f"从 {upc_addr} 收到解码响应字符串: '{response_str}'")
|
|
||||||
except Exception as decode_e:
|
|
||||||
logging.warning(f"解码从 {upc_addr} 收到的响应时发生错误: {decode_e}")
|
|
||||||
else:
|
|
||||||
logging.info(f"从 {upc_addr} 未收到响应数据 (连接可能已关闭或设备未发送)。")
|
|
||||||
except socket.timeout:
|
|
||||||
logging.warning(f"从 {upc_addr} 接收响应超时。")
|
|
||||||
except OSError as recv_e:
|
|
||||||
logging.error(f"从 {upc_addr} 接收响应时发生网络错误: {recv_e}")
|
|
||||||
|
|
||||||
client.close()
|
|
||||||
logging.debug(f"连接关闭。")
|
|
||||||
return True
|
|
||||||
except OSError as e:
|
|
||||||
logging.error(f"命令 '{upc_command}' 发送至 {upc_addr} 失败: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
# 指令定义表(从配置文件读取)
|
|
||||||
COMMAND_DEFINITIONS = {
|
|
||||||
"open1": "000100000008010F006400010001",
|
|
||||||
"close1": "000100000008010F006400010000",
|
|
||||||
"open2": "000100000008010F006500010001",
|
|
||||||
"close2": "000100000008010F006500010000",
|
|
||||||
"open3": "000100000008010F006600010001",
|
|
||||||
"close3": "000100000008010F006600010000",
|
|
||||||
"open4": "000100000008010F006700010001",
|
|
||||||
"close4": "000100000008010F006700010000",
|
|
||||||
"openall4": "000100000008010F00640004000F",
|
|
||||||
"closeall4": "000100000008010F006400040000",
|
|
||||||
"open5": "000100000008010F006800010001",
|
|
||||||
"close5": "000100000008010F006800010000",
|
|
||||||
"open6": "000100000008010F006900010001",
|
|
||||||
"close6": "000100000008010F006900010000",
|
|
||||||
"open7": "000100000008010F006A00010001",
|
|
||||||
"close7": "000100000008010F006A00010000",
|
|
||||||
"open8": "000100000008010F006B00010001",
|
|
||||||
"close8": "000100000008010F006B00010000",
|
|
||||||
"getstat": "fe010000000429C6",
|
|
||||||
"getstat01": "fe010100000429C6",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def upc_send_command(upc_addr, upc_command, log_file):
|
|
||||||
"""将命令发送给终端设备"""
|
|
||||||
data = None
|
|
||||||
|
|
||||||
# 查找指令定义
|
|
||||||
if upc_command in COMMAND_DEFINITIONS:
|
|
||||||
hex_str = COMMAND_DEFINITIONS[upc_command]
|
|
||||||
data = bytes.fromhex(hex_str)
|
|
||||||
|
|
||||||
if data is None:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} 未知命令: {upc_command},没有对应的数据可发送。"
|
|
||||||
logging.warning(logstr)
|
|
||||||
print(logstr)
|
|
||||||
else:
|
|
||||||
i = 1
|
|
||||||
while i <= 3: # 尝试发送3次
|
|
||||||
if tcp_command_send(upc_addr, upc_command, data):
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} {upc_command}命令第{i}次发送成功"
|
|
||||||
logging.info(logstr)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} {upc_command}命令第{i}次发送失败,3秒后进行第{i+1}次尝试"
|
|
||||||
logging.warning(logstr)
|
|
||||||
time.sleep(3)
|
|
||||||
i = i + 1
|
|
||||||
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} {upc_command}命令在3次尝试后发送均失败!"
|
|
||||||
logging.error(logstr)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
UPC_DEV_IP = sys.argv[1]
|
|
||||||
UPC_DEV_PORT = sys.argv[2]
|
|
||||||
upc_command = sys.argv[3]
|
|
||||||
LOG_FILE = sys.argv[4]
|
|
||||||
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
|
||||||
UPC_ADDR = (UPC_DEV_IP, int(UPC_DEV_PORT))
|
|
||||||
|
|
||||||
# 验证端口是否能Telnet通
|
|
||||||
try:
|
|
||||||
logging.debug(f"尝试通过 Telnet 检查端口 {UPC_ADDR[0]}:{UPC_ADDR[1]} 可访问性...")
|
|
||||||
tn = telnetlib.Telnet(UPC_DEV_IP, UPC_DEV_PORT)
|
|
||||||
tn.close()
|
|
||||||
logging.debug(f"端口 {UPC_ADDR[0]}:{UPC_ADDR[1]} Telnet 检查通过。")
|
|
||||||
except OSError as e:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"!!!!!ERROR!!!!!{datetime_str} {UPC_ADDR} 端口无法访问,请检查设备或网络连接: {e}!!!!!"
|
|
||||||
logging.error(logstr)
|
|
||||||
print(logstr)
|
|
||||||
except Exception as e:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"!!!!!ERROR!!!!!{datetime_str} {UPC_ADDR} Telnet检查时发生未知错误: {e}!!!!!"
|
|
||||||
logging.error(logstr, exc_info=True)
|
|
||||||
print(logstr)
|
|
||||||
else:
|
|
||||||
upc_send_command(UPC_ADDR, upc_command, LOG_FILE)
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import telnetlib
|
|
||||||
|
|
||||||
|
|
||||||
def tcp_command_send(upc_addr, upc_command, data):
|
|
||||||
"""负责发送数据和接收一次响应"""
|
|
||||||
timeout = 2
|
|
||||||
socket.setdefaulttimeout(timeout)
|
|
||||||
try:
|
|
||||||
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
logging.debug(f"尝试连接到 {upc_addr[0]}:{upc_addr[1]}...")
|
|
||||||
client.connect(upc_addr)
|
|
||||||
logging.debug(f"成功连接到 {upc_addr[0]}:{upc_addr[1]}。")
|
|
||||||
|
|
||||||
logging.info(f"正在发送命令 '{upc_command}' 到 {upc_addr}: {data!r} (原始字节)")
|
|
||||||
client.send(data)
|
|
||||||
logging.debug(f"数据发送完成。")
|
|
||||||
|
|
||||||
recv_buffer_size = 1024
|
|
||||||
response_bytes = b''
|
|
||||||
try:
|
|
||||||
logging.debug(f"尝试从 {upc_addr} 接收响应数据...")
|
|
||||||
response_bytes = client.recv(recv_buffer_size)
|
|
||||||
if response_bytes:
|
|
||||||
logging.info(f"从 {upc_addr} 收到原始响应字节: {response_bytes!r}")
|
|
||||||
try:
|
|
||||||
response_str = response_bytes.decode('utf-8', errors='ignore')
|
|
||||||
logging.info(f"从 {upc_addr} 收到解码响应字符串: '{response_str}'")
|
|
||||||
except Exception as decode_e:
|
|
||||||
logging.warning(f"解码从 {upc_addr} 收到的响应时发生错误: {decode_e}")
|
|
||||||
else:
|
|
||||||
logging.info(f"从 {upc_addr} 未收到响应数据 (连接可能已关闭或设备未发送)。")
|
|
||||||
except socket.timeout:
|
|
||||||
logging.warning(f"从 {upc_addr} 接收响应超时。")
|
|
||||||
except OSError as recv_e:
|
|
||||||
logging.error(f"从 {upc_addr} 接收响应时发生网络错误: {recv_e}")
|
|
||||||
|
|
||||||
client.close()
|
|
||||||
logging.debug(f"连接关闭。")
|
|
||||||
return True
|
|
||||||
except OSError as e:
|
|
||||||
logging.error(f"命令 '{upc_command}' 发送至 {upc_addr} 失败: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
# 指令定义表(从配置文件读取)
|
|
||||||
COMMAND_DEFINITIONS = {
|
|
||||||
"open1": "000100000008010F006400010001",
|
|
||||||
"close1": "000100000008010F006400010000",
|
|
||||||
"open2": "000100000008010F006500010001",
|
|
||||||
"close2": "000100000008010F006500010000",
|
|
||||||
"open3": "000100000008010F006600010001",
|
|
||||||
"close3": "000100000008010F006600010000",
|
|
||||||
"open4": "000100000008010F006700010001",
|
|
||||||
"close4": "000100000008010F006700010000",
|
|
||||||
"openall4": "000100000008010F00640004000F",
|
|
||||||
"closeall4": "000100000008010F006400040000",
|
|
||||||
"open5": "000100000008010F006800010001",
|
|
||||||
"close5": "000100000008010F006800010000",
|
|
||||||
"open6": "000100000008010F006900010001",
|
|
||||||
"close6": "000100000008010F006900010000",
|
|
||||||
"open7": "000100000008010F006A00010001",
|
|
||||||
"close7": "000100000008010F006A00010000",
|
|
||||||
"open8": "000100000008010F006B00010001",
|
|
||||||
"close8": "000100000008010F006B00010000",
|
|
||||||
"getstat": "fe010000000429C6",
|
|
||||||
"getstat01": "fe010100000429C6",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def upc_send_command(upc_addr, upc_command, log_file):
|
|
||||||
"""将命令发送给终端设备"""
|
|
||||||
data = None
|
|
||||||
|
|
||||||
# 查找指令定义
|
|
||||||
if upc_command in COMMAND_DEFINITIONS:
|
|
||||||
hex_str = COMMAND_DEFINITIONS[upc_command]
|
|
||||||
data = bytes.fromhex(hex_str)
|
|
||||||
|
|
||||||
if data is None:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} 未知命令: {upc_command},没有对应的数据可发送。"
|
|
||||||
logging.warning(logstr)
|
|
||||||
print(logstr)
|
|
||||||
else:
|
|
||||||
i = 1
|
|
||||||
while i <= 3: # 尝试发送3次
|
|
||||||
if tcp_command_send(upc_addr, upc_command, data):
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} {upc_command}命令第{i}次发送成功"
|
|
||||||
logging.info(logstr)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} {upc_command}命令第{i}次发送失败,3秒后进行第{i+1}次尝试"
|
|
||||||
logging.warning(logstr)
|
|
||||||
time.sleep(3)
|
|
||||||
i = i + 1
|
|
||||||
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} {upc_command}命令在3次尝试后发送均失败!"
|
|
||||||
logging.error(logstr)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
UPC_DEV_IP = sys.argv[1]
|
|
||||||
UPC_DEV_PORT = sys.argv[2]
|
|
||||||
upc_command = sys.argv[3]
|
|
||||||
LOG_FILE = sys.argv[4]
|
|
||||||
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
|
||||||
UPC_ADDR = (UPC_DEV_IP, int(UPC_DEV_PORT))
|
|
||||||
|
|
||||||
# 验证端口是否能Telnet通
|
|
||||||
try:
|
|
||||||
logging.debug(f"尝试通过 Telnet 检查端口 {UPC_ADDR[0]}:{UPC_ADDR[1]} 可访问性...")
|
|
||||||
tn = telnetlib.Telnet(UPC_DEV_IP, UPC_DEV_PORT)
|
|
||||||
tn.close()
|
|
||||||
logging.debug(f"端口 {UPC_ADDR[0]}:{UPC_ADDR[1]} Telnet 检查通过。")
|
|
||||||
except OSError as e:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"!!!!!ERROR!!!!!{datetime_str} {UPC_ADDR} 端口无法访问,请检查设备或网络连接: {e}!!!!!"
|
|
||||||
logging.error(logstr)
|
|
||||||
print(logstr)
|
|
||||||
except Exception as e:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"!!!!!ERROR!!!!!{datetime_str} {UPC_ADDR} Telnet检查时发生未知错误: {e}!!!!!"
|
|
||||||
logging.error(logstr, exc_info=True)
|
|
||||||
print(logstr)
|
|
||||||
else:
|
|
||||||
upc_send_command(UPC_ADDR, upc_command, LOG_FILE)
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import socket
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
|
|
||||||
|
|
||||||
def udp_command_send(upc_addr, upc_command, data, timeout=2):
|
|
||||||
"""通过UDP发送数据并接收响应"""
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
sock.settimeout(timeout)
|
|
||||||
|
|
||||||
try:
|
|
||||||
logging.debug(f"尝试发送UDP数据到 {upc_addr[0]}:{upc_addr[1]}...")
|
|
||||||
|
|
||||||
logging.info(f"正在发送UDP命令 '{upc_command}' 到 {upc_addr}: {data!r} (原始字节)")
|
|
||||||
sock.sendto(data, upc_addr)
|
|
||||||
logging.debug(f"UDP数据发送完成。")
|
|
||||||
|
|
||||||
# 尝试接收响应
|
|
||||||
recv_buffer_size = 1024
|
|
||||||
try:
|
|
||||||
logging.debug(f"等待从 {upc_addr} 接收UDP响应...")
|
|
||||||
response_bytes, addr = sock.recvfrom(recv_buffer_size)
|
|
||||||
if response_bytes:
|
|
||||||
logging.info(f"从 {addr} 收到UDP原始响应字节: {response_bytes!r}")
|
|
||||||
try:
|
|
||||||
response_str = response_bytes.decode('utf-8', errors='ignore')
|
|
||||||
logging.info(f"从 {addr} 收到UDP解码响应字符串: '{response_str}'")
|
|
||||||
except Exception as decode_e:
|
|
||||||
logging.warning(f"解码UDP响应时发生错误: {decode_e}")
|
|
||||||
else:
|
|
||||||
logging.info(f"未收到UDP响应数据。")
|
|
||||||
except socket.timeout:
|
|
||||||
logging.warning(f"接收UDP响应超时(设备可能不返回响应,这通常是正常的)。")
|
|
||||||
except OSError as recv_e:
|
|
||||||
logging.error(f"接收UDP响应时发生网络错误: {recv_e}")
|
|
||||||
|
|
||||||
sock.close()
|
|
||||||
logging.debug(f"UDP socket关闭。")
|
|
||||||
return True
|
|
||||||
except OSError as e:
|
|
||||||
logging.error(f"UDP命令 '{upc_command}' 发送至 {upc_addr} 失败: {e}")
|
|
||||||
return False
|
|
||||||
finally:
|
|
||||||
try:
|
|
||||||
sock.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# 指令定义表(从配置文件读取)
|
|
||||||
COMMAND_DEFINITIONS = {
|
|
||||||
"open1": "000100000008010F006400010001",
|
|
||||||
"close1": "000100000008010F006400010000",
|
|
||||||
"open2": "000100000008010F006500010001",
|
|
||||||
"close2": "000100000008010F006500010000",
|
|
||||||
"open3": "000100000008010F006600010001",
|
|
||||||
"close3": "000100000008010F006600010000",
|
|
||||||
"open4": "000100000008010F006700010001",
|
|
||||||
"close4": "000100000008010F006700010000",
|
|
||||||
"openall4": "000100000008010F00640004000F",
|
|
||||||
"closeall4": "000100000008010F006400040000",
|
|
||||||
"open5": "000100000008010F006800010001",
|
|
||||||
"close5": "000100000008010F006800010000",
|
|
||||||
"open6": "000100000008010F006900010001",
|
|
||||||
"close6": "000100000008010F006900010000",
|
|
||||||
"open7": "000100000008010F006A00010001",
|
|
||||||
"close7": "000100000008010F006A00010000",
|
|
||||||
"open8": "000100000008010F006B00010001",
|
|
||||||
"close8": "000100000008010F006B00010000",
|
|
||||||
"getstat": "fe010000000429C6",
|
|
||||||
"getstat01": "fe010100000429C6",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def upc_send_command(upc_addr, upc_command, log_file):
|
|
||||||
"""将命令发送给终端设备"""
|
|
||||||
data = None
|
|
||||||
|
|
||||||
# 查找指令定义
|
|
||||||
if upc_command in COMMAND_DEFINITIONS:
|
|
||||||
hex_str = COMMAND_DEFINITIONS[upc_command]
|
|
||||||
data = bytes.fromhex(hex_str)
|
|
||||||
|
|
||||||
if data is None:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} 未知命令: {upc_command},没有对应的数据可发送。"
|
|
||||||
logging.warning(logstr)
|
|
||||||
print(logstr)
|
|
||||||
else:
|
|
||||||
i = 1
|
|
||||||
while i <= 3: # 尝试发送3次
|
|
||||||
if udp_command_send(upc_addr, upc_command, data):
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} {upc_command}命令第{i}次发送成功"
|
|
||||||
logging.info(logstr)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} {upc_command}命令第{i}次发送失败,3秒后进行第{i+1}次尝试"
|
|
||||||
logging.warning(logstr)
|
|
||||||
time.sleep(3)
|
|
||||||
i = i + 1
|
|
||||||
|
|
||||||
datetime_str = time.strftime(ISOTIMEFORMAT, time.localtime(time.time()))
|
|
||||||
logstr = f"{datetime_str} {upc_command}命令在3次尝试后发送均失败!"
|
|
||||||
logging.error(logstr)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
UPC_DEV_IP = sys.argv[1]
|
|
||||||
UPC_DEV_PORT = int(sys.argv[2])
|
|
||||||
upc_command = sys.argv[3]
|
|
||||||
LOG_FILE = sys.argv[4]
|
|
||||||
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG)
|
|
||||||
UPC_ADDR = (UPC_DEV_IP, UPC_DEV_PORT)
|
|
||||||
|
|
||||||
# UDP 是无连接的,无需像TCP那样预先检查端口连通性
|
|
||||||
# 直接发送数据
|
|
||||||
logging.info(f"UDP模式:准备发送命令到 {UPC_ADDR}")
|
|
||||||
upc_send_command(UPC_ADDR, upc_command, LOG_FILE)
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"global": {
|
"global": {
|
||||||
"tms_server_ip": "192.168.8.9",
|
"tms_server_ip": "192.168.139.133",
|
||||||
"python_path": "/usr/bin/python3",
|
"python_path": "/usr/bin/python3",
|
||||||
"base_dir": "/home/smart/pythonPJ/upc_resent"
|
"base_dir": "/home/smart/pythonPJ/upc_resent"
|
||||||
},
|
},
|
||||||
@@ -51,9 +51,7 @@
|
|||||||
"open7": "000100000008010F006A00010001",
|
"open7": "000100000008010F006A00010001",
|
||||||
"close7": "000100000008010F006A00010000",
|
"close7": "000100000008010F006A00010000",
|
||||||
"open8": "000100000008010F006B00010001",
|
"open8": "000100000008010F006B00010001",
|
||||||
"close8": "000100000008010F006B00010000",
|
"close8": "000100000008010F006B00010000"
|
||||||
"getstat": "fe010000000429C6",
|
|
||||||
"getstat01": "fe010100000429C6"
|
|
||||||
},
|
},
|
||||||
"mappings": {
|
"mappings": {
|
||||||
"open": "openall4",
|
"open": "openall4",
|
||||||
|
|||||||
236
control.sh
Executable file
236
control.sh
Executable file
@@ -0,0 +1,236 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Auto-generated control script
|
||||||
|
# Usage: ./control.sh {start|stop|restart|status}
|
||||||
|
|
||||||
|
BASE_DIR="/home/smart/pythonPJ/upc_resent"
|
||||||
|
PYTHON_PATH="/usr/bin/python3"
|
||||||
|
|
||||||
|
# 设备列表: ID 名称 协议
|
||||||
|
DEVICES=(
|
||||||
|
"dev1" "设备73-TCP" "TCP"
|
||||||
|
"dev2" "设备125-TCP" "TCP"
|
||||||
|
"dev3" "设备UDP示例" "UDP"
|
||||||
|
)
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
show_help() {
|
||||||
|
echo "Usage: $0 {start|stop|restart|status}"
|
||||||
|
echo ""
|
||||||
|
echo "Commands:"
|
||||||
|
echo " start 启动所有服务"
|
||||||
|
echo " stop 停止所有服务"
|
||||||
|
echo " restart 重启所有服务"
|
||||||
|
echo " status 查看服务状态"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_root() {
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo -e "${YELLOW}Warning: 建议使用 root 权限运行${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
local device_id=$1
|
||||||
|
local device_name=$2
|
||||||
|
local protocol=$3
|
||||||
|
local script_path="$BASE_DIR/bin/$device_id.py"
|
||||||
|
|
||||||
|
# 检查进程是否已存在(使用更精确的匹配)
|
||||||
|
local pid=$(pgrep -f "${PYTHON_PATH}.*${script_path}" | head -1)
|
||||||
|
if [[ -n "$pid" ]]; then
|
||||||
|
echo -e "[${YELLOW}SKIP${NC}] $device_name ($device_id) - ${protocol} 已在运行 (PID: $pid)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "[START] $device_name ($device_id) - ${protocol} ... "
|
||||||
|
nohup $PYTHON_PATH "$script_path" > /dev/null 2>&1 &
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# 检查是否启动成功
|
||||||
|
pid=$(pgrep -f "${PYTHON_PATH}.*${script_path}" | head -1)
|
||||||
|
if [[ -n "$pid" ]]; then
|
||||||
|
echo -e "${GREEN}OK${NC} (PID: $pid)"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}FAILED${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
local device_id=$1
|
||||||
|
local device_name=$2
|
||||||
|
local protocol=$3
|
||||||
|
local script_path="$BASE_DIR/bin/$device_id.py"
|
||||||
|
|
||||||
|
# 使用更精确的匹配模式
|
||||||
|
local pids=$(pgrep -f "${PYTHON_PATH}.*${script_path}")
|
||||||
|
if [[ -z "$pids" ]]; then
|
||||||
|
echo -e "[${YELLOW}SKIP${NC}] $device_name ($device_id) - 未运行"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 获取第一个匹配的 PID
|
||||||
|
local pid=$(echo "$pids" | head -1)
|
||||||
|
echo -n "[STOP] $device_name ($device_id) - ${protocol} (PID: $pid) ... "
|
||||||
|
|
||||||
|
# 结束所有匹配的进程
|
||||||
|
echo "$pids" | while read -r p; do
|
||||||
|
kill "$p" 2>/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
# 等待进程结束
|
||||||
|
local i
|
||||||
|
for i in {1..10}; do
|
||||||
|
sleep 0.5
|
||||||
|
pids=$(pgrep -f "${PYTHON_PATH}.*${script_path}" || true)
|
||||||
|
if [[ -z "$pids" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 检查是否还有残留进程
|
||||||
|
pids=$(pgrep -f "${PYTHON_PATH}.*${script_path}" || true)
|
||||||
|
if [[ -n "$pids" ]]; then
|
||||||
|
# 强制结束残留进程
|
||||||
|
echo "$pids" | while read -r p; do
|
||||||
|
kill -9 "$p" 2>/dev/null
|
||||||
|
done
|
||||||
|
sleep 0.5
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 最终检查
|
||||||
|
pids=$(pgrep -f "${PYTHON_PATH}.*${script_path}" || true)
|
||||||
|
if [[ -z "$pids" ]]; then
|
||||||
|
echo -e "${GREEN}OK${NC}"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}FAILED${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
status_service() {
|
||||||
|
local device_id=$1
|
||||||
|
local device_name=$2
|
||||||
|
local protocol=$3
|
||||||
|
local script_path="$BASE_DIR/bin/$device_id.py"
|
||||||
|
|
||||||
|
local pid=$(pgrep -f "${PYTHON_PATH}.*${script_path}" | head -1)
|
||||||
|
if [[ -n "$pid" ]]; then
|
||||||
|
echo -e "${GREEN}[RUNNING]${NC} $device_name ($device_id) - ${protocol} (PID: $pid)"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}[STOPPED]${NC} $device_name ($device_id) - ${protocol}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_start() {
|
||||||
|
echo "======================================="
|
||||||
|
echo "启动 UPC Resent 服务"
|
||||||
|
echo "======================================="
|
||||||
|
check_root
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local count=0
|
||||||
|
local device_id device_name protocol
|
||||||
|
for ((i=0; i<${#DEVICES[@]}; i+=3)); do
|
||||||
|
device_id="${DEVICES[i]}"
|
||||||
|
device_name="${DEVICES[i+1]}"
|
||||||
|
protocol="${DEVICES[i+2]}"
|
||||||
|
|
||||||
|
if start_service "$device_id" "$device_name" "$protocol"; then
|
||||||
|
((count++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================="
|
||||||
|
echo "启动完成: $count/$((${#DEVICES[@]}/3)) 个服务"
|
||||||
|
echo "======================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_stop() {
|
||||||
|
echo "======================================="
|
||||||
|
echo "停止 UPC Resent 服务"
|
||||||
|
echo "======================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local count=0
|
||||||
|
local device_id device_name protocol
|
||||||
|
for ((i=0; i<${#DEVICES[@]}; i+=3)); do
|
||||||
|
device_id="${DEVICES[i]}"
|
||||||
|
device_name="${DEVICES[i+1]}"
|
||||||
|
protocol="${DEVICES[i+2]}"
|
||||||
|
|
||||||
|
if stop_service "$device_id" "$device_name" "$protocol"; then
|
||||||
|
((count++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================="
|
||||||
|
echo "停止完成: $count/$((${#DEVICES[@]}/3)) 个服务"
|
||||||
|
echo "======================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_restart() {
|
||||||
|
cmd_stop
|
||||||
|
echo ""
|
||||||
|
sleep 1
|
||||||
|
cmd_start
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_status() {
|
||||||
|
echo "======================================="
|
||||||
|
echo "UPC Resent 服务状态"
|
||||||
|
echo "======================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local running=0
|
||||||
|
local stopped=0
|
||||||
|
local device_id device_name protocol
|
||||||
|
|
||||||
|
for ((i=0; i<${#DEVICES[@]}; i+=3)); do
|
||||||
|
device_id="${DEVICES[i]}"
|
||||||
|
device_name="${DEVICES[i+1]}"
|
||||||
|
protocol="${DEVICES[i+2]}"
|
||||||
|
|
||||||
|
if status_service "$device_id" "$device_name" "$protocol"; then
|
||||||
|
((running++))
|
||||||
|
else
|
||||||
|
((stopped++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================="
|
||||||
|
echo "运行中: $running, 已停止: $stopped, 总计: $((${#DEVICES[@]}/3))"
|
||||||
|
echo "======================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主逻辑
|
||||||
|
case "${1:-}" in
|
||||||
|
start)
|
||||||
|
cmd_start
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
cmd_stop
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
cmd_restart
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
cmd_status
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import sys # sys 模块用于 sys.exit(),虽然这里没有直接使用,但通常在脚本中需要
|
|
||||||
|
|
||||||
# --- 配置日志 ---
|
|
||||||
# 确保日志文件路径正确
|
|
||||||
LOG_FILE = '/opt/upc_resent/log/upc-192.168.8.125.log'
|
|
||||||
# 定义时间格式,将被 logging.basicConfig 的 datefmt 使用
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
# 配置日志,确保只执行一次
|
|
||||||
# format 中包含了时间戳 %(asctime)s,所以不需要手动在日志字符串中添加 datetime
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG,
|
|
||||||
format='%(asctime)s - %(levelname)s - %(message)s', datefmt=ISOTIMEFORMAT)
|
|
||||||
# --- 日志配置结束 ---
|
|
||||||
|
|
||||||
|
|
||||||
def IsOpen(ip, port):
|
|
||||||
"""
|
|
||||||
检查指定IP和端口是否可达。
|
|
||||||
如果端口不可达,则记录警告并尝试重启另一个Python脚本。
|
|
||||||
"""
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
s.settimeout(1) # 设置连接超时为1秒,避免无限期阻塞
|
|
||||||
try:
|
|
||||||
logging.debug(f"尝试连接到 {ip}:{port}...")
|
|
||||||
s.connect((ip, int(port)))
|
|
||||||
s.shutdown(socket.SHUT_RDWR) # 使用 SHUT_RDWR 代替数字 2,更具可读性
|
|
||||||
|
|
||||||
print(f"端口 {port} is open") # Python 3 print 函数
|
|
||||||
logging.info(f"端口 {port} is open")
|
|
||||||
return True
|
|
||||||
except (OSError, socket.timeout) as e: # 捕获具体的网络错误和超时
|
|
||||||
print(f"端口 {port} is down") # Python 3 print 函数
|
|
||||||
logging.warning(f"端口 {port} 检查失败: {e},尝试重启程序")
|
|
||||||
|
|
||||||
# --- 重启命令 ---
|
|
||||||
# 确保这里的 python3 路径和脚本路径正确
|
|
||||||
# 这里的脚本名 "192.168.8.125.py" 看起来是硬编码的,请确认是否正确
|
|
||||||
restart_command = "/usr/bin/python3 /opt/upc_resent/bin/192.168.8.125.py &"
|
|
||||||
logging.info(f"执行重启命令: {restart_command}")
|
|
||||||
os.system(restart_command)
|
|
||||||
# --- 重启命令结束 ---
|
|
||||||
|
|
||||||
return False
|
|
||||||
except ValueError: # 捕获 int(port) 转换失败的情况
|
|
||||||
print(f"错误: 端口 '{port}' 不是有效的数字。")
|
|
||||||
logging.error(f"端口 '{port}' 不是有效的数字。")
|
|
||||||
return False
|
|
||||||
finally:
|
|
||||||
s.close() # 确保无论成功或失败,socket 都会被关闭
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# --- 目标设备IP和端口 ---
|
|
||||||
# 这些值在原脚本中是硬编码的,如果需要从命令行参数获取,请修改
|
|
||||||
target_ip = '192.168.8.9'
|
|
||||||
target_port = 10129
|
|
||||||
# --- 目标设备IP和端口结束 ---
|
|
||||||
|
|
||||||
logging.info(f"启动端口检查程序,检查 {target_ip}:{target_port}")
|
|
||||||
IsOpen(target_ip, target_port)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import sys # sys 模块用于 sys.exit(),虽然这里没有直接使用,但通常在脚本中需要
|
|
||||||
|
|
||||||
# --- 配置日志 ---
|
|
||||||
# 确保日志文件路径正确
|
|
||||||
LOG_FILE = '/opt/upc_resent/log/upc-192.168.8.73.log'
|
|
||||||
# 定义时间格式,将被 logging.basicConfig 的 datefmt 使用
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
# 配置日志,确保只执行一次
|
|
||||||
# format 中包含了时间戳 %(asctime)s,所以不需要手动在日志字符串中添加 datetime
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG,
|
|
||||||
format='%(asctime)s - %(levelname)s - %(message)s', datefmt=ISOTIMEFORMAT)
|
|
||||||
# --- 日志配置结束 ---
|
|
||||||
|
|
||||||
|
|
||||||
def IsOpen(ip, port):
|
|
||||||
"""
|
|
||||||
检查指定IP和端口是否可达。
|
|
||||||
如果端口不可达,则记录警告并尝试重启另一个Python脚本。
|
|
||||||
"""
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
s.settimeout(1) # 设置连接超时为1秒,避免无限期阻塞
|
|
||||||
try:
|
|
||||||
logging.debug(f"尝试连接到 {ip}:{port}...")
|
|
||||||
s.connect((ip, int(port)))
|
|
||||||
s.shutdown(socket.SHUT_RDWR) # 使用 SHUT_RDWR 代替数字 2,更具可读性
|
|
||||||
|
|
||||||
print(f"端口 {port} is open") # Python 3 print 函数
|
|
||||||
logging.info(f"端口 {port} is open")
|
|
||||||
return True
|
|
||||||
except (OSError, socket.timeout) as e: # 捕获具体的网络错误和超时
|
|
||||||
print(f"端口 {port} is down") # Python 3 print 函数
|
|
||||||
logging.warning(f"端口 {port} 检查失败: {e},尝试重启程序")
|
|
||||||
|
|
||||||
# --- 重启命令 ---
|
|
||||||
# 确保这里的 python3 路径和脚本路径正确
|
|
||||||
# 这里的脚本名 "192.168.8.125.py" 看起来是硬编码的,请确认是否正确
|
|
||||||
restart_command = "/usr/bin/python3 /opt/upc_resent/bin/192.168.8.73.py &"
|
|
||||||
logging.info(f"执行重启命令: {restart_command}")
|
|
||||||
os.system(restart_command)
|
|
||||||
# --- 重启命令结束 ---
|
|
||||||
|
|
||||||
return False
|
|
||||||
except ValueError: # 捕获 int(port) 转换失败的情况
|
|
||||||
print(f"错误: 端口 '{port}' 不是有效的数字。")
|
|
||||||
logging.error(f"端口 '{port}' 不是有效的数字。")
|
|
||||||
return False
|
|
||||||
finally:
|
|
||||||
s.close() # 确保无论成功或失败,socket 都会被关闭
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# --- 目标设备IP和端口 ---
|
|
||||||
# 这些值在原脚本中是硬编码的,如果需要从命令行参数获取,请修改
|
|
||||||
target_ip = '192.168.8.9'
|
|
||||||
target_port = 10079
|
|
||||||
# --- 目标设备IP和端口结束 ---
|
|
||||||
|
|
||||||
logging.info(f"启动端口检查程序,检查 {target_ip}:{target_port}")
|
|
||||||
IsOpen(target_ip, target_port)
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
|
||||||
# Device: 设备73-TCP (dev1)
|
|
||||||
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# ====== 配置参数(从配置文件读取)======
|
|
||||||
TARGET_IP = '192.168.8.9'
|
|
||||||
TARGET_PORT = 10079
|
|
||||||
LOG_FILE = '/home/smart/pythonPJ/upc_resent/log/crond-dev1.log'
|
|
||||||
RESTART_COMMAND = "/usr/bin/python3 /home/smart/pythonPJ/upc_resent/bin/dev1.py &"
|
|
||||||
DEVICE_ID = 'dev1'
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG,
|
|
||||||
format='%(asctime)s - %(levelname)s - %(message)s', datefmt=ISOTIMEFORMAT)
|
|
||||||
|
|
||||||
|
|
||||||
def is_port_open(ip, port):
|
|
||||||
"""检查指定IP和端口是否可达"""
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
s.settimeout(1)
|
|
||||||
try:
|
|
||||||
logging.debug(f"尝试连接到 {ip}:{port}...")
|
|
||||||
s.connect((ip, int(port)))
|
|
||||||
s.shutdown(socket.SHUT_RDWR)
|
|
||||||
print(f"[{DEVICE_ID}] 端口 {port} is open")
|
|
||||||
logging.info(f"端口 {port} is open")
|
|
||||||
return True
|
|
||||||
except (OSError, socket.timeout) as e:
|
|
||||||
print(f"[{DEVICE_ID}] 端口 {port} is down")
|
|
||||||
logging.warning(f"端口 {port} 检查失败: {e},尝试重启程序")
|
|
||||||
logging.info(f"执行重启命令: {RESTART_COMMAND}")
|
|
||||||
os.system(RESTART_COMMAND)
|
|
||||||
return False
|
|
||||||
except ValueError:
|
|
||||||
print(f"错误: 端口 '{port}' 不是有效的数字。")
|
|
||||||
logging.error(f"端口 '{port}' 不是有效的数字。")
|
|
||||||
return False
|
|
||||||
finally:
|
|
||||||
s.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
logging.info(f"[{DEVICE_ID}] 启动端口检查程序,检查 {TARGET_IP}:{TARGET_PORT}")
|
|
||||||
print(f"[{DEVICE_ID}] 启动端口检查程序,检查 {TARGET_IP}:{TARGET_PORT}")
|
|
||||||
is_port_open(TARGET_IP, TARGET_PORT)
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
|
||||||
# Device: 设备125-TCP (dev2)
|
|
||||||
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# ====== 配置参数(从配置文件读取)======
|
|
||||||
TARGET_IP = '192.168.8.9'
|
|
||||||
TARGET_PORT = 10129
|
|
||||||
LOG_FILE = '/home/smart/pythonPJ/upc_resent/log/crond-dev2.log'
|
|
||||||
RESTART_COMMAND = "/usr/bin/python3 /home/smart/pythonPJ/upc_resent/bin/dev2.py &"
|
|
||||||
DEVICE_ID = 'dev2'
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG,
|
|
||||||
format='%(asctime)s - %(levelname)s - %(message)s', datefmt=ISOTIMEFORMAT)
|
|
||||||
|
|
||||||
|
|
||||||
def is_port_open(ip, port):
|
|
||||||
"""检查指定IP和端口是否可达"""
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
s.settimeout(1)
|
|
||||||
try:
|
|
||||||
logging.debug(f"尝试连接到 {ip}:{port}...")
|
|
||||||
s.connect((ip, int(port)))
|
|
||||||
s.shutdown(socket.SHUT_RDWR)
|
|
||||||
print(f"[{DEVICE_ID}] 端口 {port} is open")
|
|
||||||
logging.info(f"端口 {port} is open")
|
|
||||||
return True
|
|
||||||
except (OSError, socket.timeout) as e:
|
|
||||||
print(f"[{DEVICE_ID}] 端口 {port} is down")
|
|
||||||
logging.warning(f"端口 {port} 检查失败: {e},尝试重启程序")
|
|
||||||
logging.info(f"执行重启命令: {RESTART_COMMAND}")
|
|
||||||
os.system(RESTART_COMMAND)
|
|
||||||
return False
|
|
||||||
except ValueError:
|
|
||||||
print(f"错误: 端口 '{port}' 不是有效的数字。")
|
|
||||||
logging.error(f"端口 '{port}' 不是有效的数字。")
|
|
||||||
return False
|
|
||||||
finally:
|
|
||||||
s.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
logging.info(f"[{DEVICE_ID}] 启动端口检查程序,检查 {TARGET_IP}:{TARGET_PORT}")
|
|
||||||
print(f"[{DEVICE_ID}] 启动端口检查程序,检查 {TARGET_IP}:{TARGET_PORT}")
|
|
||||||
is_port_open(TARGET_IP, TARGET_PORT)
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# Auto-generated from template. DO NOT EDIT DIRECTLY!
|
|
||||||
# Device: 设备UDP示例 (dev3) - UDP Protocol
|
|
||||||
|
|
||||||
import time
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import sys
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
# ====== 配置参数(从配置文件读取)======
|
|
||||||
TARGET_IP = '192.168.8.9'
|
|
||||||
TARGET_PORT = 10080
|
|
||||||
LOG_FILE = '/home/smart/pythonPJ/upc_resent/log/crond-dev3.log'
|
|
||||||
RESTART_COMMAND = "/usr/bin/python3 /home/smart/pythonPJ/upc_resent/bin/dev3.py &"
|
|
||||||
DEVICE_ID = 'dev3'
|
|
||||||
# =========================
|
|
||||||
|
|
||||||
ISOTIMEFORMAT = '%Y-%m-%d %X'
|
|
||||||
|
|
||||||
logging.basicConfig(filename=LOG_FILE, filemode="a", level=logging.DEBUG,
|
|
||||||
format='%(asctime)s - %(levelname)s - %(message)s', datefmt=ISOTIMEFORMAT)
|
|
||||||
|
|
||||||
|
|
||||||
def is_udp_port_open(ip, port):
|
|
||||||
"""
|
|
||||||
检查UDP端口是否可用。
|
|
||||||
UDP是无连接的,这里通过检查端口是否被占用或发送测试数据来判断。
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# 尝试绑定到该端口,如果成功说明端口未被占用(服务未启动)
|
|
||||||
# 如果失败说明端口已被占用(服务正在运行)
|
|
||||||
test_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
test_sock.settimeout(1)
|
|
||||||
test_sock.bind((ip, int(port)))
|
|
||||||
test_sock.close()
|
|
||||||
|
|
||||||
# 如果绑定成功,说明服务未启动
|
|
||||||
print(f"[{DEVICE_ID}] UDP端口 {port} 未被占用,服务可能未运行")
|
|
||||||
logging.warning(f"UDP端口 {port} 未被占用,服务可能未运行,尝试重启程序")
|
|
||||||
logging.info(f"执行重启命令: {RESTART_COMMAND}")
|
|
||||||
os.system(RESTART_COMMAND)
|
|
||||||
return False
|
|
||||||
except OSError as e:
|
|
||||||
# 绑定失败,说明端口已被占用,服务正在运行
|
|
||||||
if "Address already in use" in str(e) or "98" in str(e):
|
|
||||||
print(f"[{DEVICE_ID}] UDP端口 {port} is open (已被占用,服务运行中)")
|
|
||||||
logging.info(f"UDP端口 {port} is open (服务运行中)")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"[{DEVICE_ID}] 检查UDP端口 {port} 时发生错误: {e}")
|
|
||||||
logging.error(f"检查UDP端口 {port} 时发生错误: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def check_process_running():
|
|
||||||
"""通过进程名检查服务是否正在运行"""
|
|
||||||
try:
|
|
||||||
# 检查是否有对应设备的Python进程在运行
|
|
||||||
cmd = f"ps aux | grep '{DEVICE_ID}.py' | grep -v grep"
|
|
||||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
|
||||||
if result.returncode == 0 and result.stdout.strip():
|
|
||||||
print(f"[{DEVICE_ID}] 进程检查: 服务正在运行")
|
|
||||||
logging.info(f"进程检查: 服务正在运行")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"[{DEVICE_ID}] 进程检查: 服务未运行")
|
|
||||||
logging.warning(f"进程检查: 服务未运行,尝试重启")
|
|
||||||
logging.info(f"执行重启命令: {RESTART_COMMAND}")
|
|
||||||
os.system(RESTART_COMMAND)
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[{DEVICE_ID}] 进程检查失败: {e}")
|
|
||||||
logging.error(f"进程检查失败: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
logging.info(f"[{DEVICE_ID}] 启动UDP端口检查程序,检查 {TARGET_IP}:{TARGET_PORT}")
|
|
||||||
print(f"[{DEVICE_ID}] 启动UDP端口检查程序,检查 {TARGET_IP}:{TARGET_PORT}")
|
|
||||||
|
|
||||||
# 对于UDP,优先使用进程检查方式
|
|
||||||
check_process_running()
|
|
||||||
Binary file not shown.
@@ -1,5 +0,0 @@
|
|||||||
INFO:root:服务启动,监听 192.168.8.9:10079
|
|
||||||
INFO:root:===2026-03-21 20:14:40收到客户端192.168.9.71:56925发送的指令: 'close1'
|
|
||||||
INFO:root:===2026-03-21 20:14:40 映射到内部指令: 'close1'
|
|
||||||
INFO:root:执行外部命令: /usr/bin/python3 /opt/upc_resent/bin/sender.py 192.168.8.73 502 close1 /opt/upc_resent/log/192.168.8.73.log
|
|
||||||
INFO:root:2026-03-21 20:14:40 close1命令第1次发送成功
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
2026-03-21 21:06:19 - INFO - 启动端口检查程序,检查 192.168.8.9:10129
|
|
||||||
2026-03-21 21:06:19 - DEBUG - 尝试连接到 192.168.8.9:10129...
|
|
||||||
2026-03-21 21:06:19 - INFO - 端口 10129 is open
|
|
||||||
@@ -210,27 +210,34 @@ def generate_crontab(devices, global_config):
|
|||||||
return output_file
|
return output_file
|
||||||
|
|
||||||
|
|
||||||
def generate_start_script(devices, global_config):
|
def generate_control_script(devices, global_config):
|
||||||
"""生成启动脚本"""
|
"""生成控制脚本 (start/stop/restart/status)"""
|
||||||
lines = ['#!/bin/bash']
|
|
||||||
lines.append('# Auto-generated start script')
|
|
||||||
lines.append('')
|
|
||||||
lines.append('# 启动所有监听服务')
|
|
||||||
|
|
||||||
|
template_file = 'templates/control.sh.tpl'
|
||||||
|
with open(template_file, 'r', encoding='utf-8') as f:
|
||||||
|
template = f.read()
|
||||||
|
|
||||||
|
device_list = []
|
||||||
for device in devices:
|
for device in devices:
|
||||||
if not device.get('enabled', True):
|
if device.get('enabled', True):
|
||||||
lines.append(f"# {device['name']} ({device['id']}) - 已禁用")
|
device_list.append({
|
||||||
continue
|
'id': device['id'],
|
||||||
protocol = device.get('protocol', 'tcp').upper()
|
'name': device['name'],
|
||||||
script_path = f"{global_config['base_dir']}/bin/{device['id']}.py"
|
'protocol': device.get('protocol', 'tcp').upper()
|
||||||
lines.append(f"echo '启动 {device['name']} ({device['id']}) - {protocol}...'")
|
})
|
||||||
lines.append(f"su root -c \"{global_config['python_path']} {script_path} &\"")
|
|
||||||
|
|
||||||
lines.append('')
|
# 构建设备列表字符串
|
||||||
lines.append('echo "所有服务已启动"')
|
device_defs = "\n".join([
|
||||||
|
f" \"{d['id']}\" \"{d['name']}\" \"{d['protocol']}\""
|
||||||
|
for d in device_list
|
||||||
|
])
|
||||||
|
|
||||||
content = '\n'.join(lines) + '\n'
|
# 替换模板变量(使用 replace 避免与 bash 变量冲突)
|
||||||
output_file = 'start.sh'
|
content = template.replace('{base_dir}', global_config['base_dir'])
|
||||||
|
content = content.replace('{python_path}', global_config['python_path'])
|
||||||
|
content = content.replace('{device_defs}', device_defs)
|
||||||
|
|
||||||
|
output_file = 'control.sh'
|
||||||
with open(output_file, 'w', encoding='utf-8') as f:
|
with open(output_file, 'w', encoding='utf-8') as f:
|
||||||
f.write(content)
|
f.write(content)
|
||||||
|
|
||||||
@@ -383,15 +390,15 @@ def main():
|
|||||||
print("\n[生成配置文件]")
|
print("\n[生成配置文件]")
|
||||||
generated_files.append(generate_crontab(config['devices'], global_config))
|
generated_files.append(generate_crontab(config['devices'], global_config))
|
||||||
|
|
||||||
# 4. 生成启动脚本
|
# 4. 生成控制脚本
|
||||||
generated_files.append(generate_start_script(devices, global_config))
|
generated_files.append(generate_control_script(devices, global_config))
|
||||||
|
|
||||||
print("\n" + "=" * 50)
|
print("\n" + "=" * 50)
|
||||||
print(f"[✓] 代码生成完成!共生成 {len(generated_files)} 个文件")
|
print(f"[✓] 代码生成完成!共生成 {len(generated_files)} 个文件")
|
||||||
print("=" * 50)
|
print("=" * 50)
|
||||||
print(f"\n部署目录: {global_config['base_dir']}")
|
print(f"\n部署目录: {global_config['base_dir']}")
|
||||||
print("\n使用方法:")
|
print("\n使用方法:")
|
||||||
print(f" 1. 启动服务: ./{generated_files[-1]}")
|
print(f" 1. 控制服务: ./{generated_files[-1]} {{start|stop|restart|status}}")
|
||||||
print(f" 2. 配置 crontab: crontab crontab.txt")
|
print(f" 2. 配置 crontab: crontab crontab.txt")
|
||||||
print("\n支持的协议:")
|
print("\n支持的协议:")
|
||||||
protocols = set(d.get('protocol', 'tcp').upper() for d in devices)
|
protocols = set(d.get('protocol', 'tcp').upper() for d in devices)
|
||||||
|
|||||||
12
start.sh
12
start.sh
@@ -1,12 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Auto-generated start script
|
|
||||||
|
|
||||||
# 启动所有监听服务
|
|
||||||
echo '启动 设备73-TCP (dev1) - TCP...'
|
|
||||||
su root -c "/usr/bin/python3 /home/smart/pythonPJ/upc_resent/bin/dev1.py &"
|
|
||||||
echo '启动 设备125-TCP (dev2) - TCP...'
|
|
||||||
su root -c "/usr/bin/python3 /home/smart/pythonPJ/upc_resent/bin/dev2.py &"
|
|
||||||
echo '启动 设备UDP示例 (dev3) - UDP...'
|
|
||||||
su root -c "/usr/bin/python3 /home/smart/pythonPJ/upc_resent/bin/dev3.py &"
|
|
||||||
|
|
||||||
echo "所有服务已启动"
|
|
||||||
234
templates/control.sh.tpl
Normal file
234
templates/control.sh.tpl
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Auto-generated control script
|
||||||
|
# Usage: ./control.sh {start|stop|restart|status}
|
||||||
|
|
||||||
|
BASE_DIR="{base_dir}"
|
||||||
|
PYTHON_PATH="{python_path}"
|
||||||
|
|
||||||
|
# 设备列表: ID 名称 协议
|
||||||
|
DEVICES=(
|
||||||
|
{device_defs}
|
||||||
|
)
|
||||||
|
|
||||||
|
# 颜色定义
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
show_help() {
|
||||||
|
echo "Usage: $0 {start|stop|restart|status}"
|
||||||
|
echo ""
|
||||||
|
echo "Commands:"
|
||||||
|
echo " start 启动所有服务"
|
||||||
|
echo " stop 停止所有服务"
|
||||||
|
echo " restart 重启所有服务"
|
||||||
|
echo " status 查看服务状态"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_root() {
|
||||||
|
if [[ $EUID -ne 0 ]]; then
|
||||||
|
echo -e "${YELLOW}Warning: 建议使用 root 权限运行${NC}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
local device_id=$1
|
||||||
|
local device_name=$2
|
||||||
|
local protocol=$3
|
||||||
|
local script_path="$BASE_DIR/bin/$device_id.py"
|
||||||
|
|
||||||
|
# 检查进程是否已存在(使用更精确的匹配)
|
||||||
|
local pid=$(pgrep -f "${PYTHON_PATH}.*${script_path}" | head -1)
|
||||||
|
if [[ -n "$pid" ]]; then
|
||||||
|
echo -e "[${YELLOW}SKIP${NC}] $device_name ($device_id) - ${protocol} 已在运行 (PID: $pid)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -n "[START] $device_name ($device_id) - ${protocol} ... "
|
||||||
|
nohup $PYTHON_PATH "$script_path" > /dev/null 2>&1 &
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
# 检查是否启动成功
|
||||||
|
pid=$(pgrep -f "${PYTHON_PATH}.*${script_path}" | head -1)
|
||||||
|
if [[ -n "$pid" ]]; then
|
||||||
|
echo -e "${GREEN}OK${NC} (PID: $pid)"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}FAILED${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
local device_id=$1
|
||||||
|
local device_name=$2
|
||||||
|
local protocol=$3
|
||||||
|
local script_path="$BASE_DIR/bin/$device_id.py"
|
||||||
|
|
||||||
|
# 使用更精确的匹配模式
|
||||||
|
local pids=$(pgrep -f "${PYTHON_PATH}.*${script_path}")
|
||||||
|
if [[ -z "$pids" ]]; then
|
||||||
|
echo -e "[${YELLOW}SKIP${NC}] $device_name ($device_id) - 未运行"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 获取第一个匹配的 PID
|
||||||
|
local pid=$(echo "$pids" | head -1)
|
||||||
|
echo -n "[STOP] $device_name ($device_id) - ${protocol} (PID: $pid) ... "
|
||||||
|
|
||||||
|
# 结束所有匹配的进程
|
||||||
|
echo "$pids" | while read -r p; do
|
||||||
|
kill "$p" 2>/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
# 等待进程结束
|
||||||
|
local i
|
||||||
|
for i in {1..10}; do
|
||||||
|
sleep 0.5
|
||||||
|
pids=$(pgrep -f "${PYTHON_PATH}.*${script_path}" || true)
|
||||||
|
if [[ -z "$pids" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 检查是否还有残留进程
|
||||||
|
pids=$(pgrep -f "${PYTHON_PATH}.*${script_path}" || true)
|
||||||
|
if [[ -n "$pids" ]]; then
|
||||||
|
# 强制结束残留进程
|
||||||
|
echo "$pids" | while read -r p; do
|
||||||
|
kill -9 "$p" 2>/dev/null
|
||||||
|
done
|
||||||
|
sleep 0.5
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 最终检查
|
||||||
|
pids=$(pgrep -f "${PYTHON_PATH}.*${script_path}" || true)
|
||||||
|
if [[ -z "$pids" ]]; then
|
||||||
|
echo -e "${GREEN}OK${NC}"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}FAILED${NC}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
status_service() {
|
||||||
|
local device_id=$1
|
||||||
|
local device_name=$2
|
||||||
|
local protocol=$3
|
||||||
|
local script_path="$BASE_DIR/bin/$device_id.py"
|
||||||
|
|
||||||
|
local pid=$(pgrep -f "${PYTHON_PATH}.*${script_path}" | head -1)
|
||||||
|
if [[ -n "$pid" ]]; then
|
||||||
|
echo -e "${GREEN}[RUNNING]${NC} $device_name ($device_id) - ${protocol} (PID: $pid)"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}[STOPPED]${NC} $device_name ($device_id) - ${protocol}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_start() {
|
||||||
|
echo "======================================="
|
||||||
|
echo "启动 UPC Resent 服务"
|
||||||
|
echo "======================================="
|
||||||
|
check_root
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local count=0
|
||||||
|
local device_id device_name protocol
|
||||||
|
for ((i=0; i<${#DEVICES[@]}; i+=3)); do
|
||||||
|
device_id="${DEVICES[i]}"
|
||||||
|
device_name="${DEVICES[i+1]}"
|
||||||
|
protocol="${DEVICES[i+2]}"
|
||||||
|
|
||||||
|
if start_service "$device_id" "$device_name" "$protocol"; then
|
||||||
|
((count++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================="
|
||||||
|
echo "启动完成: $count/$((${#DEVICES[@]}/3)) 个服务"
|
||||||
|
echo "======================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_stop() {
|
||||||
|
echo "======================================="
|
||||||
|
echo "停止 UPC Resent 服务"
|
||||||
|
echo "======================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local count=0
|
||||||
|
local device_id device_name protocol
|
||||||
|
for ((i=0; i<${#DEVICES[@]}; i+=3)); do
|
||||||
|
device_id="${DEVICES[i]}"
|
||||||
|
device_name="${DEVICES[i+1]}"
|
||||||
|
protocol="${DEVICES[i+2]}"
|
||||||
|
|
||||||
|
if stop_service "$device_id" "$device_name" "$protocol"; then
|
||||||
|
((count++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================="
|
||||||
|
echo "停止完成: $count/$((${#DEVICES[@]}/3)) 个服务"
|
||||||
|
echo "======================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_restart() {
|
||||||
|
cmd_stop
|
||||||
|
echo ""
|
||||||
|
sleep 1
|
||||||
|
cmd_start
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_status() {
|
||||||
|
echo "======================================="
|
||||||
|
echo "UPC Resent 服务状态"
|
||||||
|
echo "======================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
local running=0
|
||||||
|
local stopped=0
|
||||||
|
local device_id device_name protocol
|
||||||
|
|
||||||
|
for ((i=0; i<${#DEVICES[@]}; i+=3)); do
|
||||||
|
device_id="${DEVICES[i]}"
|
||||||
|
device_name="${DEVICES[i+1]}"
|
||||||
|
protocol="${DEVICES[i+2]}"
|
||||||
|
|
||||||
|
if status_service "$device_id" "$device_name" "$protocol"; then
|
||||||
|
((running++))
|
||||||
|
else
|
||||||
|
((stopped++))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "======================================="
|
||||||
|
echo "运行中: $running, 已停止: $stopped, 总计: $((${#DEVICES[@]}/3))"
|
||||||
|
echo "======================================="
|
||||||
|
}
|
||||||
|
|
||||||
|
# 主逻辑
|
||||||
|
case "${1:-}" in
|
||||||
|
start)
|
||||||
|
cmd_start
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
cmd_stop
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
cmd_restart
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
cmd_status
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -59,9 +59,13 @@ def check_process_running():
|
|||||||
"""通过进程名检查服务是否正在运行"""
|
"""通过进程名检查服务是否正在运行"""
|
||||||
try:
|
try:
|
||||||
# 检查是否有对应设备的Python进程在运行
|
# 检查是否有对应设备的Python进程在运行
|
||||||
cmd = f"ps aux | grep '{{DEVICE_ID}}.py' | grep -v grep"
|
# 注意:需要排除 crond 脚本自身的进程 (upcrond-{{DEVICE_ID}}.py)
|
||||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
cmd = f"ps aux | grep '{{DEVICE_ID}}.py' | grep -v grep | grep -v upcrond"
|
||||||
if result.returncode == 0 and result.stdout.strip():
|
# 兼容 Python 3.6: 使用 PIPE 代替 capture_output
|
||||||
|
result = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
# 兼容 Python 3.6: 手动解码输出
|
||||||
|
stdout = result.stdout.decode('utf-8') if result.stdout else ''
|
||||||
|
if result.returncode == 0 and stdout.strip():
|
||||||
print(f"[{{DEVICE_ID}}] 进程检查: 服务正在运行")
|
print(f"[{{DEVICE_ID}}] 进程检查: 服务正在运行")
|
||||||
logging.info(f"进程检查: 服务正在运行")
|
logging.info(f"进程检查: 服务正在运行")
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
su root -c "/usr/bin/python /opt/upc_resent/bin/192.168.8.73.py &"
|
|
||||||
su root -c "/usr/bin/python /opt/upc_resent/bin/192.168.8.125.py &"
|
|
||||||
Reference in New Issue
Block a user