Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python开发---基于HJ 212协议的简单接收程序

Python开发---基于HJ 212协议的简单接收程序

原创
作者头像
MiaoGIS
修改于 2022-04-01 08:51:25
修改于 2022-04-01 08:51:25
3.1K014
代码可运行
举报
文章被收录于专栏:Python in AI-IOTPython in AI-IOT
运行总次数:14
代码可运行

HJ 212-2017是污染物在线监控(监测)系统数据传输标准的一种。

本标准适用于污染物在线监控(监测)系统、污染物排放过程(工况)自动监控系统与监控中心之间的数据传输,规定了传输的过程及参数命令、交互命令、数据命令和控制命令的格式,给出了代码定义,本标准允许扩展,但扩展内容时不得与本标准中所使用或保留的控制命令相冲突。 本标准还规定了在线监控(监测)仪器仪表和数据采集传输仪之间的数据传输格式,同时给出了代码定义。

传感器设备通过TCP连接,使用HJ 212协议向服务器发送报文数据。

服务器接收程序运行如下:

设备作为TCP Client上传数据,所以服务端接收程序是一个TCP Server程序,接收到报文,解析并存储。代码如下:

代码语言:python
代码运行次数:4
运行
AI代码解释
复制
# -*-coding:utf-8 -*-
import socket
import threading
from datetime import datetime
from hjt212 import *

def deleteConnection(item):
    global connectionList
    del connectionList['connection'+item]



class WebSocket(threading.Thread):#继承Thread

    #def __init__(self,conn,index,name,remote,path='/'):
    def __init__(self,conn,name,remote,path='/'):
        threading.Thread.__init__(self)#初始化父类Thread
        self.conn=conn
        #self.index=index
        self.name=name
        
        self.remote=remote
        self.path=path
        
        self.buffer=''
        self.buffer_utf8=''
        self.length_buffer=0

    def run(self):#重载Thread的run
        #print ('Socket %s Start!' % self.index)
        print ('Socket %s Start!'% (self.remote[0]+":"+str(self.remote[1])))
        headers={}
        self.handshaken=False

        while True:
            print(self.name)
            #print(self.handshaken)
                      
            if self.handshaken==False:
                message=self.conn.recv(1024)
                if(len(message)!=0):
		    
                    sourceIP=self.remote[0]+":"+str(self.remote[1])
                    print(u"IP::"+sourceIP+u"\n报文::"+message.hex()+u"\n时间::"+str(datetime.now()))
                    nowStr=datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    t=threading.Thread(target=savePack,args=(sourceIP,message,nowStr,self))
                    t.run()
                    
                    #print('Socket %s Start Handshaken with %s!' % (self.index,self.remote))
                    print('Socket  Start Handshaken with %s!' % (self.remote,))
                    #print('Socket %s Handshaken with %s success!' %(self.index,self.remote))
                    
                
                     
                   
                else:
                    self.handshaken = True
            else:
                
                #deleteConnection(str(self.index))
                self.conn.close()
                break #退出线程

class WebSocketServer(object):
    def __init__(self):
        self.socket=None

    def begin(self):
        print ('WebSocketServer Start!')
        self.socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        self.socket.bind(('0.0.0.0',8091))
        self.socket.listen(50)

        #global connectionlist

        #i=0
    
        while True:
            connection,address=self.socket.accept()
            
            ip=address[0]    
            
            newSocket=WebSocket(connection,ip,address)
            newSocket.start() #开始线程,执行run函数
            #global connectionList
            #connectionList['connection'+str(i)]=connection
            #i=i+1


if __name__=='__main__':
    #global connectionList
    #connectionList = {}
    server=WebSocketServer()
    server.begin()

hjt212.py文件中定义了hj212协议数据包的解析和存储:包括CRC校验,报文解析成json字典,最后根据CN编号(2051表示为分钟数据,2061表示为小时数据)分别保存在MongoDB的不同表中。

代码语言:python
代码运行次数:10
运行
AI代码解释
复制
# -*-coding:utf-8 -*-

"""
{ $and: [ { "CN": "1" },equals
{ "CN": { $ne: "2" } },doesn't equal
{ "CN": /.*abc.*/i },contains
{ "CN": { $not: /.*abc.*/i } },doesn't contain
{ "CN": /^abc.*/i },starts with
{ "CN": { $not: /^abc.*/i } },doesn't start with
{ "CN": /.*abc$/i },ends with
{ "CN": { $not: /.*abc$/i } },doesn't end with
{ "CN": { $exists: true } }, exists
{ "CN": { $exists: false } },doesn't exist
{ "CN": { $in: [abc] } },in 
{ "CN": { $nin: [abc] } },not in
{ "CN": { $all: [abc] } },array contains all
{ "CN": { $gt: "1" } },>
{ "CN": { $gte: "1" } },>=
{ "CN": { $lt: "1" } },<
{ "CN": { $lte: "1" } },<=
{ "CN": { $gte: "1", $lte: "3" } },<=...<
{ "CN": { $gt: "1", $lte: "3" } },<..<=
{ "CN": { $gte: "1", $lt: "3" } },<..<
{ "CN": { $type: 16 } }, has type 
{ "CN": { $not: { $type: 16 } } ,doesn't have type
{ $text: { $search: "abc", $language: "zhs", $caseSensitive: true } } text index search

{ $or: [ { "CN": "1" }, { "MN": { $gt: "1" } } ] }

{ $or: [ { "CN": "1" }, { "MN": { $gt: "1" } }, { $and: [ { "CN": "1" } ] } ] }

{ $or: [ { "CN": "1" }, { $and: [ { "CN": "1" } ] }, { $and: [ { "CN": "1" } ] } ] }

{ $nor: [ { "CN": "1" }, { $and: [ { "CN": "1" } ] }, { $or: [ { "CN": "1" } ] } ] }

{ $nor: [ { "CN": "1" }, { "CP": { $elemMatch: {"CN": "1" } } }, { $or: [ { "CN": "1" } ] } ] }

{ $nor: [ { "CN": "1" }, { "CP": { $not: { $elemMatch: {"CN": "1" } } } }, { $or: [ { "CN": "1" } ] } ] }


{ "PW": 1, "MN": 0}

{ "PW": 1, "Flag": -1}
"""


dictFactor1={'w01001': 'pH值', 'w01009': '溶解氧', 'w01010': '水温', 'w01014': '电导率', 'w01012': '悬浮物', 'w01018': '化学需氧量', 'w21003': '氨氮', 'w20122': '总铜', 'w21016': '氰化物'}

dictFactor2={'w01001': 'pH值', 'w01009': '溶解氧', 'w01010': '水温', 'w01014': '电导率', 'w01012': '悬浮物', 'w01018': '化学需氧量', 'w21003': '氨氮', 'w20122': '总铜', 'w21016': '氰化物'}
from datetime import datetime
global bs
global data
import binascii
import pymongo
import logging
logger=logging.getLogger('HJT212')
fh=logging.FileHandler('log.txt')
logFormatter=logging.Formatter('%(asctime)s -%(name)s -%(message)s')
fh.setFormatter(logFormatter)
logger.addHandler(fh)
logger.setLevel(logging.ERROR)

mongo=pymongo.MongoClient()
t1=mongo.water.minute
t2=mongo.water.hour
def crc32asii(v):
    return '0x%8x' % (binascii.crc32(v) & 0xffffffff)


def crc2hex(crc): 
    return '%08x' % (binascii.crc32(binascii.a2b_hex(crc)) & 0xffffffff)

def crc16(x, invert):
    a = 0xFFFF
    b = 0xA001
    for byte in x:
        a ^= ord(byte)
        for i in range(8):
            last = a % 2
            a >>= 1
            if last == 1:
                a ^= b
    s = hex(a).upper()
 
    return s[4:6]+s[2:4] if invert == True else s[2:4]+s[4:6]
def calc_crc(string):
    data = bytearray.fromhex(string)
    crc = 0xFFFF
    for pos in data:
        crc ^= pos
        for i in range(8):
            if ((crc & 1) != 0):
                crc >>= 1
                crc ^= 0xA001
            else:
                crc >>= 1
    return hex(((crc & 0xff) << 8) + (crc >> 8))


"""
unsigned int CRC16_Checkout ( unsigned char *puchMsg, unsigned int usDataLen ) 
{ 
unsigned int i,j,crc_reg,check; 
crc_reg = 0xFFFF; 
for(i=0;i<usDataLen;i++) 
{ 
crc_reg = (crc_reg>>8) ^ puchMsg[i]; 
 for(j=0;j<8;j++) 
{ 
 check = crc_reg & 0x0001; 
 crc_reg >>= 1; 
 if(check==0x0001) 
{ 
 crc_reg ^= 0xA001; 
 } 
 } 
} 
return crc_reg; 
}
"""
 
def crc(string):
    data=bytearray.fromhex(string)
    crc_reg=0xFFFF
    for x in data:
        crc_reg=(crc_reg>>8)^x
        for i in range(8):
            check=crc_reg&0x0001
            crc_reg=(crc_reg>>1)
            if(check==0x0001):
                crc_reg=(crc_reg^0xA001)
    return crc_reg

def parsePack(ip,bs,receiveTime):
    #global bs
    #bs=text.strip().split(' ')
    #packHead=bytes.fromhex(''.join(bs[:2]))
    text=bs.hex()
    packHead=bytes.fromhex(text[:4])
    packHead=packHead.decode('ascii')
    print(u"包头:%s"%packHead)
    #dataLength=bytes.fromhex(''.join(bs[2:6]))
    dataLength=bytes.fromhex(text[4:12])
    #dataLength=int(dataLength)
    dataLength=int(dataLength)*2
    print(u"数据段长度:%s"%dataLength)
    global data
    #data=bs[6:dataLength+6]
    data=text[12:dataLength+12]
    #crc1=crc(''.join(data))
    crc1=crc(data)
    print("计算CRC为:%s"%crc1)
    print(text[dataLength+12:dataLength+12+8])
    #crc2=int(bytes.fromhex(''.join(bs[dataLength+6:dataLength+6+4])),16)
    crc2=int(bytes.fromhex(text[dataLength+12:dataLength+12+8]),16)
    print("数据CRC为:%s"%crc2)
    print(u"CRC比对成功"if crc1==crc2 else u"CRC比对失败")
    print(u'数据段为:\n%s'%''.join(data))
    #print(u'数据为:\n%s'%bytes.fromhex(''.join(data)).decode('ascii'))
    print(u'数据为:\n%s'%bytes.fromhex(data).decode('ascii'))
    #dataStr=bytes.fromhex(''.join(data)).decode('ascii')
    dataStr=bytes.fromhex(data).decode('ascii')
    sepNum=dataStr.find('DataTime')
    dataStr1=dataStr[:sepNum]
    
    dataDict1=dict(map(lambda x:(x.split('=')[0],x.split('=')[1]),dataStr1.split(';')))
    print(dataDict1)
    dataStr2=dataStr[sepNum:]
    dateText=dataStr2.split(';')[0].split('=')[1]
    date=datetime.strptime(dateText,'%Y%m%d%H%M%S')
    
    print(u"数据时间为:%s"%date.strftime('%Y-%m-%d %H:%M:%S'))
    dateStr=date.strftime('%Y-%m-%d %H:%M:%S')
    list2=list(map(lambda x:x.split(','),dataStr2.split(';')[1:]))
    print(list2)
    dictValues=dict(map(lambda x:[x[0].split('=')[0],x[0].split('=')[1].strip('&')],list2))
    dictFlags=dict(map(lambda x:[x[1].split('=')[0],x[1].split('=')[1].strip('&')],list2))
    
    dictValues0=dict(map(lambda x:[dictFactor1.get(x[0].split('-')[0]),x[1]],dictValues.items()))
    dictFlags0=dict(map(lambda x:[dictFactor1.get(x[0].split('-')[0]),x[1]],dictFlags.items()))
    print(dictValues0)
    print(dictFlags0)
    #dataFoot=bytes.fromhex(''.join(bs[-2:]))
    dataFoot=bytes.fromhex(text[-4:])
    print(u'包尾为:%s'%dataFoot.decode('ascii'))
    qn=datetime.strptime(dataDict1['QN'][:-3],'%Y%m%d%H%M%S')
    qnStr=qn.strftime('%Y-%m-%d %H:%M:%S')
    dataDict1.update({'ip':ip.split(':')[0],'port':ip.split(':')[1],'DataTime':dateText,'dateStr':dateStr,'qnStr':qnStr,'receiveTime':receiveTime})
    return crc1==crc2,dataDict1,dictValues,dictFlags
    
def savePack(ip,bs,receiveTime,self):
    try:
    #if True:
        success,heads,values,flags=parsePack(ip,bs,receiveTime)
    except Exception as e:
        print("error occurred")
        logger.error(e)
        #self.handshaken = True
        return 
         

    if(success):
        #mongo.insert_one()
        print(heads)
        print(values)
        print(flags)
        values.update(heads)
        values.update(flags)
        CN=int(heads['CN'])
        if(CN==2051):
            insId=t1.insert_one(values)
            print(u'ID:%s,已经保存到分钟数据表'%str(insId.inserted_id))
        elif(CN==2061):
            insId=t2.insert_one(values)
            print(u'ID:%s,已经保存到小时数据表'%str(insId.inserted_id))
        
if __name__=='__main__':
    pass
    

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
用Python实现一个简单的WebSoc
windows python 2.79, chrome37 firefox35通过
py3study
2020/01/06
5340
环保 HJ212协议解析
由于是做环保相关的,有时需要对212协议进行拆包和解包。HJ212协议是一种字符串协议,数据传输通讯包主要由包头、数据段长度、数据段、CRC校验、包尾组成,其中“数据段”内容包括请求编码、系统编码、命令编码、密码、设备唯一标识、总包数、包号、指令参数。请求编码为请求的时间戳,系统编码ST统一规定为22,命令编码CN为该数据包的时间类型,访问密码、设备唯一标识在对接时由平台提供,指令参数为数据内容。通讯协议的数据结构如图4所示。
ccf19881030
2020/09/22
3.3K0
环保 HJ212协议解析
简单WiFi控制小车系统(树莓派+python+web控制界面)
   蛇皮走位演示视频: https://pan.baidu.com/s/1RHHr8bRHWzSEAkrpwu99aw
Fivecc
2022/11/21
1.7K0
简单WiFi控制小车系统(树莓派+python+web控制界面)
树莓派&旭日X3派通过TCP指令控制继电器的通断
小黑鸭
2023/10/16
2340
树莓派&旭日X3派通过TCP指令控制继电器的通断
通过一道CTF题目学习M1卡的AES认证机制 | 技术创作特训营第一期
随着射频识别技术的发展,射频卡被广泛应用在了门禁控制、金融支付、库存管理等场景。在此背景下,各种安全认证机制应运而生,为保护个人隐私和敏感数据提供了可靠的保障,本文将通过一道 CTF 题目介绍 M1 卡采用的 AES(Advanced Encryption Standard)认证机制,揭示其背后的原理。
yichen
2023/08/08
1K1
通过一道CTF题目学习M1卡的AES认证机制 | 技术创作特训营第一期
基于web页面开发串口程序界面---代码实现
后台web框架和串口操作采用的是Python语言,其中web框架使用的是tornado。
MiaoGIS
2020/09/14
1.3K0
基于web页面开发串口程序界面---代码实现
python爬虫以及后端开发--实用加密模板整理
都是作者累积的,且看其珍惜,大家可以尽量可以保存一下,如果转载请写好出处https://www.cnblogs.com/pythonywy
小小咸鱼YwY
2020/08/24
7320
一封钓鱼邮件带来的乐趣
整个六月你我都很忙,你忙着钓鱼、我忙着封锁 IP,一份邮件把我从紧张的氛围中拉了出来,邮件大意为“蓝队的朋友想要加分么?你如果能协助国际刑警修复从犯罪嫌疑人电脑上取证的受损图片,那么便可以在演习行动中为你加分,国际刑警求助信息 We received this PNG file, but we’re a bit concerned the transmission may have not quite been perfect,受损图片见附件”。
FB客服
2019/07/22
8710
一封钓鱼邮件带来的乐趣
pythonDES加密与解密以及hex输出和bs64格式输出
import pyDes import base64 Key = "1" #加密的key Iv = None #偏移量 def bytesToHexString(bs): ''' bytes转16进制 ''' return ''.join(['%02X ' % b for b in bs]) def hexStringTobytes(str): ''' 16进制转bytes ''' str = str.replace(" ",
小小咸鱼YwY
2020/06/19
7540
关于 Python3 的编码
对应 C 代码为:unicodeobject.c 中的 _Py_normalize_encoding 函数。
py3study
2020/01/03
1.8K0
Python 开发代码片段笔记
作者编写的一些代码片段,本版本为残废删减版,没有加入多线程,也没有实现任何有价值的功能,只是一个临时记事本,记录下本人编写代码的一些思路,有价值的完整版就不发出来了,自己组织吧,代码没啥技术含量,毕竟Python这一块没怎么认真研究过,代码也都是随性瞎写的,大佬不要喷我,将就着看吧。
王 瑞
2022/12/28
1.2K0
Python 开发代码片段笔记
黑客们会用到哪些Python技术?
Python已经成为漏洞开发领域的行业标准,读者会发现大多数概念验证工具都是用Python语言编写的(除了用Ruby写的安全漏洞检测工具)。Python允许开发者编写脚本处理远程服务,处理二进制文件,与C语言库(或者Java的Jython/。Net的IronPython)以快速且简单的方式进行交互。它“内置电池”原则的巨大标准库,为开发省去对其它框架或者语言的依赖。
小小詹同学
2019/08/23
6570
黑客们会用到哪些Python技术?
Python3编码转换
没有什么编码是不能转的 import hashlib import base64 # string to md5 input_text = "我能吞下玻璃而不伤身体" md5_string = hashlib.md5(input_text.encode(encoding='utf8')).hexdigest() # 2e536f0d3a95e676e30afb2b511c6fe2 # string to base64 base64_string = base64.b64encode(input_text.
Spaceack
2020/11/04
7180
python实现对称加密AES算法
Modes of operations allow you to encrypt more data than the block size of your symmetric block cipher. Example: CBC.
timerring
2022/07/20
9920
python实现对称加密AES算法
Apache ActiveMQ历史漏洞复现合集
编写一个python脚本,需要远程加载poc.xml进行利用,因此需要在poc所在目录利用python搭建一个简易的http服务
Timeline Sec
2024/11/23
3370
Apache ActiveMQ历史漏洞复现合集
python3黑帽子mbp版(第2章:网
写在最前面的话:很早之前就想学python了,趁着买来了书,打算开始python学习之旅。先说下我的工具:使用的是sublime text3编辑器,主要使用的网站是廖雪峰老师 的网站,借鉴了很多ODboy博客中的知识点。 tcp客户端
py3study
2020/01/06
9170
Python中String, Bytes, Hex, Base64之间的关系与转换方法详解
In this program, you are required to learn basic concepts of Python 3.
timerring
2022/07/20
7960
Python中String, Bytes, Hex, Base64之间的关系与转换方法详解
窥探比特币核心机制如何运转 原
比特币真的很酷。当然,有人在想它是否是一种有用的技术,无论我们目前是否处于加密货币泡沫中,或者它目前面临的治理问题是否会得到解决......但在纯粹的技术层面上,神秘的Satoshi Nakamoto创造了令人印象深刻的技术。
笔阁
2019/03/12
7770
窥探比特币核心机制如何运转
                                                                            原
NSSCTF
NSSCTF{c2121501-15be-4f89-a68d-ac3a3a21c33d}
故里[TRUE]
2023/04/19
5330
NSSCTF
第四届红帽杯网络安全大赛
data2三个一组转RGB,然后data1里的数字就是对应的RGB的位置,然后根据data1的字符数量分解质因数得到宽高,最后画图去npiet解
MssnHarvey
2022/08/10
5220
第四届红帽杯网络安全大赛
相关推荐
用Python实现一个简单的WebSoc
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验