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
0
投稿
猜你喜欢
- 效果图基本思路在 OpenCV 中使用VideoCapture方法初始化视频渲染对象创建灰度图像导入预训练模型,识别脸部和人脸标志计算上唇和
- 在 Python 的项目中,如何管理所用的全部依赖库呢?最主流的做法是维护一份“requirements.txt”,记录下依赖库的名字及其版
- 目录Mock概念Mock类简单的例子体验下 Mock 的功能特点一个相对正式的 Mock 例子一个完整的测试例子断言方法Mock概念mock
- 研究好多天了,也试过好多办法了,总结出目前发现最好的方法:先说一下基本的东西:<%@ codepage=65001%>
- 如何做一个可以让人家申请使用的计数器? 好了,我们来做一个与页面分离的计数器,是文本型的啦。这也很简单,
- SMTP用于发送邮件,如果要收取邮件呢?收取邮件就是编写一个MUA作为客户端,从MDA把邮件获取到用户的电脑或者手机上。收取邮件最常用的协议
- 由于最近需要使用爬虫爬取数据进行测试,所以开始了爬虫的填坑之旅,那么首先就是先系统的学习下关于正则相关的知识啦。所以将下面正则方面的知识点做
- 实训课期间忙里偷闲的学习了python的selenium包,唯一一点不好是要自己去查英文文档,明摆着欺负我这种英语不好的,想着用谷歌翻译一下
- 1.字符串处理将字符串中的数字替换成其两倍的值,例如:修改前:"AS7G123m (d)F77k"修改后:"A
- 1.join函数的语法及用法(1)语法:'sep'.join(sep_object)参数说明sep:分割符,可为&l
- 今天在GOOGLE上查图片资料,这一幕真让我纠结啊:使用【向前】【向后】这种说法,就默认了有一个对比坐标,那就是当前显示的4张缩略图。点击【
- 比如可以定义开学时间为2009年2月8日,然后程序可以算出,今天距开学那天已经是第几周,非常急需这个程序,忘高手们能提供一个,先谢谢了!自己
- 获取CPU信息我们先来获取CPU的信息:>>> import psutil>>> psutil.cpu_
- 1. 简述我们在用scrapy爬取数据时,首先就要明确我们要爬取什么数据。scrapy提供了Item对象这种简单的容器,我们可以通过Item
- 效果基于Python3。在自己写小工具的时候因为这个功能纠结了一会儿,这里写个小例子,供有需要的参考。小例子,就是点击按钮打开路径选择窗口,
- ①捕捉一个异常捕捉一个异常以用0作为除数会得到ZeroDivisionError异常为例,print(1/0)为例程序的持续执行,不因该异常
- 问题描述初步使用PyTorch进行平方根计算,通过range()创建一个张量,然后对其求平方根。a = torch.tensor(list(
- 什么是设计模式设计模式是针对软件开发中出现的常见问题的可重用解决方案。它们并不特定于任何编程语言或框架,而是描述了可应用于各种情况的一般原则
- 说到排序,我想起一个故事,大意是说唐僧师徒西游美利坚,孙悟空买了本词典,开始逐条背诵单词。他们第一次下美国馆子的时候,不管服务员推荐什么,孙
- 一个几百行代码做出http/https代理服务器的脚本,启动即可做http https透明代理使用python proxy.py 8992使