Analyse de la donnée. Partie 3 : Récupération et mise en forme de données historisées depuis Jeedom
Cet article est le troisième concernant l’analyse de donnée. Les précédents articles sont disponibles ici :
Cet article a été écrit dans un notebook jupyter avant d’être transféré sur ce blog. Les zones nommées In [ ] correspondent donc au code Python qui a été exécuté. La sortie de ce code apparaît juste en dessous.
Nous allons dans cet article effectuer une première récupération de donnée historisée de plusieurs capteurs. Puis nous allons stocker cette donnée correctement dans une time series. Il est important de traiter et stocker correctement ces valeurs si on veut en faire bon usage par la suite.
Paramètres généraux d’accès à l’API Jeedom¶
Il s’agit des paramètres nécessaires pour accéder à l’API Jeedom : l’URL et la clé API. Cette dernière peut être récupérée dans l’interface de contrôle de Jeedom. Je vais me permettre pour cette partie de cacher mes données personnelles !
adresse_API = 'http://adresse.ip.jeedom/core/api/jeeApi.php'
Api_key = 'Clé API'
import urllib.request
import json
def Jeedom_getHistory(id, start, stop):
parameters = {
"jsonrpc" : "2.0",
"method" : "cmd::getHistory",
"params": {
"id" : id,
"apikey": Api_key,
"startTime": start,
"endTime": stop
}
}
params = json.dumps(parameters).encode('utf8')
req = urllib.request.Request(adresse_API, data=params, headers={'Content-Type': 'application/json'})
response = urllib.request.urlopen(req)
return response.read().decode('utf8')
hist_temp=Jeedom_getHistory(1801,"2020-02-08 00:00:00","2020-02-08 23:59:59")
# Je n'imprime que le début parce que ça peut être très long
print(hist_temp[:255])
Transformation du format JSON en Time Series¶
Toutes les données qu’on récupère sont référencées par rapport à une date/heure. Il s’agit de données particulières, qu’on appelle time series en anglais. On transforme donc les données fournies par jeedom d’un capteur dans un format time series. Puis on s’assure que tout va bien.
import json
import pandas as pd
datas = json.loads(hist_temp)
datas2 = datas['result']
pddata = pd.DataFrame.from_dict(datas2)
pddata['datetime']=pd.to_datetime(pddata['datetime'])
pddata['value']=pd.to_numeric(pddata['value'], downcast='float')
pddata = pddata.set_index('datetime')
pddata = pddata.drop(columns=['cmd_id'])
pddata = pddata.rename(columns={'value':'T° SAM'})
print(pddata.info(verbose=True))
pddata.head()
Afficher graphiquement la timeseries¶
Pour se faire plaisir, traçons la courbe des données qu’on vient de charger
%matplotlib inline
import matplotlib.pyplot as plt
pddata.plot()
plt.show()
import json
import pandas as pd
hist_phasejour=Jeedom_getHistory(2626,"2020-02-08 00:00:00","2020-02-08 23:59:59")
datas = json.loads(hist_phasejour)
datas2 = datas['result']
pdtmp = pd.DataFrame.from_dict(datas2)
pdtmp['datetime']=pd.to_datetime(pdtmp['datetime'])
pdtmp['value']=pd.to_numeric(pdtmp['value'], downcast='integer')
pdtmp = pdtmp.set_index('datetime')
pdtmp = pdtmp.drop(columns=['cmd_id'])
pdtmp = pdtmp.rename(columns={'value':'Phase Jour'})
pdtmp
Problème : on ne connait pas la valeur au début de la timeserie¶
La valeur a dû être fixée le jour d’avant, et en téléchargeant l’historique sur une période de date limitée on n’a pas reçu cette valeur, il est donc nécessaire de récupérer la valeur au début de la période qui nous intéresse.
import pandas as pd
import math
def Jeedom_getoldvalue(id, start,stop):
parameters = {
"jsonrpc" : "2.0",
"method" : "cmd::getStatistique",
"params": {
"id" : id,
"apikey": Api_key,
"startTime": start,
"endTime": stop
}
}
params = json.dumps(parameters).encode('utf8')
req = urllib.request.Request(adresse_API, data=params, headers={'Content-Type': 'application/json'})
response = urllib.request.urlopen(req)
return response.read().decode('utf8')
print(pdtmp['2020-02-08 00:00:00':'2020-02-08 00:04:00'].empty)
if pdtmp['2020-02-08 00:00:00':'2020-02-08 00:04:00'].empty == True :
oldvalue_phase=Jeedom_getoldvalue(2626,"2020-02-07 00:00:00","2020-02-08 00:00:00")
datas = json.loads(oldvalue_phase)
datas2 = datas['result']['last']
print(type(datas2))
pdtmp = pdtmp.append(pd.DataFrame({'Phase Jour':math.ceil(float(datas2))},index={pd.to_datetime('2020-02-08 00:00:00')}))
pdtmp = pdtmp.sort_index()
print(pdtmp.info(verbose=True))
pdtmp
Intégration des deux types de données dans une seule time serie¶
On réintègre les données des deux capteurs dans le même jeu de donnée. Attention à la façon de concaténer ces données : il ne faut pas en perdre, ni créer des enregistrements inutiles qui alourdiraient les traitements postérieurs.
import pandas as pd
import matplotlib.pyplot as plt
pdresult = pd.merge(pddata,pdtmp, left_index=True, right_index=True, sort=True,how='outer').fillna(method='ffill')
pdresult.head(10)
Affichage graphique des données concaténées¶
%matplotlib inline
pdresult.plot()
plt.show()