我一直致力于通过 Python 从PLC传感器获取数据的解决方案,并且我能够使用cpppo计算出语法,这样就可以了至于以假定的序列化方式从循环中获取标记中的数据。
为了测试这个新的 Python cpppo解决方案,我已经通过VPN隧道将运行 Python 逻辑的计算机连接到PLC,我拥有它{{3}一个特定的标签/传感器。此标记也轮询 并使用与本地计算机网络连接的 非Python 解决方案进行记录通过以太网。
有没有人知道我可以用下面的方式重写这个简单代码的方式,我可以强制它在一秒内轮询3次甚至4次?还有什么可能有助于此吗?
传感器数据以方括号括起来,但以十进制精度表示以克为单位的重量,下面是原始数据的一小部分样本。
[610.5999755859375]
[607.5]
[623.5999755859375]
[599.7999877929688]
[602.5999755859375]
[610.0]
注意: Python 逻辑会将传感器中的轮询值写入csv文件,但会根据系统日期生成并插入时间戳记录,时间通过 datetime.now()
但在此之前我将值转换为字符串,然后使用str(x).replace('[','').replace(']','')
从 str()
的迭代值中删除方括号功能
from cpppo.server.enip.get_attribute import proxy_simple
from datetime import datetime
import time, csv
CsvFile = "C:\\folder\\Test\\Test.csv"
host = "<IPAddress>"
while True:
x, = proxy_simple(host).read("<TagName>")
with open(CsvFile,"a",newline='') as file:
csv_file = csv.writer(file)
for val in x:
y = str(x).replace('[','').replace(']','')
csv_file.writerow([datetime.now(), y])
#time.sleep(0.05)
当我将 Python 捕获的csv文件记录与标记的其他非Python 捕获方法的记录进行比较时, Python 生成的csv记录有时会经常丢失。
值得注意的详细信息(以防万一)
这两个系统之间存在第二个或更少的时间戳差异,因为它们会在捕获时生成时间戳。
这个特定的传感器可以在一秒内吐出三个值,但并非总是如此;有时一秒钟,或两秒钟,或一秒钟内没有。
我认为另一种方法使用Java,但比较逻辑无法访问此代码。
我正在使用Python版3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)]
和 Windows 10 。
结果
Python方法CSV (缺少相关的
606.6
值)2018-04-12 13:56:42.249408,610.5999755859375 2018-04-12 13:56:42.909309,607.5 2018-04-12 13:56:43.559472,623.5999755859375 2018-04-12 13:56:44.259771,599.7999877929688 2018-04-12 13:56:44.910270,602.5999755859375 2018-04-12 13:56:45.541044,610.0
其他方法CSV结果(包含
606.6
值)12/04/2018 13:56:41,610.6 12/04/2018 13:56:42,607.5 12/04/2018 13:56:42,623.6 12/04/2018 13:56:43,606.6 12/04/2018 13:56:43,599.8 12/04/2018 13:56:44,602.6 12/04/2018 13:56:44,610
问题注意: Python错过捕获 12/04/2018 13:56:43,606.6
记录,而它是从其他系统记录的。我怀疑这是由于每个逻辑有一些微小的延迟,因为与其他非Python捕获文件相比,我只看到它缺少值。
答案 0 :(得分:3)
代码的关键部分是:
while True:
x, = proxy_simple(host).read("<TagName>")
with open(CsvFile,"a",newline='') as file:
for val in x:
# ...
在伪代码中:
forever:
create proxy
open output file
process values from proxy
您提到传感器每秒可能产生大约3个值。如果你看一下read()
的实现,它的作用是设置一个新的reader对象并从中获取所有值。
您可能认为您的代码运行如下:
但事实上,它可能是这样运行的:
每次调用read()
时,它都会产生当时知道的值。它不会等待任何新值到来。
尝试这种重构:
source = proxy_simple(host)
with open(CsvFile,"a",newline='') as file:
while True:
for message in source.read("<TagName>"):
for val in message:
# ...
原始代码中的另一个错误是:
x, = proxy_simple(host).read("<TagName>")
如果read()
返回多个值,则只使用第一个值。这就是我在上面提出的代码中有两个for
循环的原因。
然后,您只会在每个程序运行时打开输入和输出一次,而不是每个消息一次。