Analyse Json

Bonsoir, je suis utilisateur Jeedom depuis longtemps, mais débutant dans la programmation.

Pour faire simple, je teste actuellement une offre d’électricité dont le prix varie toutes les 15mn (Sobry si vous êtes intéressé).
Je peux récupérer la liste des prix du lendemain ici :
https://api.sobry.co/api/prices/raw?start=2025-10-23&end=2025-10-24&turpe=CU4&profil=particulier

Le but serait d’identifier 2 plages horaires : nuit et après midi pour déclencher la chauffe de mon ECS. Qui est actuellement piloté par Jeedom mais via un scénario à horaire fixe…

Je ne sais pas comment faire…
Merci et bonne fin de journée

rémy

Salut,

Pour parser un json et le mettre dans une commande info, le plugin-script peut faire l’affaire.
Je te conseille de consulter sa doc qui donne quelques exemples

Voir particulièrement le paragraphe JSON : https://doc.jeedom.com/fr_FR/plugins/programming/script/#JSON

Je viens de faire le test pour récupérer la valeur de price_ttc_eur_kwh pour la 1ere période (qui commence à 0 et pas à 1 ici).

Enfin après la il y a 95 périodes je sais pas si ça vaut le coup ou pas de mettre ça dans 95 commandes jeedom et d’avoir une telle granularité.
Il faudrait voir en fonction de ton besoin et de la doc de l’api ce qui est faisable.

Après avec un petit scénario tu dois pouvoir simplement faire des comparaions entre l’heure actuelle et le prix récupéré par l’api pour lancer des on / off.

2 « J'aime »

Bonjour,

L’API retourne 96 tranches de 15 min. Pour trouver la fenêtre glissante de 3h consécutives la moins chère, l’algo classique est une sliding window sur 12 slots (12 × 15 min = 3h).

Voici le code PHP complet :

<?php

/**
 * Trouve la fenêtre de 3h consécutives la moins chère dans la journée.
 * Algo : sliding window sur 12 slots de 15 min.
 */
function getCheapest3Hours(string $date): array
{
    $url = sprintf(
        'https://api.sobry.co/api/prices/raw?start=%s&end=%s&turpe=CU4&profil=particulier',
        $date,
        date('Y-m-d', strtotime($date . ' +1 day'))
    );

    $json = file_get_contents($url);
    if (!$json) {
        throw new \RuntimeException("Impossible de contacter l'API");
    }

    $response = json_decode($json, true);
    if (!$response['success'] || empty($response['data'])) {
        throw new \RuntimeException("Données invalides");
    }

    $slots    = $response['data'];
    $n        = count($slots);
    $window   = 12; // 12 × 15 min = 3h

    if ($n < $window) {
        throw new \RuntimeException("Pas assez de données ({$n} slots)");
    }

    // 1. Somme de la première fenêtre
    $currentSum = 0.0;
    for ($i = 0; $i < $window; $i++) {
        $currentSum += $slots[$i]['price_ttc_eur_kwh'];
    }

    $minSum   = $currentSum;
    $minStart = 0;

    // 2. Sliding window : on avance slot par slot
    for ($i = $window; $i < $n; $i++) {
        $currentSum += $slots[$i]['price_ttc_eur_kwh'];
        $currentSum -= $slots[$i - $window]['price_ttc_eur_kwh'];

        if ($currentSum < $minSum) {
            $minSum   = $currentSum;
            $minStart = $i - $window + 1;
        }
    }

    $bestSlots = array_slice($slots, $minStart, $window);

    return [
        'start'         => $bestSlots[0]['timestamp'],
        'end'           => $bestSlots[$window - 1]['timestamp'],
        'avg_ttc_eur_kwh' => round($minSum / $window, 5),
        'total_sum'     => round($minSum, 5),
        'slots'         => $bestSlots,
    ];
}

// --- Utilisation ---
try {
    $result = getCheapest3Hours('2025-10-23');

    echo "✅ Meilleure fenêtre de 3h :\n";
    echo "  De  : " . $result['start'] . "\n";
    echo "  À   : " . $result['end'] . "\n";
    echo "  Prix moyen TTC : " . $result['avg_ttc_eur_kwh'] . " €/kWh\n";
    echo "  Somme des prix : " . $result['total_sum'] . " €/kWh\n";

} catch (\Exception $e) {
    echo "Erreur : " . $e->getMessage() . "\n";
}

Pourquoi la sliding window ?

Naïvement on pourrait tester toutes les fenêtres possibles en recalculant la somme à chaque fois — c’est O(n × 12). La sliding window c’est O(n) : on ajoute le slot entrant et soustrait le slot sortant, sans tout recalculer.

Fenêtre [0..11]  → somme initiale
Fenêtre [1..12]  → somme += slot[12] - slot[0]
Fenêtre [2..13]  → somme += slot[13] - slot[1]
...

Sur les données du 23/10/2025, la meilleure fenêtre serait autour de 03h45–06h45 (les slots à ~0.05094 €/kWh). Sur price_ttc_eur_kwh c’est le champ le plus pertinent car il inclut TURPE + accise + TVA.


Deux variantes utiles :

Si tu veux les 3h pas forcément consécutives (ex. pour piloter une charge interruptible), remplace l’algo par un simple tri :

usort($slots, fn($a, $b) => $a['price_ttc_eur_kwh'] <=> $b['price_ttc_eur_kwh']);
$cheapest12 = array_slice($slots, 0, 12); // 12 slots = 3h

Si la durée de 3h est paramétrable, remplace juste $window = 12 par $window = (int)($heures * 4).

Claude AI

Je trouve sa réponse pertinente. le plugin script t’impose de savoir quelle tranche horaire interroger, mais sinon tu récupérer toutes les tranches de la journée avec ce petit script php pour avoir les périodes les moins chères, consécutives, ou pas. Au final tu pourrais activer ton appareil sur les 12 périodes de 15 min les moins chères de la journée (si 3H est suffisant pour chauffer ton eau?)
Pifou

3 « J'aime »

Hello, un grand merci !
C’est super sympa d’avoir pris le temps de me répondre avant tous les détails !

La fonction php est super intéressante je vais regarder ça.
La pompe à chaleur a souvent besoins de moins de 1h pour faire son eau chaude, mais par habitude je mets un slot de 2 heures, donc je vais adapter en 4 slots consécutifs.
Par contre super question : c’est possible de trouver 4 slots entre minuits et 6h, et 4 slot entre 12h et 17h ?
Merci encore !
Belle journée

EDIT // 2 autres super question :

  • dans l’appel de la fonction en base du script, si je veux systématiquement passer la date du lendemain ? (les tarif étant connu la veille à 13h, je ferai tourner le script en fin de journée pour le lendemain). Il y aussi ce lien vers l’API avec les prix de demain : https://api.sobry.co/api/prices/tomorrow?turpe=CU4&profil=particulier

  • en retour j’aimerai 3 variable contenant heure de début et heure de fin de la période : exemple 0400 et 0600 pour la nuit.

  • si on peut passer en granularité par heure :

|granularity|String|optionnel|Granularité des données (défaut: quarter_hourly)
Valeurs possibles :
quarter_hourly - Données toutes les 15 minutes
hourly - Données horaires
daily - Données journalières

info : Sobry API - Documentation_gaNzU3MzY3Nzk3LjE3Nzg0MDQ2Nzk._ga_TFX9JYEN41czE3Nzg2NzIxODUkbzQkZzEkdDE3Nzg2NzIyMTQkajMxJGwwJGgw

Merci x3 !

Voici le code en php.
Merci ton aide !!


<?php

$url = "https://api.sobry.co/api/prices/tomorrow?turpe=CU4&profil=particulier";

$response = file_get_contents($url);

if ($response === false) {
    die("Erreur API");
}

$data = json_decode($response, true);

if (!isset($data['prices'])) {
    die("Format API invalide");
}

$prices = $data['prices'];

function findCheapest2Hours(array $prices, int $startHour, int $endHour): ?array
{
    $filtered = [];

    foreach ($prices as $price) {

        $timestamp = strtotime($price['timestamp']);
        $hour = (int)date('G', $timestamp);

        if ($hour >= $startHour && $hour < $endHour) {
            $filtered[$hour] = $price['price_ttc_eur_kwh'];
        }
    }

    ksort($filtered);

    $hours = array_keys($filtered);

    $bestTotal = null;
    $bestPair = null;

    for ($i = 0; $i < count($hours) - 1; $i++) {

        $h1 = $hours[$i];
        $h2 = $hours[$i + 1];

        if ($h2 !== $h1 + 1) {
            continue;
        }

        $total = $filtered[$h1] + $filtered[$h2];

        if ($bestTotal === null || $total < $bestTotal) {
            $bestTotal = $total;
            $bestPair = [$h1, $h2 + 1]; // fin = heure +1
        }
    }

    return $bestPair;
}

/**
 * Format hhmm
 */
function formatHHMM(int $hour): string
{
    return str_pad($hour, 2, "0", STR_PAD_LEFT) . "00";
}

// Nuit 1h → 5h
$night = findCheapest2Hours($prices, 1, 5);

// Après-midi 13h → 17h
$afternoon = findCheapest2Hours($prices, 13, 17);

// Variables finales demandées
$heure_debut_nuit = $night ? formatHHMM($night[0]) : null;
$heure_fin_nuit = $night ? formatHHMM($night[1]) : null;

$heure_debut_aprem = $afternoon ? formatHHMM($afternoon[0]) : null;
$heure_fin_aprem = $afternoon ? formatHHMM($afternoon[1]) : null;

// Résultat
echo "heure_debut_nuit = $heure_debut_nuit\n";
echo "heure_fin_nuit = $heure_fin_nuit\n";
echo "heure_debut_aprem = $heure_debut_aprem\n";
echo "heure_fin_aprem = $heure_fin_aprem\n";

1 « J'aime »

Ce sujet a été automatiquement fermé après 24 heures suivant le dernier commentaire. Aucune réponse n’est permise dorénavant.