Last active
November 28, 2018 06:14
-
-
Save Miloune/d04cf968883d02b9acda7cb9c66b22df to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# 1: executer la commande : "wget https://raw.githubusercontent.com/orcasgit/python-nokia/master/bin/nokia" | |
# 2: executer la commande : "ip addr" et récupérer l'IP de la machine | |
# 3: editer le fichier nokia : "nano nokia" | |
# 4: ligne 37 et 38, remplacer l'IP récupérée a l'étape 2 et le port par ce que vous souhaitez, il ne doit pas être utilisé sur cette machine. Exemple | |
# 'server.socket_host': '192.168.1.19', | |
# 'server.socket_port': parsed_url.port or 90, | |
# 5: sauvegarder le fichier | |
# 6: créer un application ici : https://account.withings.com/partner/dashboard_oauth2 Attention l'url de callback doit être l'ip de la marchine + le port renseigné à l'étape 4. Exemple: http://192.168.1.19:90/ | |
# 7: récupérer l'ID du client (CONSUMER_KEY) et le secret d'application (CONSUMER_SECRET) afin de les saisir dans ce fichier | |
# 8: executer la commande suivante "sudo python nokia saveconfig --client-id CONSUMER_KEY --consumer-secret CONSUMER_SECRET -b http://192.168.1.19:90/ --config nokia_mickael.cfg | |
# vous devez bien évidemment remplacer CONSUMER_KEY, CONSUMER_SECRET, l'URL de callback ainsi que le nom du fichier de conf à votre convenance | |
# 9: un log de ce type devrait apparaitre dans votre console suite à la commande précédente : | |
# NOTE: We are going to try to open a browser to the URL below. If a browser tab/window does not open, please navigate there manually | |
# https://account.withings.com/oauth2_user/authorize2?response_type=code&client_id=mycustomid&redirect_uri=http%3A%2F%2F192.168.1.19%3A90%2F&scope=user.info%2Cuser.metrics%2Cuser.activity&state=mystate | |
# 10: copier / coller cette URL dans votre navigateur, vous devez arriver sur une page Nokia qui vous demande qui vous êtes, et ensuite d'authoriser l'application pour cet utilisateur. | |
# 11: vous serez automatiquement redirigé sur http://192.168.1.19:90/ qui vous affichera un message de succès. Vous avez maintenant votre fiichier de conf a mettre dans le même répertoire que ce script. | |
import os | |
import sys; sys.path.insert(0,'/usr/local/lib/python3.4/dist-packages/') | |
import pickle, json | |
import datetime | |
import urllib, urllib.request, urllib.parse#, hashlib,subprocess | |
import pytz | |
from nokia import NokiaAuth, NokiaApi, NokiaCredentials | |
try: | |
import configparser | |
from urllib.parse import urlparse | |
except ImportError: # Python 2.x fallback | |
import ConfigParser as configparser | |
from urlparse import urlparse | |
#################################################################################################### | |
######################################## Start of custom variable ################################## | |
#nokia api settings | |
CONSUMER_KEY = '' # clé API | |
CONSUMER_SECRET = '' # secret API | |
CONFIG_NAME = 'nokia_mickael.cfg' | |
#domoticz settings | |
domoticz_host = '192.168.1.19' # Url domoticz | |
domoticz_port = '8080' # port | |
domoticz_url = 'json.htm' # Ne pas modifier | |
idx_weight = '89' # renseigner l'idx du device Poids associé si souhaité (custom sensor, nom de l'axe : kg) | |
idx_body_mass_index = None # renseigner l'idx du device IMC associé si souhaité (custom sensor, nom de l'axe : kg/m2) | |
idx_fat_free_mass = None # renseigner l'idx du device Masse hors graisse associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : kg) | |
idx_fat_ratio = '90' # renseigner l'idx du device Pourcentage graisse associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : %) | |
idx_lean_ratio = '91' # renseigner l'idx du device Pourcentage masse maigre associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : %) | |
idx_fat_mass_weight = None # renseigner l'idx du device Masse grasse associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : kg) | |
idx_heart_pulse = None # renseigner l'idx du device Rythme cardiaque associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : bpm) | |
idx_muscle_mass = None # renseigner l'idx du device Masse musculaire associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : kg) | |
idx_muscle_mass_ratio = '92' # renseigner l'idx du device Masse musculaire associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : %) | |
idx_hydration = None # renseigner l'idx du device Taux d'hydratation associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : kg) | |
idx_hydration_ratio = '93' # renseigner l'idx du device Taux d'hydratation associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : %) | |
idx_bone_mass = None # renseigner l'idx du device Masse osseuse associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : kg) | |
idx_bone_mass_ratio = '94' # renseigner l'idx du device Masse osseuse associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : %) | |
idx_pulse_wave_velocity = None # renseigner l'idx du device Vitesse d'onde de pouls associé si souhaité, sinon laisser None (custom sensor, nom de l'axe : m/s) | |
#global settings | |
debugging = True # True pour voir les logs dans la console log Dz et en ligne de commande, ou False pour ne pas les voir (attention aux majuscules) | |
timezone = pytz.UTC | |
#################################### End of custom variable ######################################## | |
#################################################################################################### | |
class NokiaUser: | |
def refresh_token(self, token): | |
config = configparser.ConfigParser() | |
config.add_section('nokia') | |
for attr in req_creds_attrs: | |
config.set('nokia', attr, getattr(token, attr)) | |
with open(os.path.join(dir_path, CONFIG_NAME), 'w') as f: | |
config.write(f) | |
dir_path = os.path.dirname(os.path.abspath(__file__)) | |
auth = NokiaAuth(CONSUMER_KEY, CONSUMER_SECRET) | |
req_auth_attrs = ['client_id', 'consumer_secret'] | |
req_creds_attrs = [ | |
'access_token', | |
'token_expiry', | |
'token_type', | |
'refresh_token', | |
'user_id' | |
] + req_auth_attrs | |
try: | |
with open(os.path.join(dir_path, CONFIG_NAME), 'rb') as cfg: | |
config = configparser.ConfigParser() | |
config.read(os.path.join(dir_path, CONFIG_NAME)) | |
nokiacfg = config['nokia'] | |
confload = NokiaCredentials() | |
for attr in req_creds_attrs: | |
setattr(confload, attr, nokiacfg.get(attr, None)) | |
pass | |
except IOError: | |
print("Use Nokia bin to create your configuration") | |
nokia_user = NokiaUser() | |
client = NokiaApi(confload, refresh_cb=nokia_user.refresh_token) | |
user = client.get_user() | |
user_shortname = user['users'][0]['shortname'] | |
measures = client.get_measures(limit=1) | |
def log(message): | |
if debugging == True: | |
print(message) | |
log_message = urllib.parse.quote(("Nokia (" + str(user_shortname) + "): " + message).encode("utf-8")) | |
url = "http://" + domoticz_host + ":" + domoticz_port + "/" + domoticz_url + "?type=command¶m=addlogmessage&message=" + log_message | |
urllib.request.urlopen(url , timeout = 5) | |
def domoticzupdate(idx, value): | |
url = "http://" + domoticz_host + ":" + domoticz_port + "/" + domoticz_url + "?type=command¶m=udevice&idx=" + idx + "&nvalue=0&svalue=" + str(value) | |
urllib.request.urlopen(url , timeout = 5) | |
def domoticzupdateWeight(idx, value): | |
url = "http://" + domoticz_host + ":" + domoticz_port + "/" + domoticz_url + "?type=command¶m=udevice&idx=" + idx + "&svalue=" + str(value) | |
urllib.request.urlopen(url , timeout = 5) | |
def domoticzrequest(url): | |
request = urllib.request.Request(url) | |
response = urllib.request.urlopen(request) | |
return response.read().decode('utf-8') | |
if idx_weight != None: | |
domoticzurl = "http://" + domoticz_host + ":" + domoticz_port + "/" + domoticz_url + "?type=devices&rid=" + idx_weight | |
json_object = json.loads(domoticzrequest(domoticzurl)) | |
if json_object["status"] == "OK": | |
if json_object["result"][0]["idx"] == idx_weight: | |
lastupdate = json_object["result"][0]["LastUpdate"] | |
date = measures[0].date.isoformat() | |
lastupdate = datetime.datetime.strptime(lastupdate, '%Y-%m-%d %H:%M:%S').replace(tzinfo=timezone).isoformat() | |
log("Last datetime measure taken: %s " %date) | |
log("Last datetime updated: %s " %lastupdate) | |
should_update = date > lastupdate | |
#should_update = True ##################################################### | |
if should_update: | |
log("Update all metrics") | |
else: | |
log("No update needed") | |
#################################################################################################### | |
weight = measures[0].weight | |
if idx_weight != None and weight != None: | |
if should_update: | |
domoticzupdate(idx_weight, weight) | |
if debugging == True: | |
log("Your currently weight: " + str(weight) + " kg") | |
#################################################################################################### | |
height = measures[0].height | |
if idx_body_mass_index != None and height != None and weight != None: | |
bmi = weight / (height*height) | |
log("Body masse index: %s kg/m2" % bmi) | |
if should_update: | |
domoticzupdate(idx_body_mass_index, bmi) | |
if debugging == True: | |
log("Your currently size: " + str(height) + " cm") | |
log("Your currently body mass index: " + str(bmi) + " kg/m2") | |
#################################################################################################### | |
fat_free_mass = measures[0].fat_free_mass | |
if idx_fat_free_mass != None and fat_free_mass != None: | |
if should_update: | |
domoticzupdate(idx_fat_free_mass, fat_free_mass) | |
if debugging == True: | |
log("Your currently fat free mass (muscle + bone) est de " + str(fat_free_mass) + " kg") | |
#################################################################################################### | |
fat_ratio = measures[0].fat_ratio | |
if idx_fat_ratio != None and fat_ratio != None: | |
if should_update: | |
domoticzupdate(idx_fat_ratio, fat_ratio) | |
if debugging == True: | |
log("Your currently fat ratio: " + str(fat_ratio) + "%") | |
if idx_lean_ratio != None and fat_ratio != None: | |
lean_mass_ratio = 100 - fat_ratio | |
if should_update: | |
domoticzupdate(idx_lean_ratio, lean_mass_ratio) | |
if debugging == True: | |
log("Your currently lean mass ratio: " + str(lean_mass_ratio) + "%") | |
#################################################################################################### | |
fat_mass_weight = measures[0].fat_mass_weight | |
if idx_fat_mass_weight != None and fat_mass_weight != None: | |
if should_update: | |
domoticzupdate(idx_fat_mass_weight, fat_mass_weight) | |
if debugging == True: | |
log("Your currently fat mass weight: " + str(fat_mass_weight) + " kg") | |
#################################################################################################### | |
heart_pulse = measures[0].heart_pulse | |
if idx_heart_pulse != None and heart_pulse != None: | |
if should_update: | |
domoticzupdate(idx_heart_pulse, heart_pulse) | |
if debugging == True: | |
log("Your currently heart pulse: " + str(heart_pulse) + " bpm") | |
#################################################################################################### | |
muscle_mass = measures[0].get_measure(76) | |
if idx_muscle_mass != None and muscle_mass != None: | |
if should_update: | |
domoticzupdate(idx_muscle_mass, muscle_mass) | |
if debugging == True: | |
log("Your currently muscle mass: " + str(muscle_mass) + " kg") | |
if idx_muscle_mass_ratio != None and muscle_mass != None and weight != None: | |
muscle_mass_ratio = muscle_mass * 100 / weight | |
if should_update: | |
domoticzupdate(idx_muscle_mass_ratio, muscle_mass_ratio) | |
if debugging == True: | |
log("Your currently muscle mass ratio: " + str(muscle_mass_ratio) + " %") | |
#################################################################################################### | |
hydration = measures[0].get_measure(77) | |
if idx_hydration != None and hydration != None: | |
if should_update: | |
domoticzupdate(idx_hydration, hydration) | |
if debugging == True: | |
log("Your currently hydratation: " + str(hydration) + " kg") | |
if idx_hydration_ratio != None and hydration != None and weight != None: | |
hydration_ratio = hydration * 100 / weight | |
if should_update: | |
domoticzupdate(idx_hydration_ratio, hydration_ratio) | |
if debugging == True: | |
log("Your currently hydratation ratio: " + str(hydration_ratio) + " %") | |
#################################################################################################### | |
bone_mass = measures[0].get_measure(88) | |
if idx_bone_mass != None and bone_mass != None: | |
if should_update: | |
domoticzupdate(idx_bone_mass, bone_mass) | |
if debugging == True: | |
log("Your currently bone mass: " + str(bone_mass) + " kg") | |
if idx_bone_mass_ratio != None and bone_mass != None and weight != None: | |
bone_mass_ratio = bone_mass * 100 / weight | |
if should_update: | |
domoticzupdate(idx_bone_mass_ratio, bone_mass_ratio) | |
if debugging == True: | |
log("Your currently bone mass ratio: " + str(bone_mass_ratio) + " %") | |
#################################################################################################### | |
pulse_wave_velocity = measures[0].get_measure(91) | |
if idx_pulse_wave_velocity != None and pulse_wave_velocity != None: | |
if should_update: | |
domoticzupdate(idx_pulse_wave_velocity, pulse_wave_velocity) | |
if debugging == True: | |
log("Your currently pulse wave velocity: " + str(pulse_wave_velocity)) | |
#################################################################################################### |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@Miloune I think you need to change line 103 to
nokia_user = NokiaUser()