智能电表解决方案基于 QuecPython_EG91X系列C1-P02开发板实现,具有以下特性:
开发板文档
版本:v1.0.0
从 Github 仓库获取源代码步骤如下:
Win10 系统。按照下图进行硬件连接:

LTE 字样的天线连接座上。完成硬件连接的工作后,长按开发板上标识为PWk的按键,直到网络灯net闪烁,或电脑设备管理器的端口列表中出现包含Quectel USB 字样的 COM 口,表示开机成功。(EG91X系列C1-P02开发板上电自动开机)

参考此章节烧录固件包 QPY_OCPU_BETA0002_EG912U_GLAA_FW.zip 至EG912U模组开发板。
dev.json中使用的TCP服务器和UART的具体参数
code文件夹中的所有文件导入到模组文件系统,如下图所示:
执行demo.py之后,程序会启动各个服务模块,并且连接上配置的TCP服务器

这里使用串口助手发送信息模拟电表上传数据,串口助手发送16进制的RFC1662报文,内容为“Hello, I am Meter!”
🚩 Warning
发送的信息需要是代码中RFC1662协议规定的报文格式!例如: 需要发送“Hello I am Meter!”,将其组装成报文格式后16进制表示为:
7E FF 03 00 21 00 12 BF 48 65 6C 6C 6F 20 49 20 61 6D 20 4D 65 74 65 72 21 9C 1F 7E
再通过串口助手以16进制的方式发送给模组

模组收到电表发来的RFC1662报文后会先进行解析,再发送给TCP服务器:

TCP服务器收到电表发来的信息:

TCP服务器向模组发送信息“Hello,I am TCP_Server!”,模组收到后会先对信息进行RFC1662协议组包,再发送给电表

🚩 Warning
图中发现信息前后出现乱码的现象,其实这并不是乱码,是因为模组发过来的是一整个RFC1662协议数据包,
而串口助手并没有解包能力,所以这是正常现象



智能电表解决方案的代码托管于 github,代码的目录结构如下:
智能电表解决方案基于名为 QFrame 的应用框架开发而来。
QFrame应用框架是 QuecPython 开发的一个基础应用框架。点此查看该框架的设计和应用指导。
一个应用程序往往会依赖多个业务模块,各业务模块之间可能存在耦合现象。
在框架设计中,业务模块之间通信是采用星型结构设计,如下图所示:

图中的 Meditor是一个中介对象(通常命名为 Application),各个业务模块之间通过 Application 对象通信,这种设计被称之为中介模式。
业务模块以应用拓展的形式安插在应用程序中,而各应用拓展之间的交互通过 Application 对象进行统一调度。
基于 QFrame 框架的应用程序必须有一个调度各业务模块的的中心对象,即上文提到的 Application 对象;应用参数也是通过该对象配置。
示例代码如下:
Application类原型:
应用拓展指的是被 Application 对象加载的业务模块。一般来说,应用拓展从 app.config 获取其自身的配置并在初始化时传递给应用实例。
应用拓展的使用包含定义和初始化两部分。应用拓展提供一个名为 AppExtensionABC 的基类,定义如下:
该基类被具体的应用拓展类继承,用来约束应用拓展类的接口定义。
__init__ 传入 Application 应用程序对象。在创建应用拓展对象时调用 init_app 来完成拓展的初始化动作;亦可不传入应用对象,而直接创建应用拓展对象,后面再显性调用 init_app 来完成初始化。load 方法用来被 Application 对象调用,用于加载各应用拓展。当应用拓展继承基类 AppExtensionABC,实现了必要的接口功能以后,可参照下面两种不同方式的代码,加载应用拓展对象。
方式一:
方式二(如uart,client等拓展对象):
demo.py 作为应用程序入口的脚本文件,它提供工厂函数 create_app,向该函数传入配置路径来初始化应用程序和加载各应用拓展。
demo.py 示例代码如下:
主要应用拓展功能有三大类 rfc1662resolver(1662协议解析)、client(tcp 客户端)和 uart(串口读写),它们均被注册进应用对象 Application 中,方便互相协作。
rfc1662resolver:负责解析和组装 RFC1662 协议报文,(RFC1662ProtocolResolver 实例对象)。client:tcp 客户端(BusinessClient 实例对象),负责与 tcp 服务器通信。uart:串口客户端(UartBusiness 实例对象),负责串口读写。RFC1662ProtocolResolver该类是一个应用拓展类,是 RFC1662 协议数据的解析器,用于处理业务中传输的 RFC1662 协议数据,对该类数据进行解包组包的功能。
该类提供如下方法:
resolve(msg)
ValueError 异常。如何注册处理函数见装饰器函数 register。msg 是一个 RFC1662Protocol 对象,该类是 RFC1662 协议的封装类,见后续介绍。msg 未能在注册表中查找到处理函数,则抛出 ValueError 异常。register(protocol)
protocol 可以理解为 RFC1662 协议的报文 id。tcp_to_meter_packet(data)
data,组包成透传 RFC1662 数据包(0x2100),即 tcp 透传给表计的数据帧。data,字节类型。module_to_meter_packet(data)
[get/set, id, data],其中:
get/set:COSEM.GET/COSEM.SET,分别对应值为 0xC0/0xC1id:功能命令字data:字节类型示例代码如下:
RFC1662Protocol该类是 RFC1662 协议的具体实现,包括解包和组包。该类对象是一个完整 RFC1662 协议包的封装形式。主要方法有:
build_rfc_0x2100:组 0x2100 协议包,返回字节,等同于 RFC1662ProtocolResolver.tcp_to_meter_packetbuild_rfc_0x2200:组 0x2200 协议包,返回字节,等同于 RFC1662ProtocolResolver.module_to_meter_packetbuild:类方法,用于解析一帧协议包,返回 RFC1662Protocol 对象。replay_get:应答 get 指令, 判断成功失败replay_set:应答 set 指令reply_event:应答 event 信息TcpClient该类向用户开放了两个接口:
recv_callback 方法,用户通过重写该方法,实现对 tcp 服务器下行数据的业务处理。send 方法,用户可调用该方法发送数据至服务器。代码如下:
BusinessClientBusinessClient 通过重写 recv_callback 方法,实现将服务器下行数据打包为 RFC1662 格式的报文,并将数据转发至串口。
代码如下:
Uart该类向用户开放了两个接口:
recv_callback 方法,用户通过重写该方法,实现对接收到的串口数据的业务处理。send 方法,用户可调用该方法向串口发送数据。代码如下:
UartBusinessUartBusiness 通过重写 recv_callback 方法,实现对接收到的串口数据的业务处理。
在子类
UartBusiness的recv_callback方法中解析 RFC1662 协议报文,构建消息对象后,通过rfc1662resolver.resolve方法分发消息处理业务。
在脚本文件 business.py 中定义一个全局的 rfc1662resolver 解析器,用于注册指定类型的消息处理函数。
如下示例代码注册 0x2100 协议透传处理函数: