diff --git a/core/ajax/Abeille.ajax.php b/core/ajax/Abeille.ajax.php index d4a755dd7b..537b7e8390 100755 --- a/core/ajax/Abeille.ajax.php +++ b/core/ajax/Abeille.ajax.php @@ -620,6 +620,7 @@ function sendToCmd($topic, $payload = '') { $e['since'] = '-'; else $e['since'] = floor((time() - strtotime($e['lastComm'])) / 3600); + $e['noack'] = $eqLogic->getStatus('ab::noack', false); // Last LQI if ($eqAddr == "0000") diff --git a/core/class/Abeille.class.php b/core/class/Abeille.class.php index 700560d93c..2eac07ab36 100644 --- a/core/class/Abeille.class.php +++ b/core/class/Abeille.class.php @@ -1750,7 +1750,7 @@ public static function checkIfBatteryInfo($eqLogic, $attrName, $attrVal) { } } - /* Deal with messages coming from parser. + /* Deal with messages coming from parser or cmd processes. Note: this is the new way to handle messages from parser, replacing progressively 'message()' */ public static function msgFromParser($msg) { global $abQueues; @@ -1772,6 +1772,22 @@ public static function msgFromParser($msg) { return; } // End 'newDevice' + /* Transmit status has changed. */ + if ($msg['type'] == "eqTxStatusUpdate") { + log::add('Abeille', 'debug', "msgFromParser(): TX status update: ".$net.'/'.$addr.", status=".$msg['txStatus']); + + $eqLogic = eqLogic::byLogicalId($net.'/'.$addr, 'Abeille'); + if (is_object($eqLogic)) { + $noack = ($msg['txStatus'] == 'ok') ? false : true; + $eqLogic->setStatus('ab::noack', $noack); + $eqLogic->save(); + } else { + log::add('Abeille', 'error', "msgFromParser(eqTxStatusUpdate): Equipement inconnu: ".$net.'/'.$addr); + } + + return; + } // End 'eqTxStatusUpdate' + /* Parser has found device infos to update. */ if ($msg['type'] == "deviceUpdates") { log::add('Abeille', 'debug', "msgFromParser(): ".$net.'/'.$addr.'/'.$ep.", Device updates, ".json_encode($msg, JSON_UNESCAPED_SLASHES)); diff --git a/core/class/AbeilleCmdQueue.class.php b/core/class/AbeilleCmdQueue.class.php index 7199052efa..45ceba79d3 100755 --- a/core/class/AbeilleCmdQueue.class.php +++ b/core/class/AbeilleCmdQueue.class.php @@ -64,12 +64,12 @@ public function checkCmdToSendInTheQueue($priority) { // } // } - public function removeFirstCmdFromQueue($priority) { - if ($this->checkCmdToSendInTheQueue($priority)) - array_shift($this->zigates[$this->zgId]['cmdQueue'][$priority]); - else - cmdLog("debug", __FUNCTION__." Trying to remove a cmd in an empty queue."); - } + // public function removeFirstCmdFromQueue($priority) { + // if ($this->checkCmdToSendInTheQueue($priority)) + // array_shift($this->zigates[$this->zgId]['cmdQueue'][$priority]); + // else + // cmdLog("debug", __FUNCTION__." Trying to remove a cmd in an empty queue."); + // } // public function zgGetQueue($priority) { // return $this->zigates[$this->zgId]['cmdQueue'][$priority]; @@ -593,7 +593,7 @@ function processAcks() { if (msg_receive($this->queueParserToCmdAck, 0, $msgType, $msgMax, $msgJson, false, MSG_IPC_NOWAIT, $errCode) == false) { if ($errCode == 7) { msg_receive($this->queueParserToCmdAck, 0, $msgType, $msgMax, $msgJson, false, MSG_IPC_NOWAIT | MSG_NOERROR); - logMessage('debug', 'processAcks() ERROR: msg TOO BIG ignored: '.$msgJson); + logMessage('error', 'processAcks() ERROR: msg TOO BIG ignored: '.$msgJson); continue; } else if ($errCode != 42) // 42 = No message cmdLog("debug", "processAcks() ERROR: msg_receive() err ".$errCode); @@ -643,7 +643,7 @@ function processAcks() { continue; } - // PDM restore response + // PDM restore response (Abeille's ABxx-yyyy specific FW) if ($msg['type'] == "AB03") { cmdLog("debug", " AB03 msg: ID=".$msg['id'].", Status=".$msg['status']); @@ -736,8 +736,39 @@ function processAcks() { // If ACK is requested but failed, removing cmd or it will lead to cmd timeout. // Note: This is done only if cmd == last sent. - if ($cmd['ackAps'] && $lastSent) + // if ($cmd['ackAps'] && $lastSent) + // $removeCmd = true; + if ($lastSent && ($cmd['waitFor'] == "ACK")) { $removeCmd = true; + + $eqStatusChanged = ''; + $net = $msg['net']; + $addr = $msg['addr']; + $eq = &getDevice($net, $addr); // By ref + if ($eq === false) { + cmdLog('error', " Unknown device: Net=${net} Addr=${addr}"); + } else { + if ($msg['status'] == '00') { // Ok ? + if ($eq['txStatus'] != 'ok') + $eqStatusChanged = 'ok'; + } else { // NO ACK ? + if ($eq['txStatus'] != 'noack') + $eqStatusChanged = 'noack'; + } + if ($eqStatusChanged != '') { + $eq['txStatus'] = $eqStatusChanged; + $msg = array( + // 'src' => 'cmd', + 'type' => 'eqTxStatusUpdate', + 'net' => $net, + 'addr' => $addr, + 'txStatus' => $eqStatusChanged // 'ok', or 'noack' + ); + msgToAbeille($msg); + cmdLog('debug', " ${net}-${addr} status changed to '${eqStatusChanged}'"); + } + } + } } /* Tcharp38: 8702 now ignored. Just means message buffered but does not @@ -762,16 +793,15 @@ function processAcks() { // } // Removing last sent cmd - if (isset($removeCmd)) { - if ($removeCmd) { - // cmdLog('debug', ' queue before='.json_encode($this->zgGetQueue($this->zgGetSentPri()))); + if (isset($removeCmd) && $removeCmd) { + // cmdLog('debug', ' queue before='.json_encode($this->zgGetQueue($this->zgGetSentPri()))); - cmdLog('debug', ' Removing cmd from queue'); - $this->removeFirstCmdFromQueue($sentPri); + cmdLog('debug', ' Removing cmd from queue'); + // $this->removeFirstCmdFromQueue($sentPri); + array_shift($this->zigates[$zgId]['cmdQueue'][$sentPri]); - // cmdLog('debug', ' queue after='.json_encode($this->zgGetQueue($this->zgGetSentPri()))); - $this->zigates[$zgId]['available'] = 1; // Zigate is free again - } + // cmdLog('debug', ' queue after='.json_encode($this->zgGetQueue($this->zgGetSentPri()))); + $this->zigates[$zgId]['available'] = 1; // Zigate is free again } } @@ -804,8 +834,9 @@ function checkZigatesStatus() { continue; // Timeout not reached yet cmdLog("debug", "WARNING: checkZigatesStatus(): Zigate".$zgId." cmd ".$cmd['cmd']." ${timeout}s TIMEOUT (SQN=".$cmd['sqn'].", SQNAPS=".$cmd['sqnAps'].") => Considering zigate available."); - $this->zgId = $zgId; - $this->removeFirstCmdFromQueue($sentPri); // Removing blocked cmd + // $this->zgId = $zgId; + // $this->removeFirstCmdFromQueue($sentPri); // Removing blocked cmd + array_shift($this->zigates[$zgId]['cmdQueue'][$sentPri]); $this->zigates[$zgId]['available'] = 1; } } // End checkZigatesStatus() diff --git a/core/class/AbeilleParser.class.php b/core/class/AbeilleParser.class.php index a6208fdfc1..13073fe4e9 100755 --- a/core/class/AbeilleParser.class.php +++ b/core/class/AbeilleParser.class.php @@ -5735,16 +5735,17 @@ function decode8702($dest, $payload, $lqi) { parserLog('debug', $dest.', Type='.$msgDecoded, "8702"); // Sending msg to cmd for flow control - $msg = array ( - 'type' => "8702", - 'net' => $dest, - 'status' => $status, - 'addr' => $dstAddr, - 'sqnAps' => $sqnAps, - 'nPDU' => $nPdu, - 'aPDU' => $aPdu, - ); - $this->msgToCmdAck($msg); + // No longer used on cmd side + // $msg = array ( + // 'type' => "8702", + // 'net' => $dest, + // 'status' => $status, + // 'addr' => $dstAddr, + // 'sqnAps' => $sqnAps, + // 'nPDU' => $nPdu, + // 'aPDU' => $aPdu, + // ); + // $this->msgToCmdAck($msg); // Monitor if requested if (isset($GLOBALS["dbgMonitorAddr"]) && !strcasecmp($GLOBALS["dbgMonitorAddr"], $dstAddr)) diff --git a/core/i18n/en_US.json b/core/i18n/en_US.json index 65421c2cfc..6ef3ca5cbc 100755 --- a/core/i18n/en_US.json +++ b/core/i18n/en_US.json @@ -210,7 +210,9 @@ "Adresse": "Address", "Dernière comm.": "Last comm.", "Depuis": "Since", - "Batterie": "Battery" + "Batterie": "Battery", + "Cliquez pour trier": "Click to sort", + "Désactivé": "Disabled" }, "plugins/Abeille/desktop/modal/Abeille-OTA.modal.php": { "Mise-à-jour des équipements": "Equipments update", diff --git a/core/php/AbeilleCmd.php b/core/php/AbeilleCmd.php index c7fcd6e7f4..61c63a036d 100644 --- a/core/php/AbeilleCmd.php +++ b/core/php/AbeilleCmd.php @@ -30,6 +30,17 @@ function cmdLog($loglevel = 'NONE', $message = "", $isEnable = 1) { logMessage($loglevel, $message); } + /* Get device infos. + Returns: device entry by reference or false */ + function &getDevice($net, $addr) { + if (!isset($GLOBALS['devices'][$net])) + return false; + if (!isset($GLOBALS['devices'][$net][$addr])) + return false; + + return $GLOBALS['devices'][$net][$addr]; + } + // Reread Jeedom useful infos on eqLogic DB update // Note: A delay is required prior to this if DB has to be updated (createDevice() in Abeille.class) function updateDeviceFromDB($eqId) { @@ -37,12 +48,12 @@ function updateDeviceFromDB($eqId) { $eqLogicId = $eqLogic->getLogicalId(); list($net, $addr) = explode("/", $eqLogicId); - // $GLOBALS['eqList'][$net][$addr]['tuyaEF00'] = $eqLogic->getConfiguration('ab::tuyaEF00', null); - // parserLog('debug', " 'tuyaEF00' updated to ".json_encode($GLOBALS['eqList'][$net][$addr]['tuyaEF00'])); - // $GLOBALS['eqList'][$net][$addr]['xiaomi'] = $eqLogic->getConfiguration('ab::xiaomi', null); - // parserLog('debug', " 'xiaomi' updated to ".json_encode($GLOBALS['eqList'][$net][$addr]['xiaomi'])); - // $GLOBALS['eqList'][$net][$addr]['customization'] = $eqLogic->getConfiguration('ab::customization', null); - // parserLog('debug', " 'customization' updated to ".json_encode($GLOBALS['eqList'][$net][$addr]['customization'])); + // $GLOBALS['devices'][$net][$addr]['tuyaEF00'] = $eqLogic->getConfiguration('ab::tuyaEF00', null); + // parserLog('debug', " 'tuyaEF00' updated to ".json_encode($GLOBALS['devices'][$net][$addr]['tuyaEF00'])); + // $GLOBALS['devices'][$net][$addr]['xiaomi'] = $eqLogic->getConfiguration('ab::xiaomi', null); + // parserLog('debug', " 'xiaomi' updated to ".json_encode($GLOBALS['devices'][$net][$addr]['xiaomi'])); + // $GLOBALS['devices'][$net][$addr]['customization'] = $eqLogic->getConfiguration('ab::customization', null); + // parserLog('debug', " 'customization' updated to ".json_encode($GLOBALS['devices'][$net][$addr]['customization'])); // TO BE COMPLETED if any other key info } @@ -52,7 +63,17 @@ function msgToCmd($msg) { $queue = msg_get_queue($abQueues["xToCmd"]["id"]); if (msg_send($queue, 1, json_encode($msg), false, false, $errCode) == false) { - parserLog("debug", "msgToCmd(): ERROR ".$errCode); + cmdLog("debug", "msgToCmd(): ERROR ".$errCode); + } + } + + /* Send msg to Abeille ('xToAbeille' queue) */ + function msgToAbeille($msg) { + global $abQueues; + + $queue = msg_get_queue($abQueues["xToAbeille"]["id"]); + if (msg_send($queue, 1, json_encode($msg), false, false, $errCode) == false) { + cmdLog("debug", "msgToAbeille(): ERROR ".$errCode); } } @@ -125,7 +146,7 @@ function configureDevice($net, $addr) { // php AbeilleCmd.php debug //check already running - $abeilleConfig = AbeilleTools::getParameters(); + $abeilleConfig = AbeilleTools::getConfig(); $running = AbeilleTools::getRunningDaemons(); $daemons = AbeilleTools::diffExpectedRunningDaemons($abeilleConfig, $running); logMessage('debug', 'Daemons status: '.json_encode($daemons)); @@ -193,11 +214,13 @@ function signalHandler($signal) { if (!isset($GLOBALS['devices'][$net])) $GLOBALS['devices'][$net] = []; - $eq = []; - $eq['ieee'] = $eqLogic->getConfiguration('IEEE', ''); $eqModel = $eqLogic->getConfiguration('ab::eqModel', []); - $eq['jsonId'] = isset($eqModel['id']) ? $eqModel['id'] : ''; - $eq['jsonLocation'] = isset($eqModel['location']) ? $eqModel['location'] : 'Abeille'; + $eq = array( + 'ieee' => $eqLogic->getConfiguration('IEEE', ''), + 'txStatus' => 'ok', // Transmit status: 'ok' or 'noack' + 'jsonId' => isset($eqModel['id']) ? $eqModel['id'] : '', + 'jsonLocation' => isset($eqModel['location']) ? $eqModel['location'] : 'Abeille', + ); if ($eq['jsonId'] != '') { // Read JSON to get list of commands to execute $model = AbeilleTools::getDeviceModel($eq['jsonId'], $eq['jsonLocation']); diff --git a/core/php/AbeilleParser.php b/core/php/AbeilleParser.php index 1328b10d7e..32ef181e28 100644 --- a/core/php/AbeilleParser.php +++ b/core/php/AbeilleParser.php @@ -352,7 +352,7 @@ function updateDeviceFromDB($eqId) { logMessage("info", ">>> Démarrage d'AbeilleParser"); // Check if already running - $config = AbeilleTools::getParameters(); + $config = AbeilleTools::getConfig(); $running = AbeilleTools::getRunningDaemons(); $daemons= AbeilleTools::diffExpectedRunningDaemons($config, $running); logMessage('debug', 'Daemons: '.json_encode($daemons)); diff --git a/desktop/modal/AbeilleHealth.modal.php b/desktop/modal/AbeilleHealth.modal.php index c5cb04ef50..b2b46cdd68 100644 --- a/desktop/modal/AbeilleHealth.modal.php +++ b/desktop/modal/AbeilleHealth.modal.php @@ -17,7 +17,7 @@ $eqLogics = Abeille::byType('Abeille'); ?> -Démons: +{{Démons}}: - {{Réseau}} - {{Equipement}} - {{Type}} - {{Adresse}} - {{IEEE}} - {{Status}} - {{Dernière comm.}} - {{Depuis}} (H) - {{LQI}} - {{Batterie}} + {{Réseau}} + {{Equipement}} + {{Type}} + {{Adresse}} + {{IEEE}} + {{Status}} + {{Dernière comm.}} + {{Depuis}} (H) + {{LQI}} + {{Batterie}} @@ -272,9 +272,15 @@ function refreshHealth() { status = '{{Désactivé}}'; else if (addr.substr(2) == "rc") // Remote control ? status = '-'; - else if (e.timeout == 1) - status = '{{Time-out}}'; - else + else if (e.timeout || e.noack) { + if (e.timeout && !e.noack) + s = "{{Time-out}}"; + else if (!e.timeout && e.noack) + s = "{{No-ACK}}"; + else + s = "{{Time-out}}&{{No-ACK}}"; + status = '' + s + ''; + } else status = '{{OK}}'; tr += ''+status+''; diff --git a/docs/fr_FR/Changelog.rst b/docs/fr_FR/Changelog.rst index d5efbf3be2..87af88c179 100644 --- a/docs/fr_FR/Changelog.rst +++ b/docs/fr_FR/Changelog.rst @@ -2,6 +2,8 @@ ChangeLog ========= - Interne: Parser: Cluster FC00 traité par message 8002 pour future migration mode 'raw'. +- Interne: Ajout surveillance 'NOACK' en plus de 'Timeout'. +- Page santé: Status amélioré => 'Time-out', ''no-ack' ou 'time-out&no-ack' 230918-BETA-1 -------------