Package: async-modbus
Async ModBusAsynchronous (as in python async/await) modbus python 3 client library.
A thin layer on on top of the venerableumodbuslibrary providing
an object oriented client API.async_modbus is async library agnostic. You should be able to use it withasyncio,curio,triooranyio.It expects an object with the same interface asStreamReaderandStreamWriterso you may need to write a thin wrapper if you are not using asyncio.
The examples below show how to use it with curio.Note: themodbus_for_url()relies on theconniolibrary which relies on
the asyncio event loop so you it's usage is limited to asyncio applications.Why another modbus library?This library is not a re-implementation of the ModBus communication protocol.
You can view it instead as a complement to theumodbuslibrary.Here is what async_modbus provides on top of umodbus:Simple yet powerful object oriented APIConvenientmodbus_for_url()helper function. Type an URL and you're ready
to go.when appropriate,numpyarrays are used. It's usage not
only reduces the memory footprint and increases speed, but also makes it easy
for users to efficiently reformat data.Compatible with theconnio,sockioandserialiolibraries which provide
transparent socket re-connection among other features.InstallationFrom within your favorite python environment type:$ pip install async_modbusNumpy will be used if installed. You can install it yourself, or include the optional dependency:$ pip install async_modbus[numpy]LibraryThe core of the async_modbus library consists of amodbus_for_url()function
and the two classesAsyncTCPClientandAsyncRTUClient.Here are some examples:asyncio examplessimple TCP clientimportasyncioimportnumpyfromasync_modbusimportmodbus_for_urlasyncdefmain():client=modbus_for_url("tcp://localhost:15020")values=numpy.array([1,0,1,1])# would also work with list<bool or int>reply=awaitclient.write_coils(slave_id=1,starting_address=1,values=values)assertreplyislen(values)reply=awaitclient.read_coils(slave_id=1,starting_address=1,quantity=len(values))assert(reply==values).all()asyncio.run(main())RTU on local serial line with custom serial optionsimportasynciofromasync_modbusimportmodbus_for_urlasyncdefmain():client=modbus_for_url("serial:///dev/ttyS0",{"baudrate":19200,"parity":"E"})values=[1,0,1,1]reply=awaitclient.write_coils(slave_id=1,starting_address=1,values=values)assertreplyislen(values)reply=awaitclient.read_discrete_inputs(slave_id=1,starting_address=1,quantity=len(values))assert(reply==values).all()asyncio.run(main())RTU over remote serial line using RFC2217importasynciofromasync_modbusimportmodbus_for_urlasyncdefmain():client=modbus_for_url("rfc2217://moxa.acme.org:6610")values=[1,0,1,1]reply=awaitclient.write_coils(slave_id=1,starting_address=1,values=values)assertreplyislen(values)reply=awaitclient.read_discrete_inputs(slave_id=1,starting_address=1,quantity=len(values))assert(reply==values).all()asyncio.run(main())asyncio TCP streamsimportasyncioimportnumpyfromasync_modbusimportAsyncTCPClientasyncdefmain():reader,writer=awaitasyncio.open_connection('localhost',15020)client=AsyncTCPClient((reader,writer))values=numpy.array([0,2**15-1,10,3,32766])reply=awaitclient.write_registers(slave_id=1,starting_address=1,values=values)assertreplyislen(values)reply=awaitclient.read_holding_registers(slave_id=1,starting_address=1,quantity=len(values))assert(reply==values).all()writer.close()awaitwriter.wait_closed()asyncio.run(main())async serial line RTU using remote raw TCPimportasyncioimportnumpyfromasync_modbusimportAsyncRTUClientfromserial_asyncioimportopen_serial_connectionasyncdefmain():reader,writer=awaitopen_serial_connection(url="socket://moxa.acme.org:6610")client=AsyncRTUClient((reader,writer))values=[0,2**15-1,10,3,32766]reply=awaitclient.write_registers(slave_id=1,starting_address=1,values=values)assertreplyislen(values)reply=awaitclient.read_input_registers(slave_id=1,starting_address=1,quantity=len(values))assert(reply==values).all()writer.close()awaitwriter.wait_closed()asyncio.run(main())curio examplescurio TCP streamsimportcuriofromasync_modbusimportAsyncTCPClientasyncdefmain():sock=awaitcurio.open_connection("0",15020)client=AsyncTCPClient(sock.as_stream())values=[1,0,1,1]reply=awaitclient.write_coils(slave_id=1,starting_address=1,values=values)assertreplyislen(values)reply=awaitclient.read_coils(slave_id=1,starting_address=1,quantity=len(values))assert(reply==values).all()awaitsock.close()CreditsDevelopment LeadTiago Coutinhocoutinhotiago@gmail.comContributorsNone yet. Why not be the first?Special thanks toumodbusnumpy