Skip to content

Commit 9e068fc

Browse files
WIP: a big 'ol refactor and new features (adamcharnock#6)
See adamcharnock#6 for full discussion. Co-authored-by: Adam Charnock <[email protected]>
1 parent 18e55d5 commit 9e068fc

File tree

61 files changed

+5465
-12205
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+5465
-12205
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
/.venv
22
/.env
33
/dist
4+
__pycache__
5+
*cache*
6+
*.egg-info

README.md

+97-125
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Outback Mate 3s Python library & command line interface
1+
# Outback Mate 3 & 3s Python library & command line interface
22

33
[![PyPI version](https://badge.fury.io/py/mate3.svg)](https://badge.fury.io/py/mate3)
44

@@ -10,140 +10,109 @@ have a Mate3s which is connected to your local network using its ethernet port.
1010

1111
Tested on Python 3.7. May work on 3.6.
1212

13-
## Installation
14-
15-
The recommended installation is as follows:
16-
17-
```
18-
pip install mate3
19-
```
13+
## Warnings
2014

21-
After this you should be able to run the `mate3` command.
15+
First, the big one:
2216

23-
---
24-
25-
If you wish to edit the mate3 source (contributions are gladly received!),
26-
then you can get the project directly from GitHub:
27-
28-
```
29-
# Install poetry if you don't have it already (if you're unsure, you don't have it)
30-
pip install poetry
17+
> **WARNING!** Please make sure you read [the license](https://github.com/adamcharnock/mate3/blob/master/LICENSE) before using any of the `write` functionality. You could easily damage your equipment by setting incorrect values (directly or indirectly).
3118
32-
# Get the source
33-
git clone https://github.com/adamcharnock/mate3.git
34-
cd mate3
19+
In addition, there are other edges cases that may cause problems, mostly related to if a device is re-assigned a new port. For example, you have two inverters, read some values, then switch their ports over in the Hub before writing some values - which may now go to the 'wrong' one. For now, it's safest not to do that, unless you restart the `Mate3Client` each time. On that note, the recommended approach if you need to poll over time is:
3520

36-
# Install mate3 and its dependencies. This also makes the mate3 command available.
37-
poetry install
21+
```python
22+
while True:
23+
with Mate3Client(...) as client:
24+
client...
25+
sleep(1)
3826
```
3927

40-
After this you should be able to run the `mate3` command and edit the
41-
project's source code.
42-
43-
## Enabling the Modbus interface on your Mate 3
44-
45-
TBA. System -> opticsre -> Modbus?
46-
47-
## Using the library
48-
49-
Example use:
28+
As opposed to
5029

5130
```python
52-
from mate3 import mate3_connection
53-
from mate3.parsers import ChargeControllerParser, ChargeControllerConfigurationParser
54-
from mate3.base_structures import Device
55-
56-
# IP address of your Mate3s
57-
host = '192.168.0.123'
58-
# The Modbus port on the Mate3s. The default (502) will be
59-
# fine unless you have configured your Mate3s differently
60-
port = 502
61-
62-
# Connect to the Mate3s
63-
with mate3_connection(host, port) as client:
64-
# Get all blocks of fields from the Mate3s
65-
# and print each one out.
66-
all_blocks = client.all_blocks()
67-
for block in all_blocks:
68-
print(block)
69-
70-
# Get all values for a specific device
71-
values = client.get_device_blocks(Device.charge_controller)
72-
print(list(values))
73-
74-
# Or get specific fields
75-
values = client.get_values(
76-
ChargeControllerParser.battery_current,
77-
ChargeControllerParser.battery_voltage
78-
)
79-
# Prints a list of currents, one for each of your charge controllers
80-
print(values[ChargeControllerParser.battery_current])
81-
# Prints a list of voltages, one for each of your charge controllers
82-
print(values[ChargeControllerParser.battery_voltage])
83-
84-
# Writing data
85-
# (BE CAREFUL! YOU COULD EASILY DAMAGE YOUR EQUIPMENT WITH THIS FEATURE!)
86-
client.set_value(
87-
field=ChargeControllerConfigurationParser.absorb_volts,
88-
value=330,
89-
port=3
90-
)
91-
31+
with Mate3Client(...) as client:
32+
while True:
33+
client...
34+
sleep(1)
9235
```
9336

94-
## Using the command line interface (CLI)
37+
Why? It means you're getting point-in-time values, and don't have to worry about changes (such as ports being switched). There are exceptions, but you should know why you're doing it.
9538

96-
### Reading data
39+
## Installation
9740

98-
A simple CLI is available which will read all available values from the Mate3:
41+
The recommended installation is as follows:
9942

43+
```sh
44+
pip install mate3
10045
```
101-
$ mate3 -h
102-
usage: mate3 [-h] [--host HOST] [--port PORT]
103-
[--format {text,prettyjson,json}]
10446

105-
Read all available data from the Mate3 controller
47+
After this you should be able to run the `mate3` command.
10648

107-
optional arguments:
108-
-h, --help show this help message and exit
109-
--host HOST, -H HOST The host name or IP address of the Mate3
110-
--port PORT, -p PORT The port number address of the Mate3
111-
--format {text,prettyjson,json}, -f {text,prettyjson,json}
112-
Output format
113-
```
49+
## Using the library
11450

115-
Example use:
51+
More documentation is needed, but you can get a pretty code idea from [./examples/getting_started.py](./examples/getting_started.py), copied (somewhat) below.
11652

117-
```
118-
$ mate3 --host 192.168.0.123
53+
```python
54+
with Mate3Client("192.168.1.12") as client:
55+
# Read all devices:
56+
client.read()
57+
58+
# What's the system name?
59+
client.devices.mate3.system_name
60+
# >>> FieldValue[system_name] | Implemented | Read @ 2020-07-19 21:27:57.747231 | Value: --- | Clean
61+
62+
# Get the battery voltage. Note that it's auto-scaled appropriately.
63+
client.devices.fndc.battery_voltage
64+
# >>> FieldValue[battery_voltage] | Implemented | Read @ 2020-07-19 21:27:57.795158 | Scale factor: -1 | Unscaled value: 544 | Value: 54.4 | Clean
65+
66+
# Get the (raw) values for the same device type on different ports
67+
for port in client.devices.fx_inverters:
68+
print(f"FET temp on port {port} = {client.devices.fx_inverters[port].fet_temperature.value}")
69+
# >>> FET temp on port 1 = 36
70+
# >>> FET temp on port 2 = 35
71+
72+
# Read only battery voltage again and check only it's read time was updated but not system name
73+
time.sleep(1)
74+
client.read(only=[client.devices.fndc.battery_voltage])
75+
client.devices.mate3.system_name
76+
client.devices.fndc.battery_voltage
77+
# >>> FieldValue[system_name] ... 2020-07-19 21:27:57 ...
78+
# >>> FieldValue[battery_voltage] ... 2020-07-19 21:27:58 ...
79+
80+
# Nice. What about modbus fields that aren't implemented?
81+
client.devices.mate3.sched_1_ac_mode.implemented
82+
# >>> False
83+
84+
# Cool. Can we set a new value? Note that we don't need to worry about scaling etc.
85+
volts = client.devices.charge_controller.config.absorb_volts
86+
# >>> ... | Scale factor: -1 | Unscaled value: 535 | Value: 53.5 | Clean
87+
client.devices.chjarge_controller.config.absorb_volts.value = volts.value + 0.1
88+
# >>> ... | Scale factor: -1 | Unscaled value: 535 | Value: 53.5 | Dirty (value to write: 536)
89+
90+
# OK, but what about fun fields like Enums? It's doable, though a bit gross ...
91+
new_value = client.devices.charge_controller.config.grid_tie_mode.field.options["Grid Tie Mode disabled"]
92+
client.devices.charge_controller.config.grid_tie_mode.value = new_value
93+
94+
95+
# Finally, write any values that have changed to the device itself - BE CAREFUL!
96+
client.write()
11997
```
12098

121-
### Writing data
12299

123-
You can also set values on the mate3s using the `mate3_write` command.
100+
## Using the command line interface (CLI)
124101

125-
**WARNING:** Please make sure you read [the license](https://github.com/adamcharnock/mate3/blob/master/LICENSE)
126-
before using this feature. You could easily damage your equipment by setting
127-
incorrect values. Don't come crying to me if you destroy your batteries,
128-
or if this library takes it upon itself to do so.
102+
A simple CLI is available, with four main sub-commands:
129103

130-
Warnings aside, here is how you use it:
104+
- `read` - reads all of the values from the Mate3 and prints to stdout in a variety of formats.
105+
- `write` - writes values to the Mate3. (If you're doing anything serious you should use the python API.)
106+
- `devices` - shows the connected devices.
107+
- `debug` - caches all of the modbus values to a file which you can then share with others to help in debugging any problems you may have.
131108

132-
```
133-
# Show the available writable fields
134-
$ mate3_write -H 192.168.0.123 --list-fields
109+
For each you can access the help (i.e. `mate3 <cmd> -h`) for more information.
135110

136-
# Start your backup generator!
137-
# (if that is what your inverter's auxiliary output is connected to)
138-
$ mate3_write -H 192.168.0.123 --set radian_inverter_configuration.aux_control=2
111+
## Writing data to Postgres
139112

140-
# Turn it off again
141-
$ mate3_write -H 192.168.0.123 --set radian_inverter_configuration.aux_control=0
142-
```
143-
144-
## Using `mate3_pg` to write data to Postgres
113+
> NB: this used to be in `mate3_pg` command, but has been moved to `./examples/postgres_monitor.py`.
145114
146-
The `mate3_pg` command reads data from your Mate3 and writes it to a Postgres database.
115+
The `postgress_monitor.py` command reads data from your Mate3 and writes it to a Postgres database.
147116

148117
In addition to a Mate3s connected to your network, you will need:
149118

@@ -153,7 +122,7 @@ In addition to a Mate3s connected to your network, you will need:
153122
Example use:
154123

155124
```
156-
$ mate3_pg \
125+
$ python postgres_monitor.py \
157126
-H 192.168.0.123 \
158127
--definitions /path/to/my/definitions.yaml \
159128
--database-url postgres://username:password@host:5432/database_name \
@@ -164,10 +133,10 @@ You will need to replace `192.168.0.123` with your Mate3s' IP. Replace `/path/to
164133
a path to your definitions file (see [example](https://github.com/adamcharnock/mate3/blob/master/pg_config.yaml)).
165134
Replace the `username`, `password`, `host`, and `database_name` values with those for your Postgres database.
166135

167-
Full details of the `mate3_pg` command:
136+
Full details of the `postgres_monitor.py` command:
168137

169138
```
170-
$ mate3_pg --help
139+
$ python postgres_monitor.py --help
171140
usage: mate3_pg [-h] --host HOST [--port PORT] [--interval INTERVAL] [--database-url DATABASE_URL] --definitions DEFINITIONS [--hypertables] [--quiet] [--debug]
172141
173142
Read all available data from the Mate3 controller
@@ -187,24 +156,28 @@ optional arguments:
187156
--debug Show debug logging
188157
```
189158

190-
## Various notes
159+
## Contributing
191160

192-
The `structures.py` and `parsers.py` files are *auto generated*
193-
from the CSV files located in `registry_data/`. The CSV files are
194-
generated though text extraction from the
195-
[axs_app_note.pdf](http://www.outbackpower.com/downloads/documents/appnotes/axs_app_note.pdf)
196-
PDF provided by OutBack. This process is handled by two python files:
161+
If you wish to edit the mate3 source (contributions are gladly received!),
162+
then you can get the project directly from GitHub:
163+
164+
```sh
165+
# Install poetry if you don't have it already (if you're unsure, you don't have it)
166+
pip install poetry
197167

198-
* `csv_generator.py` – Extract the CSV data from the PDF
199-
* `code_generator.py` – Generate the Python code from the CSV data
168+
# Get the source
169+
git clone https://github.com/adamcharnock/mate3.git
170+
cd mate3
200171

201-
## Future work
172+
# Install mate3 and its dependencies. This also makes the mate3 command available.
173+
poetry install
174+
```
202175

203-
* Web interface?
176+
After this you should be able to run the `mate3` command and edit the project's source code.
204177

205178
## Release process
206179

207-
```
180+
```sh
208181
# Check everything has been comitted
209182
git diff
210183

@@ -232,6 +205,5 @@ git push --tags
232205

233206
## Credits
234207

235-
This is a heavily refactored version of
236-
[basrijn's Outback_Mate3 library](https://github.com/basrijn/Outback_Mate3).
237-
Thank you basrijn!
208+
This was originally a heavily refactored version of
209+
[basrijn's Outback_Mate3 library](https://github.com/basrijn/Outback_Mate3), though has largely been completely rewritten since. Thanks anyway basrijn!

0 commit comments

Comments
 (0)