Bonjour;
J’aimerais débattre d’un point avec les dév…
Je suis assez frustré depuis mon passage sur les plugins zig Bee de la non remontée de certaines infos de module.
Je pense que cela vient du fait d’une mauvaise description du module lors de sa demande d’intégration, ou de l’évolution de son firmware (j’attends vos avis)
Mais prenons pour exemple le module xiaomi aquara vibration
Une fois inclus, nous avons 6 commandes de crées :
Hors le module renvoi bien plus d’info que cela. On les vois dans les logs zigbee:
0113|[2022-01-27 23:28:36]DEBUG : Reception{"devices":{"00:15:8d:00:03:1c:e0:75":{"1":{"257":{"1288":{"value":"4535512202944","cluster_name":"MultistateInputCluster"}},"1280":{"event":{"current_orientation":{"value":[{"rawValueX":65216,"rawValueY":407,"rawValueZ":1056,"X":89,"Y":0,"Z":1}],"cluster_name":"IAS Zone"}}}}}}}
Je trouves dommage (je suis pret à en discuter) que ces commandes ne soit pas créés automatiquement.
J’ai donc fait les modification suivante dans le fichier jeeZigbee.php:
ajout d’une fonction :
function checkCreateAndUpdateCmd($zigbee,$_cmdName,$value) {
$cmd = $zigbee->getCmd(null, $_cmdName);
if (!is_object($cmd)) {
$cmd = new zigbeeCmd();
$cmd->setLogicalId($_cmdName . '::raw');
$cmd->setIsVisible(1);
$cmd->setName(__($_cmdName . '::raw', __FILE__));
$cmd->setType('info');
$cmd->setSubType('string');
$cmd->setDisplay('generic_type','GENERIC');
$cmd->setEqLogic_id($zigbee->getId());
$cmd->save();
$cmd = new zigbeeCmd();
$cmd->setLogicalId($_cmdName);
$cmd->setIsVisible(1);
$cmd->setName(__($_cmdName, __FILE__));
$cmd->setType('info');
$cmd->setSubType('string');
$cmd->setDisplay('generic_type','GENERIC');
$cmd->setEqLogic_id($zigbee->getId());
$cmd->save();
}
$zigbee->checkAndUpdateCmd($_cmdName, convertValue($value));
$zigbee->checkAndUpdateCmd($_cmdName . '::raw', $value);
}
et j’ai remplacé tous les appels
$zigbee->checkAndUpdateCmd($endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id, convertValue($cmd_value));
par
checkCreateAndUpdateCmd($zigbee,$endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id,$cmd_value);
J’ai aussi rajouter un « étage » de recherche ceux qui me donne le code suivant:
/* This file is part of Jeedom.
*
* Jeedom is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Jeedom is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Jeedom. If not, see <http://www.gnu.org/licenses/>.
*/
require_once dirname(__FILE__) . "/../../../../core/php/core.inc.php";
if (!jeedom::apiAccess(init('apikey'), 'zigbee')) {
echo __('Vous n\'etes pas autorisé à effectuer cette action', __FILE__);
die();
}
if (isset($_GET['test'])) {
echo 'OK';
die();
}
$result = json_decode(file_get_contents("php://input"), true);
log::add('zigbee', 'debug', "Reception".json_encode($result));
if (!is_array($result)) {
die();
}
if (isset($result['device_left'])) {
event::add('jeedom::alert', array(
'level' => 'warning',
'page' => 'zigbee',
'message' => __('Un périphérique Zigbee a quitté le réseaux', __FILE__),
));
$zigbee = zigbee::byLogicalId($result['device_left'], 'zigbee');
if (is_object($zigbee) && config::byKey('autoRemoveExcludeDevice', 'zigbee') == 1) {
$zigbee->remove();
event::add('zigbee::includeDevice', '');
}
die();
}
if (isset($result['device_removed'])) {
event::add('jeedom::alert', array(
'level' => 'warning',
'page' => 'zigbee',
'message' => __('Un périphérique Zigbee a été supprimé du réseaux', __FILE__),
));
$zigbee = zigbee::byLogicalId($result['device_removed'], 'zigbee');
if (is_object($zigbee) && config::byKey('autoRemoveExcludeDevice', 'zigbee') == 1) {
$zigbee->remove();
event::add('zigbee::includeDevice', '');
}
die();
}
if (isset($result['device_joined'])) {
event::add('jeedom::alert', array(
'level' => 'warning',
'page' => 'zigbee',
'message' => __('Un périphérique Zigbee est en cours d\'inclusion : ', __FILE__) . $result['device_joined'],
));
die();
}
if (isset($result['device_initialized'])) {
event::add('jeedom::alert', array(
'level' => 'warning',
'page' => 'zigbee',
'message' => __('Un périphérique Zigbee a été inclus : ', __FILE__) . $result['device_initialized'] . '. ' . __('Pause de 30s avant synchronisation', __FILE__),
'ttl' => 30000
));
sleep(30);
$id = zigbee::sync();
event::add('zigbee::includeDevice', $id);
try {
$zigbee = zigbee::byId($id);
if (is_object($zigbee)) {
$zigbee->setTime();
}
} catch (\Exception $e) {
}
die();
}
$CONVERT_VALUE = array(
'ZoneStatus.Alarm_1' => 1,
'ZoneStatus.Restore_reports' => 0,
'ZoneStatus.0' => 0,
'bitmap8.1' => 1,
'bitmap8.0' => 0,
'Bool.true' => 1,
'Bool.false' => 0,
'LockState.Locked' => 1,
'LockState.Unocked' => 0,
'SystemMode.Off' => __('Arrêt', __FILE__),
'SystemMode.Auto' => __('Automatique', __FILE__),
'SystemMode.Cool' => __('Climatisation', __FILE__),
'SystemMode.Heat' => __('Chauffage', __FILE__),
'SystemMode.Emergency_Heating' => __('Chauffage d\'urgence', __FILE__),
'SystemMode.Pre_cooling' => __('Pré-Climatisation', __FILE__),
'SystemMode.Fan_only' => __('Ventilation', __FILE__),
'SystemMode.Dry' => __('Séchage', __FILE__),
'SystemMode.Sleep' => __('En veille', __FILE__),
'KeypadLockout.Level_1_lockout' => 1,
'KeypadLockout.No_lockout' => 0
);
$FIND_VALUE = array(
'Alarm_1' => 1,
'Alarm_2' => 1
);
function convertValue($_value) {
global $CONVERT_VALUE;
if (isset($CONVERT_VALUE[$_value])) {
return $CONVERT_VALUE[$_value];
}
global $FIND_VALUE;
foreach ($FIND_VALUE as $key => $value) {
if (strpos($_value, $key) !== false) {
return $value;
}
}
if (strpos($_value, 'enum8.undefined_') !== false) {
return hexdec(str_replace('enum8.undefined_', '', $_value));
}
return $_value;
}
function checkCreateAndUpdateCmd($zigbee,$_cmdName,$value) {
$cmd = $zigbee->getCmd(null, $_cmdName);
if (!is_object($cmd)) {
$cmd = new zigbeeCmd();
$cmd->setLogicalId($_cmdName . '::raw');
$cmd->setIsVisible(1);
$cmd->setName(__($_cmdName . '::raw', __FILE__));
$cmd->setType('info');
$cmd->setSubType('string');
$cmd->setDisplay('generic_type','GENERIC');
$cmd->setEqLogic_id($zigbee->getId());
$cmd->save();
$cmd = new zigbeeCmd();
$cmd->setLogicalId($_cmdName);
$cmd->setIsVisible(1);
$cmd->setName(__($_cmdName, __FILE__));
$cmd->setType('info');
$cmd->setSubType('string');
$cmd->setDisplay('generic_type','GENERIC');
$cmd->setEqLogic_id($zigbee->getId());
$cmd->save();
}
$zigbee->checkAndUpdateCmd($_cmdName, convertValue($value));
$zigbee->checkAndUpdateCmd($_cmdName . '::raw', $value);
}
if (isset($result['devices'])) {
foreach ($result['devices'] as $ieee => $endpoints) {
$masterzigbee = zigbee::byLogicalId($ieee, 'zigbee');
if (!is_object($masterzigbee) || !$masterzigbee->getIsEnable()) {
continue;
}
foreach ($endpoints as $endpoint_id => $clusters) {
$deviceArray = [$masterzigbee];
$childzigbee = zigbee::byLogicalId($ieee . '|' . $endpoint_id, 'zigbee');
if (is_object($childzigbee) && $childzigbee->getIsEnable()) {
$deviceArray[] = $childzigbee;
}
foreach ($deviceArray as $zigbee) {
if ($zigbee->getConfiguration('decode_file') != '' && file_exists(__DIR__ . '/../' . $zigbee->getConfiguration('decode_file'))) {
try {
require_once __DIR__ . '/../' . $zigbee->getConfiguration('decode_file');
$function = 'decode_' . str_replace('.', '_', $zigbee->getConfiguration('device'));
if (function_exists($function)) {
log::add('zigbee', 'debug', 'Use specific decode file for ' . $zigbee->getHumanName() . ' => ' . __DIR__ . '/../' . $zigbee->getConfiguration('decode_file'));
if ($function($zigbee, $endpoint_id, $clusters)) {
continue;
}
}
} catch (\Exception $e) {
log::add('zigbee', 'error', $e->getMessage());
}
}
foreach ($clusters as $cluster_id => $attributs) {
foreach ($attributs as $attribut_id => $value) {
if (!is_array($value) && $value === '[]') {
continue;
}
if ($cluster_id == 1) {
if ($attribut_id == 33) {
$zigbee->batteryStatus(round($value['value']));
} else if ($zigbee->getConfiguration('maxBatteryVoltage', 0) != 0 && $attribut_id == 32 && $value['value'] > 0) {
$zigbee->batteryStatus(round($value['value'] / $zigbee->getConfiguration('maxBatteryVoltage', 0) * 100));
}
} else if (strcmp($attribut_id, 'cmd') === 0) {
foreach ($value as $cmd_id => $cmd_value) {
if ($cmd_value['value'] === '[]') {
continue;
}
log::add('zigbee', 'debug', 'Search command for ' . $ieee . ' logicalId : ' . $endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id . ' => ' . $cmd_value['value'] . ' convert to ' . convertValue($cmd_value['value']));
checkCreateAndUpdateCmd($zigbee,$endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id,$cmd_value['value']);
}
} else if (strcmp($attribut_id, 'gcmd') === 0) {
foreach ($value as $cmd_id => $cmd_value) {
if ($cmd_value['value'] === '[]') {
continue;
}
log::add('zigbee', 'debug', 'Search general command for ' . $ieee . ' logicalId : ' . $endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id . ' => ' . $cmd_value['value'] . ' convert to ' . convertValue($cmd_value['value']));
checkCreateAndUpdateCmd($zigbee,$endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id,$cmd_value['value']);
}
} else if (strcmp($attribut_id, 'event') === 0) {
foreach ($value as $cmd_id => $cmd_value) {
if (is_array($cmd_value['value'])) {
foreach ($cmd_value['value'] as $sub_cmd_id => $sub_cmd_value) {
if ($sub_cmd_value === '[]') {
$sub_cmd_value = 1;
}
if (is_array($sub_cmd_value)) {
foreach ($sub_cmd_value as $sub_detailID => $sub_detailValue) {
checkCreateAndUpdateCmd($zigbee,$endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id . '::' . $sub_cmd_id.'::'.$sub_detailID,$sub_detailValue);
}
}
else
{
log::add('zigbee', 'debug', 'Search event command for ' . $ieee . ' logicalId : ' . $endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id . '::' . $sub_cmd_id . ' => ' . $sub_cmd_value . ' convert to ' . convertValue($sub_cmd_value));
checkCreateAndUpdateCmd($zigbee,$endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id . '::' . $sub_cmd_id,$sub_cmd_value);
}
}
} else {
if ($cmd_value === '[]') {
$cmd_value = 1;
}
log::add('zigbee', 'debug', 'Search event command for ' . $ieee . ' logicalId : ' . $endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id . ' => ' . $cmd_value . ' convert to ' . convertValue($cmd_value));
checkCreateAndUpdateCmd($zigbee,$endpoint_id . '::' . $cluster_id . '::' . $attribut_id . '::' . $cmd_id,$cmd_value);
}
}
} else {
log::add('zigbee', 'debug', 'Search attribut for ' . $ieee . ' logicalId : ' . $endpoint_id . '::' . $cluster_id . '::' . $attribut_id . ' => ' . $value['value'] . ' convert to ' . convertValue($value['value']));
checkCreateAndUpdateCmd($zigbee,$endpoint_id . '::' . $cluster_id . '::' . $attribut_id,$value['value']);
}
}
}
}
}
}
}
Sur l’equipement, j’ai maintenant accé à toutes les commandes
En conclusion je pense qu’il serait inrérréssant de laisser via une option la possibilité de générer automatiquement les commandes.
J’attends vos réactions