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

Major rewrite + improvements in many areas #8

Open
wants to merge 191 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
191 commits
Select commit Hold shift + click to select a range
4863116
Commit all changes
mbs38 Oct 22, 2018
ce54a5e
updated readme, threw out old stuff that does not apply anymore
mbs38 Oct 22, 2018
cc01a24
Added some command line examples
mbs38 Oct 22, 2018
541a05a
-
mbs38 Oct 22, 2018
e239019
Added verbosity argument.
mbs38 Oct 23, 2018
b1a79d9
Added VERY basic error handling for modbus communication.
mbs38 Oct 23, 2018
4907d89
Added more error handling and error messages
mbs38 Oct 23, 2018
f4e07b2
Removed syslog logging. syslog is deprecated anyway..
mbs38 Oct 23, 2018
d09fff7
Added autoremove feature for failed pollers.
mbs38 Oct 23, 2018
f2a63c9
Ensure that the program actually terminates..
mbs38 Oct 24, 2018
ed27521
Added python3-serial to install instructions
mbs38 Oct 26, 2018
94545ee
Addded command line argument for setting break time in main loop.
mbs38 Oct 26, 2018
45000be
Revert "Addded command line argument for setting break time in main l…
mbs38 Oct 27, 2018
43a4601
Added set loop time argument
mbs38 Oct 27, 2018
0ffd123
Revert "Revert "Addded command line argument for setting break time i…
mbs38 Oct 27, 2018
753064c
Revert "Revert "Revert "Addded command line argument for setting brea…
mbs38 Oct 27, 2018
4a68a43
Cleanup
mbs38 Oct 27, 2018
3245d56
some examples
mbs38 Oct 30, 2018
a91aef2
fix
mbs38 Oct 30, 2018
cb2fecc
some more
mbs38 Oct 30, 2018
627bd82
Update README.md
mbs38 Oct 30, 2018
e54dd66
cleanup
mbs38 Nov 24, 2018
f2d80bb
Put some data in some other places to make implementing the home
mbs38 Nov 26, 2018
bd07785
Adding devices to home-assistant
mbs38 Nov 26, 2018
a3a8587
Fixed bad path
mbs38 Nov 26, 2018
95833a3
More elaborate Error handling.
mbs38 Nov 27, 2018
d81e5a9
Nicer error handling.
mbs38 Nov 28, 2018
a25e6cc
Fixed some bugs
mbs38 Nov 28, 2018
52deaf6
More elaborate comments
mbs38 Nov 30, 2018
c237f96
More examples
mbs38 Nov 30, 2018
049e844
Changed payload of /connected topic
mbs38 Dec 3, 2018
e8a7279
Boolean payloads now accept True,true,TRUE,1...
mbs38 Dec 3, 2018
fe754d0
Update README.md
RichardBH Dec 5, 2018
6d88bb2
Fixed mistake in poller object example
mbs38 Dec 5, 2018
76280e6
Added Resilience in connecting
RichardBH Dec 7, 2018
83d3856
Added command line option to change modbus timeout
mbs38 Dec 7, 2018
49cadc0
Added Verbosity level 4.
RichardBH Dec 9, 2018
32304cf
Merge branch 'master' into master
mbs38 Dec 10, 2018
0af77b3
Merge pull request #1 from RichardBH/master
mbs38 Dec 10, 2018
7898b18
Autoremove now off by default
mbs38 Dec 11, 2018
6f011cf
Changed some explainations concerning the config file
mbs38 Dec 15, 2018
0048614
Merge branch 'master' of https://github.com/mbs38/spicierModbus2mqtt
mbs38 Dec 15, 2018
7f89911
Added options for MQTT authentication
Dec 16, 2018
ea86dfc
Merge pull request #2 from Kenakapheus/master
mbs38 Dec 16, 2018
c8aeff3
Merge pull request #1 from mbs38/master
RichardBH Dec 23, 2018
4773d10
Fixed off by one error in poller range error message
mbs38 Dec 24, 2018
fae3088
Randomize first polls to ensure even distribution of bus load over time
mbs38 Jan 6, 2019
0d05f14
Added Int32 conversion from 2 int16
RichardBH Jan 21, 2019
aaf8ed5
Merge pull request #3 from RichardBH/master
mbs38 Jan 21, 2019
b407bb7
Updates to Readme and Example.csv Int32BE (#4)
RichardBH Jan 22, 2019
e932445
Added tls support and small tweak logging mqtt (#6)
Buskebam Feb 4, 2019
41fd4d6
Add help texts for command line options
mbs38 Feb 6, 2019
b9b2e9a
Will was set to wrong value (True)
mbs38 Feb 7, 2019
e79dae7
Fix broken home assistant support..
mbs38 Feb 9, 2019
29e3c8c
Fix broken homeassistant support 2nd try..
mbs38 Feb 9, 2019
eb6848f
Cleaning away an ugly spot..
mbs38 Feb 9, 2019
32d3716
Clarify reference explaination
mbs38 Feb 11, 2019
7c248f5
Clarify reference explaination
mbs38 Feb 11, 2019
b14204f
Fix missing line break in function code list
mbs38 Feb 11, 2019
03312a1
Started adding data type feature
mbs38 Feb 11, 2019
74a45c0
new data types
mbs38 Feb 11, 2019
7ad762c
Runs again
mbs38 Feb 11, 2019
82c830c
New feature: types
mbs38 Feb 13, 2019
f7a6715
Fixed error in combine function
mbs38 Feb 13, 2019
6779a8d
Improve conversion
mbs38 Feb 13, 2019
92f9d2d
Fix
mbs38 Feb 13, 2019
4257c7a
Added uint32LE
mbs38 Feb 13, 2019
b36ee3c
uint16 and int16 not yet working
mbs38 Feb 13, 2019
ecad9bd
Fixed bug in reference poll
mbs38 Feb 13, 2019
9022c26
partly working 16bit intpartly working 16bit int
mbs38 Feb 13, 2019
98b4885
Changed error message, int16 now works!
mbs38 Feb 13, 2019
737c059
Added config parsing for string type
mbs38 Feb 13, 2019
4267832
Cleanup
mbs38 Feb 13, 2019
ffb0b6a
Cleanup
mbs38 Feb 13, 2019
382ec80
Cleanup
mbs38 Feb 14, 2019
5001488
Added example for data types
mbs38 Feb 14, 2019
00fd191
Added type string
mbs38 Feb 14, 2019
64dfb40
fix example
mbs38 Feb 14, 2019
4a4464b
Add some documentation concerning the new data types
mbs38 Feb 14, 2019
36124c3
More elaborate explainations concerning new data types
mbs38 Feb 14, 2019
df48a45
Cleanup
mbs38 Feb 14, 2019
7a073ba
Cleanup again.
mbs38 Feb 14, 2019
0f48244
Introduced new topic prefix/poller topic/connected
mbs38 Feb 14, 2019
24260f1
New feature: connected topic for each poller
mbs38 Feb 14, 2019
418c143
added topic for new feature: connected topic for each poller
mbs38 Feb 14, 2019
43fd99a
Fix broken coil and input status
mbs38 Feb 14, 2019
2ff5b4d
Remove multiple setting of will
mbs38 Feb 15, 2019
aea35b4
Remove poller type input_register32BE from Readme
mbs38 Feb 16, 2019
9d2c0d6
Update some comments
mbs38 Feb 16, 2019
d931228
Fix "Added Reference..." print
mbs38 Feb 16, 2019
32f4a53
Fix broken sanity check
mbs38 Feb 18, 2019
fdaf0d3
Cleanup.
mbs38 Feb 18, 2019
6c4d5de
Cleanup.
mbs38 Feb 18, 2019
65e2a51
Merge branch 'master' of https://github.com/mbs38/spiciermodbus2mqtt
mbs38 Feb 18, 2019
a4004c1
Fix off by one error in sanity check
mbs38 Feb 18, 2019
f69f9cf
client id not foo anymore :P
mbs38 May 25, 2019
158b5e4
some preliminaries
mbs38 May 25, 2019
a78639c
States are now published immediately if writing was successful.
mbs38 May 25, 2019
5e718ce
Changed to version 0.4 because of major changes (states are now
mbs38 May 25, 2019
1d671cc
New feature (states now published on writing) + added changelog
mbs38 May 25, 2019
8f5cc7c
Do not set qos on publish. Seems to break on some systems.
mbs38 May 25, 2019
21946ca
Added warning.
mbs38 Jun 25, 2019
e82bba8
Added warning in README
mbs38 Jun 25, 2019
5a6137e
Formatting.
mbs38 Jun 25, 2019
34f28e3
Formatting.
mbs38 Jun 25, 2019
4f7e9da
More error messages in case of bad configuration
mbs38 Sep 21, 2019
25380ab
somehow broke everything
mbs38 Dec 31, 2019
4fa96cd
Fixed bug in highly verbose logging (caused error messages and poller
mbs38 Dec 31, 2019
e608f7d
Implemented new register interpretation: two registers as 32bit float
mbs38 Dec 31, 2019
9b02198
Fix some documentation issues
mbs38 Jan 3, 2020
4be411a
Fix non existent function code in example file
mbs38 Feb 9, 2020
163135a
Fix example file again
mbs38 Feb 9, 2020
c425e02
Implemented scaling factor for register read (#8)
Kenakapheus Apr 21, 2020
013c548
retry automatically removed pollers on command from mqtt
mbs38 Jul 1, 2020
18f0516
Add help text
mbs38 Jul 1, 2020
422a5c7
Reactivate disabled pollers after command from mqtt now works
mbs38 Jul 1, 2020
178bf33
Merge branch 'master' of https://github.com/mbs38/spiciermodbus2mqtt
mbs38 Jul 1, 2020
3a52f56
Fix bug in combine methods uint16 and int16
mbs38 Aug 28, 2020
b9edef7
Set retain flag for homeassistant config messages
mbs38 Sep 3, 2020
4e0a7c9
Added a script that generates openhab .things and .items files from the
mbs38 Jan 26, 2021
9725134
Update README
mbs38 Jan 29, 2021
843914e
Stop console being flooded with a connection success message after each
mbs38 Mar 6, 2021
fbb7a91
Ensure catching of all modbus errors in message handler
mbs38 Mar 10, 2021
10c3f2b
autoremove: disable all pollers that share a slaveid on failure
mbs38 Mar 10, 2021
1a1cd4f
Ensure loop break to be greater zero
mbs38 Mar 10, 2021
aa07236
Merge branch 'base-autoremoved-on-devices'
mbs38 Mar 10, 2021
0f21cd5
Fix flooding
mbs38 Mar 10, 2021
d85ec1f
basics
mbs38 Mar 21, 2021
0df646c
basic diagnostics work
mbs38 Mar 21, 2021
c4e1d10
Diagnostics work, added argument --diagnostic-rate
mbs38 Mar 21, 2021
20878f6
add new diagnostics feature to readme
mbs38 Mar 21, 2021
455138d
Diagnostics work
mbs38 Mar 21, 2021
2aec51b
Diagnostics now documented
mbs38 Mar 21, 2021
8b5fa63
Fix bug in autoremove
mbs38 Mar 29, 2021
29e7d63
Fix bug in autoremove
mbs38 Mar 29, 2021
8a6d167
Move diagnostics to other topic to stay within the usual topic layout
mbs38 Apr 1, 2021
f1a38fe
Added option to always publish values (#9)
Kenakapheus Sep 2, 2021
e9044af
Added instructions on how to use scaling
mbs38 Sep 14, 2021
95c18e7
fix pep8 except excepts (#10)
meyerd Jan 5, 2022
81ab40c
Cleanup formatting (#11)
meyerd Jan 5, 2022
98b9fce
Revert "Cleanup formatting (#11)"
Jan 5, 2022
e22692b
Revert "fix pep8 except excepts (#10)"
Jan 5, 2022
bd9e659
Apply scale factor for writes (#13)
jpg0 Jan 31, 2022
f22e6f0
Added Docker support (#12)
jpg0 Jan 31, 2022
a987d34
Some refactoring (not yet tested)
mbs38 Feb 5, 2022
be0cb64
Remove a lingering print undisturbed by verbosity setting
mbs38 Feb 5, 2022
ef5371d
Merge branch 'master' of https://github.com/mbs38/spicierModbus2mqtt
mbs38 Feb 5, 2022
7cddfd1
Merge branch 'master' into refactoring
mbs38 Feb 5, 2022
60682e0
Cleanup
mbs38 Feb 5, 2022
64ec487
addtohomeassistant import now relative
mbs38 Feb 5, 2022
27afe0d
Fix hass support broken by refactoring
mbs38 Feb 5, 2022
15b9950
spiciermodbus2mqtt is now a package
mbs38 Feb 6, 2022
9055e68
Spicier is now a package, cleanup
mbs38 Feb 6, 2022
ca8ac82
Add manifest + setup
mbs38 Feb 6, 2022
42a32b6
Cleanup
mbs38 Feb 6, 2022
a2a9d4f
cleanup
mbs38 Feb 6, 2022
3e87811
Version 0.62 + add requirements to setup.py
mbs38 Feb 6, 2022
3e740f4
Add pip availability to README
mbs38 Feb 6, 2022
21895c5
Add pip availability to README
mbs38 Feb 6, 2022
80d6485
pip support (again)
mbs38 Feb 6, 2022
1e474cf
Updated to new (module) structure (#14)
jpg0 Feb 8, 2022
b018121
Fix negative float values (#17)
phe95 Oct 4, 2022
e393f71
Update README.md (#15)
tylerkoldenjtp Oct 4, 2022
57278c2
Implementation of signed int32-values (#16)
soluga Oct 4, 2022
8a3bfc8
Changed version to 0.63
mbs38 Oct 4, 2022
b0adafc
Get dockerbuild running again (#18)
ghstefan Nov 25, 2022
ea994f1
Insure compatibility with new version of pymodbus
mbs38 Nov 25, 2022
e725822
Clean up readme
mbs38 Nov 25, 2022
a39c18a
Print Modbus exception responses
mbs38 Nov 29, 2022
4033c58
Disable scaling on writing. Implementation not sufficient for all dat…
mbs38 Nov 29, 2022
0717fa0
Disable broken parse functions for int32LE and int32BE
mbs38 Nov 29, 2022
687b9a9
Don't use fc "write multiple registers" by default
mbs38 Nov 29, 2022
1184be6
Refactoring
mbs38 Dec 6, 2022
bf3acd6
Add data type list-uint16 (space seperated list)
mbs38 Dec 13, 2022
605cab2
Docker: Resolve missing serial module (#21)
marcusbirkin Jan 8, 2023
74406a7
Fix argument in modbus read/write calls name (pobably due to some ver…
mbs38 Jul 2, 2023
1fa496c
Version 0.67
mbs38 Jul 2, 2023
e55ec6c
replace unit= with slave=
mbs38 Sep 19, 2023
8601eb7
move datatypes to new file
mbs38 Sep 19, 2023
7b43e71
Use async implementation of pymodbus, remove loop-break, cleanup
mbs38 Oct 31, 2023
6e0e6b5
Add avoid-fc6 option, cleanup, logging
mbs38 Oct 31, 2023
2e427c0
Increment version
mbs38 Oct 31, 2023
a1ee82f
Merge branch 'use-async'
mbs38 Oct 31, 2023
6281a7d
Update README, fix typos
mbs38 Oct 31, 2023
3f7019e
Fix broken pip package
mbs38 Nov 1, 2023
84510a6
Increment version
mbs38 Nov 1, 2023
1c8e188
Add break inbetween requests on modbus (assume 2ms fixed break time),…
mbs38 Nov 8, 2023
15972bb
Add datatype list-uint16 again, increment version
mbs38 Nov 8, 2023
952ed56
Add loop break option again, reconnect on tcp modbus connection loss
mbs38 Nov 12, 2023
ed40061
Increment version
mbs38 Nov 12, 2023
92784f0
Update README
mbs38 Nov 12, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM python:alpine

WORKDIR /app

COPY modbus2mqtt.py ./
COPY modbus2mqtt modbus2mqtt/

RUN mkdir -p /app/conf/

# upgrade pip to avoid warnings during the docker build
RUN pip install --root-user-action=ignore --upgrade pip

RUN pip install --root-user-action=ignore --no-cache-dir pyserial pymodbus
RUN pip install --root-user-action=ignore --no-cache-dir paho-mqtt

ENTRYPOINT [ "python", "-u", "./modbus2mqtt.py", "--config", "/app/conf/modbus2mqtt.csv" ]
4 changes: 3 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
The MIT License (MIT)

Copyright (c) 2015 Oliver Wagner <[email protected]>
Copyright (c) 2018 Max Brueggemann <[email protected]>

Contains code from modbus2mqtt, copyright (c) 2015 Oliver Wagner <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include LICENSE
275 changes: 167 additions & 108 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,136 +1,195 @@
modbus2mqtt
===========
spicierModbus2mqtt
==================

Written and (C) 2015 Oliver Wagner <[email protected]>

Written and (C) 2018 Max Brueggemann <[email protected]>

Contains code from modbus2mqtt, written and (C) 2015 Oliver Wagner <[email protected]>

Provided under the terms of the MIT license.
Provided under the terms of the MIT license.


Overview
--------
modbus2mqtt is a Modbus master which continously polls slaves and publishes
register values via MQTT.
spicierModbus2mqtt is a Modbus master which continuously polls slaves and publishes
values via MQTT.

It is intended as a building block in heterogenous smart home environments where
It is intended as a building block in heterogeneous smart home environments where
an MQTT message broker is used as the centralized message bus.
See https://github.com/mqtt-smarthome for a rationale and architectural overview.

Changelog
---------
- version 0.72, 12. of November 2023: add loop break option again due to user request, reconnect on modbus tcp connection loss and serial device not found
- version 0.68, 31. of October 2023: use asyncio with pymodbus, add option to use function code 16 when writing single registers, remove loop break option
- version 0.66, 29. of November 2022: print Modbus exceptions generated by devices
- version 0.65, 25. of November 2022: fixed incompatibility with newer version of pymodbus, readjusted the Dockerfile
- version 0.64, 16. of October 2022: Adjustment of the Dockerfile (enforcing pymodbus 2.5.3, otherwise it tries to use 3.0 and this failes); typo fixed; main-/poller-loop log entry
- version 0.63, 04. of October 2022: added reading and writing of int32 values, fix regarding negative floats
- version 0.62, 6. of February 2022: major refactoring, project is now python module available via pip
- version 0.5, 21. of September 2019: print error messages in case of badly configured pollers
- version 0.4, 25. of May 2019: When writing to a device, updated states are now published immediately, if writing was successful.

Spicier?
------------
Main improvements over modbus2mqtt by Oliver Wagner:
- more abstraction when writing to coils/registers using mqtt. Writing is now
possible without having to know slave id, reference, function code etc.
- specific coils/registers can be made read only
- multiple slave devices on one bus are now fully supported
- polling speed has been increased significantly. With modbus RTU @ 38400 baud
more than 80 transactions per second have been achieved.
- switched over to pymodbus which is in active development.
- Improved error handling, the software will continuously retry when the network or device goes down.

Feel free to contribute!


Dependencies
Installation
------------
run `sudo pip3 install modbus2mqtt`

Without installation
--------------------
Requirements:

* python3
* Eclipse Paho for Python - http://www.eclipse.org/paho/clients/python/
* modbus-tk for Modbus communication - https://github.com/ljean/modbus-tk/
* pymodbus - https://github.com/riptideio/pymodbus

Installation of requirements:

Command line options
--------------------
usage: modbus2mqtt.py [-h] [--mqtt-host MQTT_HOST] [--mqtt-port MQTT_PORT]
[--mqtt-topic MQTT_TOPIC] [--rtu RTU]
[--rtu-baud RTU_BAUD] [--rtu-parity {even,odd,none}]
--registers REGISTERS [--log LOG] [--syslog]

optional arguments:
-h, --help show this help message and exit
--mqtt-host MQTT_HOST
MQTT server address. Defaults to "localhost"
--mqtt-port MQTT_PORT
MQTT server port. Defaults to 1883
--mqtt-topic MQTT_TOPIC
Topic prefix to be used for subscribing/publishing.
Defaults to "modbus/"
--clientid MQTT_CLIENT_ID
optional prefix for MQTT Client ID

--rtu RTU pyserial URL (or port name) for RTU serial port
--rtu-baud RTU_BAUD Baud rate for serial port. Defaults to 19200
--rtu-parity {even,odd,none}
Parity for serial port. Defaults to even.
--registers REGISTERS
Register specification file. Must be specified
--force FORCE
optional interval (secs) to publish existing values
does not override a register's poll interval.
Defaults to 0 (publish only on change).

--log LOG set log level to the specified value. Defaults to
WARNING. Try DEBUG for maximum detail
--syslog enable logging to syslog


Register definition
* Install python3 and python3-pip and python3-serial (on a Debian based system something like sudo apt install python3 python3-pip python3-serial will likely get you there)
* run pip3 install pymodbus
* run pip3 install paho-mqtt

Usage
-----
If you've installed using pip:

* example for rtu and mqtt broker on localhost: `modbus2mqtt --rtu /dev/ttyS0 --rtu-baud 38400 --rtu-parity none --mqtt-host localhost --config testing.csv`
* example for tcp slave and mqtt broker
on localhost: `modbus2mqtt --tcp localhost --config testing.csv`
remotely: `modbus2mqtt --tcp 192.168.1.7 --config example.csv --mqtt-host mqtt.eclipseprojects.io`


If you haven't installed modbus2mqtt you can run modbus2mqtt.py from the root directory of this repo directly:

* example for rtu and mqtt broker on localhost: `python3 modbus2mqtt.py --rtu /dev/ttyS0 --rtu-baud 38400 --rtu-parity none --mqtt-host localhost --config testing.csv`
* example for tcp slave and mqtt broker
on localhost: `python3 modbus2mqtt.py --tcp localhost --config testing.csv`
remotely: `python3 modbus2mqtt.py --tcp 192.168.1.7 --config example.csv --mqtt-host mqtt.eclipseprojects.io`

For docker support see below.

Configuration file
-------------------
The Modbus registers which are to be polled are defined in a CSV file with
the following columns:

* *Topic suffix*
The topic where the respective register will be published into. Will
be prefixed with the global topic prefix and "status/".
* *Register offset*
The register number, depending on the function code. Zero-based.
* *Size (in words)*
The register size in words.
* *Format*
The format how to interpret the register value. This can be two parts, split
by a ":" character.
The first part uses the Python
"struct" module notation. Common examples:
- >H unsigned short
- >f float

The second part is optional and specifies a Python format string, e.g.
%.2f
to format the value to two decimal digits.
* *Polling frequency*
How often the register is to be polled, in seconds. Only integers.
* *SlaveID*
The Modbus address of the slave to query. Defaults to 1.
* *FunctionCode*
The Modbus function code to use for querying the register. Defaults
to 4 (READ REGISTER). Only change if you know what you are doing.

Not all columns need to be specified. Unspecified columns take their
default values. The default values for subsequent rows can be set
by specifying a magic topic suffix of *DEFAULT*
THE FIRST LINE OF THE CONFIG FILE HAS TO BE:

"type","topic","col2","col3","col4","col5","col6"

The Modbus data which is to be polled is defined in a CSV file.
There are two types of rows, each with different columns; a "Poller" object and a "Reference" object. In the "Poller" object we define the type of the modbus data and how the request to the device should look like (which modbus references are to be read, for example: holding registers at references 0 to 10). With the reference object we define (among other things) to which topic the data of a certain data point (registers, coil..) is going to be published.
Modbus references are as transmitted on the wire. In the traditional numbering scheme these would have been called offsets. E. g. to read 400020 you would use reference 20.
Refer to the example.csv for more details.

* Use "coils", for modbus functioncode 1
* Use "input status", for modbus functioncode 2
* Use "holding registers", for modbus functioncode 3
* Use "input registers", for modbus functioncode 4

Reference objects link to the modbus reference address and define specific details about that register or bit.
Pollers and references are used together like this:
```
poll,kitchen,7,0,5,coil,1.0
ref,light0,0,rw
ref,light1,1,rw
ref,light2,2,rw
ref,light3,3,rw
ref,light4,4,rw
```
This will poll from Modbus slave id 7, starting at coil offset 0, for 5 coils, 1.0 times a second.

The first coil 0 will then be sent as an MQTT message with topic modbus/kitchen/state/light0.

The second coil 1 will then be sent as an MQTT message with topic modbus/kitchen/state/light1 and so on.


Note that the reference addresses are absolute addresses and are NOT related to the start address of the poller! If you define a reference that is not within the pollers range you will get an error message.
So another example:
```
poll,someTopic,1,2,11,coil,1.0
ref,light9,9,rw
```
This will poll states of 11 coils from slave device 1 once a second, starting at coil 2.
The state of coil 9 will be published to mqtt with the topic modbus/someTopic/state/light0
if column 3 contains an 'r'.

If you publish a value (in case of a coil: True or False) to modbus/someTopic/set/light0 and
column 3 contains a 'w', the new state will be written to coil 9 of the slave device.


Some other "interpretations" of register contents are also supported:
```
poll,garage,1,0,10,holding_register,2
ref,counter1,0,rw,float32BE
ref,counter2,2,rw,uint16
ref,somestring,3,rw,string6
```
This will poll 10 consecutive registers from Modbus slave id 1, starting at holding register 0.

The last row now contains the data format. Supported values: float32BE, float32LE, uint32BE, uint32LE, uint16 (default), stringXXX with XXX being the string length in bytes.

Note that a float32BE will of course span over two registers (0 and 1 in the above example) and that you can still define another reference object occupying the same registers. This might come in handy if you want to modify a small part of a string separately.


Topics
------
Values are published as simple strings to topics with the general <prefix>,
the function code "/status/" and the topic suffix specified per register.
A value will only be published if it's textual representation has changed,
e.g. _after_ formatting has been applied. The published MQTT messages have
Values are published as strings to topic:

"prefix/poller topic/state/reference topic"

A value will only be published if it's raw data has changed,
e.g. _before_ any formatting has been applied. The published MQTT messages have
the retain flag set.

A special topic "<prefix>/connected" is maintained.
It's a enum stating whether the module is currently running and connected to
A special topic "prefix/connected" is maintained.
It states whether the module is currently running and connected to
the broker (1) and to the Modbus interface (2).

Setting Modbus coils (FC=5) and registers (FC=6)
We also maintain a "connected"-Topic for each poller (prefix/poller_topic/connected). This is useful when using Modbus RTU with multiple slave devices because a non-responsive device can be detected.

For diagnostic purposes (mainly for Modbus via serial) the topics prefix/poller_topic/state/diagnostics_errors_percent and prefix/poller_topic/state/diagnostics_errors_total are available. This feature can be enabled by passing the argument "--diagnostics-rate X" with x being the amount of seconds between each recalculation and publishing of the error rate in percent and the amount of errors within the time frame X. Set X to something like 600 to get diagnostic messages every 10 minutes.

Writing to Modbus coils and registers
------------------------------------------------

modbus2mqtt subscibes to two topics:
spiciermodbus2mqtt subscribes to:

- prefix/set/+/5/+ # where the first + is the slaveId and the second is the register
- prefix/set/+/6/+ # payload values are written the the devices (assumes 16bit Int)
"prefix/poller topic/set/reference topic"

There is only limited sanity checking currently on the payload values.

If you want to write to a coil:

Changelog
---------
* 0.4 - 2015/07/31 - nzfarmer
- added support for MQTT subscribe + Mobdus write
Topics are of the form: prefix/set/<slaveid (0:255)>/<fc (5,6)>/<register> (payload = value to write)
- added CNTL-C for controlled exit
- added --clientid for MQTT connections
- added --force to repost register values regardless of change every x seconds where x >0

* 0.3 - 2015/05/26 - owagner
- support optional string format specification
* 0.2 - 2015/05/26 - owagner
- added "--rtu-parity" option to set the parity for RTU serial communication. Defaults to "even",
to be inline with Modbus specification
- changed default for "--rtu-baud" to 19200, to be inline with Modbus specification

* 0.1 - 2015/05/25 - owagner
- Initial version

mosquitto_pub -h <mqtt broker> -t modbus/somePoller/set/someReference -m "True"

to a register:

mosquitto_pub -h <mqtt broker> -t modbus/somePoller/set/someReference -m "12346"

Scripts addToHomeAssistant.py and create-openhab-conf.py
------------------------------------------------
These scripts are not really part of this project, but I decided to include them anyway. They were written because I grew more and more frustrated with the Modbus capabilities of OpenHAB and Home Assistant.

So what exactly do they do? Completely different things actually.

* addToHomeAssistant.py can only be run within modbus2mqtt.py. It can be invoked by passing --add-to-homeassistant when running modbus2mqtt.py. It uses MQTT messages to add all the stuff from the .csv file to home assistant automatically. Just try it. I recommend using a non productive instance of Home Assistant for testing :-)


* create-openhab-conf.py can be used independently. It parses the .csv file and creates configuration files (.things and .items) for OpenHAB (version 2+ only). This is of course not necessary for using spicierModbus2mqtt whit OpenHab but it removes a lot of hassle from it. I use it to create a basic working structure and then rename and rearrange the items by hand.

Docker
------

spicierModbus2mqtt can be run as a docker container, using the included Dockerfile. It allows all usual configuration options, with the expectation that it's configuration is at `/app/conf/modbus2mqtt.csv`. For example:

`docker build -t modbus2mqtt . && docker run -v $(pwd)/example.csv:/app/conf/modbus2mqtt.csv modbus2mqtt --tcp <modbus-tcp-host> --mqtt-host <mqtt-host>`
Loading