Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plc receive function always return empty byte #35

Open
abuyusif01 opened this issue Oct 8, 2022 · 2 comments
Open

plc receive function always return empty byte #35

abuyusif01 opened this issue Oct 8, 2022 · 2 comments

Comments

@abuyusif01
Copy link

abuyusif01 commented Oct 8, 2022

As the title said, am trying to use the swat example given in examples/swat-s1, but when i try receiving something in plc1 from plc2 it always return an empty byte. I tried sending the tag with self.send(TAG, VALUE, PLC1_ADDR) and self.send(TAG, VALUE, PLC2_ADDR) neither works. I did thesame with receive, self.recieve(TAG, PLC1_ADDR) and self.recieve(TAG, PLC2_ADDR) but no luck.

From what i understand minicps use cpppo to send/receive stuff. Since i received an empty bytes i cant call float on it. It resulted to a str cant be converted to float (which make sense)

I tested it on ubuntu and endeavoros(arch based) but all result in thesame.

Sample output from plc1 terminal

DEBUG SENSO2-FL:2
DEBUG1 (b'', None)
DEBUG2 b''
DEBUG4 b'

Am really lost

@RedClouud
Copy link

I had the same issue. It is likely due to the fact that MiniCPS doesn't work with the newest version of cpppo. Although, there has been a commit in the past month which seems to have fixed it but I haven't tested it.

To fix the issue, I had to use cpppo's functions directly rather than using MiniCPS's higher level functions.

Here is an example to host a value on PLC2 called FIT201 and access it from PLC1:

  1. Go into the utils.py folder and change PLC2_PROTOCOL mode to 0 (this disables the creation of a server as we will be doing this manually)
PLC2_PROTOCOL = {
    'name': 'enip',
    'mode': 0,
    'server': PLC2_SERVER
}
  1. In PLC2, import the required libraries
import shlex
import subprocess
from cpppo.server.enip.get_attribute
import proxy_simple
  1. In PLC2, under the def main_loop(self): method:
# Start enip server and to host a REAL value, available @22/1/1
tag_string = 'FIT201:2@22/1/1=REAL'
        cmd = shlex.split(
            'enip_server --print' +
            ' ' + tag_string
        )
client = subprocess.Popen(cmd, shell=False)
  1. In PLC1, import required libraries:
from cpppo.server.enip.get_attribute import proxy_simple
from cpppo import logging
  1. In PLC1, define a request for FIT201 from PLC2:
# Request value of FIT201 from PLC2
class PLC2Parameters(proxy_simple):
    PARAMETERS = dict(proxy_simple.PARAMETERS,
                      fit201_2 = proxy_simple.parameter('@22/1/1', 'REAL', 'm^3/h'),
    )

PLC2_COMMS = PLC2Parameters(host=PLC2_ADDR)
  1. In the def main_loop(self): of PLC1, request FIT201 from PLC2:
# Get from PLC2
            try:
                params = PLC2_COMMS.parameter_substitution("fit201_2")
                value, = PLC2_COMMS.read(params)
            except Exception as exc:
                logging.warning("Access to fit201_2 at PLC2 failed: %s", exc)
                PLC2_COMMS.close_gateway(exc)
                raise

            fit201 = float(value[0])

It's janky but it works.


Updating hosted values in PLC2's server

And if you want to update the values in PLC2 then you can use the following code:
In the def main_loop(self): loop but outside the while(count <= PLC_SAMPLES): loop

via = proxy_simple('192.168.1.20')
fit201_tag = '@22/1/1'

Inside the while(count <= PLC_SAMPLES): loop:

with via: result, = via.read([(fit201_tag + '=(REAL)' + str(fit201), fit201_tag)])
print 'this is the return value: %s' % result

If you do this, you might receive an error with plc2.py. If you do, just run the script again, adding an "&" at the end:
python plc2.py &
Then do it for a second time, and it should function as expected:
python plc2.py

I know that this answer is long and not perfect so if you need any clarification then do ask!

@hugo223325
Copy link

this confuses me for a long time

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants