用Python采用Modbus-Tcp的方式读取485电子水尺数据

README.TXT

2023/6/15 
V1.0 实现了单个点位数据通信、数据解析、数据存储
2023/6/17
V2.0 实现了多个点位数据通信、数据解析、数据存储
2023/6/19
V2.1 完善log存储,仅保留近3天的log记录,避免不必要的存储;限制log大小,2MB。

架构介绍

使用Python开发服务器程序,实现以下功能:

  1. 采用问询的方式读取各类传感器数据
  2. 正确高速解析各类传感器的数据
  3. 存储解析后的各类传感器数据
  4. 存储程序运行过程中的log
  5. 管理log,超过一定量、一定时间自动删除log
  6. 打包发布 或者 在后台运行py服务器程序

硬件介绍 传感器 串口服务器 采集模块 5G通信模块

主要传感器

485电子水尺传感器

该传感器支持485通信

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

其他硬件:

485漏液侦测传感器

485采集模块

串口服务器

5G通信模块

调试工具

采集模块调试工具

在这里插入图片描述

485电子水尺调试工具

在这里插入图片描述

串口调试助手,主要用于 漏液传感器在这里插入图片描述

其他工具

CRC计算器,不过我一般都是自己写CRC校验程序,CRC校验程序放在后面完整代码了

在这里插入图片描述

WIN10自带的计算器

在这里插入图片描述

调试过程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完整代码 LOG存储功能、数据读取解析存储功能

#!D:/workplace/python
# -*- coding: utf-8 -*-
# @File  : main0620.py
# @Author:Romulushe
# @Time    : 2023/6/20 13:53
# @Software: PyCharm
# @Use: PyCharm
import os
import sys
import logging
import time
from logging.handlers import RotatingFileHandler
import shutil
import socket
import threading
import pymysql
import binascii
import time
import datetimebase_path = os.path.dirname(os.path.realpath(sys.argv[0]))def get_log_path():return os.path.join(base_path, 'logs')def cleanup_logs():log_path = get_log_path()current_time = time.time()for file_name in os.listdir(log_path):file_path = os.path.join(log_path, file_name)if os.path.isfile(file_path):creation_time = os.path.getctime(file_path)if current_time - creation_time > (3 * 24 * 60 * 60):os.remove(file_path)def configure_logging():log_path = get_log_path()os.makedirs(log_path, exist_ok=True)log_filename = get_log_filename()log_file = os.path.join(log_path, log_filename)logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s', filename=log_file)def get_log_filename():now = datetime.datetime.now()return now.strftime("%Y-%m-%d_%H-%M.log")def create_new_log():log_path = get_log_path()log_files = os.listdir(log_path)if len(log_files) >= 20:oldest_file = min(log_files)os.remove(os.path.join(log_path, oldest_file))log_filename = get_log_filename()log_filepath = os.path.join(log_path, log_filename)return log_filepathdef check_log_size(log_filepath):log_size = os.path.getsize(log_filepath)if log_size > 2 * 1024 * 1024:# 创建新的日志文件new_log_filepath = create_new_log()try:shutil.move(log_filepath, new_log_filepath)return new_log_filepathexcept PermissionError:insert_log(logger, f'{log_filepath} {PermissionError}', log_filepath)time.sleep(0.1)return log_filepathreturn log_filepathdef insert_log(logger, log_message, log_filepath):log_filepath = check_log_size(log_filepath)# 创建文件处理器file_handler = RotatingFileHandler(log_filepath, maxBytes=2 * 1024 * 1024, backupCount=1)file_handler.setLevel(logging.DEBUG)formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')file_handler.setFormatter(formatter)# 添加文件处理器到日志记录器logger.addHandler(file_handler)try:logger.debug(log_message)except PermissionError:insert_log(logger, f'{log_message} {PermissionError}', log_filepath)time.sleep(0.1)  # 延迟0.1秒# 移除文件处理器logger.removeHandler(file_handler)# 定义个函数,使其专门重复处理客户端的请求数据(也就是重复接受一个用户的消息并且重复回答,直到用户选择下线)
def client_request_1(tcp_client_1, tcp_client_address):#print(tcp_client_1)# 循环接收和发送数据while True:# #print(datetime.datetime.today())# msg=["010300000005859C","02020000000879FF"]# msg=['010300010001D5CA',"02020000000879FF"]# msg=["010300000001840A","02020000000879FF"]#8点位msg=msg_address(tcp_client_address)# interval =60interval = int(60 / len(msg))# print(interval,type(interval))for i in msg:try:tcp_client_1.send(binascii.unhexlify(i))recv_data = tcp_client_1.recv(4096)# 有消息就回复数据,消息长度为0就是说明客户端下线了if recv_data:# #print(f"recv_data:{recv_data}")bistr = binascii.hexlify(recv_data).decode('utf8')# print("==================================================")# print(f"读数:【{bistr}】,{len(bistr)}")try:if (bistr.startswith('010302') or bistr.startswith('030302') ) and len(bistr) >=14:bistr=bistr[:15]# # 输入数据input_data = bistr[:-4]# # 计算带有校验码的结果result = calculate_checksum(input_data)if bistr == result:waterLevel = int(bistr[6:10], 16)print("水深", waterLevel, "cm", bistr, bistr[6:10], bistr[:-4], bistr[-4:], "input_data:",{input_data}, " result:", {result})# #print(bistr==result)ip_address(tcp_client_address[0], tcp_client_address[1], waterLevel, 'water')if bistr.startswith("020201") and len(bistr) >= 12:bistr = bistr[:13]# 输入数据input_data = bistr[:-4]# 计算带有校验码的结果result = calculate_checksum(input_data)# #print(result==bistr)if result == bistr:data = data_address(bistr)#print(f"水泵采集模块状态:{data}")ip_address(tcp_client_address[0], tcp_client_address[1], data, 'status')ip_address(tcp_client_address[0], tcp_client_address[1], data, 'fault')if bistr.startswith("0104") and len(bistr) >= 14:bistr = bistr[:15]# 输入数据input_data = bistr[:-4]# # 计算带有校验码的结果result = calculate_checksum(input_data)if result == bistr:# #print(f"bistr[6:10]:{bistr[6:10]}")data =int(bistr[6:10], 16)#print(f"漏液检测状态:{data}")ip_address(tcp_client_address[0], tcp_client_address[1], data, 'liquid')except Exception as e:insert_log(logger, f'{tcp_client_address} {e}', log_filepath)#print(e)else:#print("%s 客户端下线了..." % tcp_client_address[1])insert_log(logger, f'{tcp_client_address[1]} OFFLINE', log_filepath)tcp_client_1.close()break# time.sleep(interval)time.sleep(2)except Exception as e:insert_log(logger, f'{tcp_client_address} {i} {e}', log_filepath)#print(f"{tcp_client_address} {i} {e}")# 连接数据库
def connect_database(host, port, user, password, db_name):try:conn = pymysql.connect(host=host, port=port, user=user, password=password, db=db_name)# print("成功连接到数据库")return connexcept pymysql.Error as e:insert_log(logger, f'DATABASE CONNECT FAILED', log_filepath)# print(f"数据库连接失败: {e}")# 插入数据
def insert_data(conn, types,table_name, create_time, location_no, parameter_desc, location, param_value):try:cursor = conn.cursor()sql = f"INSERT INTO {table_name} (TYPE, CREATE_TIME, LOCATION_NO, PARAMETER_DESC, LOCATION, PARAMVALUE) " \f"VALUES (%s, %s, %s, %s, %s, %s)"cursor.execute(sql, (types,create_time, location_no, parameter_desc, location, param_value))conn.commit()# print(f"数据插入成功: {create_time}, {parameter_desc}: {param_value}")cursor.close()except pymysql.Error as e:insert_log(logger, f'DATABASE INSERT DATA FAILED', log_filepath)# print(f"数据插入失败: {e}")def msg_address(tcp_client_address):if tcp_client_address[0] == '根据实际IP修改' or tcp_client_address[0] == '根据实际IP修改' or tcp_client_address[0] == '根据实际IP修改' :msg = ["010300000001840A", "02020000000879FF"]  # 8点位无其他,水位01,状态02return msgif (tcp_client_address[0] == '根据实际IP修改' and tcp_client_address[1] == 10010 )or tcp_client_address[0] == '根据实际IP修改' or (tcp_client_address[0] == '根据实际IP修改'  and tcp_client_address[1] == 10000 ) or tcp_client_address[0] == '根据实际IP修改'  or tcp_client_address[0] == '根据实际IP修改' :msg =["010300000001840A", "02020000000879FF"]  # 4点位非漏液,水位01,状态02return msgif (tcp_client_address[0] =='根据实际IP修改'  and tcp_client_address[1] == 10000 )or (tcp_client_address[0] == '根据实际IP修改'  and tcp_client_address[1] == 10010):msg = ["01040000000131CA"]  # 4点位漏液return msgif tcp_client_address[0] == '根据实际IP修改' :msg = ["010300010001D5CA","01040000000131CA"]  # 2点位漏液,漏液01,水位02return msgif tcp_client_address[0] == '根据实际IP修改' :msg = ["03030000000185E8","02020000000879FF"]  # 展厅漏液01,水位03,状态02# msg = ["03030000000185E8", "02020000000879FF", "01040000000131CA"]  # 展厅漏液01,水位03,状态02return msg#ip判断
def ip_address(ip,port,param_value,notes):host = ''#根据实际情况自定义port = 3306user =''#根据实际情况自定义password = ''#根据实际情况自定义db_name = ''#根据实际情况自定义table_name =''#根据实际情况自定义# 连接数据库conn = connect_database(host, port, user, password, db_name)#8点位采集+水尺if str(ip)==''#根据实际情况自定义:#只有1号端口#水位尺数据#采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()location = ''#根据实际情况自定义# 模拟数据if notes=='water':location_no =''#根据实际情况自定义parameter_desc = '水位值'# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes=='status':data=param_value# print("data:",data)status1=data[0]#1status2=data[1]#2status3=data[4]#5status4=data[6]#7# print("status1,status2,status3,status4:",status1,status2,status3,status4)# # 插入1号数据location_no = 'D04-01'parameter_desc = '1号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status1)# 插入2号数据location_no = 'D04-02'parameter_desc = '2号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status2)# 插入3号数据location_no = 'D04-03'parameter_desc = '3号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status3)# 插入4号数据location_no = 'D04-04'parameter_desc = '4号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status4)if notes=='fault':data = param_valuefault1 = data[2]#3fault2 = data[3]#4fault3 = data[5]#6fault4 = data[7]#8# print("fault1,fault2,fault3,fault4:",fault1,fault2,fault3,fault4)# 插入1号数据location_no = 'D04-05'parameter_desc = '1号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault1)# 插入2号数据location_no = 'D04-06'parameter_desc = '2号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault2)# 插入3号数据location_no = 'D04-07'parameter_desc = '3号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault3)# 插入4号数据location_no = 'D04-08'parameter_desc = '4号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault4)# 8点位采集+水尺if str(ip)==''#根据实际情况自定义:#只有1号端口#水位尺数据#采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()location =''#根据实际情况自定义# 模拟数据if notes=='water':location_no = 'D07'parameter_desc = '水位值'# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes=='status':data=param_valuestatus1=data[0]status2=data[1]status3=data[2]status4=data[3]#print("status1,status2,status3,status4:",status1,status2,status3,status4)# 插入1号数据location_no = 'D07-01'parameter_desc = '1号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status1)# 插入2号数据location_no = 'D07-02'parameter_desc = '2号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status2)# 插入3号数据location_no = 'D07-03'parameter_desc = '3号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status3)# 插入4号数据location_no = 'D07-04'parameter_desc = '4号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status4)if notes=='fault':data=param_valuefault1 = data[4]fault2 = data[5]fault3 = data[6]fault4 = data[7]#print("fault1,fault2,fault3,fault4:",fault1,fault2,fault3,fault4)# 插入1号数据location_no = 'D07-05'parameter_desc = '1号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault1)# 插入2号数据location_no = 'D07-06'parameter_desc = '2号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault2)# 插入3号数据location_no = 'D07-07'parameter_desc = '3号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault3)# 插入4号数据location_no = 'D07-08'parameter_desc = '4号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault4)# 8点位采集+水尺if str(ip) == ''#根据实际情况自定义:# 只有1号端口# 水位尺数据# 采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()location = ''#根据实际情况自定义# 模拟数据if notes == 'water':location_no = 'D08'parameter_desc = '水位值'# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes == 'status':data=param_valuestatus1 = data[0]status2 = data[1]status3 = data[2]status4 = data[3]#print("status1,status2,status3,status4:", status1, status2, status3, status4)# 插入1号数据location_no = 'D08-01'parameter_desc = '1号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status1)# 插入2号数据location_no = 'D08-02'parameter_desc = '2号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status2)# 插入3号数据location_no = 'D08-03'parameter_desc = '3号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status3)# 插入4号数据location_no = 'D08-04'parameter_desc = '4号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status4)if notes == 'fault':data=param_valuefault1 = data[4]fault2 = data[5]fault3 = data[6]fault4 = data[7]#print("fault1,fault2,fault3,fault4:", fault1, fault2, fault3, fault4)# 插入1号数据location_no = 'D08-05'parameter_desc = '1号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault1)# 插入2号数据location_no = 'D08-06'parameter_desc = '2号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault2)# 插入3号数据location_no = 'D08-07'parameter_desc = '3号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault3)# 插入4号数据location_no = 'D08-08'parameter_desc = '4号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault4)# 4点位采集+水尺if str(ip) ==''#根据实际情况自定义:# 只有1号端口# 水位尺数据# 采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()location = ''#根据实际情况自定义# 模拟数据if notes == 'water':location_no = 'D09'parameter_desc = '水位值'# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes == 'status':data=param_valuestatus1 = data[0]status2 = data[1]#print("status1,status2:", status1, status2)# 插入1号数据location_no = 'D09-01'parameter_desc = '1号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status1)# 插入2号数据location_no = 'D09-02'parameter_desc = '2号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status2)if notes == 'fault':data=param_valuefault1 = data[2]fault2 = data[3]#print("fault1,fault2:", fault1, fault2)# 插入1号数据location_no = 'D09-03'parameter_desc = '1号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault1)# 插入2号数据location_no = 'D09-04'parameter_desc = '2号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault2)if notes == 'liquid':data_liquid = param_value# 插入漏液数据location_no = 'F03'parameter_desc = ''#根据实际情况自定义location=''#根据实际情况自定义insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, data_liquid)# 4点位采集+水尺if str(ip) ==''#根据实际情况自定义:# 只有1号端口# 水位尺数据# 采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()location =''#根据实际情况自定义# 模拟数据if notes == 'water':location_no = 'D06'parameter_desc = '水位值'# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes == 'status':data=param_valuestatus1 = data[0]status2 = data[1]#print("status1,status2:", status1, status2)# 插入1号数据location_no = 'D06-01'parameter_desc = '1号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status1)# 插入2号数据location_no = 'D06-02'parameter_desc = '2号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status2)if notes == 'fault':data=param_valuefault1 = data[2]fault2 = data[3]#print("fault1,fault2:", fault1, fault2)# 插入1号数据location_no = 'D06-03'parameter_desc = '1号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault1)# 插入2号数据location_no = 'D06-04'parameter_desc = '2号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault2)# 4点位采集+水尺if str(ip) ==''#根据实际情况自定义:# 只有1号端口# 水位尺数据# 采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()location = ''#根据实际情况自定义# 模拟数据if notes == 'water':location_no = 'D05'parameter_desc = '水位值'# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes == 'status':data=param_valuestatus1 = data[0]status2 = data[1]# 插入1号数据location_no = 'D05-01'parameter_desc = '1号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status1)# 插入2号数据location_no = 'D05-02'parameter_desc = '2号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status2)if notes == 'fault':data=param_valuefault1 = data[2]fault2 = data[3]# 插入1号数据location_no = 'D05-03'parameter_desc = '1号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault1)# 插入2号数据location_no = 'D05-04'parameter_desc = '2号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault2)if notes == 'liquid':data_liquid = param_value# 插入漏液数据location_no = 'F02'parameter_desc =''#根据实际情况自定义location=''#根据实际情况自定义insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, data_liquid)# 4点位采集+水尺if str(ip) == ''#根据实际情况自定义:# 只有1号端口# 水位尺数据# 采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()location = ''#根据实际情况自定义# 模拟数据if notes == 'water':location_no = 'D03'parameter_desc = '水位值'# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes == 'status':data=param_valuestatus1 = data[0]status2 = data[1]#print("status1,status2:", status1, status2)# 插入1号数据location_no = 'D03-01'parameter_desc = '1号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status1)# 插入2号数据location_no = 'D03-02'parameter_desc = '2号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status2)if notes == 'fault':data=param_valuefault1 = data[2]fault2 = data[3]#print("fault1,fault2:", fault1, fault2)# 插入1号数据location_no = 'D03-03'parameter_desc = '1号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault1)# 插入2号数据location_no = 'D03-04'parameter_desc = '2号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault2)# 4点位采集+水尺if str(ip) == ''#根据实际情况自定义:# 只有1号端口# 水位尺数据# 采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()location =''#根据实际情况自定义# 模拟数据if notes == 'water':location_no = 'D01'parameter_desc = '水位值'# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes == 'status':data=param_valuestatus1 = data[0]status2 = data[1]#print("status1,status2:", status1, status2)# 插入1号数据location_no = 'D01-01'parameter_desc = '1号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status1)# 插入2号数据location_no = 'D01-02'parameter_desc = '2号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status2)if notes == 'fault':data=param_valuefault1 = data[2]fault2 = data[3]#print("fault1,fault2:", fault1, fault2)# 插入1号数据location_no = 'D01-03'parameter_desc = '1号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault1)# 插入2号数据location_no = 'D01-04'parameter_desc = '2号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault2)# 4点位采集+水尺if str(ip) == ''#根据实际情况自定义:# 只有1号端口# 水位尺数据# 采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()location =''#根据实际情况自定义# 模拟数据if notes == 'water':location_no = 'D02'parameter_desc = '水位值'print( 'water:',param_value)# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes == 'status':data=param_valuestatus1 = data[0]status2 = data[1]print("status1,status2:", status1, status2)# 插入1号数据location_no = 'D02-01'parameter_desc = '1号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status1)# 插入2号数据location_no = 'D02-02'parameter_desc = '2号泵浦状态'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, status2)if notes == 'fault':data=param_valuefault1 = data[2]fault2 = data[3]print("fault1,fault2:", fault1, fault2)# 插入1号数据location_no = 'D02-03'parameter_desc = '1号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault1)# 插入2号数据location_no = 'D02-04'parameter_desc = '2号泵浦故障'insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, fault2)if notes == 'liquid':data_liquid = param_valueprint('liquid:'.data_liquid)# 插入漏液数据location_no = 'F01'parameter_desc =''#根据实际情况自定义location=''#根据实际情况自定义insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, data_liquid)# 2点位采集+水尺if str(ip) == ''#根据实际情况自定义:# 只有1号端口# 水位尺数据# 采集模块数据# 数据库连接信息types = '防汛'create_time = datetime.datetime.now()# 模拟数据if notes == 'water':location_no = 'D10'parameter_desc = '水位值'location =''#根据实际情况自定义# 插入数据insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, param_value)if notes == 'liquid':data_liquid = param_value# 插入漏液数据location_no = 'F04'parameter_desc = ''#根据实际情况自定义location = ''#根据实际情况自定义insert_data(conn, types, table_name, create_time, location_no, parameter_desc, location, data_liquid)def data_address(data):extracted_data = data[6:8]binary_data = bin(int(extracted_data, 16))[2:].zfill(8)reversed_data = binary_data[::-1]return reversed_data#CRC校验
def calculate_crc(data):crc = 0xFFFFpolynomial = 0xA001for byte in data:crc ^= bytefor _ in range(8):if crc & 0x0001:crc >>= 1crc ^= polynomialelse:crc >>= 1return crcdef calculate_checksum(data):# 将输入数据转换为字节列表data_bytes = bytes.fromhex(data)# 计算校验码crc_value = calculate_crc(data_bytes)crc_bytes = crc_value.to_bytes(2, 'big')  # 将校验码转换为2字节的大端字节序checksum = ''.join(format(byte, '02x') for byte in reversed(crc_bytes))  # 转换为十六进制字符串,并反转字节顺序# 将校验码插入到原数据之后result = data + checksumreturn resultif __name__ == '__main__':configure_logging()cleanup_logs()log_filepath = create_new_log()logger = logging.getLogger()logger.setLevel(logging.DEBUG)oldtime = datetime.datetime.today()# 创建服务端套接字对象tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 设置端口复用,使程序退出后端口马上释放tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)# 绑定端口tcp_server.bind(("", 8050))# 设置监听tcp_server.listen(128)# 循环等待客户端连接请求while True:tcp_client_1, tcp_client_address = tcp_server.accept()tcp_client_1.settimeout(10)# 创建多线程对象thd = threading.Thread(target=client_request_1, args=(tcp_client_1, tcp_client_address))# #print(thd)# 设置守护主线程thd.setDaemon(True)# 启动子线程对象thd.start()# 关闭服务器套接字# tcp_server.close()`

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/23275.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十一章:MULTI-SCALE CONTEXT AGGREGATION BY DILATED CONVOLUTIONS——通过膨胀卷积的多尺度上下文聚合

0.摘要 目前用于语义分割的先进模型是基于最初设计用于图像分类的卷积网络的改进。然而,像语义分割这样的密集预测问题在结构上与图像分类不同。在这项工作中,我们开发了一个专门为密集预测设计的新的卷积网络模块。所提出的模块使用膨胀卷积来系统地聚合…

神码融信金融SBG交付二部VP李先林受邀为第十二届中国PMO大会演讲嘉宾

神码融信金融SBG交付二部VP李先林先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾,演讲议题:多项目管理的心得体会。大会将于8月12-13日在北京举办,敬请关注! 议题简要: 在后疫情时代,金融科技…

直播商城系统源码的威力:开启直播购物新时代

随着科技的不断进步和人们对互动性购物体验的追求,直播购物正成为电商行业的热门趋势。直播商城系统源码的威力在这一潮流中愈发显现,为商家和消费者提供了无限的机会和便利。 下面是一个简单的示例,展示了如何利用直播商城系统源码创建一个…

LSTM对比Bi-LSTM的电力负荷时间序列预测(Matlab)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

如何有效利用chatgpt?

如何有效地使用ChatGPT? 代码、诗歌、歌曲和短篇小说都可以由 ChatGPT 以特定的风格编写。您所需要的只是正确的问题和适当的提示。以下是有关如何有效使用ChatGPT的一些提示和想法: 头脑 风暴获取初稿解决编码问题尝试不同的提示格式查找标题寻求帮助…

集群基础1——集群概念、LVS负载均衡

文章目录 一、基本了解二、LVS负载均衡2.1 基本了解2.2 工作模式2.2.1 NAT模式2.2.2 DR模式2.2.3 LVS-TUN模式2.2.4 LVS-FULLNAT模式 三、调度器算法四、ipvsadm命令 一、基本了解 什么是集群? 多台服务器做同一件事情。 集群扩展方式: scale up&#xf…

RabbitMQ 同样的操作一次成功一次失败

RabbitMQ 是一个功能强大的消息队列系统,广泛应用于分布式系统中。然而,我遇到这样的情况:执行同样的操作,一次成功,一次失败。在本篇博文中,我将探讨这个问题的原因,并提供解决方法。 我是在表…

收费站对讲广播系统方案

收费站对讲广播系统方案 收费站对讲广播系统是一种用于收费站内部通信和广播传输的系统。它能够实现不同收费站点之间的语音通信和广播,以便快速、准确地传达信息和指令。该系统通常由以下几个核心组件组成:1. 主控台:主控台是系统的中心控制…

DevOps(二)

CD 1. 平台选择2. 技术选型3. 阶段性目标4. 搭建示例4.1 环境准备(节点机)1. java版本升级2. 编译安装git3. docker安装4. docker-compose安装5. sonarqube安装6. harbor安装7. gitlab私服 4.2 示例一(手动)1. 创建项目2. 编码3. Dockerfile4. 拷贝pytho…

离线安装docker

目录 1、下载docker 安装包 2、上传docker 到服务器目录/opt/ 3、解压docker-19.03.9.tgz 4、解压的docker文件夹全部移动至/usr/bin目录 5、将docker注册为系统服务 6、重启生效 6.1、重新加载配置文件 6.2、启动Docker服务 6.3、查看启动状态 6.4、 设置docker为开…

java中使用POI生成Excel并导出

注:本文章中代码均为本地Demo版本,若后续代码更新将不会更新文章 需求说明及实现方式 根据从数据库查询出的数据,将其写入excel表并导出 我的想法是通过在实体属性上写自定义注解的方式去完成。因为我们在代码中可以通过反射的方式去获取实体…

Ubuntu软件包安装失败:代码 bionic 和 focal的区别

问题 我在Ubuntu上使用apt安装软件时总是报一些错误,不是版本不对,就是依赖关系不对。尝试了各种方法,突然想到是不是软件源有问题。 查看/etc/apt/sources.list文件,发现使用了阿里云的软件源: deb http://mirrors…