Siemens LOGO! PLC data in the wrong order

Question:

So I’m accessing an Siemens LOGO! PLC to extract some data from. I managed to do that with my work partner but we’re stuck on how the data is being saved. The data is being timestamped in a dictionary with the output and input bytes from the PLC. But the data comes in a certain order and is timestamped the moment the data is extracted.

Now the problem is that the timestamps and data isn’t saved in the same order that the data comes in. Somewhere in the process it makes a mistake (I think), but we can’t seem to find it.

Here’s the Python Code we use:

# initial testing to connect to a PLC
#connects to PLC save I/O into json format with timestamp
import snap7
import time
import ctypes
import math
import json

PLCip = "x.x.x.x" #input  ip
Port = 000 # input port
Rack = 0
Slot = 1
size_to_read = 100
datadb = (ctypes.c_uint8 * size_to_read)()

#creates client and connect to plc, returns true if connected
Client = snap7.client.Client()
Client.connect(PLCip, Rack, Slot)
print("Connected:", Client.get_connected())

#converts sum INT to bits
def access_bit(data, num):
    base = int(num // 8)
    shift = int(num % 8)
    return (data[base] & (1<<shift)) >> shift

#empty dict for storing I/O data
mydata = {}

#save data dict to json format
def save_to_file(stamp, input, output, file):
    mydata[stamp] = {'input': input, 'output': output}
    with open(file,'a') as f:
        json.dump(mydata, f)

while True:
    # ts = time.time()    #gets current time 
    _now = time.time()
    ts = time.localtime(_now)
    # timestamp = (time.strftime('%H:%M:%S',ts),str('%.3f'%_now).split('.')[1])
    timestamp = time.strftime('%X',ts)
    datestamp = time.strftime('%d-%m-%Y',ts)
    log_folder='logs/'
    color=['black/','orange/','metal/']

    #json_file = str(log_folder)+str(datestamp)+'-'+str(timestamp)+'.json'
    json_file = str(log_folder)+str(color[2])+str(datestamp)+'.json'

    data = Client.eb_read(0,2)  # reads input data from 2 bytes
    data_input = format(int.from_bytes(data, "little"), "b")    #converts from int to bits

    outputdata = Client.ab_read(0,2)    #reads output data from 2 bytes
    data_output = format(int.from_bytes(outputdata, "little"), "b")    #converts from int to bits

    #save it to json file with parameters
    save_to_file(timestamp,data_input,data_output, json_file)
    #print to cli for debugging
    print_text= "Time: {}nInput: {}nOutput: {}n".format(timestamp,data_input,data_output)
    print(print_text)
    #wait 1 second and restart
    time.sleep(1)

And the data we get:

{"13:41:57": {"input": "1001010000", "output": "0"}}{"13:41:57": {"input": "1001010000", "output": "0"}, "13:41:58": {"input": "1001010000", "output": "0"}}{"13:41:57": {"input": "1001010000", "output": "0"}, "13:41:58": {"input": "1001010000", "output": "0"}, "13:41:59": {"input": "1001010000", "output": "0"}}{"13:41:57": {"input": "1001010000", "output": "0"}, "13:41:58": {"input": "1001010000", "output": "0"}, "13:41:59": {"input": "1001010000", "output": "0"}, "13:42:00": {"input": "1001010000", "output": "0"}}{"13:41:57": {"input": "1001010000", "output": "0"}, "13:41:58": {"input": "1001010000", "output": "0"}, "13:41:59": {"input": "1001010000", "output": "0"}, "13:42:00": {"input": "1001010000", "output": "0"}, "13:42:01": {"input": "1001010000", "output": "1001"}}{"13:41:57": {"input": "1001010000", "output": "0"}, "13:41:58": {"input": "1001010000", "output": "0"}, "13:41:59": {"input": "1001010000", "output": "0"}, "13:42:00": {"input": "1001010000", "output": "0"}, "13:42:01": {"input": "1001010000", "output": "1001"}, "13:42:02": {"input": "1010010000", "output": "101"}}{"13:41:57": {"input": "1001010000", "output": "0"}, "13:41:58": {"input": "1001010000", "output": "0"}, "13:41:59": {"input": "1001010000", "output": "0"}, "13:42:00": {"input": "1001010000", "output": "0"}, "13:42:01": {"input": "1001010000", "output": "1001"}, "13:42:02": {"input": "1010010000", "output": "101"}, "13:42:03": {"input": "1010010000", "output": "101"}}{"13:41:57": {"input": "1001010000", "output": "0"}, "13:41:58": {"input": "1001010000", "output": "0"}, "13:41:59": {"input": "1001010000", "output": "0"}, "13:42:00": {"input": "1001010000", "output": "0"}, "13:42:01": {"input": "1001010000", "output": "1001"}, "13:42:02": {"input": "1010010000", "output": "101"}, "13:42:03": {"input": "1010010000", "output": "101"}, "13:42:04": {"input": "1001010000", "output": "0"}}{"13:41:57": {"input": "1001010000", "output": "0"}, "13:41:58": {"input": "1001010000", "output": "0"}, "13:41:59": {"input": "1001010000", "output": "0"}, "13:42:00": {"input": "1001010000", "output": "0"}, "13:42:01": {"input": "1001010000", "output": "1001"}, "13:42:02": {"input": "1010010000", "output": "101"}, "13:42:03": {"input": "1010010000", "output": "101"}, "13:42:04": {"input": "1001010000", "output": "0"}, "13:42:05": {"input": "1001010001", "output": "1001"}}{"13:41:57": {"input": "1001010000", "output": "0"}, "13:41:58": {"input": "1001010000", "output": "0"}, "13:41:59": {"input": "1001010000", 

This is one continuous execution of the script. As you can see the timestamps aren’t really in order.
Can anyone help us solve this problem. Maybe you guys can see something I can’t see.

Many thanks!

Asked By: JD_Bachelor

||

Answers:

I found out why it was so duplicating the data packets.
Because the dict data is defined outside the while loop it keeps adding new keys,values to the dict. The dict is being wrapped into a json file and keeps getting exponentially increasing.

The dict data needs to be defined inside the while loop so that it can be reused every time it dumps the dict into the json.

...
#save data dict to json format
def save_to_file(stamp, input, output, file):
    mydata[stamp] = {'input': input, 'output': output}
    with open(file,'a') as f:
        json.dump(mydata, f)

while True:
    mydata={}
    # ts = time.time()    #gets current time 
    _now = time.time()
    ts = time.localtime(_now)
    # timestamp = (time.strftime('%H:%M:%S',ts),str('%.3f'%_now).split('.')[1])
    timestamp = time.strftime('%X',ts)
    datestamp = time.strftime('%d-%m-%Y',ts)
    log_folder='logs/'
    color=['black/','orange/','metal/']
...
Answered By: JD_Bachelor

Can you explain to me how to communicate with the logo’s PLC via JS?

Answered By: Jorge Vieira
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.