pyscada / PyScada

PyScada is a open source scada system that uses the Django framework as backend
http://pyscada.rtfd.io/
GNU Affero General Public License v3.0
520 stars 163 forks source link

Modbus RTU - not reading from RTU device via virtual serial over USB #21

Closed paulalting closed 5 years ago

paulalting commented 5 years ago

I was able to setup PyScada on a small Cubieboard 2 operating Armbian which is Debian for ARM, which I have used now for many years.

Normally this Cubieboard is running my own C code application that is my own form of SCADA, having Modbus TCP/RTU and built in HTTP server. It normally communicates Modbus RTU to my microcontroller, an Arduino DUE via USB serial on port /dev/ttyACM0. The line settings are 115200 baud at 8 data bits no parity and one stop bit. I use libmodbus in my code and it works fine.

Now, coming to PyScada, I have installed it on the same Cubieboard and have configured what I guess is correct, by looking at the method of this person https://cwraig.id.au/2017/09/24/pyscada-on-raspberry-pi-for-temperature-monitoring-with-ds18b20-on-1-wire-part-4-pyscada-hmi-configuration/

I have set up the Modbus device for protocol being Serial RTU, the framer again RTU and unit ID of 1, which I guess is slave ID.

I next added a variable that links back to this device and using FC3 for holding registers, as this is what I do in my own application.

I have tried various addresses for the data variable as I don't know if PyScada for FC3 would use 0 or 1 or 4000 or 40000 as the first address in the holding register map ? I have tried all of the above and I get no displayed data in a simple label with value or custom HTML.

I ssh to the cubieboard and can see that /dev/ttyACM0 is there and is not being used by my own application while I test with PyScada.

Do you have any method to see what the Modbus (PyModbus) module is doing or some other backend way to see data or errors ?

On my controller, I would normally see an LED flash each time it is being polled by my application, but not so with PyScada, it appears to simply not be polling this device at all.

Martin, have you tested and proved the Modbus RTU as working and can you suggest anything for me to check or try please. Many thanks, Paul

paulalting commented 5 years ago

Investigating further, I have made a small Python script using PyModbus to retrieve data from my solar controller based on Arduino DUE. The code operates on the very same system as the PyScada is installed on, the Cubieboard II, and is as follows:

from pymodbus.client.sync import ModbusSerialClient as ModbusClient
import time

due = ModbusClient(method='rtu', port='/dev/ttyACM0', parity='N', baudrate=115200, bytesize=8, stopbits=1, timeout=1)
connection = due.connect()

while connection:

    try:
        mb = due.read_holding_registers(0, 8, unit=1)
        for x in range(8):
            print 'Cell:{:d} {:.2f}V '.format(x+1, mb.registers[x] / 100.0),
        else:
            print 'Cell:{:d} {:.2f}V'.format(x+1, mb.registers[x] / 100.0)

        time.sleep(0.5)
    except:
        print("Unit1 occur error")
        print(mb)
        due.close()
        due.connect()

    time.sleep(60)

The result is: `paul@quadlog:~ $ python ql.py

Cell:1 3.28V Cell:2 3.28V Cell:3 3.28V Cell:4 3.28V Cell:5 3.28V Cell:6 3.28V Cell:7 3.30V Cell:8 3.30V Cell:8 3.30V Cell:1 3.28V Cell:2 3.28V Cell:3 3.28V Cell:4 3.28V Cell:5 3.28V Cell:6 3.28V Cell:7 3.30V Cell:8 3.30V Cell:8 3.30V Cell:1 3.28V Cell:2 3.28V Cell:3 3.28V Cell:4 3.28V Cell:5 3.28V Cell:6 3.28V Cell:7 3.30V Cell:8 3.30V Cell:8 3.30V Cell:1 3.28V Cell:2 3.28V Cell:3 3.28V Cell:4 3.28V Cell:5 3.28V Cell:6 3.28V Cell:7 3.30V Cell:8 3.30V Cell:8 3.30V ` The above script operates fine as is or even while my main C application is operating using the same port to obtain data via Modbus. If you are interested, it is collecting the voltages from eight Lithium cells from my off grid cabin. Each cell is 400Amp at 3.3 volts, Winston LFP Lithium Cell.

I have looked carefully at the configuration for PyScada and believe I have the Modbus parts configured correctly, as well as the HMI components to then display the data, but no data is displayed. If I go to the section PyScada Core:variable states, I see the variables have NaN for last variable state.

Again, PyScada appears not to be polling the controller as I do no see any activity on the RX/TX LEDs on the Arduino DUE as I do with both my own C based SCADA application as well as the Python scrip above.

I would really like to be able to test PyScada with the setup I have before I make any choice about using it for a small industrial project where I normally use Allan Bradley CompactLogix PLC and FactoryTalkView for a agricultural storage shed to control environmental conditions.

Also, I would look at using PyScada to monitor and control a remote site for radio amateur repeaters on top of a mountain that I partly look after.

Much appreciate any help, Paul Alting van Geusau (VK7KPA - Tasmania, Australia)

trombastic commented 5 years ago

Dear Paul,

thank you very much for the detailed description of your problem. Regarding your setup, I think you do not need to use the Framer option, leave it default (-----), this is only useful if you like to use Modbus RTU via Ethernet for example.

i hope this will solve your problem, best wishes,

Martin (DC2TMS)

paulalting commented 5 years ago

Hello Martin, Oh, so you are a radio amateur too, maybe catch you on DMR sometime if you have it, or on 40M band :). Great, I will try your suggestion right away. Many thanks for your reply. If I can get this to work, I would be interested to help extent and progress PyScada, as I quite like the work you have done so far to it.

Paul

paulalting commented 5 years ago

No luck with change mentioned above. Images detail setup for Modbus Device and also for one Modbus variable 20190527_Modbus_Device 20190527_Modbus_variable

Still it does not poll my Modbus device as I do not see any LED activity as would normally. Do I need to restart or reset anything after a change in any section of Admin, or does the update happen directly ?

Paul

trombastic commented 5 years ago

Dear Paul,

first: has the user pyscada the right to access the serial port /dev/ACM0 ?, and second can you have a look in the pyscada_debug.log file (/var/www/pyscada/PyScadaServer/pyscada_debug.log) and when there is a Exception logged can you attache it here or send it to my via eMail?

Martin

trombastic commented 5 years ago

pyscada should restart by itself if you change a device or variable

paulalting commented 5 years ago

After adding dialout to user pyscada it now polls the device: $ sudo usermod -a -G dialout pyscada

Two issues:

I am getting data but need to stop slave device from being reset on every request from PyScada. Data displayed as is in Modbus slave controller - Arduino DUE: 20190527_data_01

It would be good if the documentation could mention that user pyscada needs to be part dialout group if devices are using serial.

Starting to get somewhere, thanks Martin for your help.

paulalting commented 5 years ago

I checked for any debug log, but there is none at the directory you mention. Maybe logging needs to be configured or setup ?

clavay commented 5 years ago

The framer option is only for TCP or UDP. Maybe an help text would be great in the admin part to explain it.

For the connection I think it's because the request_data and write_data functions connect and disconnect to the slave each time it want to request the data. Maybe it's possible to keep the connection as we do for visa ?

paulalting commented 5 years ago

My Modbus slave, an Arduino DUE is not reset like an ordinary Arduino that is reset when a communications port connection is open, resetting the device. That is and was always a painful concept and that does not happen on my system. I normally disable that sort of functionality in my systems.

It appears that when on the 'Device' section (Modbus Device), the 'active' check box is unchecked, then that only stops data going to database and or web side. It does not stop the polling of the device.

paulalting commented 5 years ago

I have looked through some code and found in section pyscada/modbus/device.py that yes the connection is closed and that is the cause of my slave being reset. I confirmed this by altering my simple python example to close the connection directly after doing a modbus function call for holding registers. This does cause the device to reset.

@clavay yes you are correct. Can we look at leaving the connection connected until either the device is explicitly deactivated by user or on critical error ?

My idea would be that on initiation of a device communications the device handler opens the communications channel and then a connection on that channel with possible communications check. If communications check is good, then leave channel connected for life of process otherwise do a disconnect and log error.

This issue is fairly important for me as I can not leave PyScada running on my system as I can not have the slave device being reset.

Many thanks for your effort. Paul

paulalting commented 5 years ago

I have found the small USB to TTL serial interface board I am using still had its reset line connected to the main DUE processor. I have cut this line and this now stops the issue of slave device resetting and allowing PyScada to communicate successfully with the slave device now.

I will close this issue for now so other things can be addressed. Many thanks Paul