sunspec / pysunspec Goto Github PK
View Code? Open in Web Editor NEWPython SunSpec Tools
License: MIT License
Python SunSpec Tools
License: MIT License
Hi there,
I've the same issue as mentioned in the last comment of #9,
I'm writing 1 to reg 40375 (you have to choose the reg -1, so 40374) and get a "write ok".
But when reading it, it hasn't been changed. Pls. have a look:
modbus write 10.0.0.11 502 126 40374 1
using MODBUS TCP
dev : 10.0.0.11 9600N81
addr: 126
op : write
reg : 9DB6 (40374), data: 1
connecting...
Connecting to 10.0.0.11
[00][01][00][00][00][09][7E][10][9D][B6][00][01][02][00][01]
Waiting for a confirmation...
<00><01><00><00><00><06><7E><10><9D><B6><00><01>
write ok
isn't working, result is:
modbus read 10.0.0.11 502 126 40374
using MODBUS TCP
dev : 10.0.0.11 9600N81
addr: 126
op : read
reg : 9DB6 (40374), num: 1
connecting...
Connecting to 10.0.0.11
reading with function code 0x03
[00][01][00][00][00][06][7E][03][9D][B6][00][01]
Waiting for a confirmation...
<00><01><00><00><00><05><7E><03><02><00><00>
reg 9DB6: 0000
Writing a 2 does the same, just 1 and 2 are allowed. Reading always shows 0, hmpf.
And the battery isn't loading.
SMA support answered: "We haven't any infos concerning that, sorry."
Fun, isn't it?
Thx a lot in advance for any hints!
smeop
I‘ve noticed that SMA inverters use maximum unsigned values or minimum signed values in the respective data type number to indicate a NaN value. For example, model 101 single phase inverters will do so for phases B and C. This behaviour is documented by SMA.
Is this behaviour covered by the sunspec standard and this library? Couldn‘t find it in either code or specs I‘ve looked at?
Run the make_xls tool. Now it gets this error. This was working before.
Error loading model 00016 at C:\Python27\lib\site-packages\sunspec\core..\models\smdx\smdx_00016.xml: Unknown point type: uint64
Expected behaviour
A git clone should work out of the box or error / warn if dependencies are missing.
Actual behaviour
Git clone is installed correctly in develop mode. Module can be imported, client can be instantiated, but has the attributes client.model_1
, client.model_111
, ... instead of the expected client.common
, client.inverter
, ...
Steps to reproduce
git clone https://github.com/sunspec/pysunspec
pip install -e pysunspec
and then try an example such as https://pysunspec.readthedocs.io/en/latest/pysunspec.html#interacting-with-a-sunspec-device.
Suggested fix
Error out or warn the user / developer that the model definitions could not be found.
Notes
The README states that the clone should have --recursive
for the git submodules, but that may be overlooked in development, customized or automated installations. This is to warn / fail early in case of an inconsistent and non-functioning installation.
I have a couple of device types specifically 64113 and 64114 that don't have mappings in your release. How can I pull specific registers from them? I'd like to pull the whole block if possible.
I tried to do something like:
d.model_64113['40644']
That doesn't seem to work.
hi
i try to test the installation with Python3.6 using python -m unittest discover -v sunspec and get errors
Ran 40 tests in 0.046s
FAILED (errors=14)
Does pysunspec support Python3 already ?
Thanks
I have cloned pysunspec with command:
"$ git clone --recursive https://github.com/sunspec/pysunspec.git"
But i don't know why i have older version of submodule (models), in newest version brand:master manifest.py have:
...except Exception as e:
older one which was cloned with --recursive have:
...except Exception, e:
There are similar _methods in the ModbusClientRTU
and ModbusClientDeviceTCP
classes and so I thought I would do a comparison of the _read method to see if there's interest in creating something along the lines of a ModbusClientBase
class. Below is a pseudo code draft of how such a class might look.
class ModbusClientBase:
def _read(addr, count, op=FUNC_READ_HOLDING, trace_func=None, slave_id=None):
resp = ''
len_found = False
except_code = None
if slave_id is not None: #an RTU instance instead of TCP
len_remaining = #RTU version
req_structure = #RTU structure for the req struct command
trace_func_structure = #RTU structure for the trace func inputs
else: #TCP instance and not RTU instance
len_remaining = #TCP version
req_structure = #TCP structure for the req struct command
trace_func_structure = #TCP structure for the trace func inputs
req = struct.pack(req_structure, #Maybe a list containing the other TCP vs RTU specific arguments)
if self.trace_func: #RTU has trace_func as an input and TCP has it attached to self. Should a uniform method be chosen?
s = # This portion would need to be dynamically constructed based on TCP vs RTU
for c in req:
s += '%02X' % (ord(c))
self.trace_func(s)
# The TCP and RTU differ in their send methods and so binding a brief function in
# the above if statement to a variable `send` then call it here. For example, in
# the TCP case send = self.socket.sendall
while len_remaining > 0:
# Same idea here for a `receive` variable as the `send` variable listed above
c = receive(len_remaining)
len_read = len(c)
if len_read > 0:
resp += c
len_remaining -= len_read
if len_found is False and len(resp) >= #Dynamically set original len_remaining based on TCP vs RTU:
if not (ord(resp[#TCP VS RTU specific value]) & 0x80): #This statement
# appears in the while loop in the RTU version and outside the loop in
# the TCP version
else:
raise ModbusClientError('Response timeout')
if trace_func:
s = # This portion is RTU vs TCP specific and would need to be structured in the first
# if statement
for c in resp:
s += '%02X' % (ord(c))
trace_func(s)
# There's a CRC check in RTU version but not TCP version. I am not familiar with CRC and so
# I don't know if this is something that should be in both
if except_code:
raise ModbusClientException('Modbus exception %d' % (except_code))
return resp[# This splice depends on RTU vs TCP and would need to be configured in the first if statement]
The ModbusClientRTU._read method can be found at here and the ModbusClientDeviceTCP._read method can be found here.
Pros:
Cons:
Masking exceptions often makes it harder to understand and fix the problem, not easier. For example, running unit tests without having the models cloned (such as in #35 and others) results in this unhelpful message.
======================================================================
ERROR: test_client_device (sunspec.core.test.test_client.TestClientDevice)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/epc/t/612/pysunspec/sunspec/core/test/test_client.py", line 48, in test_client_device
pathlist=self.pathlist)
File "/epc/t/612/pysunspec/sunspec/core/device.py", line 175, in from_pics
raise SunSpecError('Error loading PICS: %s' % str(e))
SunSpecError: Error loading PICS: Block index out of range: 1
That is masking a slightly better custom message which would have read:
Model file for model model 1 not found
which is masking the actually useful (and automatic) message:
[Errno 2] No such file or directory: '/epc/t/612/pysunspec/sunspec/core/../models/smdx/smdx_00001.xml'
Now certainly there are times that useful information can be added to a standard message. Above could be enhanced by a mention of the models
subrepo and the search path feature so that a user/developer can look at the docs related to those topics.
In Python 3 you can simply raise ... from ...
as below but I have not yet found a clean 2/3 compatible way to get a result like this.
altendky@tp:~$ cat rf.py
try:
raise Exception('inner')
except Exception as e:
raise Exception('outer') from e
altendky@tp:~$ python3 rf.py
Traceback (most recent call last):
File "rf.py", line 2, in <module>
raise Exception('inner')
Exception: inner
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "rf.py", line 4, in <module>
raise Exception('outer') from e
Exception: outer
Regardless of chaining, is there any interest in discussing improving the clarity of the errors?
I'm testing a Outback AXS Port with a FlexMax 60 Solar Charger. I have pysunspec setup on Ubuntu and have successfully connected to the AXS Port and inserted data from the FlexMax block (64112) into InfluxDB for Grafana. The problem i'm having is when i try to read the actual AXS Port block (64110), i'm getting a error on the read() saying either Connection Refused, Connection Reset By Peer, or Broken Pipe. I'm not understanding why this error is happening only when reading this particular block. Anybody have any ideas? I'm new to Python, just wondering what I could possibly be doing wrong.
--user
hazards mixing library versions unexpectedly and installing into the system can corrupt entire installations in Linux.setup.py
directly so as to handle all dependencies at least. Also, don't use easy_install
.sudo
to install. It's not consistent but lots of people have destroyed their python installations by doing this. The issue is that you end up mixing pip package management with the Linux system's package management and they don't necessarily cooperate well.Receive following error on running the test file:
sudo python pysunspec_test.py
pySunSpec version: 1.0.8
Test device path: /usr/local/lib/python2.7/dist-packages/sunspec/core/test/devices
Traceback (most recent call last):
File "pysunspec_test.py", line 13, in
test.test_all()
File "/usr/local/lib/python2.7/dist-packages/sunspec/core/test/test_all.py", line 58, in test_all
(count_run, count_passed, count_failed) = module.test_all(pathlist, stop_on_failure)
File "/usr/local/lib/python2.7/dist-packages/sunspec/core/test/test_device.py", line 577, in test_all
if test(pathlist) is True:
File "/usr/local/lib/python2.7/dist-packages/sunspec/core/test/test_device.py", line 418, in test_device_from_pics
d1.from_pics(filename='pics_test_device_1.xml', pathlist=pathlist)
File "/usr/local/lib/python2.7/dist-packages/sunspec/core/device.py", line 127, in from_pics
raise SunSpecError('Error loading PICS: %s' % str(e))
sunspec.core.util.SunSpecError: Error loading PICS: Block index out of range: 1
What could be the reason ?
Please feel free to remove this if you think it is not an issue or relevant and also correct me if I am wrong but I believe the pysunspec library is incompatible with SMA's sunspec implementation in the controls model (123).
SMA defines some of its control registers as "Parameter for PV system control" which are WO as opposed to sunspec's definition of RW.
This means that there is no point object created when a read() occurs for these registers, namely, Conn, WMaxLimPct, etc. Therefore the point member value_sf is never set even though there is a valid sf_point member which is of type ScaleFactor. This results in incorrect setting and reading of values as they are not scaled by the scale factor.
Note that:
Example:
m.controls.OutPFSet = 1
print m.controls.OutPFSet
1
print m.controls.model.points['OutPFSet']
Point: id = OutPFSet impl= True addr = 40353 value_base = 1 sf_value = -4
print m.controls.model.points['OutPFSet'].value_getter()
1
m.controls.OutPFSet = 0.66
print m.controls.OutPFSet
0
print m.controls.model.points['OutPFSet']
Point: id = OutPFSet impl= True addr = 40353 value_base = 0 sf_value = -4
print m.controls.model.points['OutPFSet'].value_getter()
0
m.controls.OutPFSet = 6600
print m.controls.OutPFSet
6600
print m.controls.model.points['OutPFSet']
Point: id = OutPFSet impl= True addr = 40353 value_base = 6600 sf_value = -4
print m.controls.model.points['OutPFSet'].value_getter()
6600
print m.controls.model.points['OutPFSet'].value_sf
None
print m.controls.model.points['OutPFSet'].sf_point.value_base
-4
Found a bug in version 1.0.7, sunspec/core/client.py line 197:
raise SunSpecClientError('Error reading model %s' % model_type)
should be:
raise SunSpecClientError('Error reading model %s' % self.model_type)
if type(c) == bytes and sys.version_info > (3,):
temp = ""
for i in c:
temp += chr(i)
c = temp
It seems that if we switch the read bytes to str
then they will never compare equal to the bytes
(byte string) below. Why are we trying to work with str
in py3 at all for generic incoming bytes? Sure, occasionally we'll want to decode some bytes to a string but not every byte and not with chr()
normally.
pysunspec/sunspec/core/client.py
Line 229 in 5242ea9
The original symptom is:
Traceback (most recent call last):
File "/home/altendky/st.pysunspec/Pysunspec_demo.py", line 188, in <module>
sys.exit(main(sys.argv[1:]))
File "/home/altendky/st.pysunspec/Pysunspec_demo.py", line 122, in main
d = sunspec.core.client.SunSpecClientDevice(**client_args)
File "/home/altendky/pysunspec/sunspec/core/client.py", line 775, in __init__
self.device.scan(progress=scan_progress, delay=scan_delay)
File "/home/altendky/pysunspec/sunspec/core/client.py", line 283, in scan
raise SunSpecClientError(error)
sunspec.core.client.SunSpecClientError: Device responded - not SunSpec register map
Despite having gotten a response starting with SunS
for base address 0
.
Wil be nice to export data to domoticz
https://www.domoticz.com/wiki/Domoticz_API/JSON_URL%27s
A configurable file where i can put idx to every readed value from inverter to domoticz sensors and domoticz ip, (eg. Localhost)
To trigger the script within domoticz is not a problem.
That wil be very cool.
Shouldn't version tags be v1.0.8
not v.1.0.8
? Ditto for v.1.0.7
. Previous ones look correct. Noticed this when I was preparing a vcversioner pull request.
git cloned your repo
sudo python setup.py install
$ pysunspec_test.py
pySunSpec version: 1.0.7
Test device path: /usr/local/lib/python2.7/dist-packages/sunspec/core/test/devices
Traceback (most recent call last):
File "/usr/local/bin/pysunspec_test.py", line 13, in <module>
test.test_all()
File "/usr/local/lib/python2.7/dist-packages/sunspec/core/test/test_all.py", line 42, in test_all
(count_run, count_passed, count_failed) = module.test_all(pathlist, stop_on_failure)
File "/usr/local/lib/python2.7/dist-packages/sunspec/core/test/test_device.py", line 561, in test_all
if test(pathlist) is True:
File "/usr/local/lib/python2.7/dist-packages/sunspec/core/test/test_device.py", line 402, in test_device_from_pics
d1.from_pics(filename='pics_test_device_1.xml', pathlist=pathlist)
File "/usr/local/lib/python2.7/dist-packages/sunspec/core/device.py", line 111, in from_pics
raise SunSpecError('Error loading PICS: %s' % str(e))
sunspec.core.util.SunSpecError: Error loading PICS: Block index out of range: 1
Checked the path shown:
$ ls /usr/local/lib/python2.7/dist-packages/sunspec/core/test/devices
mbmap_test_device_1_a.xml mbmap_test_device_2.xml mbmap_test_inverter_3.xml pics_test_inverter_2.xml
mbmap_test_device_1_b.xml mbmap_test_device_3.xml pics_test_device_1.xml
mbmap_test_device_1_c.xml mbmap_test_inverter_1.xml pics_test_device_2.xml
mbmap_test_device_1.xml mbmap_test_inverter_2.xml pics_test_inverter_1.xml
What am I missing?
Introduced in: 62ec0c6
on some systems (Debian based), you could be able to download it as a package (raspberry pi for ex.)
```
$ sudo apt-get install python-serial
```
If this is really needed (envs are the way to go for development and are described below) then it belongs down in the dependencies section below. It's quite out of place where it is now.
I found a bug the python 3 branch for model_11
The parsing of the MAC address should be different in py3.
In Python 3 the sock.recvfrom(...) call returns bytes while Python 2.7 recvfrom returns a string.
I couldn't find the line of code where sock.recvfrom(...) is called but this can be fixed in another way:
The function data_to_eui48 in core/util.py needs to be changed:
def data_to_eui48(data):
return '%02X:%02X:%02X:%02X:%02X:%02X' % (ord(data[2]), ord(data[3]), ord(data[4]), ord(data[5]), ord(data[6]), ord(data[7]))
data is no longer of type str but of type bytes.
Therefore the line
data=data.decode('utf-8','backslashreplace')
needs to be added.
A cleaner fix would be to search for all calls of sock.recvfrom(...) and change its output
I followed the instructions in the readme. It sends me to the latest release to download, unzip and install. I do that but use python3 instead of python for my commands. Then I try to run
python3 -m unittest discover -v sunspec
Attached are my errors. It looks like python2 compatible code.
Help..
I also tried a git clone and a setup for python3 I get this:
charles:pysunspec$ sudo python3 setup.py install
r```
unning install
running build
running build_py
running build_scripts
running install_lib
byte-compiling /usr/local/lib/python3.6/dist-packages/sunspec/models/smdx/manifest.py to manifest.cpython-36.pyc
File "/usr/local/lib/python3.6/dist-packages/sunspec/models/smdx/manifest.py", line 89
except Exception, e:
^
SyntaxError: invalid syntax
running install_scripts
changing mode of /usr/local/bin/suns.py to 777
running install_egg_info
Removing /usr/local/lib/python3.6/dist-packages/pysunspec-2.0.0.egg-info
Writing /usr/local/lib/python3.6/dist-packages/pysunspec-2.0.0.egg-info
But the tests run to completion.
Ran 45 tests in 0.529s
-
In our case we had mismatched smdx files vs. what our device was reporting and the result was that the model was loaded as empty without even having an error reported in the model's load_error
attribute.
Pull request to follow.
The following function in sunspec/core/util.py is intended to convert a text string to bytes for writing to a device (i.e. via Modbus).
def str_to_data(s, slen=None):
if slen is None:
slen = len(s)
if sys.version_info > (3,):
s = bytes(s, 'latin-1')
if slen < 16:
s += b'\x00'
slen += 1
return struct.pack(str(slen) + 's', s)
The part I don't understand is:
if slen < 16:
s += b'\x00'
slen += 1
pysunspec/sunspec/core/util.py
Line 148 in 5242ea9
Why is this here? It seems like all it does is add a null character if the string length is less than 16 bytes (or 8 Modbus registers). If you are unlucky enough to be writing an 8-register string, this causes an erroneous write of zero to the register immediately following the string. Indeed, this is how I discovered the bug.
Before I submit a pull request to delete these three lines of code, I'd like to understand what the intended purpose for adding the null byte is.
It seems like the only time you'd want to add a null byte would be to fill in the last word if the string had an odd number of characters. For this case, perhaps the check should be if slen % 2 == 1
instead of if slen < 16
.
As far as I can tell, these to_data
functions are only called with slen
as an even number (i.e., point_len * 2
), as in sunspec/core/client.py (on the last line in the code block below):
for block in self.blocks:
for point in block.points_list:
if point.dirty:
point_addr = int(point.addr)
point_len = int(point.point_type.len)
point_data = point.point_type.to_data(point.value_base, (point_len * 2))
As far as I can tell Travis isn't building for the master branch, only for PRs. It should build both.
I suspect that many users of this library will not be interested in Git and submodules etc. At least, those that want to distribute would find it a bit smoother if there were a wheel. There are always nuances but building a wheel is pretty much just venv/bin/python setup.py bdist_wheel
.
I'll try to get a PR for this. We've already got Travis going and I think this is pure Python so we should be able to build a universal wheel there. Probably also use https://github.com/habnabit/vcversioner (I've used it for my own project).
Traceback (most recent call last):
File "C:\Users\jkn\Documents\GitHub\models\makeXLS.py", line 78, in
writeSmdxFile (xls, smdxFile)
File "C:\Users\jkn\Documents\GitHub\models\makeXLS.py", line 38, in writeSmdxFile
model = device.model_type_get(getModelId(smdxFile))
File "C:\Python27\lib\site-packages\sunspec\core\device.py", line 525, in model_type_get
raise SunSpecError('Error loading model %s at %s: %s' % (model_id, filename, str(e)))
sunspec.core.util.SunSpecError: Error loading model 00016 at C:\Python27\lib\site-packages\sunspec\core..\models\smdx\smdx_00016.xml: Unknown point type: uint64
Small bug in sunspec.core.client lines 370 ..
` def getitem(self, key):
return self._get_property(name)
# return self.dict.get(key, None)
def __setitem__(self, key, item):
return self._set_property(name, item)
# self.__dict__.set(key, item)`
I'm guessing the "key" argument was meant to be renamed "name"?
The count attribute needs it suns.py suns_point_type_info defined
Here is the traceback when I try to get sunspec data out of our solaredge inverter with the suns.py
command:
$ suns.py -i 192.168.2.26 -a 1 -T 30
Timestamp: 2017-10-20T15:29:41Z
Traceback (most recent call last):
File "/usr/bin/suns.py", line 88, in <module>
sd.read()
File "/usr/lib/python2.7/dist-packages/sunspec/core/client.py", line 477, in read
self.device.read_points()
File "/usr/lib/python2.7/dist-packages/sunspec/core/client.py", line 101, in read_points
model.read_points()
File "/usr/lib/python2.7/dist-packages/sunspec/core/client.py", line 246, in read_points
raise SunSpecClientError(e)
sunspec.core.client.SunSpecClientError: Modbus read error: Connection error: [Errno 111] Connection refused
Note that the inverter modbus seems to work though as I'm able to retrieve data through a perl tcp modbus client:
$ perl mbtget -r3 -n 100 -a 40001 192.168.2.26
values:
1 (ad 40001): 28243
2 (ad 40002): 1
3 (ad 40003): 65
4 (ad 40004): 21359
5 (ad 40005): 27745
6 (ad 40006): 29253
7 (ad 40007): 25703
8 (ad 40008): 25888
9 (ad 40009): 0
10 (ad 40010): 0
11 (ad 40011): 0
12 (ad 40012): 0
13 (ad 40013): 0
14 (ad 40014): 0
15 (ad 40015): 0
16 (ad 40016): 0
17 (ad 40017): 0
18 (ad 40018): 0
19 (ad 40019): 0
20 (ad 40020): 21317
21 (ad 40021): 13110
22 (ad 40022): 14384
23 (ad 40023): 0
24 (ad 40024): 0
25 (ad 40025): 0
26 (ad 40026): 0
27 (ad 40027): 0
28 (ad 40028): 0
29 (ad 40029): 0
30 (ad 40030): 0
31 (ad 40031): 0
32 (ad 40032): 0
33 (ad 40033): 0
34 (ad 40034): 0
35 (ad 40035): 0
36 (ad 40036): 0
37 (ad 40037): 0
38 (ad 40038): 0
39 (ad 40039): 0
40 (ad 40040): 0
41 (ad 40041): 0
42 (ad 40042): 0
43 (ad 40043): 0
44 (ad 40044): 12336
45 (ad 40045): 12339
46 (ad 40046): 11826
47 (ad 40047): 12337
48 (ad 40048): 13824
49 (ad 40049): 0
50 (ad 40050): 0
51 (ad 40051): 0
52 (ad 40052): 14131
53 (ad 40053): 12593
54 (ad 40054): 12343
55 (ad 40055): 13123
56 (ad 40056): 0
57 (ad 40057): 0
58 (ad 40058): 0
59 (ad 40059): 0
60 (ad 40060): 0
61 (ad 40061): 0
62 (ad 40062): 0
63 (ad 40063): 0
64 (ad 40064): 0
65 (ad 40065): 0
66 (ad 40066): 0
67 (ad 40067): 0
68 (ad 40068): 2
69 (ad 40069): 101
70 (ad 40070): 50
71 (ad 40071): 102
72 (ad 40072): 102
73 (ad 40073): 65535
74 (ad 40074): 65535
75 (ad 40075): 65534
76 (ad 40076): 2374
77 (ad 40077): 65535
78 (ad 40078): 65535
79 (ad 40079): 65535
80 (ad 40080): 65535
81 (ad 40081): 65535
82 (ad 40082): 65535
83 (ad 40083): 15959
84 (ad 40084): 65534
85 (ad 40085): 5012
86 (ad 40086): 65534
87 (ad 40087): 24435
88 (ad 40088): 65534
89 (ad 40089): 18503
90 (ad 40090): 65534
91 (ad 40091): 6531
92 (ad 40092): 65534
93 (ad 40093): 30
94 (ad 40094): 7612
95 (ad 40095): 0
96 (ad 40096): 4280
97 (ad 40097): 65532
98 (ad 40098): 3785
99 (ad 40099): 65535
100 (ad 40100): 16202
Any idea what is wrong with suns.py
here?
PointType class is missing units attribute
Just a simple issue that prevents me to reuse the code with a new class which inherits Point. I can make a pull request to correct it if possible.
At sunspec.core.device.Model.load, line 709:
now:
point = point_class(block, point_type, str(point_addr))
what I'ld like:
point = point_class(block=block, point_type=point_type, addr=str(point_addr))
Hi,
Actually i would like to add a new Vendor specific Model to the smdx folder. As i understand an xml file needs to be created so that the pysunspec has access to this Vendor specific model. What i do not understand is the 'manifest.xml' in the smdx folder containing the md5 hash for all models.
Should an md5 hash be created for the new model, how can this be done.
Thanks for the help
Be careful with models submodule version.
For instance it does not contain this commit sunspec/models@4d923bb that defines new SF, and is not retrocompatible with current model in pysunspec git repo.
I'm trying to pull information out of a Outback AXS Port device.
d = client.SunSpecClientDevice(client.TCP, 0, None, None, None, None, ip_addr, 502, 2)
d.common.read()
print (d.common)
d.inverter.read()
print (d.inverter)
Output:
['common', 'model_64110', 'model_64120', 'inverter', 'model_64255', 'model_64113', 'model_64114']
Connection error: [Errno 111] Connection refused
The documentation isn't clear. What do I need to do? I've tried to close it and open a new connection. Fails there as well.
Hi,
Sorry but after reading many times the Interacting with a sunspec device, I'm still unable to understand how to read values from a device. I'm able to get data from common and inverter with
l_d.common.SN
In my case, I'm trying to get the informations from the power limitation of an SMA device (inverter manager). I have the following device models:
['common', 'model_11', 'model_12', 'inverter', 'nameplate', 'settings', 'status', 'controls', 'storage', 'volt_var', 'freq_watt_param', 'reactive_current', 'watt_pf', 'volt_watt',
'mppt', 'lvrt', 'hvrt', 'base_met', 'mini_met']
after using this code:
l_d = client.SunSpecClientDevice(client.TCP, l_modbus_slave_address, ipaddr=l_ip_address, timeout=l_timeout)
l_d.inverter.read() # retreives latest inverter model contents
l_d.common.read()
self.__logger.info("--> ************* device models *************: %s" % (l_d.models))
after that, I get followings when I do a:
self.__logger.info("-->inverter ************* reactive_current *************: %s" % (l_d.reactive_current))
=> => =>
inverter ************* reactive_current *************:
reactive_current (128):
How can I read the data of the 128 block? or storage? I still don't understand :-(
Thx !!
I would like to use the pysunspec module to retrieve data from a SMA Sunny Island, but it does not seem to work. I get the following message when using the suns.py
script:
$ suns.py -i 192.168.1.77
Error: Device responded - not SunSpec register map
So it says that the Sunny Island is not a SunSpec device, whereas the Sunny Island is supposed to speak the SunSpec modbus protocol, according to the SMA website: http://www.sma.de/en/products/battery-inverters/sunny-island-60h-80h.html#Downloads-206198
Any idea why it does not work?
Latest pip doesn't support Python 3.3. CPython support for 3.3 was dropped in September 2017. Do we need to retain 3.3 support?
This came up over in #46 where I set Travis to update pip (and setuptools and wheel). That isn't really related to the point of the PR so I've removed it.
Can't find the symbols and values for enumerated and bitfield types
I can successfully read values from a SMA Sunny Island device, but I got the following error when I try to set a value in a rw field:
$ python
Python 2.7.9 (default, Mar 1 2015, 12:57:24)
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sunspec.core.client as client
>>> d = client.SunSpecClientDevice(client.TCP, 126, ipaddr='192.168.1.77')
>>> d.models
['common', 'model_11', 'model_12', 'inverter', 'nameplate', 'settings', 'status', 'controls', 'storage', 'volt_var', 'freq_watt_param', 'reactive_current', 'watt_pf', 'volt_watt', 'mppt']
>>> d.storage.WChaMax
>>> d.storage.read()
>>> d.storage.WChaMax
6000
>>> d.storage.WChaMax = 5900
>>> d.storage.write()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/bruno/.virtualenvs/pysunspec/local/lib/python2.7/site-packages/sunspec/core/client.py", line 303, in write
self.model.write_points()
File "/home/bruno/.virtualenvs/pysunspec/local/lib/python2.7/site-packages/sunspec/core/client.py", line 242, in write_points
point.write()
File "/home/bruno/.virtualenvs/pysunspec/local/lib/python2.7/site-packages/sunspec/core/client.py", line 259, in write
self.block.model.device.write(int(self.addr), data)
File "/home/bruno/.virtualenvs/pysunspec/local/lib/python2.7/site-packages/sunspec/core/client.py", line 80, in write
raise SunSpecClientError('Modbus write error: %s' % str(e))
sunspec.core.client.SunSpecClientError: Modbus write error: Modbus exception: 1
According to SMA SunSpec documentation, WChaMax should be writable:
Modbus register number | SunSpec-Name | Description / Number code(s) | Type | Access |
---|---|---|---|---|
40372 | WChaMax | Setpoint for maximum active charging power. Reference value for WChaGra, WDisChaGra | uint16 | RW |
I also tried with other rw fields, and I also got an error.
Any idea of what is wrong ?
Been trying this library with an embedded device containing openWRT operating system. I could succesfully execute:
>>> import sunspec.core.client as client
>>> d = client.SunSpecClientDevice(client.RTU, 1, '/dev/ttyPORT1')
But when asking to print it all, I only get empty objects:
>>> print d
model_1 (1):
model_113 (113):
model_120 (120):
model_121 (121):
model_122 (122):
model_123 (123):
model_160 (160):
I have double checked that the device is in fact configured in Modbus RTU mode, 9600, 8N1. I have also checked that Fronius doesn't provide a different device id for sunspec-compatible readings.
Could you give a piece of advice on why this could happen?
smdx schema now includes a category attribute
Is there any interest in a pull request providing both Python 2 and Python 3 support?
Are the tests passing for other people? They fail with an exception for me. I'll work this out but figured it would be worth checking here.
/epc/t/313/pysunspec/venv/bin/python scripts/pysunspec_test.py
pySunSpec version: 1.0.7
Test device path: /epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/test/devices
Traceback (most recent call last):
File "scripts/pysunspec_test.py", line 13, in <module>
test.test_all()
File "/epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/test/test_all.py", line 58, in test_all
(count_run, count_passed, count_failed) = module.test_all(pathlist, stop_on_failure)
File "/epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/test/test_device.py", line 577, in test_all
if test(pathlist) is True:
File "/epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/test/test_device.py", line 418, in test_device_from_pics
d1.from_pics(filename='pics_test_device_1.xml', pathlist=pathlist)
File "/epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/device.py", line 127, in from_pics
raise SunSpecError('Error loading PICS: %s' % str(e))
sunspec.core.util.SunSpecError: Error loading PICS: Block index out of range: 1
Or, with an except
removed to see the original trace:
/epc/t/313/pysunspec/venv/bin/python scripts/pysunspec_test.py
pySunSpec version: 1.0.7
Test device path: /epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/test/devices
Traceback (most recent call last):
File "scripts/pysunspec_test.py", line 13, in <module>
test.test_all()
File "/epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/test/test_all.py", line 58, in test_all
(count_run, count_passed, count_failed) = module.test_all(pathlist, stop_on_failure)
File "/epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/test/test_device.py", line 577, in test_all
if test(pathlist) is True:
File "/epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/test/test_device.py", line 418, in test_device_from_pics
d1.from_pics(filename='pics_test_device_1.xml', pathlist=pathlist)
File "/epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/device.py", line 120, in from_pics
model.from_pics(m)
File "/epc/t/313/pysunspec/venv/lib/python2.7/site-packages/sunspec/core/device.py", line 481, in from_pics
raise SunSpecError('Block index out of range: %s' % (str(block_index)))
sunspec.core.util.SunSpecError: Block index out of range: 1
I tend towards keeping up to date so the reference to 2.4 (replaced by 2.5 over a decade ago) in the readme is a bit scary. But, whatever versions we intend to support should be included in testing. It looks like Travis only provides 2.7 and 2.6 (in the py2 family) so we may need to do something special (install old versions from a ppa?) or add another testing platform to get coverage. tox may also be a good piece of the puzzle.
So, is the 2.4-2.7 reference in the readme the official list of what we need to support? Latest patch level on each? Obviously with interest in py3 versions in the future.
When I try to run the tests on Linux (Debian) laptop, I get the following error:
$ pysunspec_test.py
pySunSpec version: 1.0.7
Test device path: /home/bruno/.virtualenvs/tmp-d3111b3cabc0fa7b/lib/python2.7/site-packages/sunspec/core/test/devices
Traceback (most recent call last):
File "/home/bruno/.virtualenvs/tmp-d3111b3cabc0fa7b/bin/pysunspec_test.py", line 13, in <module>
test.test_all()
File "/home/bruno/.virtualenvs/tmp-d3111b3cabc0fa7b/local/lib/python2.7/site-packages/sunspec/core/test/test_all.py", line 42, in test_all
(count_run, count_passed, count_failed) = module.test_all(pathlist, stop_on_failure)
File "/home/bruno/.virtualenvs/tmp-d3111b3cabc0fa7b/lib/python2.7/site-packages/sunspec/core/test/test_device.py", line 561, in test_all
if test(pathlist) is True:
File "/home/bruno/.virtualenvs/tmp-d3111b3cabc0fa7b/lib/python2.7/site-packages/sunspec/core/test/test_device.py", line 402, in test_device_from_pics
d1.from_pics(filename='pics_test_device_1.xml', pathlist=pathlist)
File "/home/bruno/.virtualenvs/tmp-d3111b3cabc0fa7b/local/lib/python2.7/site-packages/sunspec/core/device.py", line 111, in from_pics
raise SunSpecError('Error loading PICS: %s' % str(e))
Is there any way to use the SMA proprietary Modbus profile
http://files.sma.de/dl/24399/SMA_Modbus-de-en_V15.zip
With this package. I can connect to my inverter but I cant read all values.
Any way to include this in a release or how can I include it in my installation.
cheers
I've built a simple web application based on pysunspec and bottle to be able to query sunspec data through http requests.
It works very well when I use a single-threaded server like Python wsgiref, but I noticed that when I use a multi-threaded server like cherrypy, the following errors start to occur:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/bottle.py", line 862, in _handle
return route.call(**args)
File "/usr/lib/python2.7/dist-packages/bottle.py", line 1729, in wrapper
rv = callback(*a, **ka)
File "/usr/lib/python2.7/dist-packages/sunspecweb/server.py", line 13, in wrapper
return func(*args,**kwargs)
File "/usr/lib/python2.7/dist-packages/sunspecweb/server.py", line 125, in get_device_model
m.read()
File "/usr/lib/python2.7/dist-packages/sunspec/core/client.py", line 336, in read
self.model.read_points()
File "/usr/lib/python2.7/dist-packages/sunspec/core/client.py", line 197, in read_points
data = self.device.read(self.addr, self.len)
File "/usr/lib/python2.7/dist-packages/sunspec/core/client.py", line 82, in read
return self.modbus_device.read(addr, count)
File "/usr/lib/python2.7/dist-packages/sunspec/core/modbus/client.py", line 453, in read
data = self._read(addr + read_offset, read_count, op=op)
File "/usr/lib/python2.7/dist-packages/sunspec/core/modbus/client.py", line 407, in _read
c = self.socket.recv(len_remaining)
AttributeError: 'NoneType' object has no attribute 'recv'
Is pysunspec supposed to be thread safe?
The check for a valid SunSpec address fails when the address is 0. Should expand the check to base_addr is not None.
How do I completely remove the pysunspec library from my Debian Linux system. I don't see an uninstall script....RDK
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.