|
1 | 1 | # python-e3dc |
2 | 2 |
|
| 3 | +[](https://badge.fury.io/py/pye3dc) |
| 4 | +[](https://github.com/fsantini/python-e3dc/blob/master/LICENSE) |
| 5 | +[](https://github.com/psf/black) |
| 6 | + |
3 | 7 | **NOTE: With Release 0.6.0 at least Python 3.7 is required** |
4 | 8 |
|
5 | | -Python API for querying E3/DC systems, either through the manufacturer's portal or directly via RSCP connection |
| 9 | +Python API for querying an [E3/DC](https://e3dc.de/) systems |
6 | 10 |
|
7 | | -This library provides an interface to query an E3/DC solar power management system through the web interface of the manufacturer. |
| 11 | +This is supported either directly via RSCP connection or through the manufacturer's portal. The RSCP implementation has currently the most capabilities. |
8 | 12 |
|
9 | | -In order to use it you need (web connection): |
| 13 | +In order to use it you need: |
10 | 14 | - Your user name |
11 | 15 | - Your password |
12 | | -- The serial number of the system which can be found when logging into the E3/DC webpage: |
13 | | -  |
| 16 | +- The IP address of the E3/DC system |
| 17 | +- The RSCP Password (encryption key), as set on the device under Main Page -> Personalize -> User profile -> RSCP password |
14 | 18 |
|
15 | | -Alternatively, for a local connection, you need: |
| 19 | +Alternatively, for a web connection, you need: |
16 | 20 | - Your user name |
17 | 21 | - Your password |
18 | | -- The IP address of the E3/DC system |
19 | | -- The encryption key as set under the preferences of the system. |
| 22 | +- The serial number of the system, which can be found when logging into the E3/DC webpage. |
20 | 23 |
|
21 | 24 | ## Installation |
22 | 25 |
|
23 | 26 | This package can be installed from pip: |
24 | 27 |
|
25 | 28 | `pip install pye3dc` |
26 | 29 |
|
27 | | -## Usage |
| 30 | +## Local Connection |
| 31 | + |
| 32 | +### Configuration |
| 33 | + |
| 34 | +There is a great variety of E3/DC implementation configurations, that can't automatically be detected. For example the `index` of the root power meter can be either `0` or `6`, depending how the system was installed. It is also possible to not only have one power meter or inverter. |
| 35 | +This library assumes, that there is one inverter installed and the root power meter has an index of `6` for S10 mini and `0` for other systems. |
| 36 | + |
| 37 | +For any other conigurations, there is an optional `configuration` object that can be used to alter the defaults: |
| 38 | + |
| 39 | +``` |
| 40 | +{ |
| 41 | + "pvis": [ |
| 42 | + { |
| 43 | + "index": 0, |
| 44 | + "strings": 2, |
| 45 | + "phases": 3 |
| 46 | + } |
| 47 | + ], |
| 48 | + "powermeters": [ |
| 49 | + { |
| 50 | + "index": 6 |
| 51 | + } |
| 52 | + ], |
| 53 | + "batteries": [ |
| 54 | + { |
| 55 | + "index": 0, |
| 56 | + "dcbs": 2 |
| 57 | + } |
| 58 | + ] |
| 59 | +} |
| 60 | +``` |
| 61 | + |
| 62 | +> Note: Not all options need to be configured. |
| 63 | +
|
| 64 | +### Usage |
28 | 65 |
|
29 | 66 | An example script using the library is the following: |
| 67 | + |
30 | 68 | ```python |
31 | 69 | from e3dc import E3DC |
32 | 70 |
|
33 | 71 | TCP_IP = '192.168.1.57' |
34 | 72 | USERNAME = 'test@test.com' |
35 | 73 | PASS = 'MySecurePassword' |
36 | 74 | KEY = 'abc123' |
37 | | -SERIALNUMBER = '1234567890' |
38 | | - |
39 | | -print("web connection") |
40 | | -e3dc = E3DC(E3DC.CONNECT_WEB, username=USERNAME, password=PASS, serialNumber = SERIALNUMBER, isPasswordMd5=False) |
41 | | -# connect to the portal and poll the status. This might raise an exception in case of failed login. This operation is performed with Ajax |
42 | | -print(e3dc.poll()) |
43 | | -# Poll the status of the switches using a remote RSCP connection via websockets |
44 | | -# return value is in the format {'id': switchID, 'type': switchType, 'name': switchName, 'status': switchStatus} |
45 | | -print(e3dc.poll_switches()) |
| 75 | +CONFIG = {} |
| 76 | +# CONFIG = {"powermeters": [{"index": 6}]} |
46 | 77 |
|
47 | 78 | print("local connection") |
48 | | -e3dc = E3DC(E3DC.CONNECT_LOCAL, username=USERNAME, password=PASS, ipAddress = TCP_IP, key = KEY) |
| 79 | +e3dc = E3DC(E3DC.CONNECT_LOCAL, username=USERNAME, password=PASS, ipAddress = TCP_IP, key = KEY, configuration = CONFIG) |
49 | 80 | # The following connections are performed through the RSCP interface |
50 | 81 | print(e3dc.poll()) |
51 | | -print(e3dc.poll_switches()) |
| 82 | +print(e3dc.get_pvi_data()) |
52 | 83 | ``` |
53 | 84 |
|
54 | | -## poll() return values |
| 85 | +### poll() return values |
55 | 86 |
|
56 | 87 | Poll returns a dictionary like the following: |
57 | 88 | ```python |
58 | 89 | { |
59 | | - 'consumption': {'battery': 470, 'house': 477, 'wallbox': 0}, # consumption in W. Positive values are exiting the system |
60 | | - 'production': {'grid': -4, 'solar': 951}, # production in W. Positive values are entering the system |
61 | | - 'stateOfCharge' : 77, # battery charge status in % |
62 | | - 'sysStatus': '2623', # status |
63 | | - 'time': datetime.datetime(2017, 8, 14, 7, 6, 13) # timestamp of the poll |
64 | | -} |
| 90 | + 'autarky': 100, |
| 91 | + 'consumption': { |
| 92 | + 'battery': 470, |
| 93 | + 'house': 477, |
| 94 | + 'wallbox': 0 |
| 95 | + }, |
| 96 | + 'production': { |
| 97 | + 'solar' : 951, |
| 98 | + 'add' : 0, |
| 99 | + 'grid' : -4 |
| 100 | + }, |
| 101 | + 'stateOfCharge': 77, |
| 102 | + 'selfConsumption': 100, |
| 103 | + 'time': datetime.datetime(2021, 8, 14, 7, 6, 13) |
| 104 | +} |
65 | 105 | ``` |
66 | 106 |
|
67 | | -## Setting swiches |
| 107 | +### Available methods |
68 | 108 |
|
69 | | -The e3dcObj.set_switch_onoff(switchID, value, keepAlive = False) method sets a smart switch on or off, where value is a boolean and True = on, False = off. |
70 | | -The switchID is a number returned by the poll_switches method. This method only supports on/off switches and not dimmers or motors. |
| 109 | +* `poll()` |
| 110 | +* `get_system_info()` |
| 111 | +* `get_system_status()` |
| 112 | +* `poll_switches()` |
| 113 | +* `get_idle_periods()` |
| 114 | +* `set_idle_periods()` |
| 115 | +* `get_db_data()` |
| 116 | +* `get_battery_data()` |
| 117 | +* `get_batteries_data()` |
| 118 | +* `get_pvi_data()` |
| 119 | +* `get_pvis_data()` |
| 120 | +* `get_powermeter_data()` |
| 121 | +* `get_powermeters_data()` |
| 122 | +* `get_power_settings()` |
| 123 | +* `set_power_limits()` |
| 124 | +* `set_powersave()` |
| 125 | +* `set_weather_regulated_charge()` |
71 | 126 |
|
72 | | -## Note: The RSCP interface |
| 127 | +> A documentation for these methods is not yet generated. Please have a look at the docstrings in `_e3dc.py` for details. |
73 | 128 |
|
74 | | -The switch statuses are obtained and manipulated via a rather complicated protocol, called by E3/DC RSCP. This protocol is binary and based on websockets. |
| 129 | +### Note: The RSCP interface |
75 | 130 |
|
76 | | -The E3DC object automatically connects to the websocket and authenticates. Both the poll_switches and set_switch_onoff methods accept an optional keepAlive parameter. |
| 131 | +The communication to an E3/DC system has to be implementes via a rather complicated protocol, called by E3/DC RSCP. This protocol is binary and based on websockets. The documentation provided by E3/DC is limited and outdated . It can be found in the E3/DC download portal. |
77 | 132 |
|
78 | 133 | If keepAlive is false, the websocket connection is closed after the command. This makes sense because these requests are not meant to be made as often as the status requests, however, if keepAlive is True, the connection is left open and kept alive in the background in a separate thread. |
79 | 134 |
|
| 135 | +## Web connection |
| 136 | + |
| 137 | +### Usage |
| 138 | + |
| 139 | +An example script using the library is the following: |
| 140 | + |
| 141 | +```python |
| 142 | +from e3dc import E3DC |
| 143 | + |
| 144 | +TCP_IP = '192.168.1.57' |
| 145 | +USERNAME = 'test@test.com' |
| 146 | +PASS = 'MySecurePassword' |
| 147 | +SERIALNUMBER = '1234567890' |
| 148 | + |
| 149 | +print("web connection") |
| 150 | +e3dc = E3DC(E3DC.CONNECT_WEB, username=USERNAME, password=PASS, serialNumber = SERIALNUMBER, isPasswordMd5=False) |
| 151 | +# connect to the portal and poll the status. This might raise an exception in case of failed login. This operation is performed with Ajax |
| 152 | +print(e3dc.poll()) |
| 153 | +# Poll the status of the switches using a remote RSCP connection via websockets |
| 154 | +# return value is in the format {'id': switchID, 'type': switchType, 'name': switchName, 'status': switchStatus} |
| 155 | +print(e3dc.poll_switches()) |
| 156 | +``` |
| 157 | + |
80 | 158 | ## Known limitations |
81 | 159 |
|
82 | 160 | One limitation of the package concerns the implemented RSCP methods. At the moment, only switch status requests and setting of on/off switches is implemented. I also lack the hardware to test different configurations. However, the RSCP protocol is (to my knowledge) fully implemented and it should be easy to extend the requests to other cases. |
83 | 161 |
|
84 | | -# Copyright notice |
| 162 | +## Projects using this library |
| 163 | + |
| 164 | +* [e3dc-rest](https://github.com/vchrisb/e3dc-rest): a simple REST API to access an E3/DC system |
| 165 | +* [e3dc-to-mqtt](https://github.com/mdhom/e3dc-to-mqtt): publish E3/DC data via MQTT |
| 166 | + |
| 167 | +## Contribution |
| 168 | + |
| 169 | +* open an issue before making a pull request |
| 170 | +* note the E3/DC system you tested with and implementation details |
| 171 | +* pull request checks will enforce code styling (black, flake8, isort) |
| 172 | +* consider adding yourself to `AUTHORS` |
| 173 | + |
| 174 | +## Copyright notice |
85 | 175 |
|
86 | 176 | The Rijndael algorithm comes from the python-cryptoplus package by Philippe Teuwen (https://github.com/doegox/python-cryptoplus) and distributed under a MIT license. |
0 commit comments