Enocean A5-20-01 bug et proposition de correction

Tags: #<Tag:0x00007f752d0493f0> #<Tag:0x00007f752d049288>

Enocean A5-20-01 bug et proposition de correction

Bonjour,

Je souhaite piloter des vannes thermostatiques Micropelt MICITRV004 A5-20-01 en température avec le capteur interne de chaque vanne. J’ai déjà pu le faire par le passé en modifiant les requêtes de réglage température mais j’ai recréé les commandes suite à l’ajout de nouvelles vannes (avec le design de l’équipement bien plus réussi et complet que le précédent). Suite à la recréation des vannes sous jeedom, impossible de les piloter autrement qu’en ouverture. Le mode température a un comportement incohérent : vanne bloquée ouverte après reset vanne, puis fermée sans raison au bout de 24h, ne réagit pas aux consignes, s’ouvre lorsque la température est supérieure à la consigne (devrait être l’inverse).

Je suis sur une smart en 4.1.25 stable v4 avec plugin openenocean 2021-09-06 16:45:49. Le comportement des différentes vannes est identique, donc pas lié à une version firmware vanne.

Après avoir fait tous les tests possibles sans succès, vérifié les log debug, j’ai tenté ma chance avec jeexplorer et ai pu identifier le problème dans la gestion spécifique du profil A5-20-01 sous plugins/openenocean/core/class/openenocean.class.php :
- envoi systématique d’une valeur TMP. Lors du fonctionnement sur le capteur interne le TMP doit être à 0 (http://www.micropelt.com/fileadmin/user_upload/_PDF_MVA004_Datasheet_1DSMVA004_0720v13e.pdf page 12).
- arrondi intval sur le calcul TMP après la différence avec 255. Le résultat du calcul est parfois décalé +/-1 avec les exemples micropelt
- log debug difficile à analyser lorsque qu’il y a plus d’une vanne avec source de température externe
- envoi très réguliers de nouveaux ordres aux vannes alors que ni la consigne ni la température n’a changé

Le fonctionnement de la vanne semble incohérent si on lui envoie sa propre température et l’envoi régulier de ces ordres semble finir par la mettre en défaut dans les 24h.

Ayant déjà codé en php par le passé, je me suis lancé et suis arrivé à un résultat qui permet un pilotage en température. Les modifications :
- gestion des ordres TMP:0 pour le pilotage interne
- enrichissement des logs debug (affiche la référence externe, la température reçue, la valeur TMP envoyée ou si la référence est erronée le retour en référence interne)
- actualisation du cache de dernier ordre envoyé à chaque changement de température
- envoi d’un nouvel ordre uniquement si la température ou la consigne a changé (comparaison avec le cache)
- fallback en référence interne si la référence externe ne fonctionne pas ou renvoie une température incorrecte (autre que 0-40°c)
- déplacement de l’arrondi intval (valeur résultat identique aux exemples micropelt)
- vérification de la prise en compte de référence externe enocean et zwave

Détail des modifications openenocean.class.php:

	public function computeTherm() {
		log::add('openenocean','debug','Computing Therm for ' . $this->getHumanName());
		$lastdata=$this->getCache('lastdata');
		if (isset($lastdata['TMP'])){
			log::add('openenocean','debug','Last data ' . $lastdata['TMP']);
			if($this->getConfiguration('sourceTemp','') != ''){
				$cmdSource = cmd::byId(str_replace('#','',$this->getConfiguration('sourceTemp','')));
				if (!is_object($cmdSource)){
					$sourceTemp = 0;
					log::add('openenocean','debug','sourceTemp cannot provide valid temperature, set to internal TMP:'.$sourceTemp);
				} else {
					$sourceTemp = $cmdSource->execCmd();
					if (is_numeric($sourceTemp) and $sourceTemp>=0 and $sourceTemp<=40){
						log::add('openenocean','debug','sourceTemp received temperature '.$sourceTemp.' from '.$cmdSource->getHumanName());
					} else {
						$sourceTemp = 0;
						log::add('openenocean','debug','sourceTemp cannot provide valid temperature from '. $cmdSource->getHumanName() .', set to internal TMP:'.$sourceTemp);
					}
				}
			} else {
				$sourceTemp = 0;
                log::add('openenocean','debug','sourceTemp not configured, set to internal TMP:'.$sourceTemp);
			}
            if ($sourceTemp != 0){
			    $sourceTemp = 255-intval($sourceTemp*6.375);
            }
			$profile = array(
			'func' => $this->getConfiguration('func'),
			'rorg' => $this->getConfiguration('rorg'),
			'type' => $this->getConfiguration('type'),
			);
            if ($sourceTemp != $lastdata['TMP']) {
                $lastdata['TMP'] = $sourceTemp;
                $this->setCache('lastdata',$lastdata);
                log::add('openenocean','debug','new data changed to ' . $lastdata['TMP']);
                $value = json_encode(array('apikey' => jeedom::getApiKey('openenocean'), 'cmd' => 'send', 'dest' => $this->getLogicalId(), 'profile' => $profile, 'command' => $lastdata));
                $socket = socket_create(AF_INET, SOCK_STREAM, 0);
                socket_connect($socket, '127.0.0.1', config::byKey('socketport', 'openenocean'));
                socket_write($socket, $value, strlen($value));
                socket_close($socket);
            } else {
                log::add('openenocean','debug','new data same as old one ' . $sourceTemp);
            }
		}
		return;
	}

et function execute sous partie a5-20-01

				if ($eqLogic->getConfiguration('device') == 'a5-20-01'){
					if (strpos($value[1],'sourceTemp') !== false) {
						$cmdSource = cmd::byId(str_replace('#','',$eqLogic->getConfiguration('sourceTemp','')));
						if (!is_object($cmdSource)){
							$cmdSource = 0;
						}
						if (!is_object($cmdSource)){
							$sourceTemp =0;
						} else {
							$sourceTemp = $cmdSource->execCmd();
							if (!(is_numeric($sourceTemp) and $sourceTemp>=0 and $sourceTemp<=40)){
								$sourceTemp = 0;
							}
						}
						if($sourceTemp!=0){
							$sourceTemp = 255 - intval($sourceTemp*6.375);
						}
						$data[trim($value[0])] = trim(str_replace('#sourceTemp#', $sourceTemp, $value[1]));
					}
				}

Les logs avant modification:

[DEBUG] : Computing Therm for [Maison][Thermostatique Chbre]
[DEBUG] : Last data 123
[DEBUG] : new data 123
[DEBUG] : Client connected to [127.0.0.1:38900]
[DEBUG] : Message read from socket: {"apikey":"xxxxxxxxx","cmd":"send","dest":"yyyyyy","profile":{"func":"20","rorg":"a5","type":"01"},"command":{"direction":"2","delay":"1","SPS":"1","SP":147,"TMP":123}}

Les logs après modification:

[DEBUG] : Message read from socket: {"apikey":"xxxxxxxxx","cmd":"send","dest":"yyyyyy","profile":{"func":"20","rorg":"a5","type":"01"},"command":{"direction":"2","delay":"1","SPS":"1","SP":128,"TMP":"0"}}
...
[DEBUG] : Computing Therm for [Maison][Thermostatique Sdb]
[DEBUG] : Last data 0
[DEBUG] : sourceTemp not configured, set to internal TMP:0
[DEBUG] : new data same as old one 0
...
[DEBUG] : Message read from socket: {"apikey":"xxxxxxxxx","cmd":"send","dest":"058C4577","profile":{"func":"20","rorg":"a5","type":"01"},"command":{"direction":"2","delay":"1","SPS":"1","SP":134,"TMP":"179"}}
...
[DEBUG] : Computing Therm for [Maison][Thermostatique Chbre]
[DEBUG] : Last data 179
[DEBUG] : sourceTemp received temperature 12.04 from [Maison][Température Extérieure][Température]
[DEBUG] : new data same as old one 179

Je n’ai pas trouvé de github avec le code du plugin pour faire un pull request, probablement du fait du plugin payant.
En espérant que cette proposition soit reçue favorablement.

Cordialement,
Romain

1 J'aime