TypeError
As tu bien déclaré ces commandes en type numérique et as tu activé l’historique ??
Bon je ne sais pas pourquoi, j’ai dû faire des modifs en même temps que j’écrivais ma demande
j’ai bien les données qui remontent même si les premières ne sont pas très cohérentes… je vais suivre cela de près dans les prochains jours…
Par contre je n’ai pas l’info de la dernière douche comme sur ton image.
Un grand merci pour ton tuto et ton aide!!!
C’est une ancienne copie d’écran tu l’as maintenant au dessus du graphe
Si tu veux l’enlever:
#hide_value# : hides the serie's last value displayed at the the top (default: no)
Bon là je comprend plus rien… Je n’ai plus le graphique
et j’ai ce message d’erreur …

Pourtant j’ai bien les historiques
Je tourne en rond et je ne sais pas où est le problème… (certainement sous mes yeux, mais je bloque…)
Parce qu’on est le 13?
Tu as du changer quelque chose. Vérifies si l’historique de la commande Present existe tjs. Si tu as renommé l’équipement ou les commandes il te faut modifier le script
effectivement j’avais pas vu heureusement que c’est pas vendredi…
N’arrivant pas du tout à m’en sortir j’ai fait appel à un « ami » Chatgpt et ca fonctionne maintenant
Voici les optimisations qu’il à fait ainsi qu’un code optimisé:
Résumé des modifications
- Ajout de vérifications pour les données :
- Vérification que
hist
,hist.data
sont définis et quehist.data
est un tableau non vide avant de tenter d’accéder à ses propriétés.
- Ajout de consoles de log :
- Utilisation de
console.log
etconsole.error
pour diagnostiquer les données reçues et les erreurs de la requête AJAX.
- Prévention des index négatifs :
- Utilisation de
Math.max(0, hist.data.length - nb_values)
pour éviter d’accéder à des indices négatifs dans le tableau des données.
Explications des modifications :
- Ajout des consoles de log :
console.error('Error in AJAX request:', error);
pour afficher les erreurs de la requête AJAX.console.log('AJAX request successful. Data received:', hist);
pour vérifier les données reçues de l’API.
- Vérifications des données :
- Ajout de la condition
if (hist && hist.data && Array.isArray(hist.data) && hist.data.length > 0)
pour s’assurer quehist.data
est un tableau non vide avant de tenter d’y accéder.
- Prévention des index négatifs :
- Utilisation de
Math.max(0, hist.data.length - nb_values)
pour éviter les index négatifs lorsquenb_values
est supérieur à la longueur des données.
@rootard ; tout ça grâce au travail que tu as fourni!!! encore un grand merci à toi!
Comment les enfants vont me détester !!
Tu as raison ca va être comme chez moi
Bonjour @rootard, je viens d’installer tgw (hier pour être précis). Comment as-tu fais pour identifier la touchette Hydrao ?
Merci
Salut
Avec le plugin-mqttdiscovery elle apparaît en tant que device inconnu…quand l’eau est ouverte.
Par contre je n’ai que l’info presence et le rssi
Moi j’ai plein de device inconnu mais je ne vois rien de plus quand l’eau est ouverte.
J’imagine qu’il faut que je rajoute une antenne dans la salle de bains.
J’imagine aussi que c’est tagué inconnu dans la marque ou modèle.
Merci
EDI : avec un scanner bluetooth sur mobile, je trouve bien la couchette « HYDRA_SHOWER ».
Maintenant faut que je comprenne pourquoi elle ne remonte pas dans l’application…
Rapproche ton antenne
J’ai mis une antenne déportée sur un RPI et ça fonctionne.
Je vais pouvoir regarder votre tuto
Merci
Petite question concernant le scénario. Le -90 correspond à la durée d’absence qui aurait été modifié dans MQTTDiscovery ? Si oui pourquoi avoir passé de 120 à 90 ? (pour le moment je reproduis sans trop me poser de question)
Merci
Bonjour
Oui exact: l’objectif est de déterminer l’arret de la douche pas la panne d’un device classique…
J’ai reduit le timeout peut etre pas assez d’ailleurs
Bonjour,
J’ai eu la même erreur que toi. J’ai fais comme toi pour avoir le script en demandant à ChatGPT.
Pour ceux qui souhaite les lignes corrigées en attendant l’implémentation par @rootard les voici :
Il a corrigé une lecture de paramètre (a mon avis un mauvais copier coller)
var max_days = isNaN('#nb_values#')? 30 : parseInt('#max_days#'); // les N dernières jours, max 30
remplacé par :
var max_days = isNaN('#max_days#') ? 30 : parseInt('#max_days#'); // les N derniers jours, max 30
Concernant la vérification de hist et hist.data :
Il faut mettre dans un bloc if le code suivant :
const k = isNaN(nb_values) ? 0: hist.data.length-nb_values;
for(let i = k; i<hist.data.length; i++) {
dates.push (new Date(hist.data[i][0]).toLocaleString('fr-FR',
{ dateStyle:'short', timeStyle: 'short', timeZone: 'UTC' }));
serie_data.push(hist.data[i][1]);
}
var graph = cmd.find('.graph'+ #id#);
barChart(graph,dates,graph_title, serie_title,serie_unit,serie_data,serie_name,serie_color);
Cela donne :
if (hist.data && hist.data.length > 0) {
const k = isNaN(nb_values) ? 0 : Math.max(0, hist.data.length - nb_values);
for (let i = k; i < hist.data.length; i++) {
if (hist.data[i] && hist.data[i].length > 1) {
dates.push(new Date(hist.data[i][0]).toLocaleString('fr-FR', { dateStyle: 'short', timeStyle: 'short', timeZone: 'UTC' }));
serie_data.push(hist.data[i][1]);
}
}
var graph = cmd.find('.graph' + #id#);
barChart(graph, dates, graph_title, serie_title, serie_unit, serie_data, serie_name, serie_color);
}
Il m’a rajouté un else avec une alert() mais je n’aime pas avoir des alert() a la rigueur un console.log() mais je m’en sert qu’en debug perso.
Merci pour les fix, repo mis à jour
Juste pour info. Voici le code final fourni par Chatgpt (au cas où :)). pour ma part ca fonctionne parfaitement
<div class="tooltips cmd cmd-widget #history#" style="min-height:35px" data-type="info" data-subtype="numeric" data-cmd_id="#id#"
data-cmd_uid="#uid#" data-version="#version#" data-eqLogic_id="#eqLogic_id#" style="display:block;">
<div class="title #hide_name#">
<div class="cmdName">#name_display#</div>
</div>
<center>
<div class="data" style="position:relative; margin-top:10px;">
<span class="value" style="font-size: 2em;" data-type="info"></span>
<span class="unit" style="font-size: 1em;"> #unite# </span>
</div>
<div class="timeCmd #history#" style="position:relative; margin-bottom:5px; font-size:10px;font-weight:normal"></div>
<div class="graph#id#" style="width: 400px; height: 400px;"></div>
</center>
<script>
function barChart(graph, categories_x, title_g, title_y, unit_y, serie_data, serie_name, serie_color) {
var fmt = '{value} ' + unit_y;
var unite = ' ' + unit_y;
graph.highcharts({
credits: {
enabled: false
},
chart: {
type: 'column', // bar pour graphiques horizontaux, pie pour des graphiques en camembert
},
title: {
text: title_g, // Titre du graphique
style: { 'color': 'var(--txt-color)', 'fontSize': '14px' }
},
xAxis: {
categories: categories_x, // labels axe X > ID du dableau des dates
labels: {
style: {
fontSize: '10px',
}
}
},
yAxis: {
title: {
text: title_y // titre de l'axe Y
},
labels: {
format: fmt // format tooltip
}
},
series: [{
name: serie_name, // nom de la série (Y)
data: serie_data,
color: serie_color, // couleur de la série
tooltip: {
valueSuffix: unite
}
}]
});
}
jeedom.cmd.addUpdateFunction('#id#', function(_options) {
var serie_title = ('#serie_title#' != '#' + 'serie_title#') ? "#serie_title#" : "#name_display#"; // valeurs en Y
var serie_name = ('#serie_name#' != '#' + 'serie_name#') ? "#serie_name#" : "Historique " + "#name_display#"; // nom de la série
var graph_title = ('#graph_title#' != '#' + 'graph_title#') ? "#graph_title#" : ''; // titre du graphique
var serie_unit = '#unite#'; // unite axe Y
var max_days = isNaN('#nb_values#') ? 30 : parseInt('#max_days#'); // les N dernières jours, max 30
var nb_values = isNaN('#nb_values#') ? 10 : parseInt('#nb_values#'); // les N dernières valeurs, max 10
var serie_color = ('#serie_color#' != '#' + 'serie_color#') ? "#serie_color#" : '';
var hide = ('#hide_value#' != '#' + 'hide_value#') ? true : false; // masquer la valeur
var cmd = $('.cmd[data-cmd_id=#id#]');
var start = moment().subtract(max_days, 'days').startOf('day').format('YYYY-MM-DD 00:00:00');
var stop = moment().format('YYYY-MM-DD 23:59:59');
var dates = [];
var serie_data = [];
if (hide) {
cmd.find('.data').hide();
cmd.find('.timeCmd').hide();
} else {
cmd.find('.data').show();
cmd.find('.timeCmd').show();
var state = parseFloat(_options.display_value);
cmd.find('.value').empty().append(state);
jeedom.cmd.displayDuration(_options.valueDate, cmd.find('.timeCmd'));
}
jeedom.history.get({
cmd_id: #id#,
dateStart: start,
dateEnd: stop,
error: function (error) {
console.error('Error in AJAX request:', error);
},
success: function (hist) {
console.log('AJAX request successful. Data received:', hist);
if (hist && hist.data && Array.isArray(hist.data) && hist.data.length > 0) {
const k = isNaN(nb_values) ? 0 : Math.max(0, hist.data.length - nb_values);
for (let i = k; i < hist.data.length; i++) {
dates.push(new Date(hist.data[i][0]).toLocaleString('fr-FR',
{ dateStyle: 'short', timeStyle: 'short', timeZone: 'UTC' }));
serie_data.push(hist.data[i][1]);
}
var graph = cmd.find('.graph' + #id#);
barChart(graph, dates, graph_title, serie_title, serie_unit, serie_data, serie_name, serie_color);
} else {
console.error('Invalid data format or no data:', hist);
}
}
});
});
jeedom.cmd.refreshValue([{ cmd_id: '#id#', display_value: '#state#', valueDate: '#valueDate#', collectDate: '#collectDate#', alertLevel: '#alertLevel#' }]);
</script>
</div>