Initiating and finishing a manual operation works a bit strange. First
of all the Maximum Manual Operation Time is controlled by a setting
(--id 4) and defaults to 0 (infinite). And instead of waiting for the
timer to expire (which you have to do when its set to 0) you can finish
a manual operation by passing "--no-check".
Note: For some reason no response is given when a manual operation is
written to. That's why execute_action() returns succesfully (with None)
when its executing the "setmanual" action and the response queue size is 0.
A loop around getsetting based on the settings available in the
database to retrieve all settings from the WPU.
> ./itho-wpu.py --action getsettings
> 0. Niet Gebruikt: 0 (min: 0, max: 65535, step: 1)
> 1. Hardware Configuratie: 70 (min: 0, max: 65535, step: 1)
> 2. Jaar Inbedrijfstelling: 2010 (min: 2004, max: 2099, step: 1)
By default direnv outputs this while executing:
direnv: loading ~/python-itho-wpu/.envrc
In a cronjob this results in emails, or when no MTA is configured:
CRON: (CRON) info (No MTA installed, discarding output)
Instead of hardcoding the datalog structure for listversion 11 (my WPU
version), get the datalog structure from the database and match that
against the result from the getdatatype call.
This way all WPU versions that are in the database are automatically
The SQLite database (a subset of the Itho database) can be used to
dynamically interact with an Itho WPU based on the WPU version.
> usage: convert-itho-db.py [-h] --itho-db [ITHO_DB] [--sqlite-db [SQLITE_DB]]
> Convert Itho Servicetool database to SQLite
> optional arguments:
> -h, --help show this help message and exit
> --itho-db [ITHO_DB] Itho Database file (default: None)
> --sqlite-db [SQLITE_DB]
> Itho Database file (default: heatpump.sqlite)
> --force Force overwrite SQLite database (default: False)
Action "getdatatype" returns a list of bytes representing the datatype
for each field in action "getdatalog". This is a subset of these
* 0x0: integer (1 byte)
* 0xc: integer (1 byte)
* 0x10: unsigned integer (2 bytes)
* 0x92: 2 decimal signed float (2 bytes)
Messages have 6 header bytes, data bytes and 1 checksum byte.
The 6 header bytes are:
1: i2c destination address (0x82)
2: i2c reply address (0x80)
3,4: message class
5: message type (0x04 = request)
6: data length (0x00 in case of a request)
Remove the slave thread, set_callback already spawns a thread.
I2CSlave.callback() now puts the result (if valid) in a queue. This item
can be picked up by I2CMaster for further processing.
I2CMaster will wait 0.21s for a result in the queue. 0.21s, because I
always see a response in < 0.2s. If there is no result, it will send the
request again (max 20 retries). This is because I don't get reliable
responses (via pigpiod?). In an earlier commit I mentioned to configure
pigpiod with -s 2 (sample rate 2 microseconds). This doesn't seem to be
true. For example -s 10 gives the same reliability (and less CPU usage
--master-only allows to only run the I2C master functionality.
--slave-only allows to only run the I2C slave functionality.
The I2C slave functionality via the "set_callback" mechanism (--type
callback) just executes the pigpio "event_callback()" function and waits
for 2 seconds for a response. The amount of seconds can now be
configured via --slave-timeout.
Argument "--type [callback,wait]" is added to be able to switch between
"wait_for_event()" (previous functionality) and "event_callback()" in
the I2C slave functionality.
In a thread set_callback() executes event_callback() and just (very
dirty) sleeps 2 seconds to get a response or else cancels the event and
To get the most reliable output pigpiod is started with -s 2 (sample
rate 2 microseconds). Still most of the time too few bytes are received
on the "getdatalog" action (153 bytes expected).