Calcul moyenne base de données

Eléphanteau du PHP | 22 Messages

22 nov. 2023, 23:20

Bonjour,
Avec ton aide j'ai bien avancé j'ai fait des moyennes min et max sur des Températures et ça fonctionne
Par contre mon pb vient calcul min max du % d'humidité :

Le calcul moyenne du %Hum fonctionne correctement par contre dés que j'essaye le calcul du min ou max j'ai le message d'erreur suivant :
Fatal error: Uncaught TypeError: round(): Argument #1 ($num) must be of type int|float, string given in /storage/ssd4/987/21478987/public_html/esp-weather-station.php:174 Stack trace: #0 /storage/ssd4/987/21478987/public_html/esp-weather-station.php(174): round() #1 {main} thrown in /storage/ssd4/987/21478987/public_html/esp-weather-station.php on line 174


Code : Tout sélectionner

$max_humiX = maxReadingX($nber_days_avg, 'value2'); $avg_humiX = avgReadingX($nber_days_avg, 'value2');
Ligne 174 :

Code : Tout sélectionner

<td><?php echo round($max_humiX['max_amount'], 0); ?> %</td> <td><?php echo round($avg_humiX['avg_amount'], 0); ?> %</td>

Code : Tout sélectionner

function avgReadingX($nbdays, $value) { global $servername, $username, $password, $dbname; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "SELECT AVG(" . $value . ") AS avg_amount FROM SensorData WHERE reading_time >= NOW() - INTERVAL ". $nbdays ." DAY"; if ($result = $conn->query($sql)) { return $result->fetch_assoc(); } else { return false; } $conn->close(); } function maxReadingX($nbdays, $value) { global $servername, $username, $password, $dbname; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "SELECT MAX(" . $value . ") AS max_amount FROM SensorData WHERE reading_time >= NOW() - INTERVAL ". $nbdays ." DAY"; if ($result = $conn->query($sql)) { return $result->fetch_assoc(); } else { return false; } $conn->close(); }
Je peux déposer tout le code mais ça peut être fastidieux si tu me donnes des pistes je vais essayer de chercher par moi-même

Avatar du membre
Mammouth du PHP | 1564 Messages

22 nov. 2023, 23:55

L'erreur parle, elle dit que le type envoyé à la fonction PHP round() doit être un entier ou float (à virgule).

Essaye en le castant :
round( (float) $max_humiX['max_amount'], 0);
Pareil pour l'autre si ça fonctionne. ;)

On aurait pu mettre (int) pour le caster en nombre entier mais si c'est un nombre à virgule, on gardera les virgules avec float.

Eléphanteau du PHP | 22 Messages

24 nov. 2023, 12:35

Bonjour,
Merci pour tes remarque je les ai utilisé et j'ai réussi à avancer sur la syntaxe reste encore des petits soucis de calculs
Voici le bilan en vert les calculs sont ok et en rouge nok j'ai vérifié en faisant les calculs par excel
Image

J'ai essayé de trouver par différence mais je bloque, voici les lignes correspondantes, je vais partir de l'exemple de Temp et Humidité
Mini Humidité est OK
Mini Tem est non ok

Les données sont obtenues de la façon suivante :

Code : Tout sélectionner

if (isset($_GET["readingsCount"])){ $data = $_GET["readingsCount"]; $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data);
Appel fonction
Temp :

Code : Tout sélectionner

$min_temp1 = minReading1('value1');
Humidité ok

Code : Tout sélectionner

$min_humi1 = minReading1('value2');

La fonction mini reading1

Code : Tout sélectionner

function minReading1( $value) { global $servername, $username, $password, $dbname; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } $sql = "SELECT MIN(" . $value . ") AS min_amount FROM SensorData WHERE DAYOFYEAR(reading_time) = DAYOFYEAR(NOW())"; if ($result = $conn->query($sql)) { return $result->fetch_assoc(); } else { return false; } $conn->close(); }
Et pour finir l'affichage :
Temp

Code : Tout sélectionner

<td><?php echo round( (float) $min_temp1['min_amount'], 1); ?> &deg;C</td>
Humidité :

Code : Tout sélectionner

<td><?php echo round( (float) $min_humi1['min_amount'], 0); ?> %</td>

Dans tous les cas les valeurs sont stockés dans le BD sous forme de var(10)
Modifié en dernier par FredD le 24 nov. 2023, 13:05, modifié 1 fois.

Avatar du membre
Mammouth du PHP | 1564 Messages

24 nov. 2023, 12:51

Attention avec DAYOFYEAR car il te retournera les données de n'importe quelle année (le jour i de l'année 2022, de l'année 2023,...). Peut être une piste ;)

Tu as des erreurs SQL dans les logs ?

Eléphanteau du PHP | 22 Messages

24 nov. 2023, 14:52

Bonjour,
Tu as des erreurs SQL dans les logs ?
Pour cela peux tu me dire comment y accéder?

Dernier point je viens de faire un check avec excel sur plus de valeurs du jour en fait aucun calcul n'est OK , ce matin sur peu de valeurs la diff devait être minime donc c'est bien le mode de calcul qui est nok
Calcul moyenne sur la journée

Code : Tout sélectionner

$sql = "SELECT AVG(" . $value . ") AS avg_amount FROM SensorData WHERE reading_time >= NOW() - INTERVAL 1 DAY ";
Calcul max

Code : Tout sélectionner

$sql = "SELECT MAX(" . $value . ") AS max_amount FROM SensorData WHERE reading_time >= NOW() - INTERVAL 1 DAY ";
Calcul min

Code : Tout sélectionner

$sql = "SELECT MIN(" . $value . ") AS min_amount FROM SensorData WHERE reading_time >= NOW() - INTERVAL 1 DAY ";
Je vais tenter une approche between
Merci.
Modifié en dernier par FredD le 24 nov. 2023, 18:39, modifié 2 fois.

Avatar du membre
Mammouth du PHP | 1564 Messages

24 nov. 2023, 15:16

Tu travail en local WAMP ou LAMP ? Les logs sont accessibles depuis l'icône verte en bas à droite > PHP > PHP error log

Si tu est en production, sur un site web, voir avec ton hébergeur si il enregistre les logs (et où) et y accéder.

Eléphanteau du PHP | 22 Messages

24 nov. 2023, 22:11

Je continue mes investigations j'ai fait ce test directement dans phpadmin:

Code : Tout sélectionner

SELECT MAX(`value1`) FROM SensorData;

est j'obtiens 9.93 ce qui est le même résultat qu' avec la fonction dans php, pourtant c'est juste impossible j'ai dans ma BD des mesures dans la maiso navec des valeurs à 19 20°C même aujourd'hui le max était à 9.5°c
et pour

Code : Tout sélectionner

SELECT MIN(`value1`) FROM SensorData;
en fait pas de résultat alors que des valeurs existent

Pour info mes valeurs sont en :
value1 varchar(10) utf8_unicode_ci Oui NULL
En conclusion le pb ne vient peut être pas des lignes php mais de la BD??
Modifié en dernier par FredD le 25 nov. 2023, 00:08, modifié 1 fois.

Avatar du membre
Mammouth du PHP | 1564 Messages

24 nov. 2023, 22:18

Passe tes colonne à DECIMAL, pas VARCHAR, le MAX() peut l'interpreter différemment je penses.

Le passage à DECIMAL risque de faire des conversions, bizarre, pense à sauvegarder.

met DECIMAL (4,2) pour avoir des nombres flottants allant de 0.00 à 99.99

Eléphanteau du PHP | 22 Messages

25 nov. 2023, 16:37

J'ai essayé mais j'ai le message suivant :

Erreur de requête:
#1292 - Truncated incorrect DECIMAL value: ''
ALTER TABLE `SensorData` CHANGE `value1` `value1` DECIMAL(4,2) NULL DEFAULT NULL;

Avatar du membre
Mammouth du PHP | 1564 Messages

25 nov. 2023, 17:20

C'est parce qu'une colonne est vide, avant la conversion met tous les champs qui sont vides : '' à 0.00
UPDATE SensorData SET value1 = '0.00' WHERE value1 = ''

Eléphanteau du PHP | 22 Messages

26 nov. 2023, 01:39

Bonjour,
Je ne saisis pas la remarque :
C'est parce qu'une colonne est vide, avant la conversion met tous les champs qui sont vides : '' à 0.00
UPDATE SensorData SET value1 = '0.00' WHERE value1 = ''

Avatar du membre
Mammouth du PHP | 1564 Messages

26 nov. 2023, 02:22

L'erreur SQL que tu mentionne est due au fait que tu souhaite convertir ta colonne de VARCHAR à DECIMAL, elle te dit "non je peux pas convertir certaines valeurs qui sont vides, soit ''.

Pour contrer cela, fait un UPDATE de toutes tes valeurs VARCHAR, si certains sont vides (soit '') met 0.00, d'où ma requête SQL.