dgibson / python-smadata2

Python code for communicating with SMA photovoltaic inverters within built in Bluetooth
GNU General Public License v2.0
23 stars 12 forks source link

sma2mon download: AttributeError: 'Connection' object has no attribute 'serial' #1

Closed mitchpitch closed 6 years ago

mitchpitch commented 7 years ago

I get this error when downloading. The connection and status are working.

./sma2mon download standalone-inverter-0000 (SN: xyz) Traceback (most recent call last): File "./sma2mon", line 6, in smadata2.sma2mon.main() File "/home/pi/python-smadata2-master/smadata2/sma2mon.py", line 166, in main args.func(config, args) File "/home/pi/python-smadata2-master/smadata2/sma2mon.py", line 89, in download data = smadata2.download.download_inverter(ic, db) File "/home/pi/python-smadata2-master/smadata2/download.py", line 24, in download_inverter lasttime = db.get_last_historic(ic.serial) AttributeError: 'Connection' object has no attribute 'serial'

dgibson commented 7 years ago

First of all: hi.. you're the first person who's contacted me about this (other than people I already knew personally). I'm glad you're interested.

Just to set expectations; to this point sma2mon has been a project I've just worked on for my personal use. I made it available publicly as a "why not" (and through habit - I'm a free software developer in my day job). I'm certainly happy for other people to use it, and I'll do what I can to keep it working for them, but I have very limited time to spend on it.

So, looking at this specific problem. I think it means the inverter serial number hasn't been specified in the configuration file. For example, my config has:

$ cat .smadata2.json { "systems": [ { "name": "Sunny Scone", "pvoutput-sid": "26744", "inverters": [ { "name": "Inverter 1", "bluetooth": "00:80:25:A4:BE:37", "serial": "2130083553" }, { "name": "Inverter 2", "bluetooth": "00:80:25:A5:0B:F7", "serial": "2130083736" } ] } ] }

The serial number is used as a database key to store the results, which is why it's needed. I think it's essentially arbitrary, but I use the actual serial numbers physicall stamped on my inverters.

moozer commented 6 years ago

I am having this issue now also.

Looking at https://github.com/dgibson/python-smadata2/blob/d182250bc35b2fc65cbfa82676ed05f8a4f07eb3/smadata2/download.py#L23-L39

it seems that the code was never finished.

@dgibson I would like to have this functioning. My current solution is a C program that has stopped building, and I would like to move to something readable - like this project.

dgibson commented 6 years ago

The same problem as the original commenter?

My previous comment explains that you need to add each inverter's serial number to the configuration file. I'm not sure why you're concluding "the code was never finished".

The code to download instant and historical data from the inverter should work fine. Code to upload to pvoutput or similar was indeed, never finished.

moozer commented 6 years ago

That is good to hear - it is the download functionality that I want.

The ic parameter given to download comes from https://github.com/dgibson/python-smadata2/blob/d182250bc35b2fc65cbfa82676ed05f8a4f07eb3/smadata2/sma2mon.py#L87-L89

It is the invobject that holds serial and starttime. That one is not given to the function.

The way I see the above, it is a code issue, not a config issue.

dgibson commented 6 years ago

Oh! Good catch. That is indeed a bug, introduced by https://github.com/dgibson/python-smadata2/commit/fd2bc3c985e223c7b9cfd9de0efc25e460cbd265. The download_inverter function is supposed to take the config object (inv) not the connection object (ic).

Aha! And I just found I have a fix in my local tree, which I forgot to push out. Sorry about that.

I've just polished up that fix, along with a couple of other more recent extensions and pushed it out.

Give that a shot.

moozer commented 6 years ago

Progress - now I get a new error :-)

➜ ./sma2mon --config roejlegaard.json download
Inverter 1 (SN: 2130012345)
Traceback (most recent call last):
  File "./sma2mon", line 6, in <module>
    smadata2.sma2mon.main()
  File "/mnt/storage/moz/git/python-smadata2/smadata2/sma2mon.py", line 164, in main
    args.func(config, args)
  File "/mnt/storage/moz/git/python-smadata2/smadata2/sma2mon.py", line 87, in download
    data = smadata2.download.download_inverter(inv, db)
  File "/mnt/storage/moz/git/python-smadata2/smadata2/download.py", line 32, in download_inverter
    data = sma.historic(lasttime+1, now)
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

Since my database is empty "lasttime" is None. What would be a good default value?

dgibson commented 6 years ago

Ah, right. So there's actually already a fallback in there if the db is empty - you can set the 'start-time' property in the configuration. The intention is that this should contain the date the inverter was installed / activated (and will therefore will be before the earliest reading).

moozer commented 6 years ago

I added "start-time": "2015-01-01 00:00" to the config and now it works.

Thanks for the help.

Just FIY: The program I used to use is here: https://github.com/moozer/smatool-source It might contain relevant details if you want to dig more into the protocol. It is a program I found somewhere, and it has been useful for a while.

dgibson commented 6 years ago

Good to hear it's working now.

I'm aware of smatool, it's protocol knowledge is... pretty limited. Or at least it was when I looked at it a few years ago. It was what I tried to use when I first set up my system. I gave up on it and wrote my own because 1) I had to suppress retching anytime I glanced at its code and 2) it has (had?) a bug which broke it totally for me. It doesn't really decipher the protocol - basically just has a canned set of commands / responses with some pieces to substitute. Because of that it applies PPP escaping / de-escaping to its whole packets, whereas PPP is actually just one inner protocol layer. Most people get away with that because the rfcomm packets which enclose the PPP fragments won't trigger the escaping. But it so happens that the MAC address of one of my inverters has a sequence that triggers the escaping, so everything breaks. Fixing it there isn't terribly straightforward, because as mentioned it just uses canned data and isn't really aware of where the PPP portion begins. In theory I guess I could have fixed it in-situ, but then there was the aforementioned retching. Plus, of course, I didn't realize that escaping/layering was the problem until I'd done enough protocol analysis that I was halfway to my own implementation anyway.