我一直在研究一种用Python从PLC传感器获取数据的解决方案,我能够使用cpppo计算出语法等,这对于以假定的序列化方式从标记循环中获取数据来说非常有效。
为了测试这个新的python cpppo解决方案,我将运行python逻辑的机器通过vpn隧道连接到一个plc,并让它poll一个特定的标记/传感器。此标记还通过另一个通过以太网连接到本地机器网络的非python解决方案进行轮询和记录。
问题
有没有人知道我可以用一种方式重新编写下面的代码,这种方式我可以强迫它在一秒钟内轮询3次甚至4次还有什么其他的原因吗?
通过贡献“这个”,我说的是“其他”或“非python”方法似乎在一秒钟内3次记录来自同一个标记的轮询响应,而python cpppo解决方案似乎只记录了每秒最多2次的轮询记录,因此时不时地丢失一个权重值,当一秒钟内有3个权重值时,有时只有每秒2次,所以不总是一秒钟3个值,但有时一秒钟有3个值。
python - 有没有一种方法可以帮助使该Python逻辑更快地运行-LMLPHP
数据
返回的传感器数据用方括号括起来,但以克表示重量,精度为十进制,下面是原始数据的一个小样本。

[610.5999755859375]
[607.5]
[623.5999755859375]
[599.7999877929688]
[602.5999755859375]
[610.0]

Python代码
注意: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捕获的文件相比,我只看到它缺少值。

最佳答案

代码的关键部分是:

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对象并从中产生所有值。
你可能认为你的代码是这样运行的:
创建代理
打开输出文件
过程值
转到3
但事实上,它可能是这样运行的:
创建代理
打开输出文件
过程值
转到1
每次调用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循环。
然后,您将只在每次程序运行时打开输入和输出一次,而不是每次消息打开一次。

07-26 09:36
查看更多