jneilliii / OctoPrint-TPLinkSmartplug

105 stars 57 forks source link

HS110 energy monitoring #17

Closed 3axis closed 5 years ago

3axis commented 7 years ago

For the extra £5 I got the energy monitoring version, it would be nice if the plug-in could be extended to use this feature.

spaelectronics commented 6 years ago

I agree with this. This would be very helpful!

jneilliii commented 6 years ago

I'm not familiar with that model and what those other features are, but what kind of information would you guys like to see and where?

3axis commented 6 years ago

I will take a look tonight and put some info here and pictures if I can.

3axis commented 6 years ago

The Kasa app shows a summary of todays usage in kWh and runtime in hours. All to 2 decimal places.

Clicking on the > arrow for usage gives: Today: Current power W, Total Consumption kWh Past 7 days: Daily Average kWh, Total Consumption kWh Past 30 days: Daily Average kWh, Total Consumption kWh

Clicking on the > arrow for runtime gives: Today: Current Runtime hours, Total Runtime hours Past 7 days: Daily Average hours, Total Runtime hours Past 30 days: Daily Average hours, Total Runtime hours

A stats page showing this could be useful.

Options (tick box on stats page) to shown one or more of these pairs on the top bar would be good.

Perhaps default (ticked) to Total Consumption kWh and Total Runtime hours pair showing in the top bar, for example "Total: 2.55 kWH, 6.5 hrs".

adammhaile commented 6 years ago

+1 - Have that model too and this would be great.

KissmanCZ commented 6 years ago

Still nothing? Please ass this feature, thanks.

jneilliii commented 6 years ago

Sorry guys, been busy with work. I'll probably have time this weekend to work on this, but because I don't have that model will lead on you heavily for testing. Will post here with links when ready.

jneilliii commented 6 years ago

I have an initial framework that I need to get one of you to install and send me back the plugin_tplinksmartplug_debug.log file so I can check on how the response comes back from the plug. Make sure that debug logging is enabled in the plugin settings first and then install using the url below in plugin manager and once OctoPrint reloads it should put the information I need in that file. I'm going to start with the realtime statistics, as that seems to be the most useful information initially and will potentially expand that later for the monthly and yearly stats.

https://github.com/jneilliii/OctoPrint-TPLinkSmartplug/archive/0.9.7.zip

KissmanCZ commented 6 years ago

Ok ;) wait i second, going to install ;)

KissmanCZ commented 6 years ago

plugin_tplinksmartplug_debug(1).log

and I am lost ability to power up or down my devices with this version....

jneilliii commented 6 years ago

Perfect, thanks. This will help a lot. I'll be able to work on this again maybe tomorrow night after work. Just have to figure out where I actually want to add this to the UI. Navbar seems to make sense, but because it's possible to have more than one plug, it might make more sense as a pop-up or hover tooltip to the icon to show the data.

Based on your log this is the pertinent information I think, just have to figure out how to translate it. Looks like your plug has been on for 1 hour with current of 23 mA, what is that voltage reading?

{'emeter': {'get_realtime': {'total_wh': 1, 'current_ma': 23, 'power_mw': 0, 'voltage_mv': 247579, 'err_code': 0}}
jneilliii commented 6 years ago

@KissmanCZ, if you don't mind it would be helpful if you were to turn on the polling option and re-post that debug log file after performing a print, just to see how the numbers change over time. This would verify that the realtime data is fluctuating as expected and possibly help me figure out the math involved and how to display this data.

I don't think I want to get into full on logging of the realtime data, but eventually I will add in the other query options available through the api calls for power this month, power this year, etc. as documented here and here.

jneilliii commented 6 years ago

I just noticed your note about not being able to toggle the power with this version. Nothing I added should have effected that at all, but I could be wrong. Looking through the log it looks like it's sending the off command and then checks the status and that is saying the plug turns off. Is it just that the icon never changes to off and stays green? If you refresh the page, does it change the icon? There was another issue posted that sounded like that with the last release prior to this testing version. They experienced the plug switch and then instantly switch back to the previous state.

KissmanCZ commented 6 years ago

Voltage will be voltage_mv': 247579 in miliVolts, so 247,579 V. I can cross check values with original TP-Link app.

Regarding power off & on. If socket is already on, I can turn it off with plugin but green icon will rotate indefinitely. When I refresh page, green icon will stop rotating but still will be green (and socket will be off).

If socket is off, I am not able to power on. Only green icon rotating. When I refresh page, icon will not rotate anymore.

KissmanCZ commented 6 years ago

plugin_tplinksmartplug_debug(2).log Going to create log during print :) 20 min.

jneilliii commented 6 years ago

Now I'm a little worried...looks like it's returning multiple lines with different information.

[2018-08-31 00:08:07,490] DEBUG: {'emeter': {'get_realtime': {'current': 0.83259, 'total': 0.041, 'voltage': 308.482856, 'power': 247.542432, 'err_code': 0}}
[2018-08-31 00:08:11,163] DEBUG: {'emeter': {'get_realtime': {'total_wh': 10, 'current_ma': 21, 'power_mw': 0, 'voltage_mv': 249109, 'err_code': 0}}
[2018-08-31 00:09:06,132] DEBUG: {'emeter': {'get_realtime': {'current': 0.72872, 'total': 0.045, 'voltage': 308.843947, 'power': 214.437271, 'err_code': 0}}
[2018-08-31 00:09:06,284] DEBUG: {'emeter': {'get_realtime': {'total_wh': 10, 'current_ma': 21, 'power_mw': 0, 'voltage_mv': 249454, 'err_code': 0}}
[2018-08-31 00:10:06,236] DEBUG: {'emeter': {'get_realtime': {'current': 0.693164, 'total': 0.048, 'voltage': 308.837316, 'power': 203.561036, 'err_code': 0}}
[2018-08-31 00:10:06,383] DEBUG: {'emeter': {'get_realtime': {'total_wh': 10, 'current_ma': 20, 'power_mw': 0, 'voltage_mv': 249455, 'err_code': 0}}
[2018-08-31 00:11:06,340] DEBUG: {'emeter': {'get_realtime': {'current': 0.100264, 'total': 0.049, 'voltage': 309.478414, 'power': 9.699506, 'err_code': 0}}
[2018-08-31 00:11:06,485] DEBUG: {'emeter': {'get_realtime': {'total_wh': 10, 'current_ma': 21, 'power_mw': 0, 'voltage_mv': 249892, 'err_code': 0}}
[2018-08-31 00:12:06,445] DEBUG: {'emeter': {'get_realtime': {'current': 0.103301, 'total': 0.049, 'voltage': 309.534815, 'power': 9.921544, 'err_code': 0}}
[2018-08-31 00:12:06,575] DEBUG: {'emeter': {'get_realtime': {'total_wh': 10, 'current_ma': 21, 'power_mw': 0, 'voltage_mv': 249936, 'err_code': 0}}
[2018-08-31 00:13:06,494] DEBUG: {'emeter': {'get_realtime': {'current': 0.10446, 'total': 0.05, 'voltage': 309.538758, 'power': 9.911718, 'err_code': 0}}
[2018-08-31 00:13:06,726] DEBUG: {'emeter': {'get_realtime': {'total_wh': 10, 'current_ma': 20, 'power_mw': 0, 'voltage_mv': 249896, 'err_code': 0}}
[2018-08-31 00:14:06,941] DEBUG: {'emeter': {'get_realtime': {'current': 0.104055, 'total': 0.05, 'voltage': 309.472503, 'power': 9.902486, 'err_code': 0}}
[2018-08-31 00:14:07,082] DEBUG: {'emeter': {'get_realtime': {'total_wh': 10, 'current_ma': 21, 'power_mw': 0, 'voltage_mv': 249892, 'err_code': 0}}
[2018-08-31 00:15:06,625] DEBUG: {'emeter': {'get_realtime': {'current': 0.101442, 'total': 0.05, 'voltage': 309.340228, 'power': 9.943042, 'err_code': 0}}
[2018-08-31 00:15:06,731] DEBUG: {'emeter': {'get_realtime': {'total_wh': 10, 'current_ma': 21, 'power_mw': 0, 'voltage_mv': 249760, 'err_code': 0}}
[2018-08-31 00:16:06,768] DEBUG: {'emeter': {'get_realtime': {'current': 0.101174, 'total': 0.05, 'voltage': 309.660206, 'power': 9.876569, 'err_code': 0}}
[2018-08-31 00:16:06,988] DEBUG: {'emeter': {'get_realtime': {'total_wh': 10, 'current_ma': 21, 'power_mw': 0, 'voltage_mv': 250046, 'err_code': 0}}
jneilliii commented 6 years ago

Just made a slight change to try and thin down the logs to see if I was just recording more than necessary. Please turn off debug logging and reinstall from the same url as before. With polling enabled it should record just the energy response from the server to the debug log file.

This change should also isolate the energy commands from the on/off commands. I wasn't having the same issue as you were with powering on/off my device so not sure it this change will help in your situation or not, but it should put it back to the way it was before.

KissmanCZ commented 6 years ago

I have two HS110 in my setup ;)

/edit: i just downgraded to 0.9.6 and switching working again without any problems...

jneilliii commented 6 years ago

Ahh, that makes sense now. I just need to look at the other info then and figure out what the differences mean. I'm assuming one was connected to printer while printing and the other was either off or just not drawing any power?

jneilliii commented 6 years ago

Yep, looks like the plug "My Smart Plug" was turned off while "3D tiskarna" was powered on. So I'll need to adjust the information shown based on current state of being on or off. I'm assuming the information in the off state is some sort of summary information.

jneilliii commented 6 years ago

I just pushed a new update that will request the daily statistics for the current month and add that to the debug log file. That should be the last little bit I need to flush this out and figure out a path for development. Please reinstall using the 0.9.7 url above and send me back the log.

jneilliii commented 6 years ago

Just pushed an update to 0.9.7 version that I'll need to get some feedback on. for now I am just throwing the return data from the energy commands into the title attribute of the button. This should show the information upon hovering your mouse over the icon. Since I don't have a HS110 the return value is an error message.

image

If you guys could test and send me back the debug.log file I'll be able to push this new feature forward I think.

jneilliii commented 6 years ago

Just pushed a small update to use bootstrap tooltip for the data display.

image

KissmanCZ commented 6 years ago

This update deleted my second plug from plugin :( and reseted all setting for the first plug... and I am still not able to turn plug on. Status polling also not working. Only grey icon rotating now. plugin_tplinksmartplug_debug(3).log

jneilliii commented 6 years ago

I forgot to mention, it will actually wipe out the settings for all plugs, you have to reenter them for both plugs.

jneilliii commented 6 years ago

Ok, I just looked through this log, and I see where it is getting the status back from ip 192.168.99.235 and it's showing as being "on". Are there any errors in your browser's console window or in octoprint.log?

KissmanCZ commented 6 years ago

No errors in gui (only lost ability to power on/off plug - gray icon rotating all time). In octoprint log lot of errors:

KeyError: 'err_code'
2018-09-02 11:47:59,410 - tornado.access - ERROR - 500 POST /api/plugin/tplinksmartplug (::ffff:192.168.99.254) 93.51ms
2018-09-02 11:48:59,550 - octoprint - ERROR - Exception on /api/plugin/tplinksmartplug [POST]
Traceback (most recent call last):
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/server/util/flask.py", line 1140, in decorated_view
    return flask_login.login_required(func)(*args, **kwargs)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask_login.py", line 758, in decorated_view
    return func(*args, **kwargs)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/server/api/__init__.py", line 99, in pluginCommand
    response = api_plugin.on_api_command(command, data)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_tplinksmartplug/__init__.py", line 166, in on_api_command
    self.check_status("{ip}".format(**data))
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_tplinksmartplug/__init__.py", line 137, in check_status
    if response["emeter"]["err_code"] != 0:
jneilliii commented 6 years ago

Perfect, that's what I needed to see...I just pushed an update that should now fix the on/off issue. Please reinstall and let me know.

KissmanCZ commented 6 years ago

No, still not working :(

File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_tplinksmartplug/__init__.py", line 161, in on_api_command
    self.check_status("{ip}".format(**data))
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_tplinksmartplug/__init__.py", line 134, in check_status
    response = self.sendCommand('{"system":{"get_sysinfo":{}},"emeter":{"get_realtime":{},"get_daystat":{"month":%d,"year":%d}}}' % (today.month, today.year),plugip)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_tplinksmartplug/__init__.py", line 226, in sendCommand
    return json.loads(self.decrypt(data[4:]))
  File "/usr/lib/python2.7/json/__init__.py", line 339, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 364, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 380, in raw_decode
    obj, end = self.scan_once(s, idx)
ValueError: Unterminated string starting at: line 1 column 1014 (char 1013)
2018-09-09 19:40:36,261 - tornado.access - ERROR - 500 POST /api/plugin/tplinksmartplug (::ffff:192.168.99.254) 219.26ms
2018-09-09 19:40:47,928 - octoprint - ERROR - Exception on /api/plugin/tplinksmartplug [POST]
Traceback (most recent call last):
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/server/util/flask.py", line 1140, in decorated_view
    return flask_login.login_required(func)(*args, **kwargs)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/flask_login.py", line 758, in decorated_view
    return func(*args, **kwargs)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/server/api/__init__.py", line 99, in pluginCommand
    response = api_plugin.on_api_command(command, data)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_tplinksmartplug/__init__.py", line 161, in on_api_command
    self.check_status("{ip}".format(**data))
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_tplinksmartplug/__init__.py", line 136, in check_status
    if not response["emeter"]["err_code"]:
KeyError: 'err_code'
2018-09-09 19:40:47,942 - tornado.access - ERROR - 500 POST /api/plugin/tplinksmartplug (::ffff:192.168.99.254) 93.98ms
jneilliii commented 6 years ago

Ok, hopefully I got it now. Turn off the polling option in settings and then reinstall from the 0.9.7 url just like before.

physguyk commented 6 years ago

Did you ever get your hands on the HS110 to play with for testing this? If not, do you have a patreon or paypal or google wallet or whatever cool kids are using these days for money transfers, such that I could send you the money for one, and maybe some extra to pay for the time you're putting into this? It's a very handy plugin, so I'd like to support its development.

jneilliii commented 6 years ago

No, I haven't. If you're so inclined to send money via PayPal you can using jneilliii@gmail.com.

horendus commented 6 years ago

Hi, did you receive a HS110 yet? I'm really looking forward to having energy monitoring for these plugs showing in octoprint and ultimately, have it logged/included in the Print History plugin.

Are you still working on this? I will donate to get this functionality.

jneilliii commented 6 years ago

Nope haven't gotten one yet.

jneilliii commented 6 years ago

But I did just get the funds to get one, so as soon as I order and it gets here I'll start looking into it.

horendus commented 6 years ago

Sounds good. Ill put through a small donation to help spur you along. What are you thoughts on having it log energy usage of a print? It looks like what you have played around so far with is getting it to show the current power draw but the real end goal here would be showing energy usage of a total print (as well as adding the current power draw to the temp plotted chart. Do you know yet what other emeter values are returned when you poll the plug? Does it have a running total? That would make it very easy to figure out the power usage of a print by recording the value before and then after the print.

jneilliii commented 6 years ago

I haven't really put much thought into logging yet, just getting the values to display somewhere will be my first goal. What are your thoughts on where that should be? My initial testing was with the title attribute of the button.

jneilliii commented 6 years ago

I've ordered the plug, should be here on Thursday and I'll be able to start work on the enhancements this weekend. I'll see about some form of logging during print, never done that before, but I assume I should be able to accomplish that with some form of yaml storage provider.

horendus commented 6 years ago

Agreed, getting the current/live emeter values displaying in the UI is the first logical step. I haven't done a deep dive on the ocotoprint plugin API (yet) but it would be good to inject it into the STATE display on the left hand side of the UI. Iv seen other plugin add extra items to this display so it must be achievable.

In terms of displaying logging, having it display in a running list in the TPLINK Plugin setting menu would be a good start but injecting the final value into the "Print History" plugin (https://plugins.octoprint.org/plugins/printhistory/) would be the ultimate solution rather than trying to implement a whole new Print History menu.

horendus commented 6 years ago

The energy usage stats of a print would be best pulled directly from the TPLINK plug as this is already a baked in function and trying to recalculate within octoprint based on reading the live stats could introduced issues with accuracy and potentially allot of work.

Looking at the TPLINK Smart Plug API there is an option called .eraseStats.

I would be inclined to suggest doing an .eraseStats at the start of a print and then at the end of a print pulling the .getMonthStats. I wouldn't recommend pulling the .getDayStats as you would be limiting the reading to a maximum of 24 hours and you also run the risk of the day rolling over mid print which would throw the final calculation out.

jneilliii commented 6 years ago

Oh yeah. Doing that in the state panel does make a ton of sense. Would probably configure updates using the print progress mixin which would poll the current status at each percent increase.

Getting the integration incorporated into the print history plugin may be tricky as it appears to be utilizing a sqllite database backend and there potentially could be locking issues if trying to update at the same time, etc. but I'll take a deeper look into that code once I get the first part working right. It may eventually require a collaboration with that plugin's author.

horendus commented 6 years ago

Yes it looks like the File History plugin would need to be modified in a few ways

Add an extra field into its database for energy usage Add extra html column for displaying the energy usage value Modifying the database write at the end of the print to include the energy usage Modifying the Table Display to include fetching the energy usage value

Perhaps the prints energy usage can be written to a temp location (before the Print History database entry is made) which is then referenced by the Print History plugin when writing the database entry?

Im not sure how you would make sure this value is written BEFORE the Print History database write though. Thoughts?

jneilliii commented 5 years ago

That's why I think integration is going to be tricky. Anyway, I've got my 2 pack of plugs in and powered one up and connected and my dev branch is pulling the data exactly like I thought it would, just now have to update the code to put the information into the state sidebar panel.

image

jneilliii commented 5 years ago

Got it working well in the 0.9.7 branch. Will probably make this an official release after some more testing before moving on to the logging stuff.

I haven't integrated the print progress approach yet either, but the polling option is updating in the sidebar state panel. Let me know what you guys think about the layout?

image

jneilliii commented 5 years ago

Just released version 0.9.7 that incorporates the print progress methods. Will keep this issue/request open to deal with the logging aspect of the request.

KissmanCZ commented 5 years ago

I am not receiving values from my second plug :( and layout is not best... i am missing horizontal divider betwen plugin and % bar.

image

jneilliii commented 5 years ago

I was seeing that when I first set-up the plugs, but after a couple of off/on toggles it finally got caught up and was in sync. I did take the divider out between the last plug and progress bar. I was just setting it up to be the same as default state panel. I agree with you though, adding the divider back in at the end does look better.

KissmanCZ commented 5 years ago

And rounded values should be great I think. 65,937307 is not sexy 💃

KissmanCZ commented 5 years ago

And maybe you can put entire your data into separate box :) under files box.

jneilliii commented 5 years ago

Putting the info in its own side panel would have been a lot easier than forcing it into the state panel. I'll probably make that change.