Hope you are doing great! I recently started using python for modbus communication. I want to clear my few doubts.
What module is better for modbus implementation using Python - minimalmodbus, pymodbus, pymodbus3 or else.
I am using python3.4 but unable to install pymodbus module using pip or any means. So I installed pymodbus3.
While using pymodbus3 module, I was able to write coils using following code:
import pymodbus3
import serial
from pymodbus3.pdu import ModbusRequest
from pymodbus3.client.sync import ModbusSerialClient as ModbusClient
from pymodbus3.transaction import ModbusRtuFramer
from serial.tools.list_ports import comports
client = ModbusClient(method = "rtu", port = 'COM4',stopbits = 1, bytesize = 8, parity = 'N', baudrate= 19200)
connection = client.connect()
client.write_coil(1000, 1, unit = 0x01)
For reading coil status (function 0x01):
result = client.read_coils(1000,1)
print(result)
client.close()
Its returning None.
Or writing to register and reading is also not working:
client.write_register(0, 1000, unit=0x01)
resu= client.read_holding_registers(0, 1, unit=0x01)
print(resu)
client.close()
Positive response is welcomed!
This is a rather old question, but I want to put this information out there so there is less confusion.
pymodbus3 was a fork of pymodbus created to support python3 before pymodbus did so. pymodbus now fully supports python3 and pymodbus3 is no longer maintained and does not have all the latest that the original does.
See https://github.com/uzumaxy/pymodbus3/issues/7 for details.
Related
fist Post as i normaly find the answers if i search long enough.
But today is the day...
I bought a EnergyMeter from Aliexpress with MODBUS RTU connection and im trying to read it out. I already tried a lot of stuff from all over the Internet.
This is the Datasheet of the EnergyMeter1
I tried pyModbus and minimalmodbus.
My both Scripts:
#!/usr/bin/env python3
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
client = ModbusClient(method='rtu', port='/dev/ttyUSB0', timeout=1, stopbits = 1, bytesize = 8, parity='N', baudrate= 9600)
client.connect()
request = client.read_holding_registers(0x00,0x01,unit=2)
print (request.registers)`
and
#!/usr/bin/env python3
import time
import minimalmodbus
rs485 = minimalmodbus.Instrument('/dev/ttyUSB0', 2)
rs485.serial.baudrate = 9600
rs485.serial.bytesize = 8
rs485.serial.parity = minimalmodbus.serial.PARITY_NONE
rs485.serial.stopbits = 1
rs485.serial.timeout = 1
rs485.debug = False
rs485.mode = minimalmodbus.MODE_RTU
print (rs485)
print(rs485.read_register(0, functioncode=4,))
#Volts_A = rs485.read_float(0, functioncode=4, number_of_registers=4)
#print ('Voltage: {0:.1f} Volts'.format(Volts_A))
It seems i can read Data (first script puts out 17942 and second 17248.
But honestly, i have no clue what to do with it.
Also i dont understand that code...
The manual states that I have to send a Hi and a Low Adress, but how can i do that? 0x00 is hexa - do i have to convert this? How?
The Manual stats that i have to send Adress+functioncode+data+crc - how to do this, or is pymod/minimod doing this automatically? How does it now the right Function Code etc?
Iam totally confused, would be happy if someone could help me...
Thanks
Thanks to #Brits i got it running.
I had to use read_float(0, functioncode=4, number_of_registers=2) where 0 is decimal.
If i want to read 001A i had to convert from hex to dec = 26.
Works very good
HV_A_Phase_Spannung = Hausverbrauch.read_float(0, functioncode=4, number_of_registers=2)
print(str(f'{HV_A_Phase_Spannung :.2f}')+"V -Phase A")
First row i read out and in the second i print with decimals only 2 digits long.
I am trying to establish a HFP (Hands Free Profile) service level connection using the python test code provided in the bluez repository.
In order to even run, the example needed some modifications:
Fix the deprecated import statement:
import glib
try:
from gi.repository import GObject
except ImportError:
import gobject as GObject
=>
from gi.repository import GLib as glib
Change the mainloop object:
mainloop = GObject.MainLoop()
=>
mainloop = glib.MainLoop()
Disable audio since it is not relevant to this test:
audio_supported = False
Encode commands sent to bytes:
os.write(self.fd, cmd + "\r\n")
=>
os.write(self.fd, f"{cmd}\r\n".encode())
Decode bytes received from buffer:
buf = buf.strip()
=>
buf = buf.decode('utf8').strip()
Change BDADDR_ANY to the phone's address:
At this point the example runs, in order to actually attempt a connection I added the following code:
fd = os.open("test.log", os.O_RDWR)
profile.NewConnection(options.path, fd, opts)
At this point I get an error from NewConnection() at the following line: fd = fd.take()
Looking at the code, fd seems to be a simple file descriptor so commenting out this line helps me move on.
The actual problem that I am facing now is that I get no reply from the device after sending the initial AT command (line 78 from the link above). As per the Bluetooth HFP 1.8 spec this is supposed to start the service level connection procedure. I am not even sure that my command is making it to the device.
I also tried another example which is a bit newer. This one is able to open a RFCOMM connection through a socket (BluetoothSocket) but the connection keeps getting reset. This is because the _read_at() function (line 181) does not receive anything from the device and times out.
Referencing the following video: An OPC UA sample server in written in python using its opcua module
I am trying to implement this server on my own, so that I can later make modifications to it. I have PyDev for Eclipse installed as used in the video.
Here is the code used in the video:
from opcua import Server
from random import randint
import datetime
import time
server = Server()
url = "opc.tcp://192.168.0.8:4840"
server.set_endpoint(url)
name = "OPC_SIMULATION_SERVER"
addspace = server.register_namespace(name)
node = server.get_objects_node()
Param = node.add_object(addspace, "Parameters")
Temp = Param.add_variable(addspace, "Temperature", 0)
Press = Param.add_variable(addspace, "Pressure", 0)
Time = Param.add_variable(addspace, "Time", 0)
Temp.set_writable()
Press.set_writable()
Time.set_writable()
server.start()
print("Server started at {}".format(url))
while True:
Temperature = randint(10,50)
Pressure = randint(200, 999)
TIME = datetime.datetime.now()
print(Temperature, Pressure, TIME)
Temp.set_value(Temperature)
Press.set_value(Pressure)
Time.set_value(TIME)
time.sleep(2)
When I try to run this code, I get the following errors, which appear to be related to one another:
Error Image
If you could help me identify the source of errors, and possible resolutions to them I would appreciate it.
Edit: I was able to configure the server and it ran as expected. However, I now wish to connect it to a client to read in the data. When I try to do this, the connection is established but no data is read in. What are some potential fixes to this issue?
I try to connect to Pusher Websocket API using the following code :
https://github.com/nlsdfnbch/Pysher/
import pysher
# Add a logging handler so we can see the raw communication data
import logging
root = logging.getLogger()
root.setLevel(logging.INFO)
ch = logging.StreamHandler(sys.stdout)
root.addHandler(ch)
pusher = pysher.Pusher('de504dc5763aeef9ff52')
# We can't subscribe until we've connected, so we use a callback handler
# to subscribe when able
def connect_handler(data):
channel = pusher.subscribe('live_trades')
channel.bind('trade', callback)
pusher.connection.bind('pusher:connection_established', connect_handler)
pusher.connect()
while True:
# Do other things in the meantime here...
time.sleep(1)
instead of some valid response, i get this every few seconds :
Connection: Error - [WinError 10042] An unknown, invalid, or
unsupported option or level was specified in a getsockopt or
setsockopt call Connection: Connection closed Attempting to connect
again in 10 seconds.
what is the problem ?
I saw the same error using a different library that uses websockets. I can see from your description (and link) that Pysher uses websockets.
I found (yet another) websocket client for Python that reported an issue with websockets, specifically with Python 3.6.4: [https://github.com/websocket-client/websocket-client/issues/370]
It references the bug in Python tracker as well [https://bugs.python.org/issue32394]
Upgrading to Python 3.6.5 worked for me. Alternatively, they suggest that upgrading to Windows 10 1703+ should work too (just for completeness; I have not verified this).
I want to create a convenient simple way to connect to my running Python script remotely (via file sockets, TCP or whatever) to get a remote interactive shell.
I thought that this would be easy via IPython or so. However, I didn't really found any good example. I tried to start IPython.embed_kernel(), but that is blocking. So I tried to run that in another thread but that had many strange side effects on the rest of my script and I don't want any side effects (no replacement of sys.stdout, sys.stderr, sys.excepthook or whatever) and it also didn't worked - I could not connect. I found this related bug report and this code snippet which suggest to use mock.patch('signal.signal') but that also didn't worked. Also, why do I need that - I also don't want IPython to register any signal handlers.
There are also hacks such as pyringe and my own pydbattach to attach to some running Python instance but they seem to be too hacky.
Maybe QdbRemotePythonDebugger can help me?
My current solution is to setup an IPython ZMQ kernel. I don't just use
IPython.embed_kernel()
because that has many side effects, such as messing around with sys.stdout, sys.stderr, sys.excepthook, signal.signal, etc and I don't want these side effects. Also, embed_kernel() is blocking and doesn't really work out-of-the-box in a separate thread (see here).
So, I came up with this code, which is far too complicated in my opinion. (That is why I created a feature request here.)
def initIPythonKernel():
# You can remotely connect to this kernel. See the output on stdout.
try:
import IPython.kernel.zmq.ipkernel
from IPython.kernel.zmq.ipkernel import Kernel
from IPython.kernel.zmq.heartbeat import Heartbeat
from IPython.kernel.zmq.session import Session
from IPython.kernel import write_connection_file
import zmq
from zmq.eventloop import ioloop
from zmq.eventloop.zmqstream import ZMQStream
IPython.kernel.zmq.ipkernel.signal = lambda sig, f: None # Overwrite.
except ImportError, e:
print "IPython import error, cannot start IPython kernel. %s" % e
return
import atexit
import socket
import logging
import threading
# Do in mainthread to avoid history sqlite DB errors at exit.
# https://github.com/ipython/ipython/issues/680
assert isinstance(threading.currentThread(), threading._MainThread)
try:
connection_file = "kernel-%s.json" % os.getpid()
def cleanup_connection_file():
try:
os.remove(connection_file)
except (IOError, OSError):
pass
atexit.register(cleanup_connection_file)
logger = logging.Logger("IPython")
logger.addHandler(logging.NullHandler())
session = Session(username=u'kernel')
context = zmq.Context.instance()
ip = socket.gethostbyname(socket.gethostname())
transport = "tcp"
addr = "%s://%s" % (transport, ip)
shell_socket = context.socket(zmq.ROUTER)
shell_port = shell_socket.bind_to_random_port(addr)
iopub_socket = context.socket(zmq.PUB)
iopub_port = iopub_socket.bind_to_random_port(addr)
control_socket = context.socket(zmq.ROUTER)
control_port = control_socket.bind_to_random_port(addr)
hb_ctx = zmq.Context()
heartbeat = Heartbeat(hb_ctx, (transport, ip, 0))
hb_port = heartbeat.port
heartbeat.start()
shell_stream = ZMQStream(shell_socket)
control_stream = ZMQStream(control_socket)
kernel = Kernel(session=session,
shell_streams=[shell_stream, control_stream],
iopub_socket=iopub_socket,
log=logger)
write_connection_file(connection_file,
shell_port=shell_port, iopub_port=iopub_port, control_port=control_port, hb_port=hb_port,
ip=ip)
print "To connect another client to this IPython kernel, use:", \
"ipython console --existing %s" % connection_file
except Exception, e:
print "Exception while initializing IPython ZMQ kernel. %s" % e
return
def ipython_thread():
kernel.start()
try:
ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
pass
thread = threading.Thread(target=ipython_thread, name="IPython kernel")
thread.daemon = True
thread.start()
Note that this code is outdated now. I have made a package here which should contain a more recent version, and which can be installed via pip.
Other alternatives to attach to running CPython process without having it prepared beforehand. Those usually use the OS debugging capabilities (or use gdb/lldb) to attach to the native CPython process and then inject some code or just analyze the native CPython thread stacks.
pyringe
pyrasite
pystuck
pdb-clone
Here are other alternatives where you prepare your Python script beforehand to listen on some (tcp/file) socket to provide an interface for remote debugging and/or just a Python shell / REPL.
winpdb (cross platform) remote debugger
PyCharm IDE remote debugger,
doc
PyDev IDE remote debugger
Twisted Conch Manhole,
official example,
lothar.com example,
lysator.liu.se example,
related StackOverflow question,
blog.futurefoundries.com (2013)
very simple manhole, has also some overview over related projects
ispyd
Eric IDE
Trepan (based on pydb)
rpdb
rconsole
(part of rfoo)
Some overviews and collected code examples:
(QGIS) Example code for PyDev, Winpdb, Eric
Python Wiki: Python debugging tools,
Python Wiki: Python debuggers
(This overview is from here.)