python中的生成器实现周期性报文发送功能
作者:Logintern09 发布时间:2023-02-07 23:15:12
标签:python,周期,报文发送
使用python中的生成器实现周期性发送列表中数值的报文发送功能。
功能开发背景:提取cantest工具采集到的现场报文数据,希望使用原始的现场数据模拟验证程序现有逻辑,需要开发一个工具能够自动按照报文发送周期依次发送采集到的报文数据中的一个数值。
功能开发需求:多个报文发送对象共用同一个报文发送线程,多个对象间的报文发送周期不同,多个对象间的总报文发送数据长度不同,能够允许报文发送过程中断及恢复某个对象的报文发送。
功能开发实现逻辑:在固定发送对象某个数值的基础程序版本上增加新的功能,考虑使用python中生成器实现周期性提取对象数值发送报文的功能。
目前只需要发送两个对象的报文数据,先定义两个使用yield生成器:
def yield_item_value_1(self):
item_value_list = self.item_value_dict[item_list[0]]
for i in range(len(item_value_list)):
yield item_value_list[i]
def yield_item_value_2(self):
item_value_list = self.item_value_dict[item_list[1]]
for i in range(len(item_value_list)):
yield item_value_list[i]
报文发送线程中的run()函数:
def run(self):
# 实时更新item的被选状态
self.get_checkbox_res_func()
# 获取每个对象的实际物理值
self.get_item_value_dict()
self.item1_value_func = self.yield_item_value_1()
self.item2_value_func = self.yield_item_value_2()
while self.Flag:
if any(msg_send_flag_dict.values()):
# 每隔second秒执行func函数
timer = Timer(0.01, self.tick_10ms_func)
timer.start()
self.send_working_msg(self.working_can_device, self.working_can_channel)
timer.join()
else:
mes_info = "Goodbye *** 自动发送所有报文数据结束!!!"
toastone = wx.MessageDialog(None, mes_info, "信息提示",
wx.YES_DEFAULT | wx.ICON_QUESTION)
if toastone.ShowModal() == wx.ID_YES: # 如果点击了提示框的确定按钮
toastone.Destroy() # 则关闭提示框
break
报文周期性发送函数:
def send_working_msg(self, can_device, device_id):
for idx in range(len(item_list)):
if msg_send_flag_dict[item_list[idx]] == 1:
msg_id_idx = msg_operation_list.index("报文ID") - 1
msg_id = eval(str(self.operation_dict[item_list[idx]][msg_id_idx]).strip())
# 获取报文发送帧类型
msg_type_idx = msg_operation_list.index("帧类型") - 1
msg_type = str(self.operation_dict[item_list[idx]][msg_type_idx])
msg_type = 1 if msg_type == "扩展帧" else 0
# 获取报文发送周期
msg_cycle_idx = msg_operation_list.index("周期(ms)") - 1
msg_cycle = int(self.operation_dict[item_list[idx]][msg_cycle_idx])
send_cycle = msg_cycle / 10
if msg_tick_10ms_dict["_".join(["tick", "10ms", str(idx)])] >= send_cycle:
# 开始喂值
if idx == 0:
try:
item_phyValue = next(self.item1_value_func)
except StopIteration:
msg_send_flag_dict[item_list[idx]] = 0
continue
else:
try:
item_phyValue = next(self.item2_value_func)
except StopIteration:
msg_send_flag_dict[item_list[idx]] = 0
continue
msg_data = self.get_item_msg(item_list[idx], item_phyValue)
if send_msg(msg_id, msg_type, msg_data, can_device, device_id, 0):
print("发送报文成功")
# print("msg_data", msg_data)
msg_tick_10ms_dict["_".join(["tick", "10ms", str(idx)])] = 0
else:
pass
# print("发送报文失败")
# mes_info = "发送报文失败"
# toastone = wx.MessageDialog(None, mes_info, "信息提示",
# wx.YES_DEFAULT | wx.ICON_QUESTION)
# if toastone.ShowModal() == wx.ID_YES: # 如果点击了提示框的确定按钮
# toastone.Destroy() # 则关闭提示框
功能实现逻辑的待优化点:存在多个对象就需要定义多个存储报文数据的生成器。
上述功能实现逻辑优化如下:
def set_yield_func(self):
item_yield_func_dict = dict()
for i in range(len(item_list)):
item_yield_func_dict[item_list[i]] = self.yield_item_value(i)
return item_yield_func_dict
def yield_item_value(self, item_idx):
item_value_list = self.item_value_dict[item_list[item_idx]]
for i in range(len(item_value_list)):
yield item_value_list[i]
报文发送线程的run()函数中调用这个存储对象报文发送数据生成器的字典item_yield_func_dict:
def run(self):
# 实时更新item的被选状态
self.get_checkbox_res_func()
# 获取每个对象的实际物理值
self.get_item_value_dict()
self.item_yield_func_dict = self.set_yield_func()
…………
从存储每个对象生成器的字典item_yield_func_dict中获取生成器对象:
try:
item_phyValue = next(self.item_yield_func_dict[item_list[idx]])
except StopIteration:
msg_send_flag_dict[item_list[idx]] = 0
continue
来源:https://blog.csdn.net/Logintern09/article/details/129356085


猜你喜欢
- “你如何为成千上万的用户和页面提供CSS?” 这是Nicole Sullivan在她的在丹佛的Web Directions North 大会
- --使用说明 本代码适用于MsSql2000,对于其它数据库也可用.但没必要 --创建存储过程 CREATE PROCEDURE pagin
- 本文研究的主要内容是Python中装饰器相关学习总结,具体如下。装饰器(decorator)功能引入日志函数执行时间统计执行函数前预备处理执
- 前言:相信大家在童年或者生活中都玩过石头剪刀布这个游戏,这个游戏需要两个及以上的人。而今天,网上也实现了石头剪刀布的游戏。通过初步学习pyt
- 有时候我们会在页面上显示用户的所在地区,这个原理是:先得到用户的IP,然后去查询将IP转换成一个数值,最后去查这个数值所在的范围,来得到用户
- asp压缩access数据库,具体asp代码见下: Class DatabaseTools &n
- 1 使用Flask处理表单什么是表单(Form)? 表单是搜集用户数据信息的各种表单元素的集合区域。它的作用是实现用户和服务器的数据交互。通
- django中瀑布流初探img.html<!DOCTYPE html><html lang="en"&
- 一、异常处理在程序开发中如果遇到一些 不可预知的错误 或 你懒得做一些判断 时,可以选择用异常处理来做。import requestswhi
- defaultdict是普通字典dict的一个子类。通过collections库的defaultdict()方法创建。defaultdict
- 1、 <script language="JavaScript"> javascript:window.hi
- 本段源码可以学习的地方:1. 考虑到效率问题,可以通过上下文的机制,在属性被访问的时候临时构建;2. 可以重写一些魔术方法,比如 __new
- 1、Python调用Windows命令打印文件Windows命令行打印文件使用print 命令,具体用法可使用help print查看。下面
- 一、基本介绍logging 模块是python自带的一个包,因此在使用的时候,不必安装,只需要import即可。logging有 5 个不同
- thinkphp查询mssql数据库出现乱码的原因是ThinkPHP默认为UTF-8,而msmsql数据库是简体中文版,存储的是GB2312
- 本文实例讲述了Java实现基于JDBC操作mysql数据库的方法。分享给大家供大家参考,具体如下:package main;import j
- 前言:设计模式在我们编程中是十分重要的!设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用
- 在之前只知道SqlServer支持数据批量插入,殊不知道Oracle、SQLite和MySql也是支持的,不过Oracle需要使用Orace
- 如何制作一个弹出式的调查窗口?执行下面这段ASP代码: <% &n
- 1、 数据库闭包表简介像MySQL这样的关系型数据库,比较适合存储一些类似表格的扁平化数据,但是遇到像树形结构这样有深度的数据,就很难驾驭了