近期应工作需求,使用 python 实现了国网 i1协议,包含大部分功能,没有的可以自己参照国标文件自己添加,i1协议总体还是比较简单的,没有特别复杂的交互。
client 端
python
import socket
import struct
import time
import io
import os
from common import *
from threading import Thread
class I1Client(Thread):
def __init__(self):
super().__init__()
self.PARSER_MAP = {
PTYPE_WEATHER: 'parse_weather',
PTYPE_ICE: 'parse_ice',
PTYPE_GALLOP_CHAR: 'parse_gallop_char',
PTYPE_GALLOP_TRACK: 'parse_gallop_track',
PTYPE_TOWER_TILT: 'parse_tower_tilt',
PTYPE_FILTH: 'parse_filth',
PTYPE_BREEZE_FLUTTER: 'parse_breeze_flutter',
PTYPE_BREEZE_WAVEFORM: 'parse_breeze_waveform',
PTYPE_WIRE_TEMP: 'parse_wire_temp',
PTYPE_WIRE_RADIAN: 'parse_wire_radian',
PTYPE_WIRE_YAW: 'parse_wire_yaw',
PTYPE_DEVICE_TIME: 'parse_device_time',
PTYPE_DEVICE_NETADAPTER: 'parse_device_netadapter',
PTYPE_MAINSITE_REQUEST: 'parse_mainsite_request',
PTYPE_COLLECT_PARAMS: 'parse_collect_params',
PTYPE_MODEL_PARAMS: 'parse_model_params',
PTYPE_ALARM_THRESHOLDS: 'parse_alarm_thresholds',
PTYPE_DEVICE_DIRECT: 'parse_device_direct',
PTYPE_CONTROL_BASE_INFO: 'parse_control_base_info',
PTYPE_REMOTE_UPGRADE: 'parse_remote_upgrade',
PTYPE_REMOTE_UPGRADE_END: 'parse_remote_upgrade_finished',
PTYPE_REMOTE_UPGRADE_SSUE: 'parse_remote_upgrade_ssue',
PTYPE_CMD_ID: 'parse_cmd_id',
PTYPE_CMD_RESET: 'parse_cmd_reset',
PTYPE_CMD_WAKE: 'parse_cmd_wake',
PTYPE_WEATHER_PARAMS: 'parse_weather_params',
PTYPE_TOWER_TILT_PARAMS: 'parse_tower_tilt_params',
PTYPE_BREEZE_FLUTTER_PARAMS: 'parse_breeze_flutter_params',
PTYPE_WIRE_RADIAN_PARAMS: 'parse_wire_radian_params',
PTYPE_WIRE_TEMP_PARAMS: 'parse_wire_temp_params',
PTYPE_ICE_PARAMS: 'parse_ice_params',
PTYPE_WIRE_YAW_PARAMS: 'parse_wire_yaw_params',
PTYPE_GALLOP_CHAR_PARAMS: 'parse_gallop_char_params',
PTYPE_FILTH_PARAMS: 'parse_filth_params',
PTYPE_IMAGE_COLLECT_PARAMS: 'parse_image_collect_params',
PTYPE_IMAGE_TIME_TABLE: 'parse_image_time_table',
PTYPE_IMAGE_TAKE_MANUAL: 'parse_image_take_manual',
PTYPE_REQUEST_IMAGE_DATA: 'parse_request_image_data',
PTYPE_IMAGE_DATA: 'parse_image_data',
PTYPE_IMAGE_END_DATA: 'parse_image_end_data',
PTYPE_CAMERA_REMOTE_ADJUST: 'parse_camera_remote_adjust',
PTYPE_CAMERA_UPLOAD_VIDEO: 'parse_camera_upload_video',
PTYPE_CMD_SAVE_ADRESS: 'parse_cmd_save_address',
PTYPE_STOP_CONNECT: 'parse_stop_connect',
PTYPE_CAMERA_BASE_INFO: 'parse_camera_base_info',
PTYPE_CAMERA_TIME_TABLE: 'parse_camera_time_table',
PTYPE_CMD_HEARTBEAT: 'parse_cmd_heartbeat',
PTYPE_CMD_BASE_INFO: 'parse_cmd_base_info',
PTYPE_CMD_WORK_STATE: 'parse_cmd_work_state',
PTYPE_CMD_ERR_INFO: 'parse_cmd_err_info',
PTYPE_CUSTOM_DATA: 'parse_custom_data',
}
def make_weather(self):
"""C.5.1 气象监测数据报"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x0B
ptype= struct.pack("<s",b'\x0B')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
ts = struct.pack('<I', 1700000000)
avg_ws = struct.pack('<f', 3.3)
avg_wd = struct.pack('<H', 2)
max_ws = struct.pack('<f', 2.2)
extreme_ws = struct.pack('<f', 3.3)
standard_ws = struct.pack('<f', 4.4)
temp = struct.pack('<f', 5.6)
hum = struct.pack('<H', 5)
pres = struct.pack('<f', 1.2)
precipitaton = struct.pack('<f', 3.3)
precipitaton_intensity = struct.pack('<f', 3.3)
radiation_intensity = struct.pack('<H', 3)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + ts + avg_ws + avg_wd + max_ws + extreme_ws + standard_ws + temp + hum + pres + precipitaton + precipitaton_intensity + radiation_intensity
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_filth(self):
"""C.5.2 现场污秽数据报"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x5C
ptype= struct.pack("<s",b'\x5C')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
ts = struct.pack('<I', 1700000000)
esdd = struct.pack('<f', 3.2)
nsdd = struct.pack('<f', 5.6)
daily_max_temp = struct.pack('<f', 3.1)
daily_min_temp = struct.pack('<f', 7.8)
daily_max_hum = struct.pack('<H', 9)
daily_min_hum = struct.pack('<H', 8)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + ts + esdd + nsdd + daily_max_temp + daily_min_temp + daily_max_hum + daily_min_hum
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_ice(self):
"""C.5.2 覆冰监测数据报"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x22
ptype= struct.pack("<s",b'\x22')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
ts = struct.pack('<I', 1700000000)
eq_icethickness = struct.pack('<f',3.4)
tension = struct.pack('<f',4.5)
tension_difference = struct.pack('<f',2.1)
t_sensor_num = struct.pack('<B',2)
t_sensor_list = b''
for i in range(2):
t_sensor_list += struct.pack('<f',3.2)
t_sensor_list += struct.pack('<f',2.3)
t_sensor_list += struct.pack('<f',5.8)
instantaneous_windspeed = struct.pack('<f',3.2)
instantaneous_winddirection = struct.pack('<H',6)
air_temperature = struct.pack('<f',2.3)
humidity = struct.pack('<H',2)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + ts + eq_icethickness + tension + tension_difference + t_sensor_num + t_sensor_list + instantaneous_windspeed + instantaneous_winddirection + air_temperature + humidity
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_breeze_flutter(self):
"""C.5.2 微风振动特征量"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x1E
ptype= struct.pack("<s",b'\x1E')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
unit_sum = struct.pack('<B', 1)
unit_no = struct.pack('<B', 1)
ts = struct.pack('<f', 1.1)
strain_amplitude = struct.pack('<H', 3)
bending_amplitude = struct.pack('<f', 3.3)
vibration_frequency = struct.pack('<f', 2.2)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + unit_sum + unit_no + ts + strain_amplitude + bending_amplitude + vibration_frequency
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_breeze_waveform(self):
"""C.5.3 微风振动波形"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x1F
ptype= struct.pack("<s",b'\x1F')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
unit_sum = struct.pack('<B', 1)
unit_no = struct.pack('<B', 1)
ts = struct.pack('<f', 3.3)
samplepack_sum = struct.pack('<B', 1)
samplepack_no = struct.pack('<B', 1)
strain_data = b''
for i in range(2):
strain_data += struct.pack('<H', 2)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + unit_sum + unit_no + ts + samplepack_sum + samplepack_no + strain_data
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_gallop_char(self):
"""C.5.4 舞动特征"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x24
ptype= struct.pack("<s",b'\x24')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
unit_sum = struct.pack('<B', 1)
unit_no = struct.pack('<B', 1)
ts = struct.pack('<f', 3.3)
u_gallop_amplitude = struct.pack('<f', 3.3)
u_vertical_amplitude = struct.pack('<f', 2.2)
u_horizontal_amplitude = struct.pack('<f', 1.4)
u_angle_vertical = struct.pack('<f', 5.6)
u_gallop_frequency = struct.pack('<f', 6.6)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + unit_sum + unit_no + ts + u_gallop_amplitude + u_vertical_amplitude + u_horizontal_amplitude + u_angle_vertical + u_gallop_frequency
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_gallop_track(self):
"""C.5.5 舞动轨迹"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x25
ptype= struct.pack("<s",b'\x25')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
unit_sum = struct.pack('<B', 1)
unit_no = struct.pack('<B', 1)
ts = struct.pack('<f', 3.3)
pack_sum = struct.pack('<B', 3)
pack_no = struct.pack('<B', 3)
displacement = b''
for i in range(3):
displacement += struct.pack('<f', 3.2)
displacement += struct.pack('<f', 3.2)
displacement += struct.pack('<f', 3.2)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + unit_sum + unit_no + ts + pack_sum + pack_no + displacement
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_wire_temp(self):
"""C.5.6 导线温度"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x21
ptype= struct.pack("<s",b'\x21')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
unit_sum = struct.pack('<B', 1)
unit_no = struct.pack('<B', 1)
ts = struct.pack('<f', 3.3)
line_temp1 = struct.pack('<f', 12.2)
line_temp2 = struct.pack('<f', 14.1)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + unit_sum + unit_no + ts + line_temp1 + line_temp2
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_wire_radian(self):
"""C.5.7 导线弧垂"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x20
ptype= struct.pack("<s",b'\x20')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
ts = struct.pack('<f', 1700000000)
conductor_sag = struct.pack('<f', 1.2)
toground_distance = struct.pack('<f', 2.3)
angle = struct.pack('<f', 3.3)
measure_flag = struct.pack('<B', 1)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + ts + conductor_sag + toground_distance + angle + measure_flag
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_wire_radian(self):
"""C.5.8 风偏"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x23
ptype= struct.pack("<s",b'\x23')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
ts = struct.pack('<f', 1700000000)
windage_yaw_angle = struct.pack('<f', 3.3)
deflection_angle = struct.pack('<f', 4.5)
least_clearance = struct.pack('<f', 2.3)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + ts + windage_yaw_angle + deflection_angle + least_clearance
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_tower_tilt(self):
"""C.5.9 塔杆倾斜"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x01监测数据报文
frame_type = struct.pack("<s",b'\x01')
#报文类型->0x0C
ptype= struct.pack("<s",b'\x0C')
frame_no = struct.pack("<s",b'\x01')
#数据段
comp_id = b'00000000000000002'
ts = struct.pack('<f', 1700000000)
inclination = struct.pack('<f', 3.2)
inclination_x = struct.pack('<f', 1.1)
inclination_y = struct.pack('<f', 1.4)
angle_x = struct.pack('<f', 4.5)
angle_y = struct.pack('<f', 4.4)
#data_len表示 frame_no以后,crc 以前的数据长度
content = comp_id + ts + inclination + inclination_x + inclination_y + angle_x + angle_y
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_device_time(self):
"""C.6.3监测装置时间"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xA1
ptype= struct.pack("<s",b'\xA1')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
cloctime_stamp = struct.pack('<f', 1700000000)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + cloctime_stamp
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_device_netadapter(self):
"""C.6.4 监测装置网络适配器"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA2')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_set_flag = struct.pack('<B', 1)
request_flag = struct.pack('<B', 1)
ip = struct.pack('<4s', socket.inet_aton('192.168.232.222'))
subnet_mask = struct.pack('<f', 2)
gateway = struct.pack('<f', 2)
dns_server = struct.pack('<f', 3)
phone_number = struct.pack('<20s', b'151')
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_set_flag + request_flag + ip + subnet_mask + gateway + dns_server + phone_number
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_mainsite_request(self):
"""C.6.5 主站请求数据"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xA3
ptype= struct.pack("<s",b'\xA3')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_type = struct.pack('<B', 0xB0)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_type
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_collect_params(self):
"""C.6.6 采样参数设置"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA4')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_type = struct.pack('<B', 0xB0)
request_flag = struct.pack('<B', 0xA1)
main_time = struct.pack('<H', 3)
sample_count = struct.pack('<H', 2)
sample_frequency = struct.pack('<H', 2)
heartbeat_time = struct.pack('<B', 1)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_type + request_flag + main_time + sample_count + sample_frequency + heartbeat_time
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_model_params(self):
"""C.6.7 模型参数设置"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xA5
ptype= struct.pack("<s",b'\xA5')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_set_flag = struct.pack('<B', 0xFF)
config_total = struct.pack('<B', 2)
configs = b''
for i in range(2):
configs += struct.pack('<6s', b'666666')
configs += struct.pack('<B', 1)
configs += struct.pack('<f', 2.2)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_set_flag + config_total + configs
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_alarm_thresholds(self):
"""C.6.8 报警阈值设置"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xA6
ptype= struct.pack("<s",b'\xA6')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_type = struct.pack('<B', 0xFF)
alarm_total = struct.pack('<B', 0x02)
thresholds = b''
for i in range(0x02):
thresholds += struct.pack('<6s',b'23')
thresholds += struct.pack('<f', 3.3)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_type + alarm_total + thresholds
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_device_direct(self):
"""C.6.9 监测装置指向信息设置"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xA7
ptype= struct.pack("<s",b'\xA7')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_flag = struct.pack('<B', 1)
ip_address = struct.pack('<4s', socket.inet_aton("192.168.1.1"))
port = struct.pack('<H', 22)
domain_name = struct.pack('<64s', b'www.baidu.com')
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_flag + ip_address + port + domain_name
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_base_info(self):
"""C.6.10 基本信息设置"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xA8
ptype= struct.pack("<s",b'\xA8')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_type = struct.pack('<B', 1)
info_type = struct.pack('<B', 1)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_type + info_type
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_remote_upgrade_ssue(self):
"""C.6.11.3 软件升级补包"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xAB
ptype= struct.pack("<s",b'\xAB')
frame_no = struct.pack("<s",b'\x01')
#数据段
file_name = struct.pack('<20s', b'sdfafsdf')
complementpack_sum = struct.pack('<B', 2)
pack_no_list = [3,4]
complementpack_no = b''
for i in range(2):
complementpack_no += struct.pack('<I', pack_no_list[i])
#data_len表示 frame_no以后,crc 以前的数据长度
content = file_name + complementpack_sum + complementpack_no
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_cmd_id(self):
"""C.6.12 监测装置编码设置"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xAC
ptype= struct.pack("<s",b'\xAC')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_flag = struct.pack('<B', 1)
new_cmd_id = struct.pack('<17s', b'00000000000000003')
component_id = struct.pack('<17s', b'00000000000000004')
original_id = struct.pack('<17s', b'02')
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_flag + new_cmd_id + component_id + original_id
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_cmd_reset(self):
"""C.6.13 监测装置复位"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xAD
ptype= struct.pack("<s",b'\xAD')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_cmd_wake(self):
"""C.6.14 监测装置苏醒"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制响应报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xAE
ptype= struct.pack("<s",b'\xAE')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_image_collect_params(self):
"""C.7.1 图片采集参数"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x08控制报文
frame_type = struct.pack("<s",b'\x08')
#报文类型->0xC9
ptype= struct.pack("<s",b'\xC9')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_set_flag = struct.pack('<B', 1)
request_flag = struct.pack('<B', 1)
color_select = struct.pack('<B', 1)
resolution = struct.pack('<B', 1)
luminance = struct.pack('<B', 1)
contrast = struct.pack('<B', 1)
saturation = struct.pack('<B', 1)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_set_flag + request_flag + color_select + resolution + luminance + contrast + saturation
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_image_time_table(self):
"""C.7.2 拍照时间表"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x08图像控制响应报文
frame_type = struct.pack("<s",b'\x08')
#报文类型->0xCA
ptype= struct.pack("<s",b'\xCA')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_set_flag = struct.pack('<B', 1)
channel_no = struct.pack('<B', 1)
group_num = struct.pack('<B', 2)
groups = b''
for i in range(2):
groups += struct.pack('<B', 1)
groups += struct.pack('<B', 1)
groups += struct.pack('<B', 1)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_set_flag + channel_no + group_num + groups
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_image_take_manual(self):
"""C.7.3 手动请求拍摄照片"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x04控制报文
frame_type = struct.pack("<s",b'\x04')
#报文类型->0xCB
ptype= struct.pack("<s",b'\xCB')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_request_image_pack(self,frame_no=0x01,channel_no=0x01,presetting_no=0x01,packt_no=0x01):
b_frame = b''
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",b"00000000000000002")
frame_type = struct.pack("<s",b'\x05')
ptype= struct.pack("<s",b'\xCC')
frame_no = struct.pack("<B",frame_no)
#数据段
channel_no = struct.pack("<B",channel_no)
presetting_no = struct.pack("<B",presetting_no)
packt_no_hi = struct.pack("<H",packt_no)[0]
packt_no_lo = struct.pack("<H",packt_no)[1]
content = channel_no + presetting_no+packt_no_hi.to_bytes() + packt_no_lo.to_bytes()
data_len = struct.pack("<H",len(content))
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def image_send(self,):
# 创建socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 服务器地址端口
dest_addr = ('0.0.0.0', 50001)
# 发送数据
with open("pic.jpg", "rb") as f:
image_data = f.read()
chunk_size = 1024 # 每个数据包大小
n_chunks = len(image_data) // chunk_size
frame_img_request = gen_request_image_pack(1,1,1,n_chunks)
client_socket.sendto(frame_img_request, dest_addr)
data = client_socket.recv(1024)
print("data",data)
pack_dict = {}
for i in range(0,n_chunks):
chunk = image_data[i * chunk_size: (i + 1) * chunk_size]
pack_dict[i] = chunk
frame = gen_image_pack(chunk,i+1,1,1,n_chunks,i)
client_socket.sendto(frame, dest_addr)
img_end = gen_image_end_pack(n_chunks,1,1,1700000000)
client_socket.sendto(img_end, dest_addr)
# 接收数据
data = client_socket.recv(1024)
sum = struct.unpack('<H',data[26:28])[0]
frame_type = data[21]
ptype = data[22]
ssue_pack_no_list = []
print('ptype',ptype)
if ptype == 0xCF:
offset = 28
if len(data) > 33:
for i in range(sum):
no = struct.unpack('<H',data[offset:offset+2])[0]
print(no)
ssue_pack_no_list.append(no)
offset += 2
for pack_no in ssue_pack_no_list:
frame = gen_image_pack(pack_dict[pack_no],pack_no,1,1,n_chunks,pack_no)
client_socket.sendto(frame, dest_addr)
img_end = gen_image_end_pack(n_chunks,1,1,1700000000)
client_socket.sendto(img_end, dest_addr)
# 关闭连接
client_socket.close()
def gen_image_end_pack(self,frame_no,channel_no,presetting_no,timestamp):
b_frame = b''
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",b"00000000000000001")
frame_type = struct.pack("<s",b'\x05')
ptype= struct.pack("<s",b'\xCE')
frame_no = struct.pack("<B",frame_no)
channel_no = struct.pack("<B",channel_no)
presetting_no = struct.pack("<B",presetting_no)
timestamp = struct.pack("<I",timestamp)
content = channel_no + presetting_no + timestamp
data_len = struct.pack("<H",len(content))
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_camera_remote_ajust(self):
"""C.7.8 摄像机远程调节"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x08图像控制响应报文
frame_type = struct.pack("<s",b'\x08')
#报文类型->0xD0
ptype= struct.pack("<s",b'\xD0')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_camera_upload_video(self):
"""C.7.9 启动终止摄像视频传输"""
b_frame = b''
return b_frame
def make_camera_time_table(self):
"""C.7.10 摄像机定时工作时间表"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x08')
#报文类型->0xD5
ptype= struct.pack("<s",b'\xD5')
frame_no = struct.pack("<s",b'\x01')
#数据段
command_status = struct.pack('<B', 0xFF)
request_set_flag = struct.pack('<B',1)
t_b = b''
time_list = [{'start_time':1700000000,'end_time':1700000001},{'start_time':1700000002,'end_time':1700000004},{'start_time':1700000005,'end_time':1700000006},{'start_time':1700000007,'end_time':1700000009}]
for t in time_list:
t_b += struct.pack('<f',t['start_time'])
t_b += struct.pack('<f',t['end_time'])
#data_len表示 frame_no以后,crc 以前的数据长度
content = command_status + request_set_flag + t_b
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_cmd_heartbeat(self):
"""C.8.1 心跳"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x09')
#报文类型->0xE6
ptype= struct.pack("<s",b'\xE6')
frame_no = struct.pack("<s",b'\x01')
#数据段
cloctime_stamp = struct.pack("<f",time.time())
#data_len表示 frame_no以后,crc 以前的数据长度
content = cloctime_stamp
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_cmd_base_info(self):
"""C.8.2 基本信息报"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x09工作状态报文
frame_type = struct.pack("<s",b'\x09')
#报文类型->0xE7
ptype= struct.pack("<s",b'\xE7')
frame_no = struct.pack("<s",b'\x01')
#数据段
smartquip_name = struct.pack('<50s', b'sfsfafs')
model = struct.pack('<10s', b'sdffd')
data_trans_protocol_version = struct.pack('<4s', b'sdfd')
essential_info_version = struct.pack('<4s', b'sdfs')
bs_manufacture = struct.pack('<50s', b'sdf')
bs_production_date = struct.pack('<4s', b'sdfd')
bs_identifier = struct.pack('<20s', b'ererere')
#data_len表示 frame_no以后,crc 以前的数据长度
content = smartquip_name + model + data_trans_protocol_version + essential_info_version + bs_manufacture + bs_production_date + bs_identifier
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_cmd_work_state(self):
"""C.8.3 工作状态报"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x09工作状态报文
frame_type = struct.pack("<s",b'\x09')
#报文类型->0xE8
ptype= struct.pack("<s",b'\xE8')
frame_no = struct.pack("<s",b'\x01')
#数据段
time_stamp = struct.pack('<f', 1700000000)
operation_temperature = struct.pack('<f', 3.3)
battery_capacity = struct.pack('<f', 2.3)
floating_charge = struct.pack('<B', 1)
total_working_time = struct.pack('<I', 3)
working_time = struct.pack('<I', 3)
connection_state = struct.pack('<B', 1)
#data_len表示 frame_no以后,crc 以前的数据长度
content = time_stamp + operation_temperature + battery_capacity + floating_charge + total_working_time + working_time + connection_state
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_cmd_err_info(self):
"""C.8.4 故障信息报"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
device_id = struct.pack("<17s",b'00000000000000001')
#帧类型->0x09工作状态报文
frame_type = struct.pack("<s",b'\x09')
#报文类型->0xE9
ptype= struct.pack("<s",b'\xE9')
frame_no = struct.pack("<s",b'\x01')
#数据段
time_stamp = struct.pack('<f', 1700000000)
fault_desc = "故障描述".encode("utf-8")
#data_len表示 frame_no以后,crc 以前的数据长度
content = time_stamp + fault_desc
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_device_time(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.3 监测装置时间查询 解析设备的响应"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
cloctime_stamp = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type':'device_time',
'command_status':command_status,
'cloctime_stamp':cloctime_stamp,
}
def parse_device_netadapter(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.4 监测装置网络适配器查询"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_set_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
ip = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
subnet_mask = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
gateway = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
dns_server = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
phone_number = struct.unpack('<20s', raw[offset:offset+20])[0]; offset += 20
return {
'type':'device_netadapter',
'command_status':command_status,
'request_set_flag':request_set_flag,
'request_flag':request_flag,
'ip':ip,
'subnet_mask':subnet_mask,
'gateway':gateway,
'dns_server':dns_server,
'phone_number':phone_number,
}
def parse_mainsite_request(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.5 主站系统请求数据"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'mainsite_request',
'command_status':command_status,
'request_type':request_type,
}
def parse_collect_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.6 采样参数设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
main_time = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
sample_count = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
sample_frequency = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
heartbeat_time = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'mainsite_request',
'command_status':command_status,
'request_type':request_type,
'request_flag':request_flag,
'main_time':main_time,
'sample_count':sample_count,
'sample_frequency':sample_frequency,
'heartbeat_time':heartbeat_time,
}
def parse_model_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.7 模型参数查询/设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_set_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
config_total = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
configs = []
for i in range(config_total):
config = {}
config['config_name'] = struct.unpack('<6s', raw[offset:offset+6])[0]; offset += 6
config['config_datatype'] = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
config['config_data'] = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
configs.append(config)
return {
'type':'model_params',
'command_status':command_status,
'request_set_flag':request_set_flag,
'config_total':config_total,
'configs':configs,
}
def parse_alarm_thresholds(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.8 报警阈值查询/设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
alarm_total = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
thresholds = {}
for i in range(alarm_total):
key = struct.unpack('<6s', raw[offset:offset+6])[0]; offset += 6
value = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
thresholds[key] = value
return {
'type':'alarm_thresholds',
'command_status':command_status,
'request_type':request_type,
'alarm_total':alarm_total,
'threshods':threshods,
}
def parse_device_direct(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.9 监测装置指向信息查询/设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
ip_address = struct.unpack('<4s', raw[offset:offset+4])[0]; offset += 4
port = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
domain_name = struct.unpack('<64s', raw[offset:offset+64])[0]; offset += 64
return {
'type':'device_direct',
'command_status':command_status,
'request_flag':request_flag,
'ip_address':ip_address,
'port':port,
'domain_name':domain_name,
}
def parse_control_base_info(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.10 基本信息查询/设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
info_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'base_info',
'command_status':command_status,
'request_type':request_type,
'info_type':info_type,
}
def parse_remote_upgrade(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.11.3 软件数据报补包上传"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
file_name = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
complementpack_sum = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
complementpack_no = []
for i in range(complementpack_sum):
complementpack_no.append(struct.unpack('<I', raw[offset:offset+4])[0])
offset += 4
return {
'type':'remote_upgrade',
'command_status':command_status,
'file_name':file_name,
'complementpack_sum':complementpack_sum,
'complementpack_no':complementpack_no,
}
def parse_remote_upgrade_finished(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.11.3 软件数据报补包上传"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
file_name = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
complementpack_sum = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
complementpack_no = []
for i in range(complementpack_sum):
complementpack_no.append(struct.unpack('<I', raw[offset:offset+4])[0])
offset += 4
return {
'type':'remote_upgrade',
'command_status':command_status,
'file_name':file_name,
'complementpack_sum':complementpack_sum,
'complementpack_no':complementpack_no,
}
def parse_cmd_id(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.12 监测装置编码设置/查询"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
new_cmd_id = struct.unpack('<17s', raw[offset:offset+17])[0]; offset += 17
component_id = struct.unpack('<17s', raw[offset:offset+17])[0]; offset += 17
original_id = struct.unpack('<2s', raw[offset:offset+1])[0]; offset += 2
return {
'type':'cmd_id',
'command_status':command_status,
'request_flag':request_flag,
'new_cmd_id':new_cmd_id,
'component_id':component_id,
'original_id':original_id,
}
def parse_cmd_reset(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.13 监测装置复位"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'cmd_reset',
'command_status':command_status,
}
def parse_cmd_wake(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.14 监测装置苏醒"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'cmd_reset',
'command_status':command_status,
}
def parse_image_collect_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.1 图像采集参数设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_set_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
color_select = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
resolution = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
luminance = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
contrast = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
saturation = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'image_collect_params',
'command_status':command_status,
'request_set_flag':request_set_flag,
'request_flag':request_flag,
'color_select':color_select,
'resolution':resolution,
'luminance':luminance,
'contrast':contrast,
'saturation':saturation,
}
def parse_image_time_table(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.2 拍照时间表设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_set_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
channel_no = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
group_num = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
groups = []
for i in range(group_num):
group = {}
group['hour'] = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
group['minute'] = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
group['presetting_no'] = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
groups.append(group)
return {
'type':'image_collect_params',
'command_status':command_status,
'request_set_flag':request_set_flag,
'channel_no':channel_no,
'group_num':group_num,
'groups':groups,
}
def parse_image_take_manual(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.3 手动请求拍摄照片"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'image_take_manual',
'command_status':command_status,
}
def parse_camera_remote_adjust(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.8 摄像机远程调节"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'camera_remote_adjust',
'command_status':command_status,
}
def parse_camera_time_table(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.10 摄像机时间表"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
start_time1 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
end_time1 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
start_time2 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
end_time2 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
start_time3 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
end_time3 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
start_time4 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
end_time4 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type':'camera_time_table',
'command_status':command_status,
'start_time1':start_time1,
'end_time1':end_time1,
'start_time2':start_time2,
'end_time2':end_time2,
'start_time3':start_time3,
'end_time3':end_time3,
'start_time4':start_time4,
'end_time4':end_time4,
}
#解包函数,解析通用字段,数据段根据报文类型由专门的解析函数处理
def parse_frame(self,raw: bytes):
"""返回 dict 或 None"""
header = struct.unpack("<2s",raw[:2])[0]
if len(raw) < 10 or raw[:2] != SYNC_HEAD or raw[-1] != SYNC_TAIL:
print("tail matters")
return None
pkt_len = struct.unpack('<H', raw[2:4])[0]
if len(raw) < 22+pkt_len:
print("package len matters")
return None
payload = raw[2: 2+ 22 +pkt_len]
if crc16(payload) != struct.unpack('<H', raw[-3:-1])[0]:
print("crc matters")
return None
cmd_id = raw[4:21].decode()
frame_type = raw[21]
ptype = raw[22]
seq = raw[23]
content = raw[24:]
#if frame_type != FRAME_TYPE_DATA:
# return None
print("ptype:",ptype)
parser = getattr(self,self.PARSER_MAP.get(ptype))
if not parser:
return None
try:
return parser(cmd_id, seq, raw, 24)
except Exception as e:
return None
def run(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
dest_addr = ('0.0.0.0', 50001)
for attr in dir(self):
if attr.startswith("make_"):
func = getattr(self,attr)
frame = func()
print("fuc:",func)
print("frame:",frame)
time.sleep(1)
sock.sendto(frame, dest_addr)
break
while True:
data = sock.recv(1024)
res = self.parse_frame(data)
print("client parse:",res)
#通用封包
def gen_pack():
#封包
content = ice_data_pack()
print(content,len(content))
b_frame = b''
header = struct.pack('<2s',b'\x5A\xA5')
data_len = struct.pack("<H",len(content))
device_id = struct.pack("<17s",b"00000000000000001")
frame_type = struct.pack("<s",b'\x01')
ptype= struct.pack("<s",b'\x22')
frame_no = struct.pack("<s",b'\x01')
content = content
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
parse_frame(b_frame)
def gen_request_image_pack(frame_no,channel_no,presetting_no,packt_no):
b_frame = b''
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",b"00000000000000001")
frame_type = struct.pack("<s",b'\x05')
ptype= struct.pack("<s",b'\xCC')
frame_no = struct.pack("<B",frame_no)
channel_no = struct.pack("<B",channel_no)
presetting_no = struct.pack("<B",presetting_no)
packt_no_hi = struct.pack("<H",packt_no)[0]
packt_no_lo = struct.pack("<H",packt_no)[1]
content = channel_no + presetting_no+packt_no_hi.to_bytes() + packt_no_lo.to_bytes()
data_len = struct.pack("<H",len(content))
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def gen_image_pack(img_bytes,frame_no,channel_no,presetting_no,packt_no,subpacket_no):
b_frame = b''
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",b"00000000000000001")
frame_type = struct.pack("<s",b'\x05')
ptype= struct.pack("<s",b'\xCD')
frame_no = struct.pack("<B",frame_no)
channel_no = struct.pack("<B",channel_no)
presetting_no = struct.pack("<B",presetting_no)
packt_no = struct.pack("<H",packt_no)
subpacket_no = struct.pack("<H",subpacket_no)
content = channel_no + presetting_no+packt_no + subpacket_no + img_bytes
data_len = struct.pack("<H",len(content))
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def gen_image_end_pack(frame_no,channel_no,presetting_no,timestamp):
b_frame = b''
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",b"00000000000000001")
frame_type = struct.pack("<s",b'\x05')
ptype= struct.pack("<s",b'\xCE')
frame_no = struct.pack("<B",frame_no)
channel_no = struct.pack("<B",channel_no)
presetting_no = struct.pack("<B",presetting_no)
timestamp = struct.pack("<I",timestamp)
content = channel_no + presetting_no + timestamp
data_len = struct.pack("<H",len(content))
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def append_image_data():
import os
if os.path.exists("pic2.jpg"):
os.remove("/pic2.jpg")
pic = open("pic.jpg",'rb').read()
a = pic[:10]
b = pic[10:]
f = open("pic2.jpg",'ab')
f.write(a)
f.close()
f = open("pic2.jpg",'ab')
f.write(b)
f.close()
def clear_image():
import os
if os.path.exists("00000000000000002_1.jpg"):
os.remove("00000000000000002_1.jpg")
def image_send():
# 创建socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 服务器地址端口
dest_addr = ('0.0.0.0', 50001)
# 发送数据
with open("pic.jpg", "rb") as f:
image_data = f.read()
chunk_size = 1024 # 每个数据包大小
n_chunks = len(image_data) // chunk_size
frame_img_request = gen_request_image_pack(1,1,1,n_chunks)
client_socket.sendto(frame_img_request, dest_addr)
data = client_socket.recv(1024)
print("data",data)
pack_dict = {}
for i in range(0,n_chunks):
chunk = image_data[i * chunk_size: (i + 1) * chunk_size]
pack_dict[i] = chunk
frame = gen_image_pack(chunk,i+1,1,1,n_chunks,i)
client_socket.sendto(frame, dest_addr)
img_end = gen_image_end_pack(n_chunks,1,1,1700000000)
client_socket.sendto(img_end, dest_addr)
# 接收数据
data = client_socket.recv(1024)
'''sum = struct.unpack('<H',data[26:28])[0]
frame_type = data[21]
ptype = data[22]
ssue_pack_no_list = []
print('ptype',ptype)
if ptype == 0xCF:
offset = 28
if len(data) > 33:
for i in range(sum):
no = struct.unpack('<H',data[offset:offset+2])[0]
print(no)
ssue_pack_no_list.append(no)
offset += 2
for pack_no in ssue_pack_no_list:
frame = gen_image_pack(pack_dict[pack_no],pack_no,1,1,n_chunks,pack_no)
client_socket.sendto(frame, dest_addr)
img_end = gen_image_end_pack(n_chunks,1,1,1700000000)
client_socket.sendto(img_end, dest_addr)'''
# 关闭连接
client_socket.close()
def client_main():
c = I1Client()
c.start()
if __name__ == '__main__':
c = I1Client()
c.start()
server端
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Q/GDW 1242-2015 全数据报解析服务端
支持:气象/覆冰/舞动特征量/舞动轨迹/远程图像数据报
"""
import socket
import struct
import time
import logging
import io
import os
from common import *
from threading import Thread
logging.basicConfig(level=logging.INFO,
format='%(asctime)s %(levelname)s %(message)s')
class I1Server(Thread):
def __init__(self):
super().__init__()
self.image_pack_no_list = []
self.image_total_pack = 0
self.image_pack_dict = {}
self.image_ssue_list = []
self.cmd_id = ""
self.channel_no = 0
#解析函数映射
self.PARSER_MAP = {
PTYPE_WEATHER: 'parse_weather',
PTYPE_ICE: 'parse_ice',
PTYPE_GALLOP_CHAR: 'parse_gallop_char',
PTYPE_GALLOP_TRACK: 'parse_gallop_track',
PTYPE_TOWER_TILT: 'parse_tower_tilt',
PTYPE_FILTH: 'parse_filth',
PTYPE_BREEZE_FLUTTER: 'parse_breeze_flutter',
PTYPE_BREEZE_WAVEFORM: 'parse_breeze_waveform',
PTYPE_WIRE_TEMP: 'parse_wire_temp',
PTYPE_WIRE_RADIAN: 'parse_wire_radian',
PTYPE_WIRE_YAW: 'parse_wire_yaw',
PTYPE_DEVICE_TIME: 'parse_device_time',
PTYPE_DEVICE_NETADAPTER: 'parse_device_netadapter',
PTYPE_MAINSITE_REQUEST: 'parse_mainsite_request',
PTYPE_COLLECT_PARAMS: 'parse_collect_params',
PTYPE_MODEL_PARAMS: 'parse_model_params',
PTYPE_ALARM_THRESHOLDS: 'parse_alarm_thresholds',
PTYPE_DEVICE_DIRECT: 'parse_device_direct',
PTYPE_CONTROL_BASE_INFO: 'parse_control_base_info',
PTYPE_REMOTE_UPGRADE__SSUE: 'parse_remote_upgrade',
PTYPE_CMD_ID: 'parse_cmd_id',
PTYPE_CMD_RESET: 'parse_cmd_reset',
PTYPE_CMD_WAKE: 'parse_cmd_wake',
PTYPE_WEATHER_PARAMS: 'parse_weather_params',
PTYPE_TOWER_TILT_PARAMS: 'parse_tower_tilt_params',
PTYPE_BREEZE_FLUTTER_PARAMS: 'parse_breeze_flutter_params',
PTYPE_WIRE_RADIAN_PARAMS: 'parse_wire_radian_params',
PTYPE_WIRE_TEMP_PARAMS: 'parse_wire_temp_params',
PTYPE_ICE_PARAMS: 'parse_ice_params',
PTYPE_WIRE_YAW_PARAMS: 'parse_wire_yaw_params',
PTYPE_GALLOP_CHAR_PARAMS: 'parse_gallop_char_params',
PTYPE_FILTH_PARAMS: 'parse_filth_params',
PTYPE_IMAGE_COLLECT_PARAMS: 'parse_image_collect_params',
PTYPE_IMAGE_TIME_TABLE: 'parse_image_time_table',
PTYPE_IMAGE_TAKE_MANUAL: 'parse_image_take_manual',
PTYPE_REQUEST_IMAGE_DATA: 'parse_request_image_data',
PTYPE_IMAGE_DATA: 'parse_image_data',
PTYPE_IMAGE_END_DATA: 'parse_image_end_data',
PTYPE_CAMERA_REMOTE_ADJUST: 'parse_camera_remote_adjust',
PTYPE_CAMERA_UPLOAD_VIDEO: 'parse_camera_upload_video',
PTYPE_CMD_SAVE_ADRESS: 'parse_cmd_save_address',
PTYPE_STOP_CONNECT: 'parse_stop_connect',
PTYPE_CAMERA_BASE_INFO: 'parse_camera_base_info',
PTYPE_CAMERA_TIME_TABLE: 'parse_camera_time_table',
PTYPE_CMD_HEARTBEAT: 'parse_cmd_heartbeat',
PTYPE_CMD_BASE_INFO: 'parse_cmd_base_info',
PTYPE_CMD_WORK_STATE: 'parse_cmd_work_state',
PTYPE_CMD_ERR_INFO: 'parse_cmd_err_info',
PTYPE_CUSTOM_DATA: 'parse_custom_data',
}
# -------------------- 通用封包 --------------------
def make_monitor_resp_frame(self,cmd_id: str, seq: int, ptype: int) -> bytes:
"""构造数据响应报(帧类型 0x02)"""
payload = struct.pack('<H', 17+6) + cmd_id.encode() + bytes([FRAME_TYPE_RESP, ptype, seq, 0xFF])
crc = crc16(payload)
return SYNC_HEAD + payload + struct.pack('<H', crc) + bytes([SYNC_TAIL])
def make_image_resp_frame(self,cmd_id: str, seq: int, ptype: int) -> bytes:
if ptype == 0xCC:
return
# -------------------- 解析函数群 --------------------
def parse_weather(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.5.1 气象监测数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
ts = struct.unpack('<I', raw[offset:offset+4]); offset += 4
avg_ws = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
avg_wd = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
max_ws = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
extreme_ws = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
standard_ws = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
temp = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
hum = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
pres = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
precipitaton = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
precipitaton_intensity = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
radiation_intensity = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
return {
'type': 'weather',
'comp_id': comp_id,
'ts': ts,
'avg_ws': avg_ws,
'avg_wd': avg_wd,
'max_ws': max_ws,
'extreme_ws': extreme_ws,
'standard_ws': standard_ws,
'temp': temp,
'hum': hum,
'pres': pres,
'precipitaton': precipitaton,
'precipitaton_intensity': precipitaton_intensity,
'radiation_intensity': radiation_intensity,
}
def parse_filth(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.5.2 现场污秽数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
ts = struct.unpack('<f', raw[offset:offset+4]); offset += 4
esdd = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
nsdd = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
daily_max_temp = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
daily_min_temp = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
daily_max_hum = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
daily_min_hum = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
return {
'type': 'filth',
'comp_id': comp_id,
'ts': ts,
'esdd': esdd,
'nsdd': nsdd,
'daily_max_temp': daily_max_temp,
'daily_min_temp': daily_min_temp,
'daily_max_hum': daily_max_hum,
'daily_min_hum': daily_min_hum,
}
def parse_ice(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.5.3 覆冰监测数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
time_stamp = struct.unpack('<I', raw[offset:offset+4]); offset += 4
eq_icethickness = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
tension = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
tension_difference = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
t_sensor_num = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
t_sensor_list = []
for i in range(t_sensor_num):
ts = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
crossa = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
forwarda = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
t_sensor_list.append({'tension':ts,'crosswise_angle':crossa,'forward_tilt_angle':forwarda})
instantaneous_windspeed = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
instantaneous_winddirection = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
air_temperature = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
humidity = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
ret = {
'type': 'ice',
'comp_id': comp_id,
'time_stamp': time_stamp,
'eq_icethickness': eq_icethickness,
'tension': tension,
'tension_difference': tension_difference,
't_sensor_num': t_sensor_num,
't_sensor_list': t_sensor_list,
'instantaneous_windspeed': instantaneous_windspeed,
'instantaneous_winddirection': instantaneous_winddirection,
'air_temperature': air_temperature,
'humidity': humidity,
}
print(ret)
return ret
def parse_breeze_flutter(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C5.4.1 微风振动特征量数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
unit_sum = struct.unpack('<B', raw[offset:offset+1]); offset += 1
unit_no = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
ts = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
strain_amplitude = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
bending_amplitude = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
vibration_frequency = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type': 'breeze_flutter',
'comp_id': comp_id,
'unit_sum': unit_sum,
'unit_no': unit_no,
'ts': ts,
'strain_amplitude': strain_amplitude,
'bending_amplitude': bending_amplitude,
'vibration_frequency': vibration_frequency,
}
def parse_breeze_waveform(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.5.4.2 微风振动波形信号数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
unit_sum = struct.unpack('<B', raw[offset:offset+1]); offset += 1
unit_no = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
ts = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
samplepack_sum = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
samplepack_no = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
strain_data = []
while offset + 2 < len(raw)-3:
strain_data.append(struct.unpack('<H', raw[offset:offset+2])[0])
offset += 2
return {
'type': 'breeze_waveform',
'comp_id': comp_id,
'unit_sum': unit_sum,
'unit_no': unit_no,
'ts': ts,
'samplepack_sum': samplepack_sum,
'samplepack_no': samplepack_no,
'strain_data': strain_data,
}
def parse_gallop_char(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.5.5.1 导线舞动特征量数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
unit_sum = raw[offset]; offset += 1
unit_no = raw[offset]; offset += 1
ts = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
u_gallop_amplitude = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
u_vertical_amplitude = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
u_horizontal_amplitude = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
u_angle_vertical = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
u_gallop_frequency = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type': 'gallop_char',
'comp_id': comp_id,
'unit_sum': unit_sum,
'unit_no': unit_no,
'ts': ts,
'u_gallop_amplitude': u_gallop_amplitude,
'u_vertical_amplitude': u_vertical_amplitude,
'u_horizontal_amplitude': u_horizontal_amplitude,
'u_angle_vertical': u_angle_vertical,
'u_gallop_frequency': u_gallop_frequency,
}
def parse_gallop_track(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.5.5.2 导线舞动轨迹数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
unit_sum = raw[offset]; offset += 1
unit_no = raw[offset]; offset += 1
ts, = struct.unpack('<I', raw[offset:offset+4]); offset += 4
pack_sum = raw[offset]; offset += 1
pack_no = raw[offset]; offset += 1
displacement = []
while offset+12 < (len(raw)-3):
x = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
y = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
z = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
displacement.append([x,y,z]) # 剩余全是位移点
pts = len(sample_bytes) // 12
return {
'type': 'gallop_track',
'comp_id': comp_id,
'unit_sum': unit_sum,
'unit_no': unit_no,
'ts': ts,
'pack_sum': u_gallop_amplitude,
'pack_no': u_vertical_amplitude,
'displacement': u_horizontal_amplitude,
}
def gallop_track_pack_count(self):
pass
def gallop_grack_pack_merge(self):
pass
def parse_wire_temp(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.5.6 导线温度数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
unit_sum = raw[offset]; offset += 1
unit_no = raw[offset]; offset += 1
ts = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
line_temp1 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
line_temp2 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type': 'wire_temp',
'comp_id': comp_id,
'unit_sum': unit_sum,
'unit_no': unit_no,
'ts': ts,
'line_temp1': line_temp1,
'line_temp2': line_temp2,
}
def parse_wire_radian(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C5.7 导线弧垂数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
ts = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
conductor_sag = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
toground_distance = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
angle = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
measure_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type': 'wire_radian',
'comp_id': comp_id,
'ts': ts,
'conductor_sag': conductor_sag,
'toground_distance': toground_distance,
'angle': angle,
'measure_flag': measure_flag,
}
def parse_wire_yaw(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.5.8 导线风偏数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
ts = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
windage_yaw_angle = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
deflection_angle = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
least_clearance = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type': 'wire_yaw',
'comp_id': comp_id,
'ts': ts,
'windage_yaw_angle': conductor_sag,
'deflection_angle': toground_distance,
'least_clearance': angle,
}
def parse_tower_tilt(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.5.9 塔杆倾斜数据报"""
comp_id = raw[offset:offset+17].decode(); offset += 17
ts = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
inclination = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
inclination_x = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
inclination_y = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
angle_x = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
angle_y = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type': 'tower_tilt',
'comp_id': comp_id,
'ts': ts,
'inclination': inclination,
'inclination_x': inclination_x,
'inclination_y': inclination_y,
'angle_x': inclination_y,
'angle_y': inclination_y,
}
#----------------
# C.6 控制报文
#----------------
def make_device_time(self,cmd_id: str, request_set_flag,clocktime_stamp):
"""C.6.3 监测装置时间查询 发送给设备"""
header = struct.pack('<H',23205)
data_len = struct.pack("<H",5)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA1
ptype= struct.pack("<s",b'\xA1')
frame_no = struct.pack("<s",b'\x01')
request_set_flag = struct.pack('<B',request_set_flag)
clocktime_stamp = struct.pack('<f',clocktime_stamp)
content = request_set_flag + clocktime_stamp
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_device_time(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.3 监测装置时间查询 解析设备的响应"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
cloctime_stamp = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type':'device_time',
'command_status':command_status,
'cloctime_stamp':cloctime_stamp,
}
def make_device_netadapter(self,cmd_id: str, request_set_flag,request_flag,ip,subnet_mask,gateway,dns_server,phone_number):
"""C.6.4 监测装置网络适配器查询 发送给设备"""
header = struct.pack('<H',23205)
data_len = struct.pack("<H",38)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA2')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
request_flag = struct.pack('<B',request_flag)
ip = struct.pack('<4s',socket.inet_aton(ip))
subnet_mask = struct.pack('<4s',socket.inet_aton(subnet_mask))
gateway = struct.pack('<4s',socket.inet_aton(gateway))
dns_server = struct.pack('<4s',socket.inet_aton(dns_server))
phone_number = struct.pack('<20s',phone_number)
content = request_set_flag + request_flag + ip + subnet_mask + gateway + dns_server + phone_number
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_device_netadapter(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.4 监测装置网络适配器查询"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_set_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
ip = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
subnet_mask = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
gateway = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
dns_server = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
phone_number = struct.unpack('<20s', raw[offset:offset+20])[0]; offset += 20
return {
'type':'device_netadapter',
'command_status':command_status,
'request_set_flag':request_set_flag,
'request_flag':request_flag,
'ip':ip,
'subnet_mask':subnet_mask,
'gateway':gateway,
'dns_server':dns_server,
'phone_number':phone_number,
}
def make_mainsite_request(self,cmd_id: str, request_type,data_start_time,data_end_time):
"""C.6.5 主站系统请求数据 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA3')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_type = struct.pack('<B',request_type)
data_start_time = struct.pack('<f',data_start_time)
data_end_time = struct.pack('<f',socket.data_end_time(ip))
content = request_type + data_start_time + data_end_time
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_mainsite_request(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.5 主站系统请求数据"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'mainsite_request',
'command_status':command_status,
'request_type':request_type,
}
def make_collect_params(self,cmd_id: str, request_set_flag,request_type,request_flag,main_time,sample_count,sample_frequency,heartbeat_time):
"""C.6.6 采样参数设置 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",10)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA4')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
request_type = struct.pack('<B',request_type)
request_flag = struct.pack('<B',request_flag)
main_time = struct.pack('<H',main_time)
sample_count = struct.pack('<H',sample_count)
sample_frequency = struct.pack('<H',sample_frequency)
heartbeat_time = struct.pack('<B',heartbeat_time)
content = request_set_flag + request_type + request_flag+ main_time + sample_count + sample_frequency + heartbeat_time
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_collect_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.6 采样参数设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
main_time = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
sample_count = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
sample_frequency = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
heartbeat_time = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'mainsite_request',
'command_status':command_status,
'request_type':request_type,
'request_flag':request_flag,
'main_time':main_time,
'sample_count':sample_count,
'sample_frequency':sample_frequency,
'heartbeat_time':heartbeat_time,
}
def make_model_params(self,cmd_id: str, request_set_flag,config_total,configs):
"""C.6.7 模型参数查询/设置 发送给设备"""
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA5')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
config_total = struct.pack('<B',config_total)
configs_b = b''
for i in range(config_total):
configs_b += struct.pack('<6s',configs['config_name'])
configs_b += struct.pack('<B',configs['config_datatype'])
if configs['config_datatype'] == 0x00 or configs['config_datatype'] == 0x01:
configs_b += struct.pack('<I',configs['config_data'])
else:
configs_b += struct.pack('<f',configs['config_data'])
content = request_set_flag + config_total + configs_b
#data_len不固定,所以放到 content后面统计
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_model_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.7 模型参数查询/设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_set_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
config_total = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
configs = []
for i in range(config_total):
config = {}
config['config_name'] = struct.unpack('<6s', raw[offset:offset+6])[0]; offset += 6
config['config_datatype'] = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
config['config_data'] = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
configs.append(config)
return {
'type':'model_params',
'command_status':command_status,
'request_set_flag':request_set_flag,
'config_total':config_total,
'configs':configs,
}
def make_alarm_thresholds(self,cmd_id: str, request_set_flag,request_type,alarm_total,alarm_para):
"""C.6.8 报警阈值查询/设置 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA6')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
request_type = struct.pack('<B',request_type)
alarm_total = struct.pack('<B',alarm_total)
params_b = b''
for key,value in alarm_para.items():
params_b += struct.pack('<6s',key)
params_b += struct.pack('<f',value)
content = request_set_flag + request_type + alarm_total + params_b
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_alarm_thresholds(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.8 报警阈值查询/设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
alarm_total = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
thresholds = {}
for i in range(config_total):
key = struct.unpack('<6s', raw[offset:offset+6])[0]; offset += 6
value = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
thresholds[key] = value
return {
'type':'alarm_thresholds',
'command_status':command_status,
'request_type':request_type,
'alarm_total':alarm_total,
'threshods':threshods,
}
def make_device_direct(self,cmd_id: str, request_set_flag,request_flag,ip_address,port,domain_name):
"""C.6.9 监测装置指向信息查询/设置 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA7')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
request_flag = struct.pack('<B',request_flag)
ip_address = struct.pack('<4s',sockt.inet_aton(ip_address))
port = struct.pack('<H',port)
domain_name = struct.pack('<64s',domain_name)
content = request_set_flag + request_flag + ip_address + port + domain_name
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_device_direct(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.9 监测装置指向信息查询/设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
ip_address = struct.unpack('<4s', raw[offset:offset+4])[0]; offset += 4
port = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
domain_name = struct.unpack('<64s', raw[offset:offset+64])[0]; offset += 64
return {
'type':'device_direct',
'command_status':command_status,
'request_flag':request_flag,
'ip_address':ip_address,
'port':port,
'domain_name':domain_name,
}
def parse_control_base_info(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
def make_base_info(self,cmd_id: str, request_set_flag,request_type,info_type):
"""C.6.10 基本信息查询/设置 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA8')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
request_type = struct.pack('<B',request_type)
info_type = struct.pack('<4s',info_type)
content = request_set_flag + request_type + info_type
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_base_info(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.10 基本信息查询/设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
info_type = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'base_info',
'command_status':command_status,
'request_type':request_type,
'info_type':info_type,
}
#---------------------
# C.6.11 远程升级数据报
#---------------------
def make_remote_upgrade(self,cmd_id: str, packet_no,subpacket_no,sample):
"""C.6.11.1 软件数据报 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xA9')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
packet_no = struct.pack('<B',packet_no)
subpacket_no = struct.pack('<B',subpacket_no)
sample = struct.pack('<%ds' % len(sample),sample)
content = packet_no + subpacket_no + sample
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_remote_upgrade_finished(self,cmd_id: str, file_name,packet_no,time_stamp):
"""C.6.11.2 软件数据下发结束标记 发送给设备"""
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xAA')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
file_name = struct.pack('<20s',file_name)
packet_no = struct.pack('<I',packet_no)
time_stamp = struct.pack('<f',time_stamp)
content = file_name + packet_no + time_stamp
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_remote_upgrade(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.11.3 软件数据报补包上传"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
file_name = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
complementpack_sum = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
complementpack_no = []
for i in range(complementpack_sum):
complementpack_no.append(struct.unpack('<I', raw[offset:offset+4])[0])
offset += 4
return {
'type':'remote_upgrade',
'command_status':command_status,
'file_name':file_name,
'complementpack_sum':complementpack_sum,
'complementpack_no':complementpack_no,
}
def make_cmd_id(self,cmd_id: str, request_set_flag,request_flag,new_cmd_id,component_id,original_id):
"""C.6.12 监测装置编码设置/查询 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xAC')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
request_flag = struct.pack('<B',request_flag)
new_cmd_id = struct.pack('<17s',new_cmd_id)
component_id = struct.pack('<17s',component_id)
original_id = struct.pack('<17s',original_id)
content = request_set_flag + request_flag + new_cmd_id + component_id + original_id
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_cmd_id(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.12 监测装置编码设置/查询"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
new_cmd_id = struct.unpack('<17s', raw[offset:offset+17])[0]; offset += 17
component_id = struct.unpack('<17s', raw[offset:offset+17])[0]; offset += 17
original_id = struct.unpack('<2s', raw[offset:offset+1])[0]; offset += 2
return {
'type':'cmd_id',
'command_status':command_status,
'request_flag':request_flag,
'new_cmd_id':new_cmd_id,
'component_id':component_id,
'original_id':original_id,
}
def make_cmd_reset(self,cmd_id: str, reset_mode):
"""C.6.12 监测装置复位 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xAD')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
reset_mode = struct.pack('<B',reset_mode)
content = reset_mode
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_cmd_reset(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.13 监测装置复位"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'cmd_reset',
'command_status':command_status,
}
def make_cmd_wake(self,cmd_id: str, reference_revival_time,revival_cycle,duration_time):
"""C.6.14 监测装置苏醒 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xAE')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
reference_revival_time = struct.pack('<f',reference_revival_time)
revival_cycle = struct.pack('<H',revival_cycle)
duration_time = struct.pack('<H',duration_time)
content = reference_revival_time + revival_cycle + duration_time
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_cmd_wake(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.6.14 监测装置苏醒"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'cmd_reset',
'command_status':command_status,
}
def parse_weather_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
def parse_tower_tilt_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
def parse_breeze_flutter_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
def parse_wire_radian_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
def parse_wire_temp_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
def parse_ice_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
def parse_wire_yaw_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
def parse_gallop_char_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
def parse_filth_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
pass
#----------------
# 远程图像数据报文
#----------------
def make_image_collect_params(self,cmd_id: str, request_set_flag,request_flag,color_select,resolution,luminance,contrast,saturation):
"""C.7.1 图像采集参数设置 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xC9')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
request_flag = struct.pack('<B',request_flag)
color_select = struct.pack('<B',color_select)
resolution = struct.pack('<B',resolution)
luminance = struct.pack('<B',luminance)
contrast = struct.pack('<B',contrast)
saturation = struct.pack('<B',saturation)
content = request_set_flag + request_flag + color_select + resolution + luminance + contrast + saturation
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_image_collect_params(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.1 图像采集参数设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_set_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
color_select = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
resolution = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
luminance = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
contrast = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
saturation = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'image_collect_params',
'command_status':command_status,
'request_set_flag':request_set_flag,
'request_flag':request_flag,
'color_select':color_select,
'resolution':resolution,
'luminance':luminance,
'contrast':contrast,
'saturation':saturation,
}
def make_image_time_table(self,cmd_id: str, request_set_flag,channel_no,group_num,groups):
"""C.7.2 拍照时间表设置 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xCA')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
channel_no = struct.pack('<B',channel_no)
group_num = struct.pack('<B',group_num)
groups_b = b''
for i in range(group_num):
groups_b += struct.pack('<B',groups[i]['hour'])
groups_b += struct.pack('<B',groups[i]['minute'])
groups_b += struct.pack('<B',groups[i]['presetting_no'])
content = request_set_flag + channel_no + group_num + groups_b
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_image_time_table(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.2 拍照时间表设置"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
request_set_flag = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
channel_no = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
group_num = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
groups = []
for i in range(group_num):
group = {}
group['hour'] = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
group['minute'] = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
group['presetting_no'] = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
groups.append(group)
return {
'type':'image_collect_params',
'command_status':command_status,
'request_set_flag':request_set_flag,
'channel_no':channel_no,
'group_num':group_num,
'groups':groups,
}
def make_image_take_manual(self,cmd_id: str,channel_no,presetting_no):
"""C.7.3 手动请求拍摄照片 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xCB')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
channel_no = struct.pack('<B',channel_no)
presetting_no = struct.pack('<B',presetting_no)
content = channel_no + presetting_no
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_image_take_manual(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.3 手动请求拍摄照片"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'image_take_manual',
'command_status':command_status,
}
def parse_request_image_data(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C7.4 监测装置请求上送照片,收到图像请求,直接把原报文再发回客户端"""
return {'type':'request_image'}
def parse_image_data(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.5 远程图像数据报"""
channel = raw[offset]; offset += 1
self.channel_no = channel
self.cmd_id = cmd_id
preset = raw[offset]; offset += 1
total_pack = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
self.image_total_pack = total_pack
pack_no = struct.unpack('<H', raw[offset:offset+2])[0]; offset += 2
self.image_pack_no_list.append(pack_no)
img_bytes = raw[offset:-3]
self.image_pack_dict[pack_no] = img_bytes
# 简单拼包示例:按 dev+channel 落盘
#key = f"{cmd_id}_{channel}"
#with open(f"{key}_pack{pack_no:03d}.jpg", 'b+') as f:
# f.write(img_bytes)
# 若收完最后一包可尝试合并
if pack_no == total_pack:
print("[IMAGE] Last pack received, merge by yourself.")
return {'type': 'image', 'channel': channel, 'pack': pack_no, 'size': len(img_bytes)}
def count_image_pack(self):
"""统计图像数据包个数够不够"""
#if self.count == 0:
# self.count += 1
# self.image_ssue_list = [2,3]
# return [2,3]
if len(set(self.image_pack_no_list)) == self.image_total_pack:
self.image_ssue_list = []
return []
else:
self.image_ssue_list = list(set(list(range(1,self.image_total_pack+1))) - set(self.image_pack_no_list))
return self.image_ssue_list
def parse_image_end_data(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.6 远程图像数据上送结束标记"""
ssue_pack_nos = self.count_image_pack()
channel_no = raw[26]
presetting_no = raw[27]
if len(ssue_pack_nos) == 0:
#数据包完整,可以落盘
print("够了")
self.save_image()
self.clear_cache()
else:
print("缺包")
return {'type':'image_end',"channel_no":channel_no,"presetting_no":presetting_no}
def save_image(self):
print("save_image")
path = "/cores/wserver/wxxxx-data/user-data/project01/"
img_name = str(self.cmd_id) + "_" + str(self.channel_no) +"_" +str(int(time.time())) + ".jpg"
full_path = os.path.join(path,img_name)
pack_no_sorted = sorted(self.image_pack_dict)
sorted_pack_list = [self.image_pack_dict[pack_no] for pack_no in pack_no_sorted]
img_content = b"".join(sorted_pack_list)
with open(full_path,'wb') as img_file:
img_file.write(img_content)
def clear_cache(self):
self.image_pack_dict = []
self.image_pack_no_list = []
self.image_total_pack = 0
def make_ssue_image_resp(self,res):
"""C.7.7 远程图像补包数据下发"""
header = struct.pack("<H",23205)
cmd_id = struct.pack('<17s',self.cmd_id.encode('utf-8'))
frame_type = struct.pack('<B',FRAME_TYPE_IMAGE_RESP)
ptype = b'\xCF'
frame_no = b'\x01'
channel_no = struct.pack('<B',res['channel_no'])
presetting_no = struct.pack('<B',res['presetting_no'])
complementpack_sum = struct.pack('<H',len(self.image_ssue_list))
complementpack_no = b''
for ssue in self.image_ssue_list:
complementpack_no += struct.pack('<H',ssue)
data_len = len(channel_no + presetting_no + complementpack_sum + complementpack_no)
data_len = struct.pack('<H',data_len)
payload = data_len + cmd_id + frame_type + ptype + frame_no + channel_no + presetting_no +complementpack_sum + complementpack_no
crc = crc16(payload)
crc_b = struct.pack("<H",crc)
frame = header + payload + crc_b + b'\x96'
return frame
def make_camera_remote_adjust(self,cmd_id: str,channel_no,presetting_no,action):
"""C.7.8 摄像机远程调节 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xD0')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
channel_no = struct.pack('<B',channel_no)
presetting_no = struct.pack('<B',presetting_no)
action = struct.pack('<B',action)
content = channel_no + presetting_no + action
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_camera_remote_adjust(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.8 摄像机远程调节"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'camera_remote_adjust',
'command_status':command_status,
}
def make_camera_upload_video(self,cmd_id: str,channel_no,control,port):
"""C.7.9 启动视频传输 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xD1')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
channel_no = struct.pack('<B',channel_no)
control = struct.pack('<B',control)
port = struct.pack('<H',port)
content = channel_no + control + port
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def make_camera_time_table(self,cmd_id: str,request_set_flag,time_list):
"""C.7.10 摄像机定时工作时间表 发送给设备"""
header = struct.pack('<H',23205)
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",9)
device_id = struct.pack("<17s",cmd_id.encode('utf-8'))
#帧类型->0x03控制报文
frame_type = struct.pack("<s",b'\x03')
#报文类型->0xA2
ptype= struct.pack("<s",b'\xD5')
frame_no = struct.pack("<s",b'\x01')
#0x00表示查询,0x01表示设置
request_set_flag = struct.pack('<B',request_set_flag)
t_b = b''
for t in time_list:
t_b += struct.pack('<f',t['start_time'])
t_b += struct.pack('<f',t['end_time'])
content = request_set_flag + t_b
#data_len表示 frame_no以后,crc 以前的数据长度
data_len = struct.pack("<H",len(content))
#组装payload
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def parse_camera_time_table(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.7.10 摄像机时间表"""
command_status = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
start_time1 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
end_time1 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
start_time2 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
end_time2 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
start_time3 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
end_time3 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
start_time4 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
end_time4 = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type':'camera_time_table',
'command_status':command_status,
'start_time1':start_time1,
'end_time1':end_time1,
'start_time2':start_time2,
'end_time2':end_time2,
'start_time3':start_time3,
'end_time3':end_time3,
'start_time4':start_time4,
'end_time4':end_time4,
}
#-------------------
# 监测装置工作状态报文
#-------------------
def parse_cmd_heartbeat(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.8.1 心跳报"""
clocktime_stamp = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
return {
'type':'cmd_heartbeat',
'clocktime_stamp':clocktime_stamp,
}
def parse_cmd_base_info(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.8.2 基本信息报"""
smartquip_name = struct.unpack('<50s', raw[offset:offset+50])[0]; offset += 50
model = struct.unpack('<10s', raw[offset:offset+10])[0]; offset += 10
data_trans_protocol_version = struct.unpack('<4s', raw[offset:offset+4])[0]; offset += 4
essential_info_version = struct.unpack('<4s', raw[offset:offset+4])[0]; offset += 4
bs_manufacture = struct.unpack('<50s', raw[offset:offset+50])[0]; offset += 50
bs_production_date = struct.unpack('<4s', raw[offset:offset+4])[0]; offset += 4
bs_identifier = struct.unpack('<20s', raw[offset:offset+20])[0]; offset += 20
return {
'type':'cmd_base_info',
'smartquip_name':smartquip_name,
'model':model,
'data_trans_protocol_version':data_trans_protocol_version,
'essential_info_version':essential_info_version,
'bs_manufacture':bs_manufacture,
'bs_production_date':bs_production_date,
'bs_identifier':bs_identifier,
}
def parse_cmd_work_state(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.8.3 工作状态报"""
time_stamp = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
operation_temperature = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
battery_capacity = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
floating_charge = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
total_working_time = struct.unpack('<I', raw[offset:offset+4])[0]; offset += 4
working_time = struct.unpack('<I', raw[offset:offset+4])[0]; offset += 4
connection_state = struct.unpack('<B', raw[offset:offset+1])[0]; offset += 1
return {
'type':'cmd_work_state',
'time_stamp':time_stamp,
'operation_temperature':operation_temperature,
'battery_capacity':battery_capacity,
'floating_charge':floating_charge,
'total_working_time':total_working_time,
'working_time':working_time,
'connection_state':connection_state,
}
def parse_cmd_err_info(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""C.8.3 工作状态报"""
time_stamp = struct.unpack('<f', raw[offset:offset+4])[0]; offset += 4
fault_desc = raw[offset:-3].decode("utf-8")
return {
'type':'cmd_err_info',
'time_stamp':time_stamp,
'fault_desc':fault_desc,
}
def parse_custom_data(self,cmd_id: str, seq: int, raw: bytes, offset: int):
"""自定义数据报"""
data = struct.unpack("<5s",raw[offset:offset+5])
print(data)
#解包函数,解析通用字段,数据段根据报文类型由专门的解析函数处理
def parse_frame(self,raw: bytes):
"""返回 dict 或 None"""
header = struct.unpack("<2s",raw[:2])[0]
if len(raw) < 10 or raw[:2] != SYNC_HEAD or raw[-1] != SYNC_TAIL:
print("tail matters")
return None
pkt_len = struct.unpack('<H', raw[2:4])[0]
if len(raw) < 22+pkt_len:
print("package len matters")
return None
payload = raw[2: 2+ 22 +pkt_len]
if crc16(payload) != struct.unpack('<H', raw[-3:-1])[0]:
print("crc matters")
return None
cmd_id = raw[4:21].decode()
frame_type = raw[21]
ptype = raw[22]
seq = raw[23]
content = raw[24:]
#if frame_type != FRAME_TYPE_DATA:
# return None
parser = getattr(self,self.PARSER_MAP.get(ptype))
if not parser:
return None
try:
return parser(cmd_id, seq, raw, 24)
except Exception as e:
return None
# -------------------- 主循环 --------------------
def run(self,ip='0.0.0.0', port=50001):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((ip, port))
while True:
data, addr = sock.recvfrom(4096)
res = self.parse_frame(data)
print("res:",res)
if res:
ptype = {
'weather': PTYPE_WEATHER,
'filth': PTYPE_FILTH,
'breeze_flutter': PTYPE_BREEZE_FLUTTER,
'breeze_waveform': PTYPE_BREEZE_WAVEFORM,
'wire_temp': PTYPE_WIRE_TEMP,
'wire_radian': PTYPE_WIRE_RADIAN,
'tower_tilt': PTYPE_TOWER_TILT,
'device_time': PTYPE_DEVICE_TIME,
'device_netadapter': PTYPE_DEVICE_NETADAPTER,
'mainsite_request': PTYPE_MAINSITE_REQUEST,
'collect_params': PTYPE_COLLECT_PARAMS,
'model_params': PTYPE_MODEL_PARAMS,
'alarm_thresholds': PTYPE_ALARM_THRESHOLDS,
'device_direct': PTYPE_DEVICE_DIRECT,
'control_base_info': PTYPE_CONTROL_BASE_INFO,
'remote_upgrade': PTYPE_REMOTE_UPGRADE,
'cmd_id': PTYPE_CMD_ID,
'cmd_reset': PTYPE_CMD_RESET,
'cmd_wake': PTYPE_CMD_WAKE,
'weather_params': PTYPE_WEATHER_PARAMS,
'tower_tilt_params': PTYPE_TOWER_TILT_PARAMS,
'breeze_flutter_params': PTYPE_WEATHER,
'wire_radian_params': PTYPE_WIRE_RADIAN_PARAMS,
'wire_temp_params': PTYPE_WIRE_TEMP_PARAMS,
'ice_params': PTYPE_ICE_PARAMS,
'wire_yaw_params': PTYPE_WIRE_YAW_PARAMS,
'gallop_char_params': PTYPE_GALLOP_CHAR_PARAMS,
'filth_params': PTYPE_FILTH_PARAMS,
'image_collect_params': PTYPE_IMAGE_COLLECT_PARAMS,
'image_time_table': PTYPE_IMAGE_TIME_TABLE,
'image_take_manual': PTYPE_IMAGE_TAKE_MANUAL,
'camera_remote_adjust': PTYPE_CAMERA_REMOTE_ADJUST,
'camera_time_table': PTYPE_CAMERA_TIME_TABLE,
'cmd_heartbeat': PTYPE_CMD_HEARTBEAT,
'cmd_base_info': PTYPE_CMD_BASE_INFO,
'cmd_work_state': PTYPE_CMD_WORK_STATE,
'cmd_err_info': PTYPE_CMD_ERR_INFO,
'ice': PTYPE_ICE,
'gallop_char': PTYPE_GALLOP_CHAR,
'gallop_track': PTYPE_GALLOP_TRACK,
'request_image': PTYPE_REQUEST_IMAGE_DATA,
'image': PTYPE_IMAGE_DATA,
'image_end': PTYPE_IMAGE_END_DATA,
}[res['type']]
if ptype == 0xCC:
resp = data
print("resp",resp)
sock.sendto(resp, addr)
if ptype == 0xCE:
resp = self.make_ssue_image_resp(res)
sock.sendto(resp, addr)
else:
resp = self.make_monitor_resp_frame(data[4:21].decode(), data[23], ptype)
# 覆冰数据封包
def ice_data_pack():
ice_data = {
'type': 'ice',
'comp_id': '00000000000000002',
'time_stamp': 1700000000,
'eq_icethickness': 5.2,
'tension': 3.3,
'tension_difference': 4.4,
't_sensor_num': 2,
't_sensor_list': [{'tension':3.3,'crosswise_angle':4.4,'forward_tilt_angle':5.5},{'tension':3.3,'crosswise_angle':4.4,'forward_tilt_angle':5.5}],
'instantaneous_windspeed': 6.6,
'instantaneous_winddirection': 4,
'air_temperature': 3.3,
'humidity': 3,
}
comp_id = struct.pack('<17s',ice_data['comp_id'].encode('utf-8'))
time_stamp = struct.pack('<I',ice_data['time_stamp'])
eq_icethickness = struct.pack('<f',ice_data['eq_icethickness'])
tension = struct.pack('<f',ice_data['tension'])
tension_difference = struct.pack('<f',ice_data['tension_difference'])
t_sensor_num = struct.pack('<B',ice_data['t_sensor_num'])
t_sensor_list = b''
for i in range(ice_data['t_sensor_num']):
t_sensor_list += struct.pack('<f',ice_data['t_sensor_list'][i]['tension'])
t_sensor_list += struct.pack('<f',ice_data['t_sensor_list'][i]['crosswise_angle'])
t_sensor_list += struct.pack('<f',ice_data['t_sensor_list'][i]['forward_tilt_angle'])
instantaneous_windspeed = struct.pack('<f',ice_data['instantaneous_windspeed'])
instantaneous_winddirection = struct.pack('<H',ice_data['instantaneous_winddirection'])
air_temperature = struct.pack('<f',ice_data['air_temperature'])
humidity = struct.pack('<H',ice_data['humidity'])
content = comp_id + time_stamp + eq_icethickness+tension+tension_difference+t_sensor_num+t_sensor_list+instantaneous_windspeed+instantaneous_winddirection+air_temperature+humidity
return content
#通用封包
def gen_pack():
#封包
content = ice_data_pack()
print(content,len(content))
b_frame = b''
header = struct.pack('<2s',b'\x5A\xA5')
data_len = struct.pack("<H",len(content))
device_id = struct.pack("<17s",b"00000000000000001")
frame_type = struct.pack("<s",b'\x01')
ptype= struct.pack("<s",b'\x22')
frame_no = struct.pack("<s",b'\x01')
content = content
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
parse_frame(b_frame)
def gen_request_image_pack(frame_no,channel_no,presetting_no,packt_no):
b_frame = b''
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",b"00000000000000002")
frame_type = struct.pack("<s",b'\x05')
ptype= struct.pack("<s",b'\xCC')
frame_no = struct.pack("<B",frame_no)
channel_no = struct.pack("<B",channel_no)
presetting_no = struct.pack("<B",presetting_no)
packt_no_hi = struct.pack("<H",packt_no)[0]
packt_no_lo = struct.pack("<H",packt_no)[1]
content = channel_no + presetting_no+packt_no_hi.to_bytes() + packt_no_lo.to_bytes()
data_len = struct.pack("<H",len(content))
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def gen_image_pack(img_bytes,frame_no,channel_no,presetting_no,packt_no,subpacket_no):
b_frame = b''
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",b"00000000000000002")
frame_type = struct.pack("<s",b'\x05')
ptype= struct.pack("<s",b'\xCD')
frame_no = struct.pack("<B",frame_no)
channel_no = struct.pack("<B",channel_no)
presetting_no = struct.pack("<B",presetting_no)
packt_no = struct.pack("<H",packt_no)
subpacket_no = struct.pack("<H",subpacket_no)
content = channel_no + presetting_no+packt_no + subpacket_no + img_bytes
data_len = struct.pack("<H",len(content))
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def gen_image_end_pack(frame_no,channel_no,presetting_no,timestamp):
b_frame = b''
header = struct.pack('<H',23205)
device_id = struct.pack("<17s",b"00000000000000001")
frame_type = struct.pack("<s",b'\x05')
ptype= struct.pack("<s",b'\xCE')
frame_no = struct.pack("<B",frame_no)
channel_no = struct.pack("<B",channel_no)
presetting_no = struct.pack("<B",presetting_no)
timestamp = struct.pack("<I",timestamp)
content = channel_no + presetting_no + timestamp
data_len = struct.pack("<H",len(content))
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
return b_frame
def append_image_data():
import os
if os.path.exists("pic2.jpg"):
os.remove("pic2.jpg")
pic = open("pic.jpg",'rb').read()
a = pic[:10]
b = pic[10:]
f = open("pic2.jpg",'ab')
f.write(a)
f.close()
f = open("pic2.jpg",'ab')
f.write(b)
f.close()
def clear_image():
import os
if os.path.exists("00000000000000002_1.jpg"):
os.remove("00000000000000002_1.jpg")
def image_send():
# 创建socket对象
client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 服务器地址端口
dest_addr = ('0.0.0.0', 50001)
# 发送数据
with open("pic.jpg", "rb") as f:
image_data = f.read()
chunk_size = 1024 # 每个数据包大小
n_chunks = len(image_data) // chunk_size
frame_img_request = gen_request_image_pack(1,1,1,n_chunks)
client_socket.sendto(frame_img_request, dest_addr)
data = client_socket.recv(1024)
print("data",data)
pack_dict = {}
for i in range(0,n_chunks):
chunk = image_data[i * chunk_size: (i + 1) * chunk_size]
pack_dict[i] = chunk
frame = gen_image_pack(chunk,i+1,1,1,n_chunks,i)
client_socket.sendto(frame, dest_addr)
img_end = gen_image_end_pack(n_chunks,1,1,1700000000)
client_socket.sendto(img_end, dest_addr)
# 接收数据
data = client_socket.recv(1024)
sum = struct.unpack('<H',data[26:28])[0]
frame_type = data[21]
ptype = data[22]
ssue_pack_no_list = []
print('ptype',ptype)
if ptype == 0xCF:
offset = 28
if len(data) > 33:
for i in range(sum):
no = struct.unpack('<H',data[offset:offset+2])[0]
print(no)
ssue_pack_no_list.append(no)
offset += 2
for pack_no in ssue_pack_no_list:
frame = gen_image_pack(pack_dict[pack_no],pack_no,1,1,n_chunks,pack_no)
client_socket.sendto(frame, dest_addr)
img_end = gen_image_end_pack(n_chunks,1,1,1700000000)
client_socket.sendto(img_end, dest_addr)
# 关闭连接
client_socket.close()
def server_main():
#封包
content = ice_data_pack()
print(content,len(content))
b_frame = b''
header = struct.pack('<H',23205)
data_len = struct.pack("<H",len(content))
device_id = struct.pack("<17s",b"00000000000000001")
frame_type = struct.pack("<s",b'\x01')
ptype= struct.pack("<s",b'\x22')
frame_no = struct.pack("<s",b'\x01')
content = content
payload = data_len + device_id + frame_type + ptype + frame_no + content
crc = crc16(payload)
crc_b = struct.pack('<H',crc)
b_frame = header + payload + crc_b + b'\x96'
s = I1Server()
s.start()
if __name__ == '__main__':
main()
python
# -------------------- 协议常量 --------------------
SYNC_HEAD = b'\xA5\x5A'
SYNC_TAIL = 0x96
#帧类型
#数据监测报(监测装置-> 主站系统)
FRAME_TYPE_DATA = 0x01
#数据响应报(主站系统-> 监测装置)
FRAME_TYPE_RESP = 0x02
#控制数据报(主站系统-> 监测装置)
FRAME_TYPE_CONTROL = 0x03
#控制响应报(监测装置-> 主站系统)
FRAME_TYPE_CONTROL_RESP = 0x04
#远程图像数据报(监测装置-> 主站系统)
FRAME_TYPE_IMAGE = 0x05
#图像数据响应报(主站系统-> 监测装置)
FRAME_TYPE_IMAGE_RESP = 0x06
#远程图像控制报(主站系统-> 监测装置)
FRAME_TYPE_IMAGE_CONTROL = 0x07
#图像控制响应报(监测装置-> 主站系统)
FRAME_TYPE_IMAGE_CONTROL_RESP = 0x08
#工作状态报(监测装置-> 主站系统)
FRAME_TYPE_WORK_STATUS = 0x09
#工作状态响应报(主站系统-> 监测装置)
FRAME_TYPE_WORK_STATUS_RESP = 0x0A
#同步数据报(两个监测系统?的数据同步)
FRAME_TYPE_FFH = 0xFF
# 报文类型,只列了部分用到的
PTYPE_WEATHER = 0x0B
PTYPE_TOWER_TILT = 0x0C
PTYPE_FILTH = 0x5C
PTYPE_ICE = 0x22
PTYPE_BREEZE_FLUTTER = 0x1E
PTYPE_BREEZE_WAVEFORM = 0x1F
PTYPE_GALLOP_CHAR = 0x24
PTYPE_GALLOP_TRACK = 0x25
PTYPE_WIRE_TEMP = 0x21
PTYPE_WIRE_RADIAN = 0x20
PTYPE_WIRE_YAW = 0x23
PTYPE_DEVICE_TIME = 0xA1
PTYPE_DEVICE_NETADAPTER = 0xA2
PTYPE_MAINSITE_REQUEST = 0xA3
PTYPE_COLLECT_PARAMS = 0xA4
PTYPE_MODEL_PARAMS = 0xA5
PTYPE_ALARM_THRESHOLDS = 0xA6
PTYPE_DEVICE_DIRECT = 0xA7
PTYPE_CONTROL_BASE_INFO = 0xA8
PTYPE_REMOTE_UPGRADE = 0xA9
PTYPE_REMOTE_UPGRADE_END = 0xAA
PTYPE_REMOTE_UPGRADE__SSUE = 0xAB
PTYPE_CMD_ID = 0xAC
PTYPE_CMD_RESET = 0xAD
PTYPE_CMD_WAKE = 0xAE
PTYPE_WEATHER_PARAMS = 0xAF
PTYPE_TOWER_TILT_PARAMS = 0xB0
PTYPE_BREEZE_FLUTTER_PARAMS = 0xB1
PTYPE_WIRE_RADIAN_PARAMS = 0xB2
PTYPE_WIRE_TEMP_PARAMS = 0xB3
PTYPE_ICE_PARAMS = 0xB4
PTYPE_WIRE_YAW_PARAMS = 0xB5
PTYPE_GALLOP_CHAR_PARAMS = 0xB6
PTYPE_FILTH_PARAMS = 0xB7
PTYPE_IMAGE_COLLECT_PARAMS = 0xC9
PTYPE_IMAGE_TIME_TABLE = 0xCA
PTYPE_IMAGE_TAKE_MANUAL = 0xCB
PTYPE_REQUEST_IMAGE_DATA = 0xCC
PTYPE_IMAGE_DATA = 0xCD
PTYPE_IMAGE_END_DATA = 0xCE
PTYPE_IMAGE_SSUE_DATA = 0xCF
PTYPE_CAMERA_REMOTE_ADJUST = 0xD0
PTYPE_CAMERA_UPLOAD_VIDEO = 0xD1
PTYPE_CMD_SAVE_ADRESS = 0xD2
PTYPE_STOP_CONNECT = 0xD3
PTYPE_CAMERA_BASE_INFO = 0xD4
PTYPE_CAMERA_TIME_TABLE = 0xD5
PTYPE_CMD_HEARTBEAT = 0xE6
PTYPE_CMD_BASE_INFO = 0xE7
PTYPE_CMD_WORK_STATE = 0xE8
PTYPE_CMD_ERR_INFO = 0xE9
PTYPE_CUSTOM_DATA = 0x21
# crc16校验表,高位表
crc16_table_h = [
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
]
#crc16校验表,低位表
crc16_table_l = [
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04,
0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8,
0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10,
0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C,
0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0,
0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C,
0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54,
0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98,
0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40
]
#校验函数
def crc16(data: bytes) -> int:
hi, lo = 0xFF, 0xFF
for b in data:
idx = hi ^ b
hi = lo ^ crc16_table_h[idx]
lo = crc16_table_l[idx]
return (hi << 8) | lo