pypvs 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. pypvs-0.1.3/LICENSE +21 -0
  2. pypvs-0.1.3/MANIFEST.in +3 -0
  3. pypvs-0.1.3/PKG-INFO +57 -0
  4. pypvs-0.1.3/README.md +36 -0
  5. pypvs-0.1.3/doc/LocalAPI.md +281 -0
  6. pypvs-0.1.3/doc/varserver-variables-public.csv +106 -0
  7. pypvs-0.1.3/examples/simple_fcgi_async.py +35 -0
  8. pypvs-0.1.3/examples/simple_pvs_async.py +53 -0
  9. pypvs-0.1.3/examples/updater_ess_async.py +58 -0
  10. pypvs-0.1.3/examples/updater_gateway_async.py +58 -0
  11. pypvs-0.1.3/examples/updater_inverter_async.py +58 -0
  12. pypvs-0.1.3/examples/updater_meter_async.py +58 -0
  13. pypvs-0.1.3/examples/updater_transfer_switch_async.py +58 -0
  14. pypvs-0.1.3/examples/zeroconf_find_pvs_async.py +67 -0
  15. pypvs-0.1.3/examples/zeroconf_test_simple.py +25 -0
  16. pypvs-0.1.3/pyproject.toml +32 -0
  17. pypvs-0.1.3/setup.cfg +4 -0
  18. pypvs-0.1.3/setup.py +30 -0
  19. pypvs-0.1.3/src/pypvs/__init__.py +21 -0
  20. pypvs-0.1.3/src/pypvs/const.py +32 -0
  21. pypvs-0.1.3/src/pypvs/exceptions.py +25 -0
  22. pypvs-0.1.3/src/pypvs/firmware.py +37 -0
  23. pypvs-0.1.3/src/pypvs/models/__init__.py +0 -0
  24. pypvs-0.1.3/src/pypvs/models/common.py +41 -0
  25. pypvs-0.1.3/src/pypvs/models/ess.py +69 -0
  26. pypvs-0.1.3/src/pypvs/models/gateway.py +37 -0
  27. pypvs-0.1.3/src/pypvs/models/inverter.py +44 -0
  28. pypvs-0.1.3/src/pypvs/models/meter.py +73 -0
  29. pypvs-0.1.3/src/pypvs/models/pvs.py +27 -0
  30. pypvs-0.1.3/src/pypvs/models/transfer_switch.py +49 -0
  31. pypvs-0.1.3/src/pypvs/pvs.py +189 -0
  32. pypvs-0.1.3/src/pypvs/pvs_fcgi.py +129 -0
  33. pypvs-0.1.3/src/pypvs/updaters/__init__.py +0 -0
  34. pypvs-0.1.3/src/pypvs/updaters/base.py +33 -0
  35. pypvs-0.1.3/src/pypvs/updaters/ess.py +62 -0
  36. pypvs-0.1.3/src/pypvs/updaters/gateway.py +45 -0
  37. pypvs-0.1.3/src/pypvs/updaters/meter.py +62 -0
  38. pypvs-0.1.3/src/pypvs/updaters/production_inverters.py +62 -0
  39. pypvs-0.1.3/src/pypvs/updaters/transfer_switch.py +62 -0
  40. pypvs-0.1.3/src/pypvs.egg-info/PKG-INFO +57 -0
  41. pypvs-0.1.3/src/pypvs.egg-info/SOURCES.txt +44 -0
  42. pypvs-0.1.3/src/pypvs.egg-info/dependency_links.txt +1 -0
  43. pypvs-0.1.3/src/pypvs.egg-info/not-zip-safe +1 -0
  44. pypvs-0.1.3/src/pypvs.egg-info/requires.txt +1 -0
  45. pypvs-0.1.3/src/pypvs.egg-info/top_level.txt +1 -0
  46. pypvs-0.1.3/tests/test_pvs.py +10 -0
pypvs-0.1.3/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 SunStrong Management
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ include README.md
2
+ recursive-include doc *
3
+ recursive-include examples *
pypvs-0.1.3/PKG-INFO ADDED
@@ -0,0 +1,57 @@
1
+ Metadata-Version: 2.4
2
+ Name: pypvs
3
+ Version: 0.1.3
4
+ Summary: A Python package that exposes data and commands for a Sunpower PVS6 gateway.
5
+ Home-page: https://github.com/SunStrong-Management/pypvs.git
6
+ Author: Aleksandar Mitev @ SunStrong Management
7
+ Author-email: Aleksandar Mitev <amitev@sunstrongmanagement.com>
8
+ License-Expression: MIT
9
+ Project-URL: Homepage, https://github.com/SunStrong-Management/pypvs
10
+ Project-URL: Issues, https://github.com/SunStrong-Management/pypvs/issues
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.6
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: aiohttp
17
+ Dynamic: author
18
+ Dynamic: home-page
19
+ Dynamic: license-file
20
+ Dynamic: requires-python
21
+
22
+ # pypvs
23
+
24
+ `pypvs` is a Python package that exposes data and commands for a Sunpower PVS6 gateway
25
+
26
+ ## Installation
27
+
28
+ You can install it using pip:
29
+ ```
30
+ pip install pypvs
31
+ ```
32
+
33
+ # Running the examples
34
+
35
+ Initialize virtual environment and install requirements
36
+ ```
37
+ virtualenv venv
38
+ . venv/bin/activate
39
+ pip install -r requirements.txt
40
+ ```
41
+
42
+ Install `pypvs` in development mode
43
+ ```
44
+ pip install -e .
45
+ ```
46
+
47
+ Then run the example scripts
48
+ ```
49
+ python examples/simple_fcgi_async.py
50
+
51
+ python examples/simple_pvs_async.py
52
+ ```
53
+
54
+ # Access to the PVS via varserver
55
+
56
+ Please refer to [LocalAPI documentation](doc/LocalAPI.md) for details on accessing the PVS via varserver.
57
+
pypvs-0.1.3/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # pypvs
2
+
3
+ `pypvs` is a Python package that exposes data and commands for a Sunpower PVS6 gateway
4
+
5
+ ## Installation
6
+
7
+ You can install it using pip:
8
+ ```
9
+ pip install pypvs
10
+ ```
11
+
12
+ # Running the examples
13
+
14
+ Initialize virtual environment and install requirements
15
+ ```
16
+ virtualenv venv
17
+ . venv/bin/activate
18
+ pip install -r requirements.txt
19
+ ```
20
+
21
+ Install `pypvs` in development mode
22
+ ```
23
+ pip install -e .
24
+ ```
25
+
26
+ Then run the example scripts
27
+ ```
28
+ python examples/simple_fcgi_async.py
29
+
30
+ python examples/simple_pvs_async.py
31
+ ```
32
+
33
+ # Access to the PVS via varserver
34
+
35
+ Please refer to [LocalAPI documentation](doc/LocalAPI.md) for details on accessing the PVS via varserver.
36
+
@@ -0,0 +1,281 @@
1
+ # Local Monitoring using FCGI Web Services
2
+ SunStrong Management is pleased to announce an API for local PVS monitoring. The API is available on the PVS Ethernet and Wi-Fi interfaces and can be used to access some of the legacy dl_cgi APIs as well as the new varserver FCGI APIs.
3
+
4
+ These APIs will support local communication between the PVS and the SunStrong Connect application, as well as custom monitoring solutions developed by system owners and the open source development community.
5
+
6
+ The interface supports Basic Authentication (username/password). Users must authenticate before accessing the dl_cgi and FCGI APIs. Some limited Varserver data points and dl_cgi endpoints are available without authentication.
7
+
8
+ Varserver is a highly efficient in-memory key-value data store used for system configuration management, telemetry reporting, and inter-process communications. Data is stored/retrieved as unstructured primitive data points which represent a single telemetry value or configuration/control point. Some data is represented as JSON object structures stored in string variables.
9
+
10
+ The Varserver web services only expose two APIs:
11
+
12
+ - auth - user login/logout
13
+
14
+ - vars - Varserver interface for setting and getting variables
15
+
16
+ ## Our commitment to open source
17
+ The SunStrong Management team have made available the following open source components to support the community:
18
+
19
+ - A Python wrapper around the VarServer FCGI web services (PyPVS)
20
+
21
+ - A Home Assistant plugin which can be installed in Home Assistant via the Home Assistant Community Store (HACS).
22
+
23
+ ### Availability
24
+ The FCGI Web services and authenticated dl_cgi endpoints are available in PVS6 firmware build 61840 and later. Support for PVS5 devices is coming soon. PVS2 devices are not, and will never be supported.
25
+
26
+ ### Disclaimer
27
+ Use of this interface is at your own risk. SunStrong Management is releasing these components as-is, and assume no liability for use/mis-use of these components.
28
+
29
+ ## Theory of Operation
30
+ For most users, the PyPVS library and HA plugin will be sufficient to get started, but for those interested in the more technical details of the API, read on….
31
+
32
+ ### Authentication
33
+ Before accessing data, users must authenticate against the PVS using a username and password. The username is: ssm_owner
34
+ The password is: the last 5 characters of the PVS serial number
35
+
36
+ Upon successful login, the requester receives an access token which is then delivered (via a cookie) to the PVS in subsequent data queries.
37
+
38
+ ### Data queries:
39
+ Data points can be queried by name; by partial name match; by tags; and by cache id. Any query can be associated with a user specified cache id, and then subsequently retrieved using that cache id. Users can arbitrarily group data points as needed and retrieve those groupings by cache id. Note that match queries search the entire varserver name space and are less efficient than cached queries. It is strongly recommended, particularly when making frequent match or tag queries, to cache the query, and then make subsequent queries using the cache id. While the varserver FCGI interface is very efficient, we do not recommend making queries faster than once every few seconds, in case you overload the PVS CPU. This is particularly important on SunVault systems where the CPU already has a lot to do.
40
+
41
+ ### Data Output Formats
42
+ Two data output formats are currently supported:
43
+
44
+ - a JSON array containing one object per data point with name and value, and possibly other attributes in future
45
+
46
+ - a JSON object containing key/value pairs, where the key is the datapoint name, and the value is its current value.
47
+
48
+ ### Available data points
49
+ This list is subject to change, and we will most likely not be updating it regularly. To check the data points available on your system, run a match query, but beware this will generate a lot of data.
50
+
51
+ Check the attached file [Varserver Variables](varserver-variables-public.csv) for the list of currenlty accessible variables.
52
+
53
+ ### Examples
54
+ All the examples are shown below using curl to demonstrate the API features.
55
+ in all the examples below:
56
+
57
+ - **pwd** = <last 5 digits of PVS serial number>
58
+ - **ip** = <IP address of PVS>
59
+ - **cookies.txt** is a file containing cookies (used to store auth tokens)
60
+
61
+ The `jq` utility is used to format the response into a more readable format
62
+
63
+ #### Authentication - login
64
+ ```
65
+ $ auth=`echo -n "ssm_owner:$pwd" | base64`
66
+ $ curl -k \
67
+ -b cookies.txt \
68
+ -c cookies.txt \
69
+ -H "Authorization: basic $auth" \
70
+ https://$ip/auth?login
71
+ {"session": "3z02Z55QKi4VZevR6EW4psExaTNZaiaGGeUBqKlXnHIJBPoPV6uzztgcAXGd3rFf" }
72
+ $ cat cookies.txt
73
+ # Netscape HTTP Cookie File
74
+ # https://curl.se/docs/http-cookies.html
75
+ # This file was generated by libcurl! Edit at your own risk.
76
+ #HttpOnly_localhost FALSE / TRUE 0 session NCA7CIW7zoXxsFfWAH64OrrNS6OrN2zU0hTAcgtUvCMqOsug98TldqceGBxI2ZxK
77
+ ```
78
+
79
+ #### Authentication - logout
80
+ ```
81
+ $ curl -k \
82
+ -b cookies.txt \
83
+ -c cookies.txt \
84
+ -H "Authorization: basic $auth" \
85
+ https://$ip/auth?logout
86
+ ```
87
+
88
+ #### Query a list of variables by name
89
+ ```
90
+ $ curl -s \
91
+ -k \
92
+ -b cookies.txt \
93
+ -c cookies.txt \
94
+ https://$ip/vars?name=/sys/info/sw_rev,/sys/info/lmac | jq
95
+ {
96
+ "values": [
97
+ {
98
+ "name": "/sys/info/sw_rev",
99
+ "value": "2025.06.24.61840"
100
+ },
101
+ {
102
+ "name": "/sys/info/lmac",
103
+ "value": "00:22:F2:13:85:54"
104
+ }
105
+ ],
106
+ "count": 2
107
+ }
108
+ ```
109
+
110
+ #### Query all variables which match a substring
111
+ ```
112
+ $ curl -s \
113
+ -k \
114
+ -b cookies.txt \
115
+ -c cookies.txt \
116
+ https://$ip/vars?match=rev | jq
117
+ {
118
+ "values": [
119
+ {
120
+ "name": "/sys/info/hwrev",
121
+ "value": "6.03"
122
+ },
123
+ {
124
+ "name": "/sys/info/fwrev",
125
+ "value": " Major 2, Revision 0x00000001, Build 3"
126
+ },
127
+ {
128
+ "name": "/sys/info/sw_rev",
129
+ "value": "2025.06.24.61840"
130
+ }
131
+ ],
132
+ "count": 3
133
+ }
134
+ ```
135
+
136
+ #### Query all variables which match a substring and output as an object
137
+ ```
138
+ $ curl -s \
139
+ -k \
140
+ -b cookies.txt \
141
+ -c cookies.txt \
142
+ "https://$ip/vars?match=rev&fmt=obj" | jq
143
+ {
144
+ "/sys/info/hwrev": "6.03",
145
+ "/sys/info/fwrev": " Major 2, Revision 0x00000001, Build 3",
146
+ "/sys/info/sw_rev": "2025.06.24.61840"
147
+ }
148
+ ```
149
+
150
+ #### Query all livedata power values using a match expression, create a cache, and output as an object
151
+ ```
152
+ $ curl -s \
153
+ -k \
154
+ -b cookies.txt \
155
+ -c cookies.txt \
156
+ "https://$ip/vars?match=livedata&fmt=obj&cache=ldata" | jq
157
+ {
158
+ "/sys/livedata/time": "1751083263",
159
+ "/sys/livedata/pv_p": "0.015622",
160
+ "/sys/livedata/pv_en": "40747.871094",
161
+ "/sys/livedata/net_p": "0.674694",
162
+ "/sys/livedata/net_en": "6121.310059",
163
+ "/sys/livedata/site_load_p": "1.876316",
164
+ "/sys/livedata/site_load_en": "46378.703125",
165
+ "/sys/livedata/ess_en": "-490.477997",
166
+ "/sys/livedata/ess_p": "1.186000",
167
+ "/sys/livedata/soc": "0.860000",
168
+ "/sys/livedata/backupTimeRemaining": "570",
169
+ "/sys/livedata/midstate": "2"
170
+ }
171
+ ```
172
+
173
+ #### Query a cached data set and output as an object
174
+ ```
175
+ $ curl -s \
176
+ -k \
177
+ -b cookies.txt \
178
+ -c cookies.txt \
179
+ "https://$ip/vars?fmt=obj&cache=ldata" | jq
180
+ {
181
+ "/sys/livedata/time": "1751083345",
182
+ "/sys/livedata/pv_p": "0.023758",
183
+ "/sys/livedata/pv_en": "40747.871094",
184
+ "/sys/livedata/net_p": "0.653675",
185
+ "/sys/livedata/net_en": "6121.330078",
186
+ "/sys/livedata/site_load_p": "2.539433",
187
+ "/sys/livedata/site_load_en": "46378.734375",
188
+ "/sys/livedata/ess_en": "-490.463989",
189
+ "/sys/livedata/ess_p": "1.862000",
190
+ "/sys/livedata/soc": "0.860000",
191
+ "/sys/livedata/backupTimeRemaining": "555",
192
+ "/sys/livedata/midstate": "2"
193
+ }
194
+ ```
195
+
196
+ #### Query all meter data values using a match expression, create a cache, and output as an object
197
+ ```
198
+ $ curl -s \
199
+ -k \
200
+ -b cookies.txt \
201
+ -c cookies.txt \
202
+ "https://$ip/vars?match=meter/data&fmt=obj&cache=mdata" | jq
203
+ {
204
+ "/sys/devices/11/meter/data": {
205
+ "ctSclFctr": 50,
206
+ "freqHz": 60.0150032,
207
+ "msmtEps": "2025-06-28T04:10:00Z",
208
+ "netLtea3phsumKwh": 40747.87,
209
+ "p3phsumKw": 0.0158712063,
210
+ "prodMdlNm": "PVS6M0400p",
211
+ "q3phsumKvar": 1.25327051,
212
+ "s3phsumKva": 1.26208436,
213
+ "sn": "PVS6M23084354p",
214
+ "totPfRto": 0.00977255497,
215
+ "v12V": 248.283142,
216
+ "vldFldMsk": "67174655"
217
+ },
218
+ "/sys/devices/12/meter/data": {
219
+ "ctSclFctr": 300,
220
+ "freqHz": 60.0150032,
221
+ "i1A": 13.9226713,
222
+ "i2A": 12.32792,
223
+ "msmtEps": "2025-06-28T04:10:00Z",
224
+ "negLtea3phsumKwh": 13600.36,
225
+ "netLtea3phsumKwh": 6121.360000000001,
226
+ "p1Kw": 0.316900551,
227
+ "p2Kw": 0.16260837,
228
+ "p3phsumKw": 0.479508936,
229
+ "posLtea3phsumKwh": 19721.78,
230
+ "prodMdlNm": "PVS6M0400c",
231
+ "q3phsumKvar": -3.15799665,
232
+ "s3phsumKva": 3.25863361,
233
+ "sn": "PVS6M23084354c",
234
+ "totPfRto": 0.196262509,
235
+ "v12V": 248.283142,
236
+ "v1nV": 124.040031,
237
+ "v2nV": 124.243462,
238
+ "vldFldMsk": "70239999"
239
+ }
240
+ }
241
+ ```
242
+
243
+ #### Query all inverter data, create a cache, and output as an object
244
+ ```
245
+ $ curl -s \
246
+ -k \
247
+ -b cookies.txt \
248
+ -c cookies.txt \
249
+ "https://$ip/vars?match=inverter/data&fmt=obj&cache=mdata" | jq
250
+ {
251
+ "/sys/devices/21/inverter/data": {
252
+ "freqHz": 60.01,
253
+ "iMppt1A": 0.03,
254
+ "ltea3phsumKwh": 686.5164000000001,
255
+ "msmtEps": "2025-06-28T03:35:00Z",
256
+ "pMppt1Kw": 0.00068,
257
+ "prodMdlNm": "AC_Module_Type_H",
258
+ "sn": "E00122307107854",
259
+ "tHtsnkDegc": 24,
260
+ "vMppt1V": 17.93,
261
+ "vldFld2Msk": "1",
262
+ "vldFldMsk": "8125",
263
+ "vln3phavgV": 249.54
264
+ },
265
+ ...
266
+ "/sys/devices/61/inverter/data": {
267
+ "freqHz": 60.01,
268
+ "iMppt1A": 0.04,
269
+ "ltea3phsumKwh": 731.5522,
270
+ "msmtEps": "2025-06-28T03:35:00Z",
271
+ "pMppt1Kw": 0.00058,
272
+ "prodMdlNm": "AC_Module_Type_H",
273
+ "sn": "E00122308008125",
274
+ "tHtsnkDegc": 24,
275
+ "vMppt1V": 13.09,
276
+ "vldFld2Msk": "1",
277
+ "vldFldMsk": "8125",
278
+ "vln3phavgV": 249.84
279
+ }
280
+ }
281
+ ```
@@ -0,0 +1,106 @@
1
+ name,type,value,tags,description,read,write
2
+ /sys/telemetryws/enable,uint16,1,N/A,Variable to enable telemetry websockets,ssm_owner,ssm_owner
3
+ /sys/livedata/time,int64,N/A,livedata,Telemetry Websockets timestamp,ssm_owner,
4
+ /sys/livedata/pv_p,float,N/A,livedata,Production Power (kW),ssm_owner,
5
+ /sys/livedata/pv_en,float,N/A,livedata,Production Energy (kWh),ssm_owner,
6
+ /sys/livedata/net_p,float,N/A,livedata,Net Consumption Power (kW),ssm_owner,
7
+ /sys/livedata/net_en,float,N/A,livedata,Net Consumption Energy (kWh),ssm_owner,
8
+ /sys/livedata/site_load_p,float,N/A,livedata,Site Load Power (kW),ssm_owner,
9
+ /sys/livedata/site_load_en,float,N/A,livedata,Site Load Energy (kWh),ssm_owner,
10
+ /sys/livedata/ess_en,float,N/A,livedata,Battery Energy (kWh),ssm_owner,
11
+ /sys/livedata/ess_p,float,N/A,livedata,Battery Power (kW),ssm_owner,
12
+ /sys/livedata/soc,float,N/A,livedata,Battery State of Charge (%),ssm_owner,
13
+ /sys/livedata/backupTimeRemaining,uint32,N/A,livedata,Battery Backup Time Remaining (minutes),ssm_owner,
14
+ /sys/livedata/midstate,int32,N/A,livedata,MID State,ssm_owner,
15
+ /network/report/send,uint16,N/A,N/A,Trigger communicator to send a network interface report,ssm_owner,ssm_owner
16
+ /metrics/network/interface_report_request,uint32,N/A,"metrics,network",Count of Network Interface Report requests,ssm_owner,ssm_owner
17
+ /sys/info/serialnum,str,TBD,diag,PVS Serial Number,ssm_owner,
18
+ /sys/info/model,str,TBD,diag,PVS model number,ssm_owner,
19
+ /sys/info/hwrev,str,TBD,diag,PVS Hardware Revision,ssm_owner,
20
+ /sys/info/uptime,str,TBD,diag,PVS uptime,ssm_owner,
21
+ /sys/info/fwrev,str,TBD,diag,PVS Firmware Revision,ssm_owner,
22
+ /sys/info/boardtype,str,TBD,diag,PVS Board Type,ssm_owner,
23
+ /sys/info/sw_rev,str,TBD,diag,SPWR Software Revision,ssm_owner,
24
+ /sys/info/ssid,str,TBD,diag,PVS ssid,ssm_owner,
25
+ /sys/info/wpa_key,str,TBD,diag,PVS wpa key,ssm_owner,
26
+ /sys/info/lmac,str,TBD,diag,LAN0 MAC address,ssm_owner,
27
+ /sys/info/sys_type,str,Unknown,diag,"system type (PV-only, storage)",ssm_owner,
28
+ /sys/info/finance_type,str,UNKNOWN,diag,"Finance type for the site that this PVS is running at. Viable values are UNKNOWN, CASH, LEASE, and LOAN",ssm_owner,
29
+ /sys/info/active_interface,str,TBD,diag,Current active network interface,ssm_owner,
30
+ /sys/info/active_interface_mac,str,TBD,diag,Current active network interface mac address,ssm_owner,
31
+ /sys/info/ram_usage,uint16,0,diag,Current RAM usage in percentage,ssm_owner,
32
+ /sys/info/flash_usage,uint16,0,diag,Current Flash usage in percentage,ssm_owner,
33
+ /sys/info/cpu_usage,uint16,0,diag,Current CPU usage in percentage,ssm_owner,
34
+ /sys/pvs/flashwear_type_b,uint16,0x05,sysstats,"Percentage lifetime estimation as HEX value (0x01 = 10%, 0x9 = 90%). E.g. 0x1 means that 10% of the EMMC lifetime passed. This value holds current value for TYPE B cell.",ssm_owner,
35
+ /sys/pvs/usb_erase_count,uint16,0,sysstats,SMART Attribute 229 Erase Count Usage which is a measurement to tell the health state of USB drive.,ssm_owner,
36
+ /sys/toggle_cell/low_data_mode,uint32,0,"netstats,toggle_cell",toggle_cell low data mode status,ssm_owner,
37
+ /sys/toggle_cell/cell_connected,uint16,0,"netstats,toggle_cell","Cell connection status, 0=disconnected, 1=connected",ssm_owner,
38
+ /sys/toggle_cell/broadband_connected,uint16,0,"netstats,toggle_cell","Broadband connection status, 0=disconnected, 1=connected",ssm_owner,
39
+ /net/wwan0/state,str,N/A,"netstats,network,toggle_cell",wwan0 interface state,ssm_owner,
40
+ /net/wan0/state,str,N/A,"netstats,network,toggle_cell",wan0 interface state,ssm_owner,
41
+ /net/wan1/state,str,N/A,"netstats,network,toggle_cell",wan1 (USB dongle ethernet adapter) interface state,ssm_owner,
42
+ /net/sta0/state,str,N/A,"netstats,network,toggle_cell",sta0 interface state,ssm_owner,
43
+ /sys/devices/inverter/{index}/freqHz,float,0,"telemetry,inverter",Frequency in Hz dectected by the inverter,ssm_owner,
44
+ /sys/devices/inverter/{index}/i3phsumA,float,0,"telemetry,inverter",Sum of phase currents in A,ssm_owner,
45
+ /sys/devices/inverter/{index}/iMppt1A,float,0,"telemetry,inverter",Current of MPPT1 in A,ssm_owner,
46
+ /sys/devices/inverter/{index}/ltea3phsumKwh,float,0,"telemetry,inverter",Lifetime sum of 3-phase energy in kWh,ssm_owner,
47
+ /sys/devices/inverter/{index}/msmtEps,str,n/a,"telemetry,inverter",Timestamp of the last measurement,ssm_owner,
48
+ /sys/devices/inverter/{index}/p3phsumKw,float,0,"telemetry,inverter",Sum of 3-phase power in kW,ssm_owner,
49
+ /sys/devices/inverter/{index}/pMppt1Kw,float,0,"telemetry,inverter",Power of MPPT1 in kW,ssm_owner,
50
+ /sys/devices/inverter/{index}/prodMdlNm,str,n/a,"telemetry,inverter",Product model name,ssm_owner,
51
+ /sys/devices/inverter/{index}/sn,str,n/a,"telemetry,inverter",Serial number of the inverter,ssm_owner,
52
+ /sys/devices/inverter/{index}/tHtsnkDegc,int32,0,"telemetry,inverter",Temperature of the heat sink in °C,ssm_owner,
53
+ /sys/devices/inverter/{index}/vMppt1V,float,0,"telemetry,inverter",Voltage of MPPT1 in V,ssm_owner,
54
+ /sys/devices/inverter/{index}/vln3phavgV,float,0,"telemetry,inverter",Average line-to-neutral voltage of 3-phase system in V,ssm_owner,
55
+ /sys/devices/ess/{index}/chrgLimitPmaxKw,float,0,"telemetry,ess",Maximum allowed charge power (kW),ssm_owner,
56
+ /sys/devices/ess/{index}/customerSocVal,float,0,"telemetry,ess",Customer-reported state of charge (SOC) value,ssm_owner,
57
+ /sys/devices/ess/{index}/dischrgLimPmaxKw,float,0,"telemetry,ess",Maximum allowed discharge power (kW),ssm_owner,
58
+ /sys/devices/ess/{index}/maxTBattCellDegc,float,0,"telemetry,ess",Maximum battery cell temperature (°C),ssm_owner,
59
+ /sys/devices/ess/{index}/maxVBattCellV,float,0,"telemetry,ess",Maximum battery cell voltage (V),ssm_owner,
60
+ /sys/devices/ess/{index}/minTBattCellDegc,float,0,"telemetry,ess",Minimum battery cell temperature (°C),ssm_owner,
61
+ /sys/devices/ess/{index}/minVBattCellV,float,0,"telemetry,ess",Minimum battery cell voltage (V),ssm_owner,
62
+ /sys/devices/ess/{index}/msmtEps,str,n/a,"telemetry,ess",Timestamp of the last measurement,ssm_owner,
63
+ /sys/devices/ess/{index}/negLtea3phsumKwh,float,0,"telemetry,ess",Total negative energy (kWh) over 3 phases,ssm_owner,
64
+ /sys/devices/ess/{index}/opMode,str,n/a,"telemetry,ess",Operating mode of the ESS,ssm_owner,
65
+ /sys/devices/ess/{index}/p3phsumKw,float,0,"telemetry,ess",Total real power (kW) over 3 phases,ssm_owner,
66
+ /sys/devices/ess/{index}/posLtea3phsumKwh,float,0,"telemetry,ess",Total positive energy (kWh) over 3 phases,ssm_owner,
67
+ /sys/devices/ess/{index}/prodMdlNm,str,n/a,"telemetry,ess",Product model name,ssm_owner,
68
+ /sys/devices/ess/{index}/sn,str,n/a,"telemetry,ess",Device serial number,ssm_owner,
69
+ /sys/devices/ess/{index}/socVal,float,0,"telemetry,ess",State of charge (SOC) value,ssm_owner,
70
+ /sys/devices/ess/{index}/sohVal,int16,0,"telemetry,ess",State of health (SOH) value,ssm_owner,
71
+ /sys/devices/ess/{index}/tInvtrDegc,float,0,"telemetry,ess",Inverter temperature (°C),ssm_owner,
72
+ /sys/devices/ess/{index}/v1nV,float,0,"telemetry,ess",Voltage between phase 1 and neutral (V),ssm_owner,
73
+ /sys/devices/ess/{index}/v2nV,float,0,"telemetry,ess",Voltage between phase 2 and neutral (V),ssm_owner,
74
+ /sys/devices/ess/{index}/vBattV,float,0,"telemetry,ess",Battery voltage (V),ssm_owner,
75
+ /sys/devices/meter/{index}/ctSclFctr,int32,0,"telemetry,meter",CT scaling factor,ssm_owner,
76
+ /sys/devices/meter/{index}/freqHz,float,0,"telemetry,meter",Frequency in Hz,ssm_owner,
77
+ /sys/devices/meter/{index}/i1A,float,0,"telemetry,meter",Current in A for phase 1,ssm_owner,
78
+ /sys/devices/meter/{index}/i2A,float,0,"telemetry,meter",Current in A for phase 2,ssm_owner,
79
+ /sys/devices/meter/{index}/msmtEps,str,n/a,"telemetry,meter",Timestamp of the last measurement,ssm_owner,
80
+ /sys/devices/meter/{index}/negLtea3phsumKwh,float,0,"telemetry,meter",Negative lifetime sum of 3-phase energy in kWh,ssm_owner,
81
+ /sys/devices/meter/{index}/netLtea3phsumKwh,float,0,"telemetry,meter",Net lifetime sum of 3-phase energy in kWh,ssm_owner,
82
+ /sys/devices/meter/{index}/p1Kw,float,0,"telemetry,meter",Power in kW for phase 1,ssm_owner,
83
+ /sys/devices/meter/{index}/p2Kw,float,0,"telemetry,meter",Power in kW for phase 2,ssm_owner,
84
+ /sys/devices/meter/{index}/p3phsumKw,float,0,"telemetry,meter",Sum of 3-phase power in kW,ssm_owner,
85
+ /sys/devices/meter/{index}/posLtea3phsumKwh,float,0,"telemetry,meter",Positive lifetime sum of 3-phase energy in kWh,ssm_owner,
86
+ /sys/devices/meter/{index}/prodMdlNm,str,n/a,"telemetry,meter",Product model name,ssm_owner,
87
+ /sys/devices/meter/{index}/q3phsumKvar,float,0,"telemetry,meter",Sum of 3-phase reactive power in kVar,ssm_owner,
88
+ /sys/devices/meter/{index}/s3phsumKva,float,0,"telemetry,meter",Sum of 3-phase apparent power in kVA,ssm_owner,
89
+ /sys/devices/meter/{index}/sn,str,n/a,"telemetry,meter",Serial number of the meter,ssm_owner,
90
+ /sys/devices/meter/{index}/totPfRto,float,0,"telemetry,meter",Total power factor ratio,ssm_owner,
91
+ /sys/devices/meter/{index}/v12V,float,0,"telemetry,meter",Voltage between phase 1 and 2 in V,ssm_owner,
92
+ /sys/devices/meter/{index}/v1nV,float,0,"telemetry,meter",Voltage between phase 1 and neutral in V,ssm_owner,
93
+ /sys/devices/meter/{index}/v2nV,float,0,"telemetry,meter",Voltage between phase 2 and neutral in V,ssm_owner,
94
+ /sys/devices/transfer_switch/{index}/midStEnum,str,n/a,"telemetry,transfer_switch",MID state,ssm_owner,
95
+ /sys/devices/transfer_switch/{index}/msmtEps,str,n/a,"telemetry,transfer_switch",Timestamp of the last measurement,ssm_owner,
96
+ /sys/devices/transfer_switch/{index}/prodMdlNm,str,n/a,"telemetry,transfer_switch",Product model name,ssm_owner,
97
+ /sys/devices/transfer_switch/{index}/pvd1StEnum,str,n/a,"telemetry,transfer_switch",PV Disconnect (PVD) state,ssm_owner,
98
+ /sys/devices/transfer_switch/{index}/sn,str,n/a,"telemetry,transfer_switch",Serial number of the transfer switch,ssm_owner,
99
+ /sys/devices/transfer_switch/{index}/tDegc,float,0,"telemetry,transfer_switch",Temperature in degrees Celsius,ssm_owner,
100
+ /sys/devices/transfer_switch/{index}/v1nGridV,float,0,"telemetry,transfer_switch",Grid voltage for phase 1,ssm_owner,
101
+ /sys/devices/transfer_switch/{index}/v1nV,float,0,"telemetry,transfer_switch",Voltage between phase 1 and neutral,ssm_owner,
102
+ /sys/devices/transfer_switch/{index}/v2nGridV,float,0,"telemetry,transfer_switch",Grid voltage between phase 2 and neutral,ssm_owner,
103
+ /sys/devices/transfer_switch/{index}/v2nV,float,0,"telemetry,transfer_switch",Voltage between phase 2 and neutral,ssm_owner,
104
+ /sys/devices/transfer_switch/{index}/vSpplyV,float,0,"telemetry,transfer_switch",Supply voltage,ssm_owner,
105
+ /ess/config/dcm/mode_param/control_mode,str,STANDBY,"ess,config",ESS control mode,ssm_owner,ssm_owner
106
+ /ess/config/dcm/control_param/min_customer_soc,float,0.30,"ess,config","Minimal customer SoC is used to calculate corresponding system soc threshold min_soc, should be between 0.0 and 1.0 including borders",ssm_owner,ssm_owner
@@ -0,0 +1,35 @@
1
+ # This example demonstrates how to use the PVSFCGIClient class to
2
+ # interact with a Sunpower PVS6 gateway using basic authentication.
3
+ #
4
+
5
+ import asyncio
6
+ import aiohttp
7
+ import logging
8
+
9
+ from pypvs.pvs_fcgi import PVSFCGIClient
10
+
11
+ logging.basicConfig(level=logging.DEBUG)
12
+
13
+ # Example
14
+ async def main():
15
+ async with aiohttp.ClientSession() as session:
16
+ pvs_serial = "ZT192585000549A1072"
17
+ # The username is: ssm_owner
18
+ # The password is: the last 5 characters of the PVS serial number
19
+ client = PVSFCGIClient(session, auth_user="ssm_owner", auth_password=pvs_serial[-5:])
20
+ client.pvs_url = "https://localhost:18443" # Replace with your PVS URL
21
+
22
+ # Use basic authentication with the username and password
23
+ client.set_pvs_details({
24
+ "serial": pvs_serial
25
+ })
26
+
27
+ # We don't need to call login_basic() because refresh of the session cookies
28
+ # is handled automatically by the PVSFCGIClient class.
29
+ # await client.login_basic()
30
+
31
+ response = await client.execute_post_request("/vars", params={"name": "/sys/info/uptime"})
32
+ print(f"Response: {response}")
33
+
34
+ if __name__ == "__main__":
35
+ asyncio.run(main())
@@ -0,0 +1,53 @@
1
+ # This is an example of how to use the PVS class to get data
2
+ # from a Sunpower PVS6 gateway using asyncio.
3
+ #
4
+
5
+ import time
6
+ import asyncio
7
+ import aiohttp
8
+ import logging
9
+
10
+ from pypvs.pvs import PVS
11
+ from pypvs.exceptions import ENDPOINT_PROBE_EXCEPTIONS
12
+
13
+ logging.basicConfig(level=logging.DEBUG)
14
+
15
+ async def fetch_data(pvs):
16
+ # get the uptime
17
+ uptime = await pvs.getVarserverVar("/sys/info/uptime")
18
+ # print both the uptime and the local time
19
+ print(f">>>>>> Uptime: {uptime}, Local time: {time.time()}")
20
+
21
+ livedata = await pvs.getVarserverVars("/sys/livedata")
22
+ # print livedata well formatted
23
+ print(">>>>>> LiveData:")
24
+ for key, value in livedata.items():
25
+ print(f"{key}: {value}")
26
+
27
+ # Example
28
+ async def main():
29
+ host = "192.168.11.29"
30
+
31
+ async with aiohttp.ClientSession() as session:
32
+ pvs = PVS(session=session, host=host, user="ssm_owner")
33
+ try:
34
+ await pvs.discover()
35
+ pvs_serial = pvs.serial_number
36
+ # The password is the last 5 characters of the PVS serial number
37
+ pvs_password = pvs_serial[-5:]
38
+ await pvs.setup(auth_password=pvs_password)
39
+ logging.info(f"Connected to PVS with serial: {pvs_serial}")
40
+ except ENDPOINT_PROBE_EXCEPTIONS as e:
41
+ logging.error(f"Cannot communicate with the PVS: {e}")
42
+ return
43
+
44
+ # setup a periodic task to fetch data every 5 seconds
45
+ while True:
46
+ await fetch_data(pvs)
47
+ await asyncio.sleep(5)
48
+
49
+ if __name__ == "__main__":
50
+ try:
51
+ asyncio.run(main())
52
+ except KeyboardInterrupt:
53
+ print("Exiting...")
@@ -0,0 +1,58 @@
1
+ # This is an example of how to use a PVS updater to get data
2
+ #
3
+
4
+ import asyncio
5
+ import aiohttp
6
+
7
+ from pypvs.pvs import PVS
8
+ from pypvs.updaters.ess import PVSESSUpdater
9
+ from pypvs.models.pvs import PVSData
10
+ from pypvs.models.common import CommonProperties
11
+ from pypvs.const import SupportedFeatures
12
+ from pypvs.exceptions import ENDPOINT_PROBE_EXCEPTIONS
13
+
14
+ import logging
15
+ logging.basicConfig(level=logging.DEBUG)
16
+
17
+ # Example
18
+ async def main():
19
+ host = "localhost:18443"
20
+
21
+ async with aiohttp.ClientSession() as session:
22
+ pvs = PVS(session=session, host=host, user="ssm_owner")
23
+ try:
24
+ await pvs.discover()
25
+ pvs_serial = pvs.serial_number
26
+ # The password is the last 5 characters of the PVS serial number
27
+ pvs_password = pvs_serial[-5:]
28
+ await pvs.setup(auth_password=pvs_password)
29
+ logging.info(f"Connected to PVS with serial: {pvs_serial}")
30
+ except ENDPOINT_PROBE_EXCEPTIONS as e:
31
+ logging.error(f"Cannot communicate with the PVS: {e}")
32
+ return
33
+
34
+ common_properties = CommonProperties()
35
+ ess_updater = PVSESSUpdater(pvs.getVarserverVar, pvs.getVarserverVars, common_properties)
36
+
37
+ discovered_features = SupportedFeatures(0)
38
+ ess_is_there = await ess_updater.probe(discovered_features)
39
+ if not ess_is_there:
40
+ print("No ESS found for that PVS on varserver")
41
+ return
42
+
43
+ # setup a periodic task to fetch data every 5 seconds
44
+ pvs_data = PVSData()
45
+ while True:
46
+ await ess_updater.update(pvs_data)
47
+
48
+ print(">>>>>> ESS:")
49
+ for ess in pvs_data.ess.values():
50
+ print(f"{ess.serial_number}: {ess}")
51
+
52
+ await asyncio.sleep(5)
53
+
54
+ if __name__ == "__main__":
55
+ try:
56
+ asyncio.run(main())
57
+ except KeyboardInterrupt:
58
+ print("Exiting...")