MiScale : Conversion profiles de BLEA vers scenario, scripts,

Bonjour,

Je regarde actuellement pour me débarraser de BLEA en passant sous Theengs Gateway. (Merci @Mips au passage pour tes 2 plugins. Ils fonctionnent très bien).

Pour la balance MiScale, il y a des calculs spécifiques (IMC, …) qui sont effectués avec le plugin-blea :

Est-ce que quelqu’un s’est déjà « amusé » à convertir cela dans un scenario ou utiliser directement le code dans un script par exemple ?

Quel serait la meilleure façon de faire selon vous ?

Merci.

1 « J'aime »

Salut,

Je relis ce post et du coup je me pose une question: les infos supplémentaires devraient être décodées à la source (par theengsgateway ?) ou ce sont toutes des infos calculées?

Si calculé à partir d’une info qui remonte déjà alors ca serait faisable dans un virtuel par exemple ou c’est plus compliqué?

J’essaie de comprendre ce qu’il manque pour voir si dans plugin-mqttdiscovery il y a nécessité de laisser plus de flexibilité sur les commandes créés.

1 « J'aime »

Salut,
Je suis intéressé pour que tu améliores le plugin :slight_smile:
Voici ce que remonte ma balance quand je me pèse :

{
  "name": "MIBFS",
  "id": "88:22:B2:xx:xx:xx",
  "rssi": -82,
  "rssi": -78,
  "brand": "Xiaomi",
  "model": "Mi Body Composition Scale",
  "model_id": "XMTZC02HM/XMTZC05HM",
  "type": "SCALE",
  "weighing_mode": "person",
  "unit": "kg",
  "weight": 84.65,
  "impedance": 460,
  "mfr": "Anhui Huami Information Technology Co., Ltd."
}

Cela signifie qu’il faut stocker son âge (ou sa date de naissance) et sa taille quelque part.
Et le sexe aussi, si tu reprends la totale des formules.

Je ne sais pas comment cela fonctionne s’il y a plusieurs personnes dans le foyer pour gérer les formules.

Non mqttdiscovery ne va pas gérer lui les formules, ca n’a pas de sens selon moi dans ce plugin mais je voulais comprendre si avec les formules de calculs de jeedom c’était faisable (via virtuel par exemple)

Ok, je comprends.
Le plugin BLEA fait pas mal de calcul en fonction de l’age, du sexe et du poids pour donner les infos.
Un virtuel va galérer je pense.
Un scénario avec bloc code à la rigueur, voir un plugin à part entière, s’en sortirait mieux.

Je ne comprends toujours pas comment il peut faire ca à partir de l’âge ou autre alors que juste le poid remonte :thinking:

Le calcul de base de l’IMC, c’est juste

IMC = Poids / Taille x Taille

Ensuite il semble y avoir des coéfficients pour l’age et le sexe.

Ensuite, la balance donne aussi l’impédance.
Là, je vois qu’il calcule tout un tas de trucs
LBM : Lean body mass
BMR : métabolisme de base
Pourcentage de graisse
Pourcentage d’eau
Os

Je vois qu’un commentaire peut-être retrouvé dans un autre fichier :

Peut-être à gérer dans Theengs Gateway, sinon dans Jeedom.

Bonsoir,

Dans le plugin-blea il y une page de configuration spécifique qui permet de stocker les infos des personnes.

Les calculs sont fait à partir de ces infos, ainsi que le poids et l’impedance données par la balance à chaque pesée.

A chaque fois qu’une pesée est faite, le plugin fait aussi des calculs pour retrouver le profil de la bonne personne et lui associer les nouvelles valeurs pour avoir un historique. Par default, il y a déjà beaucoup de commandes. Des qu’une personne est ajoutée dans les profils, toutes les commandes sont dupliquées pour la personne concernée.

Peut être que chaque personne peut être gérée par un virtuel et les calculs seraient effectués dans un scénario ou script ( peut être plus simple de réutiliser l’existant) pour lequel les valeurs d’entrées seraient les valeurs du profil (la taille, le poids, la date de naissance, le sexe) et les deux valeurs remontées par la balance (poids et impédance).

Édit : Dans Theengs Décoder, il est aussi possible de faire des calculs. Ça serait en effet plus simple si cela était fait à la source et remontait automatiquement dans le plugin-mqttdiscovery. Ça vaut peut être le coup en effet de poser la question côté Theengs.

Salut,

Hier soir, j’ai demandé à Copilot de me convertir le code Python en PHP, et je l’ai mis dans un bloc Code d’un scénario.
Je suis parti de la source que j’ai trouvé pour ne pas piller BLEA :

  • La partie metric donne les % de gras, le BMR…
    Testé et fonctionne.

  • La partie scale est une série de valeurs utilisées en interne.
    Testé indirectement et fonctionne avec mes données.

  • La partie score, je n’ai pas compris ce que c’était :slight_smile:
    Je laisse tout car c’est long à convertir.

Ce bout de code sert de base :

  • Je n’ai pas amélioré le tout pour chercher les données dans un virtuel et alimenter un virtuel en retour,
  • Je n’ai pas fait de code qui cherche qui peut bien se peser,
  • Je n’ai testé qu’avec mes données, et j’ai comparé avec l’application Zepp,
  • Je n’ai pas d’environnement dédié PHP pour debuguer correctement.

Je verrai si j’ai l’envie et le temps d’aller plus loin en mode scénario.

Et pour finir, je renvoi sur une vidéo Youtube de Scilabus qui montre que l’indicateur IMC n’est qu’un indicateur :
Obésité, surpoids, normalité : quand l’IMC se trompe

Bon jeu :slight_smile:

class Person {
  public $age;
  public $height;
  public $sex;
  public $weight;
  public $impedance;
}

$person = new Person();
$person->age = 49;         	// Age
$person->height = 180; 		// Taille en cm
$person->sex = 'male';  	// 'male' ou 'female'
$person->weight = 80;   	// poids en kg
$person->impedance = 460;  	// impedance

$person->scaleType = 'xiaomi';


// Metrics
$person->bmrCoef = round(getLBMCoefficient($person), 2);
$person->bmr = round(getBMR($person), 2);

$person->bodyfat = round(getFatPercentage($person), 2);
$person->water = round(getWaterPercentage($person), 2);
$person->bone = round(getBoneMass($person), 2);
$person->muscle = round(getMuscleMass($person), 2);
$person->visceral_fat = round(getVisceralFat($person), 2);
$person->bmi = round(getBMI($person), 2);
$person->protein = round(getProteinPercentage($person, True), 2);

$person->ideal = round(getIdealWeight($person, $orig=True), 2);
$person->metabolicAge = round(getMetabolicAge($person), 2);

$scenario->setLog('person:'.json_encode($person));


$fatPercentageScale = getFatPercentageScale($person);
$test = getBodyType($person->bodyfat, $person->muscle, $fatPercentageScale, $muscleMassScale);
$scenario->setLog('getBodyType:'.$test);


// Score
/*
$scale = getBmiDeductScore($person);
$scenario->setLog('getBmiDeductScore:'.$scale); 

$scale = getBodyFatDeductScore($person);
$scenario->setLog('getBodyFatDeductScore:'.$scale); 

$scale = getMuscleDeductScore($person);
$scenario->setLog('getMuscleDeductScore:'.$scale); 

$scale = getWaterDeductScore($person);
$scenario->setLog('getWaterDeductScore:'.$scale); 

$scale = getBoneDeductScore($person);
$scenario->setLog('getBoneDeductScore:'.$scale); 
*/

//------------- bodyMetrics ----------
/**
 * Set the value to a boundary if it overflows
 */
function checkValueOverflow($value, $minimum, $maximum) {
    if ($value < $minimum) {
        return $minimum;
    } elseif ($value > $maximum) {
        return $maximum;
    } else {
        return $value;
    }
}


/** 
 * Get LBM coefficient (with impedance)
 */
function getLBMCoefficient($person) {
    $lbm =  ($person->height * 9.058 / 100) * ($person->height / 100);
    $lbm += $person->weight * 0.32 + 12.226;
    $lbm -= $person->impedance * 0.0068;
    $lbm -= $person->age * 0.0542;
    return $lbm;
}

/** 
 * Get BMR
 */
function getBMR($person) {
    if ($person->sex == 'female') {
        $bmr = 864.6 + $person->weight * 10.2036;
        $bmr -= $person->height * 0.39336;
        $bmr -= $person->age * 6.204;
    } else {
        $bmr = 877.8 + $person->weight * 14.916;
        $bmr -= $person->height * 0.726;
        $bmr -= $person->age * 8.976;
    }

    // Capping
    if ($person->sex == 'female' && $bmr > 2996) {
        $bmr = 5000;
    } elseif ($person->sex == 'male' && $bmr > 2322) {
        $bmr = 5000;
    }
    return checkValueOverflow($bmr, 500, 10000);
}

/** 
 * Get fat percentage
 */
function getFatPercentage($person) {
    // Set a constant to remove from LBM
    if ($person->sex == 'female' && $person->age <= 49) {
        $const = 9.25;
    } elseif ($person->sex == 'female' && $person->age > 49) {
        $const = 7.25;
    } else {
        $const = 0.8;
    }

    // Calculate body fat percentage
    $LBM = getLBMCoefficient($person);

    if ($person->sex == 'male' && $person->weight < 61) {
        $coefficient = 0.98;
    } elseif ($person->sex == 'female' && $person->weight > 60) {
        $coefficient = 0.96;
        if ($person->height > 160) {
            $coefficient *= 1.03;
        }
    } elseif ($person->sex == 'female' && $person->weight < 50) {
        $coefficient = 1.02;
        if ($person->height > 160) {
            $coefficient *= 1.03;
        }
    } else {
        $coefficient = 1.0;
    }
    $fatPercentage = (1.0 - (((floatval($LBM) - $const) * $coefficient) / $person->weight)) * 100;

    // Capping body fat percentage
    if ($fatPercentage > 63) {
        $fatPercentage = 75;
    }
    return checkValueOverflow($fatPercentage, 5, 75);
}

/**
 * Get water percentage
 */
function getWaterPercentage($person) {
    $fatPercentage = getFatPercentage($person);
    $waterPercentage = (100 - $fatPercentage) * 0.7;

    if ($waterPercentage <= 50) {
        $coefficient = 1.02;
    } else {
        $coefficient = 0.98;
    }

    // Capping water percentage
    if ($waterPercentage * $coefficient >= 65) {
        $waterPercentage = 75;
    }
    return checkValueOverflow($waterPercentage * $coefficient, 35, 75);
}

/**
 * Get bone mass
 */
function getBoneMass($person) {
    if ($person->sex == 'female') {
        $base = 0.245691014;
    } else {
        $base = 0.18016894;
    }

    $boneMass = ($base - (getLBMCoefficient($person) * 0.05158)) * -1;

    if ($boneMass > 2.2) {
        $boneMass += 0.1;
    } else {
        $boneMass -= 0.1;
    }

    // Capping boneMass
    if ($person->sex == 'female' && $boneMass > 5.1) {
        $boneMass = 8;
    } elseif ($person->sex == 'male' && $boneMass > 5.2) {
        $boneMass = 8;
    }
    return checkValueOverflow($boneMass, 0.5 , 8);
}

/** 
 * Get muscle mass
 */
function getMuscleMass($person) {
    $fatPercentage = getFatPercentage($person);
    $boneMass = getBoneMass($person);
    $muscleMass = $person->weight - (($fatPercentage * 0.01) * $person->weight) - $boneMass;

    // Capping muscle mass
    if ($person->sex == 'female' && $muscleMass >= 84) {
        $muscleMass = 120;
    } elseif ($person->sex == 'male' && $muscleMass >= 93.5) {
        $muscleMass = 120;
    }

    return checkValueOverflow($muscleMass, 10 ,120);
}

/**
 * Get Visceral Fat
 */
function getVisceralFat($person) {
    if ($person->sex == 'female') {
        if ($person->weight > (13 - ($person->height * 0.5)) * -1) {
            $subsubcalc = (($person->height * 1.45) + ($person->height * 0.1158) * $person->height) - 120;
            $subcalc = $person->weight * 500 / $subsubcalc;
            $vfal = ($subcalc - 6) + ($person->age * 0.07);
        } else {
            $subcalc = 0.691 + ($person->height * -0.0024) + ($person->height * -0.0024);
            $vfal = ((($person->height * 0.027) - ($subcalc * $person->weight)) * -1) + ($person->age * 0.07) - $person->age;
        }
    } else {
        if ($person->height < $person->weight * 1.6) {
            $subcalc = (($person->height * 0.4) - ($person->height * ($person->height * 0.0826))) * -1;
            $vfal = (($person->weight * 305) / ($subcalc + 48)) - 2.9 + ($person->age * 0.15);
        } else {
            $subcalc = 0.765 + $person->height * -0.0015;
            $vfal = ((($person->height * 0.143) - ($person->weight * $subcalc)) * -1) + ($person->age * 0.15) - 5.0;
        }
    }

    return checkValueOverflow($vfal, 1 ,50);
}

/**
 * Get BMI
 */
function getBMI($person) {
    return checkValueOverflow($person->weight/(($person->height/100)*($person->height/100)), 10, 90);
}

/** 
 * Get ideal weight (just doing a reverse BMI, should be something better)
 */
function getIdealWeight($person, $orig=True) {
    if ($orig && $person->sex == 'female') {
        return ($person->height - 70) * 0.6;
    } elseif ($orig && $person->sex == 'male') {
        return ($person->height - 80) * 0.7;
    } else {
        return checkValueOverflow((22*$person->height)*$person->height/10000, 5.5, 198);
    }
}

/**
 * Get fat mass to ideal (guessing mi fit formula)
 */
function getFatMassToIdeal($person, $fatPercentage, $fatPercentageScale) {
    $mass = ($person->weight * ($fatPercentage / 100)) - ($person->weight * ($fatPercentageScale[2] / 100));
    if ($mass < 0) {
        return ['type' => 'to_gain', 'mass' => $mass*-1];
    } else {
        return ['type' => 'to_lose', 'mass' => $mass];
    }
}

/**
 * Get protetin percentage (warn: guessed formula)
 */
function getProteinPercentage($person, $orig=True) {
    if ($orig) {
        $proteinPercentage = ($person->muscle / $person->weight) * 100;
        $proteinPercentage -= $person->water;
    } else {
        $proteinPercentage = 100 - (floor($person->bodyfat * 100) / 100);
        $proteinPercentage -= floor($person->water * 100) / 100;
        $proteinPercentage -= floor(($person->bone/$person->weight*100) * 100) / 100;
    }

    return checkValueOverflow($proteinPercentage, 5, 32);
}

/**
 * Get body type (out of nine possible)
 */
function getBodyType($fatPercentage, $muscleMass, $fatPercentageScale, $muscleMassScale) {
    if ($fatPercentage > $fatPercentageScale[2]) {
        $factor = 0;
    } elseif ($fatPercentage < $fatPercentageScale[1]) {
        $factor = 2;
    } else {
        $factor = 1;
    }

    if ($muscleMass > $muscleMassScale[1]) {
        return 2 + ($factor * 3);
    } elseif ($muscleMass < $muscleMassScale[0]) {
        return ($factor * 3);
    } else {
        return 1 + ($factor * 3);
    }
}

/**
 * Get Metabolic Age
 */
function getMetabolicAge($person) {
    if ($person->sex == 'female') {
        $metabolicAge = ($person->height * -1.1165) + ($person->weight * 1.5784) + ($person->age * 0.4615) + ($person->impedance * 0.0415) + 83.2548;
    } else {
        $metabolicAge = ($person->height * -0.7471) + ($person->weight * 0.9161) + ($person->age * 0.4184) + ($person->impedance * 0.0517) + 54.2267;
    }
    return checkValueOverflow($metabolicAge, 15, 80);
}

//----------------------------------


//-------- body_scales ---------

/**
 * Get BMI scale
 */
function getBMIScale($scaleType) {
    if ($scaleType == 'xiaomi') {
        return [18.5, 25.0, 28.0, 32.0];
    } elseif ($scaleType == 'holtek') {
        return [18.5, 25.0, 30.0];
    }
}

/**
 * Get fat percentage scale
 */
function getFatPercentageScale($person) {

  
    if ($person->scaleType == 'xiaomi') {
        $scales = [
            ['min' => 0, 'max' => 11, 'female' => [12.0, 21.0, 30.0, 34.0], 'male' => [7.0, 16.0, 25.0, 30.0]],
            ['min' => 12, 'max' => 13, 'female' => [15.0, 24.0, 33.0, 37.0], 'male' => [7.0, 16.0, 25.0, 30.0]],
            ['min' => 14, 'max' => 15, 'female' => [18.0, 27.0, 36.0, 40.0], 'male' => [7.0, 16.0, 25.0, 30.0]],
            ['min' => 16, 'max' => 17, 'female' => [20.0, 28.0, 37.0, 41.0], 'male' => [7.0, 16.0, 25.0, 30.0]],
            ['min' => 18, 'max' => 39, 'female' => [21.0, 28.0, 35.0, 40.0], 'male' => [11.0, 17.0, 22.0, 27.0]],
            ['min' => 40, 'max' => 59, 'female' => [22.0, 29.0, 36.0, 41.0], 'male' => [12.0, 18.0, 23.0, 28.0]],
            ['min' => 60, 'max' => 100, 'female' => [23.0, 30.0, 37.0, 42.0], 'male' => [14.0, 20.0, 25.0, 30.0]],
        ];
    }

    foreach ($scales as $scale) {
        if ($person->age >= $scale['min'] && $person->age <= $scale['max']) {
            return $scale[$person->sex];
        }
    }
}

/**
 * Get BMR scale
 */
function getMuscleMassScale($person) {
    if ($person->scaleType == 'xiaomi') {
        $scales = [
            ['min' => ['male' => 170, 'female' => 160], 'female' => [36.5, 42.6], 'male' => [49.4, 59.5]],
            ['min' => ['male' => 160, 'female' => 150], 'female' => [32.9, 37.6], 'male' => [44.0, 52.5]],
            ['min' => ['male' => 0, 'female' => 0], 'female' => [29.1, 34.8], 'male' => [38.5, 46.6]]
        ];
    } elseif ($person->scaleType == 'holtek') {
        $scales = [
            ['min' => ['male' => 170, 'female' => 170], 'female' => [36.5, 42.5], 'male' => [49.5, 59.4]],
            ['min' => ['male' => 160, 'female' => 160], 'female' => [32.9, 37.5], 'male' => [44.0, 52.4]],
            ['min' => ['male' => 0, 'female' => 0], 'female' => [29.1, 34.7], 'male' => [38.5, 46.5]]
        ];
    }

    foreach ($scales as $scale) {
        if ($person->height >= $scale['min'][$person->sex]) {
            return $scale[$person->sex];
        }
    }
}

/**
 * Get water percentage scale
 */
function getWaterPercentageScale($person) {
    if ($person->scaleType == 'xiaomi') {
        if ($person->sex == 'male') {
            return [55.0, 65.1];
        } elseif ($person->sex == 'female') {
            return [45.0, 60.1];
        }
    } elseif ($person->scaleType == 'holtek') {
        return [53, 67];
    }
}

/** 
 * Get visceral fat scale
 */
function getVisceralFatScale() {
    return [10.0, 15.0];
}

/**
 * Get bone mass scale
 */
function getBoneMassScale($person) {
    if ($person->scaleType == 'xiaomi') {
        $scales = [
            ['male' => ['min' => 75.0, 'scale' => [2.0, 4.2]], 'female' => ['min' => 60.0, 'scale' => [1.8, 3.9]]],
            ['male' => ['min' => 60.0, 'scale' => [1.9, 4.1]], 'female' => ['min' => 45.0, 'scale' => [1.5, 3.8]]],
            ['male' => ['min' => 0.0, 'scale' => [1.6, 3.9]], 'female' => ['min' => 0.0, 'scale' => [1.3, 3.6]]]
        ];

        foreach ($scales as $scale) {
            if ($person->weight >= $scale[$person->sex]['min']) {
                return $scale[$person->sex]['scale'];
            }
        }
    } elseif ($person->scaleType == 'holtek') {
        $scales = [
            ['female' => ['min' => 60, 'optimal' => 2.5], 'male' => ['min' => 75, 'optimal' => 3.2]],
            ['female' => ['min' => 45, 'optimal' => 2.2], 'male' => ['min' => 69, 'optimal' => 2.9]],
            ['female' => ['min' => 0, 'optimal' => 1.8], 'male' => ['min' => 0, 'optimal' => 2.5]]
        ];

        foreach ($scales as $scale) {
            if ($person->weight >= $scale[$person->sex]['min']) {
                return [$scale[$person->sex]['optimal']-1, $scale[$person->sex]['optimal']+1];
            }
        }
    }
}


/**
 * Get BMR scale
 */
function getBMRScale($person) {
    if ($person->scaleType == 'xiaomi') {
        $coefficients = [
            'male' => [30 => 21.6, 50 => 20.07, 100 => 19.35],
            'female' => [30 => 21.24, 50 => 19.53, 100 => 18.63]
        ];
    } elseif ($person->scaleType == 'holtek') {
        $coefficients = [
            'female' => [12 => 34, 15 => 29, 17 => 24, 29 => 22, 50 => 20, 120 => 19],
            'male' => [12 => 36, 15 => 30, 17 => 26, 29 => 23, 50 => 21, 120 => 20]
        ];
    }

    foreach ($coefficients[$person->sex] as $person->ageLimit => $coefficient) {
        if ($person->age < $person->ageLimit) {
            return [$person->weight * $coefficient];
        }
    }
}

/** 
 * Get protein scale (hardcoded in mi fit)
 */
function getProteinPercentageScale() {
    return [16, 20];
}

/**
 * Get ideal weight scale (BMI scale converted to weights)
 */
function getIdealWeightScale($person, $getBMIScale) {
    $scale = [];
    foreach ($getBMIScale() as $bmiScale) {
        $scale[] = ($bmiScale*$person->height)*$person->height/10000;
    }
    return $scale;
}

/**
 * Get Body Score scale
 */
function getBodyScoreScale() {
    return [50.0, 60.0, 80.0, 90.0];
}

/**
 * Return body type scale
 */
function getBodyTypeScale() {
    return ['obese', 'overweight', 'thick-set', 'lack-exerscise', 'balanced', 'balanced-muscular', 'skinny', 'balanced-skinny', 'skinny-muscular'];
}

//----------------------------

//------------ Score --------------
function getMalus($person, $data, $min_data, $max_data, $max_malus, $min_malus = 0) {
    $result = (($data - $max_data) / ($min_data - $max_data)) * floatval($max_malus - $min_malus);
    if ($result >= 0.0) {
        return $result;
    }
    return 0.0;
}

function getBmiDeductScore($person) {
    if (!($person->height >= 90)) {
        // "BMI is not reasonable
        return 0.0;
    }

    $bmi_low = 15.0;
    $bmi_verylow = 14.0;
    $bmi_normal = 18.5;
    $bmi_overweight = 28.0;
    $bmi_obese = 32.0;
    $fat_scale = getFatPercentageScale($person);

    // Perfect range (bmi >= 18.5 and bodyfat not high for adults, bmi >= 15.0 for kids
    if ($person->bmi >= 18.5 && $person->age >= 18 && $person->bodyfat < $fat_scale[2]) {
        return 0.0;
    } elseif ($person->bmi >= $bmi_verylow && $person->age < 18 && $person->bodyfat < $fat_scale[2]) {
        return 0.0;
    }

    // Extremely skinny (bmi < 14)
    elseif ($person->bmi <= $bmi_verylow) {
        return 30.0;
    }
    // Too skinny (bmi between 14 and 15)
    elseif ($person->bmi > $bmi_verylow && $person->bmi < $bmi_low) {
        return getMalus($person, $bmi_verylow, $bmi_low, 30, 15) + 15.0;
    }
    // Skinny (for adults, between 15 and 18.5)
    elseif ($person->bmi >= $bmi_low && $person->bmi < $bmi_normal && $person->age >= 18) {
        return getMalus($person, 15.0, 18.5, 15, 5) + 5.0;
    }

    // Normal or high bmi but too much bodyfat
    elseif (($person->bmi >= $bmi_low && $person->age < 18) || ($person->bmi >= $bmi_normal && $person->age >= 18) && $person->bodyfat >= $fat_scale[2]) {
        // Obese
        if ($person->bmi >= $bmi_obese) {
            return 10.0;
        }
        // Overweight
        if ($person->bmi > $bmi_overweight) {
            return getMalus($person, 28.0, 25.0, 5, 10) + 5.0;
        } else {
            return 0.0;
        }
    }
}

function getBodyFatDeductScore($person) {
    $scale = getFatPercentageScale($person);

    if ($person->sex == 'male') {
        $best = $scale[2] - 3.0;
    } elseif ($person->sex == 'female') {
        $best = $scale[2] - 2.0;
    }

    // Slighly low in fat or low part or normal fat
    if ($person->bodyfat >= $scale[0] && $person->bodyfat < $best) {
        return 0.0;
    } elseif ($person->bodyfat >= $scale[3]) {
        return 20.0;
    } else {
        // Sightly high body fat
        if ($person->bodyfat < $scale[3]) {
            return getMalus($person, $scale[3], $scale[2], 20, 10) + 10.0;
        }

        // High part of normal fat
        elseif ($person->bodyfat <= $normal[2]) {
            return getMalus($person, $scale[2], $best, 3, 9) + 3.0;
        }

        // Very low in fat
        elseif ($person->bodyfat < $normal[0]) {
            return getMalus($person, 1.0, $scale[0], 3, 10) + 3.0;
        }
    }
}

function getMuscleDeductScore($person) {
    $scale = getMuscleMassScale($person);

    // For some reason, there's code to return self.calculate(muscle, normal[0], normal[0]+2.0, 3, 5) + 3.0
    // if your muscle is between normal[0] and normal[0] + 2.0, but it's overwritten with 0.0 before return
    if ($person->muscle >= $scale[0]) {
        return 0.0;
    } elseif ($person->muscle < ($scale[0] - 5.0)) {
        return 10.0;
    } else {
        return getMalus($person, $scale[0] - 5.0, $scale[0], 10, 5) + 5.0;
    }
}

// No malus = normal or good; maximum malus (10.0) = less than normal-5.0;
// malus = between 5 and 10, on your water being between normal-5.0 and normal
function getWaterDeductScore($person) {
    $scale = getWaterPercentageScale($person);

    if ($person->water >= $scale[0]) {
        return 0.0;
    } elseif ($person->water <= ($scale[0] - 5.0)) {
        return 10.0;
    } else {
        return getMalus($person, $scale[0] - 5.0, $scale[0], 10, 5) + 5.0;
    }
}

function getVisceralFatDeductScore($person) {
    $scale = getVisceralFatScale($person);

    if ($person->visceral_fat < $scale[0]) {
        // For some reason, the original app would try to
        // return 3.0 if vfat == 8 and 5.0 if vfat == 9
        // but i's overwritten with 0.0 anyway before return
        return 0.0;
    } elseif ($person->visceral_fat >= $scale[1]) {
        return 15.0;
    } else {
        return getMalus($person->visceral_fat, $scale[1], $scale[0], 15, 10) + 10.0;
    }
}

function getBoneDeductScore($person) {
    $scale = getBoneMassScale($person);

    if ($person->bone >= $scale[0]) {
        return 0.0;
    } elseif ($person->bone <= ($scale[0] - 0.3)) {
        return 10.0;
    } else {
        return getMalus($person->bone, $scale[0] - 0.3, $scale[0], 10, 5) + 5.0;
    }
}

function getBasalMetabolismDeductScore($person) {
    // Get normal BMR
    $normal = getBMRScale($person[0]);

    if ($person->basal_metabolism >= $normal) {
        return 0.0;
    } elseif ($person->basal_metabolism <= ($normal - 300)) {
        return 6.0;
    } else {
        // It's really + 5.0 in the app, but it's probably a mistake, should be 3.0
        return getMalus($person, $normal - 300, $normal, 6, 3) + 5.0;
    }
}

// Get protein percentage malus
function getProteinDeductScore($person) {
    // low: 10,16; normal: 16,17
    // Check limits
    if ($person->protein > 17.0) {
        return 0.0;
    } elseif ($person->protein < 10.0) {
        return 10.0;
    } else {
        // Return values for low proteins or normal proteins
        if ($person->protein <= 16.0) {
            return getMalus($person, 10.0, 16.0, 10, 5) + 5.0;
        } elseif ($person->protein <= 17.0) {
            return getMalus($person, 16.0, 17.0, 5, 3) + 3.0;
        }
    }
}

Bonjour.

C’est aussi pour cela que le plugin BLEA est inmaintenable.
Theengs Gateway fait son travaille, il reçoit une trame d’informations et elle est transmise à Jeedom.
Le reste, pour moi c’est logique, doit être effectué hors de cela. L’idée du virtuel est la bonne solution.

Imaginez qu’une mise à jour du firmware de cet équipement créer des changements qui nécessiteraient la mise à jour du décodeur, de tgw et du plugin. Ça fait beaucoup et c’est cela qui rend compliqué les changements (de plugin par exemple,)

1 « J'aime »