Résolu Aide script google - Récupération infos code source

BEBER1212

Expert
Bonjour à tous,

Je souhaiterais SVP avoir de l'aide afin de créer un script Google en Javascript pour récupérer des infos dans une page internet (code source).

Je n'y connais absolument rien en Javascript, mais il y a deux ans j'ai créé (grâce à l'aide de Zeb sur ce site) un logiciel en VB, en partant de 0, alors que je n'y connaissais rien non plus. Voilà pourquoi je reviens ici ;-)
La preuve :
Merci encore Zeb ! ;)

Alors voilà, je souhaite récupérer tous les jours, automatiquement, une valeur concernant la production de mes panneaux solaires, à l'adresse suivante :


Une fois cette valeur récupérée dans le code source (4,26 kWh pour cette date par exemple), je souhaite l'entrer automatiquement dans une cellule d'un doc google spreadsheet.

J'ai lu pas mal de choses, dont notamment le fait qu'il faille probablement utiliser "urlfetch" pour faire ce dont j'ai besoin, mais je ne sais pas du tout par où commencer.

Donc, si une bonne âme veut bien m'aider à avancer petit à petit, je suis preneur.

Merci d'avance.

P.S : j'ai commencé une "formation" en ligne de Javascript sur codecademy.com, j'ai donc quelques bases...et je vais au bout des choses.

Merci !


 

KyrO_82

Grand Maître
Bonjour BEBER1212,

Quelques précisions en plus:
- A partir de où veux-tu récupérer ces informations?
- Ce site, suntrol-portal.com, il est à toi? Peux-tu y mettre du code serveur? Accéder à la base de donnée?

Sinon, voici par où tu peux commencer: il s'agit des données pour le tracé mensuel, en json, dans lesquelles tu peux récupérer la moyenne qotidienne pour chaque jour:


Grâce à ces données en json, tu peux récupérer les moyennes quotidiennes très facilement, et tu peux récupérer tous les jours d'un moins entier en un seul accès.

Reste la question: à partir de où veux-tu récupérer ces données? Car quand tu dis que tu veux récupérer "automatiquement" ces données, ça veut dire que tu as quelque-part un programme qui le fait.
 

BEBER1212

Expert
Bonjour, et merci pour la réponse et le début de piste.

Pour répondre à tes questions :
- je souhaite récupérer les données à partir d'une feuille Google Spreadsheet, sur laquelle j'incorporerais un script qui irait chercher les données sur suntrol-portal.com
- ce site n'est pas à moi. Il s'agit d'un portail solaire sur lequel mon onduleur (connecté à internet) envoie des données toutes les heures.

Super ces données en json !! (j'ai aucune idée de ce qu'est le json, mais je vais me renseigner) Je retrouve effectivement les données que je souhaite récupérer, par jour. J'imagine qu'une fois que j'arriverais à récupérer tout ça je pourrai faire le tri pour ne garder que ce que je veux.

Voilà ce que je veux faire en détail :
Tous les soirs, je souhaite que le script aille récupérer les données, les trier pour ne garder que la valeur quotidienne et entrer cette valeur dans un tableau, à la date du jour. Facile, non ? :D
 

KyrO_82

Grand Maître
Quand j'ai demandé à partir de où, j'entendais à partir de quelle machine ;) Quel ordinateur devra aller lire ces données?

Il faut bien être conscient que tu as beau avoir un script, encore faut-il l’exécuter. Pour que cela soit automatique, il faut qu'un ordinateur aille faire cette mise à jour automatiquement, tous les jours (donc un ordinateur allumé avec un programme actif).
La deuxième solution, qui je pense est la meilleure, c'est de faire cette mise à jour lors de la consultation des données. C'est à dire que dès que tu va voir les données, un script est exécuté et met à jours la liste, même si il manque plusieurs jours dans cette liste.

Mais je ne sais pas si il est possible d'intégrer cela dans un Google Spreadsheet. Lire et décoder les données json est facile en javascript, mais encore faut-il récupérer ces données sur le serveur suntrol-portal.com (avec AJAX / XMLHttpRequest), mais ça je sais pas si c'est possible...

Je connais rien des Google Spreadsheet, dsl...


PS. json, c'est un un format de données structurées textuelles, comme le xml. Il est donc très facile d'en extraire les données, quel que soit le langage utilisé.
Tu peux utiliser le site pour afficher ton json de façon "human readable". Tu peux y voir que tes données seront accessible via json.data[date].value, où "date" est le jours du mois - 1, donc de 0 à 30.
 

BEBER1212

Expert
Le script se lancera automatiquement, une fois par jour, à heure fixe.

Google a mis en place des déclencheurs automatiques pour lancer les scripts (à l'ouverture du document, lors d'une modification, toutes les heures, tous les jours...). Ils sont forts chez Google :D
Donc pas besoin d'ordinateur allumé, ni même d'ouvrir la feuille (normalement, en tous cas c'est ce que j'espère faire).

Pour la partie Spreadsheet, je devrais m'en sortir (lancer le script, recopier la valeur récupérée dans la bonne case, à la bonne date...). Là où je vais bloquer c'est la partie JavaScript "Récupérer ma valeur sur Sunportal et l'emmener sur ma Spreadsheet".

Pour la récup des données, je vais voir comment fonctionne AJAX / XMLHttpRequest et je reviens...

J'ai vu effectivement que le lien de données sunportal que tu m'as donné correspond bien à ce que j'ai pu lire sur le json (couples nom/valeur).
 

KyrO_82

Grand Maître
Ah oui excellent ces fonctionnalités chez google :)

Je suppose qu'on peut faire ça de façon synchrone, ce qui donnerait un code de ce genre:

JavaScript:
function request(year, month) {
    var xhr = getXMLHttpRequest();
    xhr.open("GET", "http://www.suntrol-portal.com/fr/plant/graph-json/month/p/1/pid/14895/date/" + year + "-" + month + "/size/page/chart/Column3D/axis/static/output/real", false);
    xhr.send(null);
    if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0)) {
        return JSON.parse(xhr.responseText);
    } else {
        alert("Erreur"); // Gestion basique de l'erreur. A développer
    }
}
 
function readDatas(datas) {
    for(var i=0; i<datas.data.length; i++)
    {
        var day = i+1;
        var value = datas.data[i].value;
        // Reste plus qu'à introduire ces données dans la Spreadsheet
    }

}
 
datas = request(2013,11); // Ici il faut mettre le mois et l'année que l'on veut
readDatas(datas);


PS. Heu... mon code est modifié par la balise "script" du forum apparemment :o
3ème ligne, ceci est correct:
JavaScript:
xhr.open("GET", "http://www.suntrol-portal.com/fr/plant/graph-json/month/p/1/pid/14895/date/" + year + "-" + month + "/size/page/chart/Column3D/axis/static/output/real", false);
 

BEBER1212

Expert
Merci !

Avec quelques idées et bouts de code piochés ici et là sur la toile, j'avais commencé à bidouiller un bout de code. Grâce à ton code, j'ai pu y ajouter les variables "année" et "mois" que je récupère dans ma SpreadSheet en fonction de la date du jour.

Voilà ce que j'ai pour l'instant :

JavaScript:
function request(year, month) {
  var q = 'http://www.suntrol-portal.com/fr/plant/graph-json/month/p/1/pid/14895/date/'+ SpreadsheetApp.getActiveSheet().getRange(2,16).getValues() + "-" + SpreadsheetApp.getActiveSheet().getRange(2,15).getValues() +'/size/page/chart/Column3D/axis/static/output/real' ;
  var s = UrlFetchApp.fetch(q).getContentText();
  return s;
}

J'ai essayé ton code directement. Le débogueur m'indique une erreur sur la ligne 3 (manque un ")" après les arguments). Peut-être pas le même langage utilisé par Google que ce que tu m'as donné ???

Bref, déjà j'ai réussi à amener les données de sunportal sur ma Spreadsheet et ça c'est cool. Bon, j'ai tout dans la même cellule mais déjà c'est pas mal. Pour séparer tout ça, je verrai ça...demain.

Merci KyrO_82

[strike]Question : tu as trouvé les données de suntrol-portal au mois. Est-ce qu'on peut trouver ces même données, mais au jour le jour ?[/strike]
Oui, j'ai trouvé... ;)
 

BEBER1212

Expert
En fait visiblement les scripts sous Google n'acceptent pas toutes les fonctions (Ex : )

Donc ton code ne fonctionne pas pour moi... et je suis bien incapable de trouver les fonctions qui pourraient fonctionner avec les Google scripts.
Je vais donc chercher à partir de mon code si je peux ne récupérer que des bouts de données, et pas tout en bloc.
 

KyrO_82

Grand Maître
UrlFetchApp fait plus ou moins la même chose que XmlHttpRequest.
Pour l'erreur à la ligne 3, tu as bien remplacé cette ligne par ce que j'ai mis en bas de mon message précédent?
Les données au jour le jour sont disponibles aussi oui, mais inutile si tu ne veux pas les détails en fonction de l'heure de la journée. De plus les données pour un jour sont plus volumineuses que les données mensuelles, donc je conseille de rester sur ces dernières.

Avec UrlFetchApp et un peu simplifié:

JavaScript:
function request(year, month) {
    var url = "http://www.suntrol-portal.com/fr/plant/graph-json/month/p/1/pid/14895/date/" + year + "-" + month + "/size/page/chart/Column3D/axis/static/output/real";
    var datas = JSON.parse(UrlFetchApp.fetch(url).getContentText());
    var values = new Array();
    for(var i=0; i<datas.data.length; i++) {
        values[i+1] = datas.data[i].value; }
    return values;
}

var values = request(2013, 11);
alert("La production pour le 6.11.2013 est de " + values[6] + "kWh");

Encore une fois, la 2ème ligne doit être remplacé par:
JavaScript:
var url = "http://www.suntrol-portal.com/fr/plant/graph-json/month/p/1/pid/14895/date/" + year + "-" + month + "/size/page/chart/Column3D/axis/static/output/real";
 

BEBER1212

Expert
J'avais bien remplacé la ligne 3 (pas au début...). Mais la fonction XmlHttpRequest n'est pas supportée par les Google Scripts...

Merci pour ce code !!! C'est exactement ce qu'il me fallait, et je pense que finalement je n'aurais jamais réussi... Autant le VB (ce dont je me souviens) était compréhensible pour un néophyte, autant là...

En fait je comprends ton code, mais je suis incapable d'en écrire le moindre bout. La seule chose que je ne comprends pas, c'est comment le tri est fait parmi toutes les données json affichées dans la page de l'url interrogé...

Je n'ai plus qu'à essayer de mettre ça en forme. Je pense que je vais encore avoir besoin d'aide ;)
 

BEBER1212

Expert
Pour aller plus loin :
Les données récupérées sont sur une feuille appelée "Suntrol".
Elles sont en ligne, classées de 1 à 31 (jours du mois).

Sur une autre feuille "2013-2014", j'ai un tableau :
Colonnes de octobre 2013 à septembre 2014, lignes de 1 à 31. Je voudrais donc, une fois les données récupérées, remplir la cellule correspondant à la date du jour.

Pour tester un peu de code, j'ai essayé de remplir une case avec la valeur value[7], mais ça ne me donne rien.

Voilà ce que j'ai ajouté, à la fin de la fonction :

JavaScript:
 var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("2013-2014");
  sheet.getRange(14,3).setValue(values[7]);

Pourquoi ça ne fait rien ?
 

KyrO_82

Grand Maître

Mais elle sont déjà triées ces données. C'est justement l'idée d'un format de données structurées. ;)

D'abord il y a la fonction JSON.parse:
var object = JSON.parse(jsonText);
Cette fonction va "parser" la représentation json d'un objet (donc du texte) en un vrai objet manipulable par le code.

Ensuite, as-tu affiché ce json sur le site que je t'ai données? ( )
Si oui, tu peux y voir que les données json représentent un objet ayant une propriété "data" qui est un tableau contenant chaque jour du mois. Pour chaque jour, on a un objet ayant une propriété "value" contenant la valeur qui nous intéresse.

D'où la ligne de code:
value = jsonDatas.data[day-1].value;

:)

 

KyrO_82

Grand Maître
Pour ton problème suivant... Déjà, je ne garanti pas qu'il n'y a pas d'erreur dans mon code. J'ai écris ça ici dans le forum, sans tester, sans débuguer..

Es-tu sûr qu'il y a bien une valeur dans values[7]?
Ca fonctionne si tu met une valeur hard-coded? (sheet.getRange(14,3).setValue("salut");)
La valeur dans values[7] est de type float, pas du texte donc. Mais je suppose que ça devrait fonctionner quand même...

Voilà.. après je sais pas quoi te dire.. je ne connais pas la prog pour ces Spreadsheets :(

Petite remarque: Veilles bien à faire un dernière mise à jour en fin de journée. Si tu fais la mesure alors que le panneau n'a pas fini de produire de l'énergie, tu aura la valeur cumulée jusqu'à la dernière mesure effectuée (utile si tu veux afficher la production d'énergie en temps réel (mais dans ce cas les données json du jour seraient plus précises, car elles donnent l'heure de la dernière mesure)).
Et pour trouver cet instant de fin de journée, vérifies qu'il n'y ait pas de décalage horaire entre l'heure du serveur de Google et l'heure en France.
 

BEBER1212

Expert
Ah d'accord.... Je n'avais pas vu ta mise à jour avec le lien pour "détailler" le json. Pas mal !
Je comprends maintenant comment tu récupères uniquement les "value".

Pour ton code, quand je le lance dans le script lui même, j'ai l'erreur suivante :
SyntaxError: Unexpected token: � (ligne 24)
soit sur la ligne :
JavaScript:
  var datas = JSON.parse(UrlFetchApp.fetch(url).getContentText());
Mais par contre quand je le lance dans ma SpreadSheet, ça fonctionne...


Pour le moment le fait d'entrer une valeur dans une cellule ne fonctionne pas, même avec une valeur "hard-coded", comme tu dis. Je vais essayer de trouver pourquoi...

Merci encore !

Pour la mise à jour de fin de journée, oui oui. Je pense lancer le code "tard".
 

BEBER1212

Expert
En fait c'est l'erreur que j'ai (Cf mon post précédent) qui bloque la fonction et qui empêche de remplir une cellule.
Car quand je remplis une cellule (par du texte simple) avant cette ligne, ça fonctionne...
 

BEBER1212

Expert
L'erreur vient de + year + "-" + month + dans la ligne suivante :

JavaScript:
var url = "http://www.suntrol-portal.com/fr/plant/graph-json/month/p/1/pid/14895/date/" + year + "-" + month + "/size/page/chart/Column3D/axis/static/output/real";

Je reçois un mail de Google tous les soirs qui m'indique les erreurs qu'il y a eu la journée sur le script. Il me marque donc "argument non valide", et remplace + year + "-" + month + par [object%20Object]-undefined...

Si je remplace par 2013-11, plus d'erreurs (mais mon remplissage de cellule ne fonctionne toujours pas pour l'instant).
 

KyrO_82

Grand Maître
D'après l'erreur que Google t'envoies par mail, tu n'envois pas les bonnes valeurs aux paramètres "year" et "month" de la fonction.
D'après le message, "year" est un objet (alors que ça devrait être un integer ou un string)
Et "month" semble être "undefined" (rien du tout, null, alors que ça devrait aussi être un integer ou un string)

Je suppose que tu récupères l'années et le mois dans ta table Spreadsheet. Vérifie cela, car ça ne semble pas fonctionner correctement ;)
Si la lecture de cellules ne fonctionne pas c'est peut-être lié au fait que le remplissage de cellule ne fonctionne pas non plus.

Il faut que tu trouve un moyen de débuguer tout ça. Tu peux surement écrire dans la console avec console.log ce qui te permettrait de vérifier toutes tes données.
 

zeb

Modérateur
Salut Beber :hello:
Je suis fier que notre collaboration fructueuse précédente te fasse revenir ici au moindre besoin. ;)

--------------------------

Salut KyrO. [strike]C'est quoi ce problème d'affichage de la ligne 3 ?
Le double-slash est sans doute à incriminer. Mets donc un espace avant, après ou entre les deux et signale-le à Beber.[/strike]
Je viens d'expérimenter le problème. C'est le www qui le déclenche. Dans le code qui suit, j'ai mis vvv à la place.

Pour plus de lisibilité et de pédagogie, je te propose d'utiliser des variables et des vérifications à outrance :

JavaScript:
    ...

    if (year == undefined) { alert('year == undefined'); return; }
    if (month == undefined) { alert('month == undefined'); return; }

    var url = "http://"
    url += "vvvvvv.suntrol-portal.com/fr/plant/graph-json/month/p/1/pid/14895/date/";
    url += year+"-"+month;
    url += "/size/page/chart/Column3D/axis/static/output/real";

    var data_json = UrlFetchApp.fetch(url).getContentText();
    if (data_json == undefined) { alert('data_json == undefined'); return; }

    var data = JSON.parse(data_json);
    if (data == undefined) { alert('data == undefined'); return; }

    ...

évidemment, c'est un peu lourd comme écriture, mais d'une part ça pose mieux les choses pour un Beber qui est novice, et d'autre part, ça simplifie la recherche des problème.

Je ne dis pas qu'une phase de concentration de code ne sera pas inutile quand tout sera au point.

--------------------------

Post Scriptum
En Latin, data est le pluriel de datum.
En français, ce mot est singulier mais indénombrable. On ne peut pas le mettre au pluriel.
 

BEBER1212

Expert
Salut Zeb, ravi de te "revoir" ;)

Euh, pour l'erreur sur la ligne 3, j'ai comme l'impression que c'est pareil avec v v v... Me trompe-je ?
Par contre il me semble l'avoir vu correctement (sur mon tel et pas sur PC) avec ton www.

Je pense que le code avec les scripts Google doit être différent du code que vous me donnez car à chaque fois il y a des trucs qui ne fonctionnent pas. Exemple ici : L'élément "alert" n'est pas défini

J'ai donc modifié un peu les messages de vérification avec ce que j'ai pu dénicher dans d'autres codes. Voilà mon code en entier :

JavaScript:
function request(year, month) {
  
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Suntrol");
  
  var year = sheet.getRange(5,2).getValue();
  var month = sheet.getRange(5,1).getValue();
  


  if (year == undefined) { var noYear = ('year == undefined'); return noYear; }
  if (month == undefined) { var noMonth = ('month == undefined'); return noMonth; }
 
var url = "http://www.suntrol-portal.com/fr/plant/graph-json/month/p/1/pid/14895/date/";
url += year+"-"+month;
url += "/size/page/chart/Column3D/axis/static/output/real";
 
var data_json = UrlFetchApp.fetch(url).getContentText();
if (data_json == undefined) { var noDataJson = ('data_json == undefined'); return noDataJson; }
 
var data = JSON.parse(data_json);
if (data == undefined) { var noData = ('data == undefined'); return noData; }
 
  
  var values = new Array();
    for(var i=0; i<data.data.length; i++) {
        values[i+1] = data.data[i].value; }
    return values; 
}
JavaScript:

Quand je teste, sans mettre de mois ou d'année, ça ne m'ouvre pas la msgBox, mais ça plante sur JSON.parse

Par contre si je mets "if (year == 0)" et que j'entre l'année à 0, là oui j'ai la msgBox.

-----------------------

Merci pour le cours de latin.
 

KyrO_82

Grand Maître
zeb:
le http:// provoque aussi la mise en forme automatique en lien, en ajoutant <a href=...></a>
"if (year == undefined) { alert('year == undefined'); return; }" n'arrangera rien si year est un objet, comme cela semble être le cas pour BEBER1212.

BEBER1212:
JSON.parse ne va fonctionner que lorsque elle reçoit des données json correctes, donc seulement si tout le code précédent cette fonction fonctionne correctement. Lorsque tu mets l'années à 0 avec le test "if (year == 0)" tu ne passes jamais par cette fonction puisque tu fais le "return noYear;"
Par contre je ne sais pas d'où vient la "msgBox" (<- syntaxe vb6 ;))

Mais tu as essayé "console.log()" comme je te l'ai conseillé dans mon message précédent? (cela permettrait probablement de résoudre tous les problèmes)
 
Vous devez vous inscrire ou vous connecter pour répondre ici.
Derniers messages publiés
Statistiques globales
Discussions
730 098
Messages
6 717 100
Membres
1 586 287
Dernier membre
lucilleguffey
Partager cette page
Haut