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.
Example usage:
> ./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[1095]: (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
supported.
The results for these calls are static. If we cache them we don't have
to retrieve it from the WPU every time we need it.
To ignore the cache (for reading), provide the --no-cache argument.
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]]
> [--force]
>
> 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
datatypes:
* 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)
The 5th byte (6th if you include 0x80) contains the message length. To
double check if the message is correct we can check this against the
actual message length.
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
by pigpiod).
--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
stops pigpio.
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).