NEWS
Withings Daten einlesen
-
Hallo,
nach einer Woche Urlaub ohne Computer und Zugriff auf meinen ioBroker-Server habe ich heute gleichmal ein neues Projekt umgesetzt: Withings Daten in ioBroker einlesen. Eigentlich halte ich es nicht unbedingt für nötig, die Haussteuerung mit den Körperdaten zu füttern. Dennoch ergeben sich durch die Nutzung der Geräte interessante Möglichkeiten. Ich wiege mich morgens immer direkt nach dem Aufstehen. Dadurch kann ich nun auch mit dem Wiegen, die Nachtruhe beenden. Alternativ geht das auch per https://www.youtube.com/watch?v=y4xGgx2yNXE Homematic Türfensterkontakt (zB mit http://www.conrad.de/ce/de/product/185244/AlarmsensorVibrationssensor-B200 Erschütterungssensor an die Waage geklebt). Die physische Bewegung der Waage wird gemeldet.
Die zweite Anwendung für mich ist die Nutzung der Daten aus dem Schrittzähler zur eigenen Motivation.
Ich bin auf die Umsetzung durch http://www.howtobuildsoftware.com/index.php/how-do/SPt/javascript-nodejs-oauth-withings-withings-api-is-not-working-with-node-oauth gekommen. Die Nutzung von oauth hat mir bisher immer Probleme gemacht. Bluefox' Skripte für andere ähnliche Projekte bilden die Basis. Vielen Dank dafür!
Natürlich braucht man erstmal ein Withings Nutzer Konto. https://oauth.withings.com/partner/add. Das ist nötig, um an die Daten zu kommen. Wenn man das geschafft hat und erfolgreich einen Consumer Key, einen consumer secret, ein oauth access token, einen oauth access token secret und die user id erhalten hat, dann kann man folgendes Skript nutzen.
Es lassen sich generell alle Daten auf einmal als JSON abfragen. Die neuesten kommen zuerst. Für meine Zwecke brauche ich aber nur das Gewicht von der Waage die Schritte vom Aktivitätstracker. Ich finde es einfacher, jeweils gezielt das heutige Gewicht und die aktuellen Schritte abzufragen, als aus der großen JSON Datei die richtigen Daten herauszufischen. Dafür sind dann aber auch zwei Aufrufe nötig. Die Schritte werden alle 3 Minuten (20x/Stunde) und bei Skriptstart abgefragt, das Gewicht wird alle 5 Minuten (6x/Stunde) abgefragt. Das lässt genügend Raum, denn das API lässt nur 60 Abfragen / Stunde zu.
Die Abfrage des Gewichts geht über das Device "Waage" und den Measuretype "Gewicht". Dazu wird nur der letzte Eintrag genutzt.````
http://wbsapi.withings.net/measure?action=getmeas&devtype=1&meastype=1&limit=1&userid=" + userid, oauth_access_token, oauth_access_token_secretDie Abfrage der Schritte erfolgt über die Aktivitätswebschnittstelle. Es wird das aktuelle Datum im Format YYYY-MM-DD mitgegeben.
http://wbsapi.withings.net/v2/measure?action=getactivity&date=" + datum + "&userid=" + userid, oauth_access_token, oauth_access_token_secret
Ich empfehle, für die Abfrage von Daten aus dem Internet (Aktien, Wetter, TV-Programm) eine eigene Javascript-Instanz zu installieren. Beim Anpassen passieren immer wieder Fehler, die einen Neustart der Instanz provozieren. Da ist es nicht gut, wenn immer das "Produktivsystem" neu startet. Skript: >! ```` /* Withings Daten einlesen >! http://www.howtobuildsoftware.com/index.php/how-do/SPt/javascript-nodejs-oauth-withings-withings-api-is-not-working-with-node-oauth >! erstellt: 17.08.2015 von Pix mit Hilfe von Skripten von Bluefox http://forum.iobroker.org/viewtopic.php?f=21&t=960&p=7519&hilit=JSON+einlesen#p7494 */ >! //createState('Withings.json', {name:'Withings Daten JSON Format'}); createState('Withings.Gewicht', {name:'Withings Gewicht', unit: 'kg'}); createState('Withings.Gewicht.Datum', {name:'Withings Gewicht (Datum)'}); createState('Withings.Gewicht.Datum.epoc', {name:'Withings Gewicht (Datum im UNIX EPOC Format)'}); createState('Withings.Schritte', {name:'Withings Schritte'}); createState('Withings.Schritte.Datum', {name:'Withings Schritte (Datum)'}); >! function datum_heute() { var heute = new Date(); var tag_roh = heute.getDate(), tag = ((tag_roh <10) ? '0' : '') + tag_roh, monat_roh = heute.getMonth() + 1, monat = ((monat_roh <10) ? '0' : '') + monat_roh, jahr = heute.getFullYear(); >! var datum = jahr + '-' + monat + '-' + tag; //var menschdatum = new Date(datum + ' 00:00:00'); //var epocdatum = menschdatum.getTime()/1000.0; >! return(datum); } >! function withings_einlesen(datentyp) { // Eigenen Daten statt xxxxxx einfügen var consumerKey = "xxxxxxxxxxxxxxxx", consumerSecret = "xxxxxxxxxxxxxxxx", oauth_access_token = "xxxxxxxxxxxxxxxx", oauth_access_token_secret = "xxxxxxxxxxxxxxxx", userid = "xxxxxxxxxxxxxxxx"; >! var oauth = require("oauth"); var withings = new oauth.OAuth( "https://oauth.withings.com/account/request_token", "https://oauth.withings.com/account/access_token", consumerKey, consumerSecret, "1.0", null, "HMAC-SHA1" ); >! // INFO ZU API: http://oauth.withings.com/api/doc // Standardabfrage für alle Daten: // var url = withings.signUrl("http://wbsapi.withings.net/measure?action=getmeas&userid=" + userid, oauth_access_token, oauth_access_token_secret); // Abfrage einzelner Daten nach Typ if (datentyp === "gewicht") { url = withings.signUrl("http://wbsapi.withings.net/measure?action=getmeas&devtype=1&meastype=1&limit=1&userid=" + userid, oauth_access_token, oauth_access_token_secret); log('Withings Gewicht wird eingelesen'); withings.get(url, null, null, function(error, response) { if (!error) { var result; try{ result = JSON.parse(response); var data = JSON.stringify(result, null, 2); log('Kein Fehler :-D bei Withings Gewicht'); } catch (e){ log('Parse Fehler:' + e); } if (result) { var gewicht = result.body.measuregrps[0].measures[0].value; // log('-------> Gewicht: ' + gewicht); setState('Withings.Gewicht', gewicht / 1000); var gewicht_epoc = result.body.measuregrps[0].date; setState('Withings.Gewicht.Datum', new Date(gewicht_epoc)); // Datum wird umgewandelt setState('Withings.Gewicht.Datum.epoc', gewicht_epoc); //EPOC wird übernommen } } else { log('Fehler: ' + error); } }); } else if (datentyp === "schritte") { datum = datum_heute(); url = withings.signUrl("http://wbsapi.withings.net/v2/measure?action=getactivity&date=" + datum + "&userid=" + userid, oauth_access_token, oauth_access_token_secret); log('Withings Schritte werden eingelesen'); withings.get(url, null, null, function(error, response) { if (!error) { var result; try{ result = JSON.parse(response); var data = JSON.stringify(result, null, 2); log('Kein Fehler :-D bei Withings Schritte'); } catch (e){ log('Parse Fehler:' + e); } if (result) { var schritte = result.body.steps; // log('-------> Schritte: ' + schritte); setState('Withings.Schritte', schritte); var schritte_datum = result.body.date; setState('Withings.Schritte.Datum', schritte_datum); // Datum wird übernommen } } else { log('Fehler: ' + error); } }); } >! } >! schedule("*/5 * * * *", withings_einlesen('gewicht')); schedule("*/3 * * * *", withings_einlesen('schritte')); withings_einlesen('schritte'); >! ```` Um oauth zu verwenden, bitte noch die Einstellungen der Javascript Instganz pimpen und das oauth Modul installieren. ![261_bildschirmfoto_2015-08-17_um_16.47.09.png](/assets/uploads/files/261_bildschirmfoto_2015-08-17_um_16.47.09.png) Bei mir läuft das ganz gut, ein passendes VIS Widget kann ich gleich noch nachliefern. Grüße, Pix
-
Hier noch ein passendes VIS Widget:
! ````
[{"tpl":"tplMetroTileString","data":{"visibility-cond":"==","visibility-val":1,"bg_class_true":"bg-cyan","bg_class_false":"bg-transparent","icon_class_true":"icon-custom","icon_class_false":"icon-custom","badge_bg_class_true":"","badge_bg_class_false":"","icon_badge_true":"","icon_badge_false":"","brand_bg_class_true":"","brand_bg_class_false":"","name":"Withings Schritte","visibility-oid":"","content_prepend":"Withings Schritte ","content_append":"","content_oid":"javascript.1.Withings.Schritte","label_prepend":"Gewicht: {javascript.1.Withings.Gewicht} kg","label_append":"","label_id":"","state_oid":"javascript.1.Withings.Schritte.Ziel_erreicht_J","transform":false,"select_on_true":false,"icon":"/vis.0/main/img/schritte.png","icon_width":"50%","icon_height":"50%","icon_false":"/vis.0/main/img/schritte.png","icon_top":"57","icon_left":"44","hover":false},"style":{"left":"295px","top":"200px","width":"137px","height":"137px","z-index":"15","font-family":"","color":"","font-size":""},"widgetSet":"metro"}]Es verändert den Hintergrund von Transparent nach Cyan, sobald die Variable javascript.1.Withings.Schritte.Ziel_erreicht_J auf 1 geht. Dazu prüft ein zweites Skript die aktuelle Zahl der Schritte und setzt bei 10000 die Boolean-Variable um. >! ```` var idSchritte = "javascript.1.Withings.Schritte"/*Withings Schritte*/, idSchrittzielJ = "javascript.1.Withings.Schritte.Ziel_erreicht_J", >! // Schritte prüfen, bei Ziel erreicht Variable umstellen on( { id: idSchritte, valGt: 9999 }, function (data) { if (getState(idSchrittzielJ).val === 0) { setState(idSchrittzielJ, 1); log('Schrittziel erreicht, Variable gesetzt', 'info'); } }); >! // Variable täglich um Mitternacht zurücksetzen schedule("0 0 * * *", function () { setState(idSchrittzielJ, 0); log('Schrittziel-Variable zurückgesetzt', 'info'); });
Dieses Skript läuft in der Javascript Instanz 0, die Schritte werden in der Instanz 1 eingelesen. Daher musste ich die variable idSchrittzielJ im anderen Skript in der Instanz 1 definieren.
Gruß
Pix
-
Super!!! Ich teste das gleich direkt mal
-
Hey Pix,
funktioniert das ganze auch noch nachdem es jetzt Nokia ist? Denn irgendwie komme ich nicht ganz so zurecht.
-
Hallo, noch nicht am Rechner, dauert noch ein paar Tage. Werde dann checken.
Pix
-
Und gibt's was neues? Bin am überlegen mir so eine Nokia Waage zuzulegen. Heutzutage muss ja alles mit ioBroker kompatibel sein
-
Hallo,
hab den Thread gerade erst wieder gesehen und schieb ihn mal hoch: Habe mein Skript kaum geändert. Ich hab gerad kaum Zeit, aber ich leg es mir auf Wiedervorlage
Auf jeden Fall geht es. Ich musste nur den OAUTH-Schlüssel für die Withings (jetzt Nokia) API erneuern (was etwas kompliziert ist).
Gruß
Pix
-
Ok, dann probiere ich mich mal daran. Waage ist heute angekommen
-
Hallo,
wie sieht’s aus? Habe nochmal ins Skript geguckt: habe kein Änderungen vorgenommen nur die Authentifizierung erneuert.
Gruß
Pix
-
API Key und API Secret hatte ich gleich erstellt gehabt. Die weiteren Schritte muss ich noch machen… war für mich nicht sofort ersichtlich wie es geht.
-
Welche weiteren Schritte?
-
@pix:Welche weiteren Schritte?
Hab es hinbekommen Funktioniert… jedenfalls wurde schon das korrekte letzte Gewicht abgerufen und die Schrittzahl.Hinweis:
API Key = Consumer key
API Secret = Consumer secret
-
Dein kleines Schritte-Script gibt bei mir einen Fehler aus.
In Zeile 5: Missing ";" before statement
Und im log:
javascript.1 2017-09-26 14:51:36.680 error script.js.Nokia-Body_Schritte compile failed: SyntaxError: Unexpected token (
-
Schön, dass es fast klappt.
Kannst du bitte das Skript posten, auf das du dich beziehst? Ich weiß nicht, was du mit "kleines Schritte-Script" meinst.
Pix
-
Gerne. Ich fand das hier bei zwei Scripten recht übersichtlich
var idSchritte = "javascript.1.Withings.Schritte"/*Withings Schritte*/, idSchrittzielJ = "javascript.1.Withings.Schritte.Ziel_erreicht_J", // Schritte prüfen, bei Ziel erreicht Variable umstellen on( { id: idSchritte, valGt: 9999 }, function (data) { if (getState(idSchrittzielJ).val === 0) { setState(idSchrittzielJ, 1); log('Schrittziel erreicht, Variable gesetzt', 'info'); } }); // Variable täglich um Mitternacht zurücksetzen schedule("0 0 * * *", function () { setState(idSchrittzielJ, 0); log('Schrittziel-Variable zurückgesetzt', 'info'); });
-
Jetzt weiß ich, was du meinst.
Das ist das Skript zur Meldung des erreichten Schrittziels.
Es werden zwei Variablen deklariert. Nach der zweiten sollte in Semikolon und kein Komma kommen. Das ist ein Fehler.
Also vorn im „var-Bereich“
Getippt mit tapatalk
Pix
-
Alles klar. So ist ohne Fehler:
var idSchritte = "javascript.1.Withings.Schritte"/*Withings Schritte*/, idSchrittzielJ = "javascript.1.Withings.Schritte.Ziel_erreicht_J"; // Schritte prüfen, bei Ziel erreicht Variable umstellen on( { id: idSchritte, valGt: 9999 }, function (data) { if (getState(idSchrittzielJ).val === 0) { setState(idSchrittzielJ, 1); log('Schrittziel erreicht, Variable gesetzt', 'info'); } }); // Variable täglich um Mitternacht zurücksetzen schedule("0 0 * * *", function () { setState(idSchrittzielJ, 0); log('Schrittziel-Variable zurückgesetzt', 'info'); });
-
Bei mir funktioniert das Automatsiche Abrufen noch nicht. Das sollte alle 5min passieren, wenn ich das Script richtig verstehe.
Das Gewicht eingelesen, wenn ich das SCript neustarte. Dabei kommt auch ein Fehler:
javascript.1 2017-09-27 12:35:36.094 error script.js.Nokia-Body: schedule callback missing
-
@pix:Welche weiteren Schritte?
Hab es hinbekommen Funktioniert… jedenfalls wurde schon das korrekte letzte Gewicht abgerufen und die Schrittzahl.Hinweis:
API Key = Consumer key
API Secret = Consumer secret `
Hallo,
irgendwie stehe ich hier auf dem Schlauch.
Wie kommt man denn an den "oauth access token" und das "oauth access token secret" ?
Danke für Hinweise ….
-
Hinweis: steht im ersten Post.
Stichwort: Withings/Nokia API
Achtung: npm Modul oauth nicht vergessen.
Pix