Giter VIP home page Giter VIP logo

smappy's Introduction

Smappy

Wrapper for the Smappee API See https://smappee.atlassian.net/wiki/display/DEVAPI/API+Methods

Local interface to read and control your Smappee over LAN

Installation

Via pip:

  • Mac & Linux: python3 -m pip install smappy or python -m pip install smappy
  • Windows: python.exe -m pip install smappy

Via git: git clone https://github.com/EnergieID/smappy.git

API Client Usage

Create a new client by supplying your Smappee client id and secret

s = smappy.Smappee(client_id, client_secret)

Authenticate using a Smappee username and password

s.authenticate(username, password)

Re-authentication using the refresh token is done automatically when the access token has expired.

API Requests

7 API requests are supported. The methods return the parsed JSON response as a dict.

Get Service Locations

s.get_service_locations()

Get Service Location Info

s.get_service_location_info(service_location_id)

Get Consumption

  • s.get_consumption(service_location_id, start, end, aggregation)
  • s.get_sensor_consumption(service_location_id, sensor_id, start, end, aggregation)

Start & End accept epoch (in milliseconds), datetime and pandas timestamps

Aggregation: 1 = 5 min values (only available for the last 14 days), 2 = hourly values, 3 = daily values, 4 = monthly values, 5 = quarterly values

Get Events

s.get_events(service_location_id, appliance_id, start, end, max_number)

Actuators

  • s.actuator_on(self, service_location_id, actuator_id, duration)
  • s.actuator_off(self, service_location_id, actuator_id, duration)

duration = 300,900,1800 or 3600 - specifying the time in seconds the actuator should be turned on or off. Any other value results in turning on or off for an undetermined period of time.

Consumption as Pandas DataFrame

Get consumption values in a Pandas Data Frame

  • To get total Electricity consumption and Solar production, use: s.get_consumption_dataframe(service_location_id, start, end, aggregation, localize)
  • To get consumption for a specific sensor, include a sensor id: s.get_consumption_dataframe(service_location_id, start, end, aggregation, localize, sensor_id)

Use the localize flag to get localized timestamps.

Simple Smappee

If you have no client id, client secret, refresh token etc, for instance if everything concerning oAuth is handed off to a different process like a web layer. This object only uses a given access token. It has no means of refreshing it when it expires, in which case the requests will raise errors.

ss = SimpleSmappee(access_token)

It has the same methods as the normal Smappee class, except authorization and re-authorization will not work.

LAN Smappee Client

Create Client

ls = smappy.LocalSmappee(ip='192.168.0.50') # fill in local IP-address of your Smappee

Log on

ls.logon(password='admin') # default password is admin

Other methods

  • report_instantaneous_values()
  • load_instantaneous()
  • active_power()
  • active_cosfi()
  • restart()
  • reset_active_power_peaks()
  • lreset_ip_scan_cache()
  • reset_sensor_cache()
  • reset_data()
  • clear_appliances()
  • load_advanced_config()
  • load_config()
  • save_config()
  • load_command_control_config()
  • send_group()
  • on_command_control(val_id)
  • off_command_control(val_id)
  • delete_command_control(val_id)
  • delete_command_control_timers(val_id)
  • add_command_control_timed()
  • load_logfiles()
  • select_logfile(logfile)

smappy's People

Contributors

ciotlosm avatar fakezeta avatar jrtpec avatar koenr3 avatar mortenf avatar visibilityspots avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

smappy's Issues

Server Error when get consumption api

I am using node to get the api and I got the token and the servicelocations via api, but when I try to use the consumption api I got the server error.

I am using node-fetch and the function:

const getConsumption = ({ token, id }) => {
  fetch(`https://app1pub.smappee.net/dev/v1/servicelocation/${id}/consumption`, {
    method: 'GET',
    body: 'aggregation=3&from=1388534400000&to=1391212800000',
    headers: {
      'Authorization': `Bearer ${token}`,
    }
  })
  .catch(function(error) {
    console.log(error);
  })
  .then(function(res) {
    console.log(res);
    return res.json();
  }).then(function(json) {
      console.log(json);
  });
};

Please add additional function to local smappy

Accessing the consumption data via the official API allows only a resolution up to 5 Min. If you want to know the up to the second consumption I figured out to use the local smappy data like this:

>>> from smappy import LocalSmappee
>>> ls = LocalSmappee(ip='192.168.178.36')
>>> ls.logon(password='XXX')
>>> instantaneous_consumption = ls.load_instantaneous()
>>> (float(instantaneous_consumption[1]['value']) + float(instantaneous_consumption[4]['value']) + float(instantaneous_consumption[7]['value']))/1000
960.729

in Watt. This is identical to the live view in the smappy app and my.smappee.com/#home. This approach has the advantage that it does not require internet access and the disadvantage that you have to be in the same sub-network of your smappee gateway. I tried to figure out how the internet access is working in the app andmy.smappee.com/#home, but could not find it yet.

@JrtPec could you add this to your lib functions as this will be used quite often I guess.

Datetime workaround for python 2.7

Hi there,
datetime doesn't have a timestamp() method in python 2.7
to make it fully compatible, I used a function timestamp to wrap around utcnow() :

def timestamp_milli(t):
    return int((t - dt.datetime(1970, 1, 1)).total_seconds())*1000

This way, you send an int to the Smappee object get_consumption_xxx methods.
Hope this helps...
Serge

Testing needed for actuator methods

The actuator methods have been implemented, but I don't have a Smappee set-up with actuators to test on. If there is somebody out there who could test it for me, please let me know.

Always on consumption mismatch

Figures returned by the API don't match those reported in the my.smapee interface for 'always on'

start = end - dt.timedelta(days=1)
s.get_consumption(service_location_id=service_location_id, start=start, end=end, aggregation=3)
{'consumptions': [{'solar': 4555.2, 'consumption': 12436.6, 'timestamp': 1516320000000, 'alwaysOn': 91195.0}], 'serviceLocationId': 20917}

image

Smappee local MQTT

Smappee can now publish/subscribe to a local MQTT broker.
Any plans to incorporate this in the smappy lib?

I can provide some documentation, if you're interested.

LocalSmappee restart error 404

The method LocalSmappee.restart() has been reported to raise 404-errors. There is probably something wrong with the URL: http://<ip address>/gateway/apipublic/restartEMeter.

I'm looking for someone to verify the bug, and perhaps provide me with the answer. I have no documentation, all methods were inspired by issue #7.

local smappy looses connection and needs reconnect

after 60 Min the local smappy object

ls = LocalSmappee(ip='smappee')

looses connection to the local gateway and needs to reconnect:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 133, in _new_conn
    (self.host, self.port), self.timeout, **extra_kw)
  File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 87, in create_connection
    raise err
  File "/usr/lib/python3/dist-packages/urllib3/util/connection.py", line 78, in create_connection
    sock.connect(sa)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 516, in url open
    body=body, headers=headers)
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 308, in _make_request
    conn.request(method, url, **httplib_request_kw)
  File "/usr/lib/python3.4/http/client.py", line 1090, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python3.4/http/client.py", line 1128, in _send_request
    self.endheaders(body)
  File "/usr/lib/python3.4/http/client.py", line 1086, in end headers
    self._send_output(message_body)
  File "/usr/lib/python3.4/http/client.py", line 924, in _send_output
    self.send(msg)
  File "/usr/lib/python3.4/http/client.py", line 859, in send
    self.connect()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 154, in connect
    conn = self._new_conn()
  File "/usr/lib/python3/dist-packages/urllib3/connection.py", line 138, in _new_conn
    (self.host, self.timeout))
urllib3.exceptions.ConnectTimeoutError: (<urllib3.connection.HTTPConnection object at 0x7641a910>, 'Connection to smappee timed out. (connect timeout=5)')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 362, in send
    timeout=timeout
  File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 559, in url open
    _pool=self, _stacktrace=stacktrace)
  File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 265, in increment
    raise MaxRetryError(_pool, url, error)
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='smappee', port=80): Max retries exceeded with url: /gateway/apipublic/instantaneous (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x7641a910>, 'Connection to smappee timed out. (connect timeout=5)'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "smappee-pi.py", line 90, in <module>
    instantaneous_consumption = ls.load_instantaneous()
  File "/usr/local/lib/python3.4/dist-packages/smappy/smappy.py", line 517, in load_instantaneous
    r = requests.post(url, data=data, headers=self.headers, timeout=5)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 94, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 49, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 457, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 569, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/adapters.py", line 411, in send
    raise ConnectTimeout(e, request=request)
requests.exceptions.ConnectTimeout: HTTPConnectionPool(host='smappee', port=80): Max retries exceeded with url: /gateway/apipublic/instantaneous (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x7641a910>, 'Connection to smappee timed out. (connect timeout=5)'))

I can think of two approaches:

  1. the LocalSmappee objects reconnects automatically, this requires to store the password
  2. the LocalSmappee returns a failure and reconnect is handled by the user via ls.logon(password='XXX')

What do you think?

Additional local smappee REST API

With Google Chrome I was able to find additional details in:

advancedpublic.html
configpublic.html
commandcontrolpublic.html
waveformdisplay.html
logbrowser.html

getconsumption gives void answer from api

Thanks a lot for this handy tool. I have been using the localsmappy part quite extensively.

I hope you can have a look at the code again, as accessing consumption data from the web smappee API does not work properly (anymore?).
I can authenticate successfully and use Epoch Timestamps as entries for the _getConsumption command.
e.g.:
start = 1503213249
end = 1503731649
s.get_consumption(service_location_id=service_location_id, start=start, end=end, aggregation=3)

This results in an asnwer from the Smappee API like this:
{u'consumptions': [], u'serviceLocationId': 19938}

I would expect an outcome similar to the one in your example on the wiki https://github.com/EnergieID/smappy/wiki .
It would be great, if you could have a look. thanks

smappee authentication error Home Assistant

System:

arch x86_64
dev false
docker true
hassio true
os_name Linux
python_version 3.7.6
timezone Europe/Lisbon
version 0.106.2
virtualenv false

config:
smappee:
host: 198.168.1.62
client_id: xxxxxxx
client_secret: xxxxx
username: xxxxx
password: xxxxxx

Any help to get rid of this problem would be appreciated!

Logger: homeassistant.components.smappee
Integration: smappee (documentation, issues)
First occured: 11:15:27 AM (1 occurences)
Last logged: 11:15:27 AM

Local Smappee device authentication failed (HTTPConnectionPool(host='198.168.1.62', port=80): Max retries exceeded with url: /gateway/apipublic/logon (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x7f82da0e2190>, 'Connection to 198.168.1.62 timed out. (connect timeout=5)')))
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 157, in _new_conn
(self._dns_host, self.port), self.timeout, **extra_kw
File "/usr/local/lib/python3.7/site-packages/urllib3/util/connection.py", line 84, in create_connection
raise err
File "/usr/local/lib/python3.7/site-packages/urllib3/util/connection.py", line 74, in create_connection
sock.connect(sa)
socket.timeout: timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 672, in urlopen
chunked=chunked,
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 387, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/local/lib/python3.7/http/client.py", line 1252, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/lib/python3.7/http/client.py", line 1298, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.7/http/client.py", line 1247, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/local/lib/python3.7/http/client.py", line 1026, in _send_output
self.send(msg)
File "/usr/local/lib/python3.7/http/client.py", line 966, in send
self.connect()
File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 184, in connect
conn = self._new_conn()
File "/usr/local/lib/python3.7/site-packages/urllib3/connection.py", line 164, in _new_conn
% (self.host, self.timeout),
urllib3.exceptions.ConnectTimeoutError: (<urllib3.connection.HTTPConnection object at 0x7f82da0e2190>, 'Connection to 198.168.1.62 timed out. (connect timeout=5)')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py", line 720, in urlopen
method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
File "/usr/local/lib/python3.7/site-packages/urllib3/util/retry.py", line 436, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='198.168.1.62', port=80): Max retries exceeded with url: /gateway/apipublic/logon (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x7f82da0e2190>, 'Connection to 198.168.1.62 timed out. (connect timeout=5)'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/smappee/init.py", line 95, in init
self._localsmappy.logon(host_password)
File "/usr/local/lib/python3.7/site-packages/smappy/smappy.py", line 552, in logon
r = self._basic_post(url='logon', data=password)
File "/usr/local/lib/python3.7/site-packages/smappy/smappy.py", line 530, in _basic_post
r = self.session.post(_url, data=data, headers=self.headers, timeout=5)
File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 581, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "/usr/local/lib/python3.7/site-packages/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 504, in send
raise ConnectTimeout(e, request=request)
requests.exceptions.ConnectTimeout: HTTPConnectionPool(host='198.168.1.62', port=80): Max retries exceeded with url: /g

How to get the current power of the solar production (or current consumption) ?

I'm a bit confused with the interface of the Smappy Python Wrapper. I do not need the energy produced (or consumed) between two past time stamps but I need to monitor the current solar production power (or the current electrical consumption power) like displayed on the main screen of the Smappee Smartphone App.
How to simply get theses values with the Smappy Python Wrapper ?

HowTo smappee with smappy & python

@JrtPec thanks a lot for sharing your great design and implementation of the smappee REST API including the OAuth2 refresh token issue! Your software worked right away for me but I had a lot of trouble setting up the basics behind. As a beginner with Python and OAuth2 I like to share with you how I got all the bits and pieces together.

Overview of steps

  1. Buy and install smappe – the device to measure your electrical power consumption
  2. Get the client id and client secret by eMail from [email protected]
  3. Install python3
  4. Install smappy package with pip3
  5. Run a test Python script

1. Buy and install shape

Once your smappee device is installed and online connected to the smappee server (currently running on AWS) you can access the data from the server (and not from the gateway) via this REST APIs. If you want to access the smappee gateway in your local network directly please check out this

2. Get the client id and client secret

In order to access the REST APIs you need 4 things
a) your smappee user name from your smappee app (iOS or Android)
b) your smappee user password from your smappee app
c) client id for identifiying the origin of your API calls at the smappee server
d) client secret for initially getting an access token from the smappee server via OAuth2

a) and b) are under your own control from the set-up of smappee. Wheras c) and d) you receive by (unencrypted!) eMail from [email protected]

3. Install python3

Get your distribution from python.org and install…

4. Install smappy package with pip3

As a phyton beginner, all the troubles of Mac OS using python 2.7, cloning the git hub repository, missing access rights to install the package this took me a few hours (and a screwed up python installation) to get right. In the end it was as simple as that:

sudo pip3 install snappy

on Mac as it needs to be installed in the pyhton3 ( in my case /Library/Frameworks/Python.framework/Versions/3.5/). You might need to use

sudo pip install snappy

5. Run a test Python script

start Python3 from your shell and enter line by line the following commands. You have to replace client id, client secrect, user name, user password with yours:

$ python3
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from smappy.smappy import Smappee, SimpleSmappee
>>> s = Smappee("client id", "client secret")
>>> s.authenticate("user name", "user password")
>>> service_location_id = s.get_service_locations()['serviceLocations'][0]['serviceLocationId']
>>> print ("id: ", service_location_id)
id:  314

In this case the authorization worked if you get a valid service_location_ID. I have picked the first smappee device in the service location list. This data type is a bit tricky. get_service_locations returns a "DICT" of "LIST" of location in a "DICT". You can parse through if you print the results

>>> s.get_service_locations()
{'appName': 'MyFirstApp', 'serviceLocations': [{'name': 'Home', 'serviceLocationId': 314}]}

If you have multiple smappee devices you have to use the right index instead of [0].

An now we can get data

>>> s.get_consumption(service_location_id, 1475309600000, 1475527028000, 3)
{'consumptions': [{'solar': 0.0, 'consumption': 2183.0, 'alwaysOn': 15264.0, 'timestamp': 1475359200000}, {'solar': 0.0, 'consumption': 3970.4, 'alwaysOn': 15131.0, 'timestamp': 1475445600000}], 'serviceLocationId': 314}

In order to change the start and end time of data query you have to convert human readable time to unix time stamps. I do this via epoch converter
Of course python has timestamp function itself. Here we return the date from the last week:

>>> from datetime import datetime, timedelta
>>> from calendar import timegm
>>> end_time = datetime.utcnow()
>>> start_time = end_time - timedelta(weeks=1, days=0, hours=0, minutes=0, seconds=00)
>>> start = 1000 * timegm(start_time.utctimetuple())
>>> end   = 1000 * timegm(end_time.utctimetuple())
>>> s.get_consumption(service_location_id, start, end, 3)
{'consumptions': [{'solar': 0.0, 'consumption': 3970.4, 'alwaysOn': 15131.0, 'timestamp': 1475445600000}, 
{'solar': 0.0, 'consumption': 12245.3, 'alwaysOn': 14976.0, 'timestamp': 1475532000000}, 
{'solar': 0.0, 'consumption': 12717.7, 'alwaysOn': 15288.0, 'timestamp': 1475618400000}, 
{'solar': 0.0, 'consumption': 6538.7, 'alwaysOn': 18818.0, 'timestamp': 1475704800000},
{'solar': 0.0, 'consumption': 10552.6, 'alwaysOn': 20552.0, 'timestamp': 1475791200000}, 
{'solar': 0.0, 'consumption': 7814.7, 'alwaysOn': 21457.0, 'timestamp': 1475877600000}, 
{'solar': 0.0, 'consumption': 7101.0, 'alwaysOn': 17550.0, 'timestamp': 1475964000000}], 'serviceLocationId': 314} 

Now you can start your real project…

Instant readings

Can you integrate this?
`

Written by Michael Lucas @ Smappee. 2016

import json, requests, sched

smappeeIP = '192.168.0.153' # local IP of your Smappee
smappeePwd = 'admin'

headers = {'Content-Type': 'application/json;charset=UTF-8'}
payload = smappeePwd

r = requests.post('http://'+smappeeIP+'/gateway/apipublic/logon', data = payload, headers=headers)
print(r.content)

r = requests.get('http://'+smappeeIP+'/gateway/apipublic/reportInstantaneousValues', headers=headers )

print(r.content)

payload = "loadInstantaneous"
r = requests.post('http://'+smappeeIP+'/gateway/apipublic/instantaneous', headers=headers, data=payload )
print(r.content)

restart the Smappee

r = requests.post('http://'+smappeeIP+'/gateway/apipublic/restartEMeter', headers=headers)

`

New API that is much more usable and does not need a key

Dont know how interessting this is or @JrtPec you want a pull request on this, but added a fork that is based on the smappee pro and app api that supports their smarthome system, appliance finder etc. Should not interfere with the existing integrations as I added it to a new class. This version does NOT require an API key, just use the app login credentials

I was thinking about making the MQTT option too as a forth option of this API, but the realtime mqtt is spamming the mqtt server so much its borderline useless, but it exist a websocket mqtt that could be a better choice.

https://github.com/alekslyse/smappy/blob/app-api/smappy/smappy.py

Authentication error 400

Authentication throws an HTTPError 400. Need to investigate if something has changed in the API.

LocalSmappee client cannot logon again after a temporary connection loss

I'm using the smappy.LocalSmappee client to continuously get instantaneous data in a loop from my local Smappee device via my WiFi LAN. If the WiFi connection is lost (ie. if I switch off the WiFi) I get first a ReadTimeout exception from ls.load_instantaneous(). I then call the connection initialisation code again...

ls = LocalSmappee(ip)
ls.Logon(admin_password) 

...in order to try to restore the connection and on next ls.load_instantaneous() I get a ConnectionError exception. On each loop I then try to restore the connection the same way (creating a new client and calling logon()) and I always get the ConnectionError exception. This appears correct as the WiFi is always down. But if I switch on the WiFi, the behavior remains the same. I always get a ConnectionError exception... I need to restart the python script to restore the correct functionning.

New smappee software changes local commandControl interface

As the title says the current LocalSmappee does no longer work due to changes in the commandControl interface. The current calls return a HTTP Status 500.

I implemented the following to make it work:

    def get_statistics_report(self):
        """
        Returns
        -------
        dict
        """
        r = self._basic_get(url='statisticsPublicReport')
        return r.json()

    def on_command_control(self, val_id):
        """
        Parameters
        ----------
        val_id : str

        Returns
        -------
        requests.Response
        """
        data = "control,{\"controllableNodeId\":\"" + val_id + "\",\"action\":\"ON\"}"
        return self._basic_post(url='commandControlPublic', data=data)

    def off_command_control(self, val_id):
        """
        Parameters
        ----------
        val_id : str

        Returns
        -------
        requests.Response
        """
        data = "control,{\"controllableNodeId\":\"" + val_id + "\",\"action\":\"OFF\"}"
        return self._basic_post(url='commandControlPublic', data=data)

Calling "get_statistics_report" which is an oddly named call to get information about smappee returns:

[
  {
    "key": "WIFI & networking"
  },
  {
    "value": "59/70 ",
    "key": "Link quality"
  },
  {
    "value": "-51 dBm dbm (>-35 excellent) (<-35 >-65 good) (<-65 poor)",
    "key": "Signal strength"
  },
  {
    "value": "SOMESSID",
    "key": "SSID"
  },
  {
    "value": "/192.168.1.20",
    "key": "Bound IP address"
  },
  {
    "key": "Monitor application"
  },
  {
    "value": "XXXXXX\n",
    "key": "Nr of features received from acquisition engine"
  },
  {
    "value": "29/03/2018 09:46:10\n",
    "key": "Last software update"
  },
  {
    "value": "1.0.0S buildNr #1185\n",
    "key": "Application software version and build nr"
  },
  {
    "value": "4.29\n",
    "key": "Acquisition Software version"
  },
  {
    "value": "three phase 120d (star or delta)\n",
    "key": "EMeter working config"
  },
  {
    "value": "SmappeeT\n",
    "key": "EMeter type"
  },
  {
    "value": "XXXXXXXXXX\n",
    "key": "Serial ID"
  },
  {
    "value": "8",
    "key": "OS build nr"
  },
  {
    "value": "N/A",
    "key": "Gas/Water sensors"
  },
  {
    "value": "Central European Time",
    "key": "Timezone"
  },
  {
    "value": "04/04/2018 20:51:40",
    "key": "Time&Date"
  }
]

Some of the data was masked by me with 'X'.

I assume the solution would be to check for the smappee software version during logon and depending on it use the legacy or new interface.

smappee not loading

I get the following message when adding the smappee integration using cloud:

SmappeeCloud failed to setup. This although I get a success message when the integration visit the smappee website

I am on Home assistant 2021.12.0b5

Logger: homeassistant.config_entries
Source: components/smappee/init.py:104
First occurred: 14:57:05 (3 occurrences)
Last logged: 15:55:30

Error setting up entry smappeeCloud for smappee
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 313, in async_setup
result = await component.async_setup_entry(hass, self) # type: ignore
File "/usr/src/homeassistant/homeassistant/components/smappee/init.py", line 104, in async_setup_entry
await hass.async_add_executor_job(smappee.load_service_locations)
File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.9/site-packages/pysmappee/smappee.py", line 30, in load_service_locations
sl = SmappeeServiceLocation(service_location_id=service_location.get('serviceLocationId'),
File "/usr/local/lib/python3.9/site-packages/pysmappee/servicelocation.py", line 74, in init
self.load_configuration()
File "/usr/local/lib/python3.9/site-packages/pysmappee/servicelocation.py", line 227, in load_configuration
self.mqtt_connection_central = self.load_mqtt_connection(kind='central')
File "/usr/local/lib/python3.9/site-packages/pysmappee/servicelocation.py", line 522, in load_mqtt_connection
mqtt_connection.start()
File "/usr/local/lib/python3.9/site-packages/pysmappee/mqtt.py", line 219, in start
self._client.connect(host=config['MQTT'][self._farm]['host'],
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 914, in connect
return self.reconnect()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1044, in reconnect
sock = self._create_socket_connection()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3685, in _create_socket_connection
return socket.create_connection(addr, timeout=self._connect_timeout, source_address=source)
File "/usr/local/lib/python3.9/socket.py", line 844, in create_connection
raise err
File "/usr/local/lib/python3.9/socket.py", line 832, in create_connection
sock.connect(sa)
socket.timeout: timed out

Suggestion to use daytime type instead of epoch and milliseconds

Using the milliseconds since epoch like in the original smappee REST API is consistent but not very easy to handle within python. As I understood smappee uses always UTC time. Therefore, it would be nice to make use of the datetime object instead of milliseconds in the methods:

get_consumption
get_sensor_consumption

Then it is easier to adjust to different time zones and requires less python code to use smappy API.
What do you think?

UTC time stamp confusion

I do not understand the difference in results for two similar queries. Do I use the python time wrong?

>>> end_time = datetime.utcnow()
>>> start_time = end_time - timedelta(weeks=0, days=0, hours=1, minutes=0, seconds=00)
>>> start = 1000 * timegm(start_time.utctimetuple())
>>> end   = 1000 * timegm(end_time.utctimetuple())
>>> print(s.get_consumption(service_location_id, start_time, end_time, 1))
{'consumptions': [{'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 21.4, 'timestamp': 1477239000000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 23.9, 'timestamp': 1477239300000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 29.2, 'timestamp': 1477239600000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 36.1, 'timestamp': 1477239900000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 40.7, 'timestamp': 1477240200000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 41.2, 'timestamp': 1477240800000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 47.6, 'timestamp': 1477241100000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 47.4, 'timestamp': 1477241400000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 50.8, 'timestamp': 1477241700000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 55.9, 'timestamp': 1477242000000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 55.2, 'timestamp': 1477242300000}], 'serviceLocationId': 13463}
>>> print(s.get_consumption(service_location_id, start, end, 1))
{'consumptions': [{'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 56.1, 'timestamp': 1477246200000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 47.4, 'timestamp': 1477246500000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 46.9, 'timestamp': 1477246800000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 46.8, 'timestamp': 1477247100000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 47.2, 'timestamp': 1477247400000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 47.2, 'timestamp': 1477247700000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 45.8, 'timestamp': 1477248000000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 45.1, 'timestamp': 1477248300000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 47.4, 'timestamp': 1477248600000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 46.9, 'timestamp': 1477248900000}, {'alwaysOn': 66.0, 'solar': 0.0, 'consumption': 46.8, 'timestamp': 1477249200000}], 'serviceLocationId': 13463}
>>> 

the first time stamp is 2h too early
1477239000000 => GMT: Sun, 23 Oct 2016 16:10:00 GMT Your time zone: 23.10.2016, 18:10:00 GMT+2:00 DST
and the second time stamp is correct
1477246200000 => GMT: Sun, 23 Oct 2016 18:10:00 GMT Your time zone: 23.10.2016, 20:10:00 GMT+2:00 DST

The official API is asking for UTC time though.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.