Skip to content

Instantly share code, notes, and snippets.

@Miloune
Last active November 28, 2018 06:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Miloune/d04cf968883d02b9acda7cb9c66b22df to your computer and use it in GitHub Desktop.
Save Miloune/d04cf968883d02b9acda7cb9c66b22df to your computer and use it in GitHub Desktop.
#!/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&param=addlogmessage&message=" + log_message
urllib.request.urlopen(url , timeout = 5)
def domoticzupdate(idx, value):
url = "http://" + domoticz_host + ":" + domoticz_port + "/" + domoticz_url + "?type=command&param=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&param=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))
####################################################################################################
@brad
Copy link

brad commented Nov 28, 2018

@Miloune I think you need to change line 103 to nokia_user = NokiaUser()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment