dubocr / homebridge-tahoma

Homebridge plugin for TaHoma, Connexoon, Cozytouch, Energeasy Connect.
Apache License 2.0
132 stars 42 forks source link

[Volet] Implémentation du retour d'erreur "ObstructionDetected" #38

Closed lboue closed 6 years ago

lboue commented 6 years ago

Bonjour,

Je rencontre assez souvent le cas de mon volet qui se bloque lorsque la fenêtre Velux est ouverte entièrement. J'aimerais être averti dans Homebridge comme c'est le cas si je lance l'application Connexoon. Il faut ouvrir l'application pour remarquer l'erreur, ce n'est pas pratique.

Voici ce que retourne l'API Tahoma au moment du blocage :

[{
    "execution": {
        "eventTime": 1530354922928,
        "owner": "user@domain.com",
        "source": "mobile:connexoon",
        "endTime": 1530354937044,
        "effectiveStartTime": 1530354922928,
        "duration": 14116,
        "id": "5042f5ae-2e69-7448-5ca5-6448a99715f8",
        "label": "Volet Velux - Fermer - user",
        "executionType": "Immediate execution",
        "executionSubType": "MANUAL_CONTROL",
        "type": "Immediate execution - MANUAL_CONTROL",
        "failureType": "WHILEEXEC_BLOCKED_BY_HAZARD",
        "state": "FAILED",
        "commands": [{
            "deviceURL": "io://0808-0476-7160/12852936",
            "command": "close",
            "parameters": [],
            "rank": 0,
            "dynamic": false,
            "failureType": "WHILEEXEC_BLOCKED_BY_HAZARD",
            "state": "FAILED"
        }]
    }

1) On remarque qu'une erreur est bien retournée "failureType": "WHILEEXEC_BLOCKED_BY_HAZARD", 2) J'ai trouvé un moyen de lever des erreurs dans HomeKit et générer une alerte avec la Characteristic ObstructionDetected :

HMCharacteristicTypeObstructionDetected Indicates whether the accessory has detected an obstruction—for example, an automatic garage door opener may have the ability to tell if something is blocking the door. The value is a boolean indicating whether an obstruction was detected.

J'ai fait un premier test en publiant le service et cela apparaît dans HomeKit obstructiondetectedservice

Voici un exemple

volet
        .getService(Service.WindowCovering)
        .setCharacteristic(Characteristic.ObstructionDetected, true);

Serait-il possible de vérifier le retour de l'API et lever une alerte ?

Cordialement Ludovic

dubocr commented 6 years ago

Salut,

Awning.js.zip Peux-tu essayer le fichier suivant. J'ai ajouté la caractéristique pour les volets non RTS et update le status à la fin de l'execution en fonction de l'erreur.

lboue commented 6 years ago

Bonjour,

Merci d'avoir pris le temps de me répondre. Je viens de faire un test et j'ai bien l'erreur remontée par la console qui apparait bien;

[2018-7-1 23:09:59] [Connexoon] [Volet Velux] setClosure[29]
[2018-7-1 23:10:16] [Connexoon] [Volet Velux] setClosure COMPLETED
[2018-7-1 23:10:25] [Connexoon] [Volet Velux] setClosure[98]
[2018-7-1 23:10:28] [Connexoon] [Volet Velux] setClosure[100]
[2018-7-1 23:10:30] [Connexoon] [Volet Velux] setClosure CMDCANCELLED
[2018-7-1 23:11:02] [Connexoon] [Volet Velux] setClosure WHILEEXEC_BLOCKED_BY_HAZARD

Par contre pas d'erreur signalée dans HomeBridge. Je crois qu'il faut faire un truc du style : this.getService(Service.WindowCovering).setCharacteristic(Characteristic.ObstructionDetected, Characteristic.ObstructionDetected.YES)

Un exemple d'implémentation ici https://github.com/nfarina/homebridge/issues/1348.

Ludovic

lboue commented 6 years ago

En fait on ne passe pas le test if(this.obtruction != null). J'ai donc essayé de le mettre plus haut pour voir :

case ExecutionState.FAILED:
    that.positionState.updateValue(Characteristic.PositionState.STOPPED);
    that.targetPosition.updateValue(that.currentPosition.value); // Update target position in case of cancellation
    that.log.info('Before');
    this.obtruction.updateValue(error == 'WHILEEXEC_BLOCKED_BY_HAZARD');
    if(this.obtruction != null) {
        this.obtruction.updateValue(error == 'WHILEEXEC_BLOCKED_BY_HAZARD');
        //this.obtruction.service.setCharacteristic(Characteristic.ObstructionDetected, true);
        that.log.info('this.obtruction != null');
        this.getService(Service.WindowCovering).setCharacteristic(Characteristic.ObstructionDetected, Characteristic.ObstructionDetected.YES)
    }

Et j’obtiens cette erreur :

[2018-7-1 23:44:40] [Connexoon] [Volet Velux] setClosure[100]
[2018-7-1 23:44:40] [Connexoon] [Volet Velux] setClosure INITIALIZED
[2018-7-1 23:44:40] [Connexoon] Register listener
[2018-7-1 23:44:41] [Connexoon] [Volet Velux] setClosure IN_PROGRESS
[2018-7-1 23:44:53] [Connexoon] [Volet Velux] setClosure WHILEEXEC_BLOCKED_BY_HAZARD
[2018-7-1 23:44:53] [Connexoon] Before
/usr/lib/node_modules/homebridge-tahoma/accessories/Awning.js:78
                                        this.obtruction.updateValue(error == 'WHILEEXEC_BLOCKED_BY_HAZARD');
                                                        ^

TypeError: Cannot read property 'updateValue' of undefined
    at /usr/lib/node_modules/homebridge-tahoma/accessories/Awning.js:78:22
    at /usr/lib/node_modules/homebridge-tahoma/accessories/AbstractAccessory.js:113:5
    at pollingtoevent.<anonymous> (/usr/lib/node_modules/homebridge-tahoma/overkiz-api.js:104:21)
    at pollingtoevent.emit (events.js:182:13)
    at done (/usr/lib/node_modules/homebridge-tahoma/node_modules/polling-to-event/index.js:63:20)
    at /usr/lib/node_modules/homebridge-tahoma/overkiz-api.js:86:14
    at Request.authCallback [as _callback] (/usr/lib/node_modules/homebridge-tahoma/overkiz-api.js:207:17)
    at Request.self.callback (/usr/lib/node_modules/homebridge-tahoma/node_modules/request/request.js:185:22)
    at Request.emit (events.js:182:13)
    at Request.<anonymous> (/usr/lib/node_modules/homebridge-tahoma/node_modules/request/request.js:1157:10)

Il faudrait peut etre quelque chose du style that.getService(Service.WindowCovering).setCharacteristic(Characteristic.ObstructionDetected, Characteristic.ObstructionDetected.YES)

Mais j'obtiens ça : TypeError: that.getService is not a function

Si je fait un inspect de l'objet this.obstruction :

[2018-7-2 00:11:48] [Connexoon] addCharacteristic(Characteristic.ObstructionDetected)
[2018-7-2 00:11:48] [Connexoon] inspect this.obstruction=Characteristic {
  displayName: 'Obstruction Detected',
  UUID: '00000024-0000-1000-8000-0026BB765291',
  iid: null,
  value: false,
  status: null,
  eventOnlyCharacteristic: false,
  props: 
   { format: 'bool',
     unit: null,
     minValue: null,
     maxValue: null,
     minStep: null,
     perms: [ 'pr', 'ev' ] },
  subscriptions: 0,
  _events: { change: [Function: bound ] },
  _eventsCount: 1 }

Ludovic

lboue commented 6 years ago

J'ai fait un commit sur mon repo pour montrer qu'en forçant au tout début (ligne 44) avec la commande suivante l'alerte apparait bien dans HomeKit: service.setCharacteristic(Characteristic.ObstructionDetected, true);

Je ne sais pas comment faire la même chose depuis la méthode setClosure.

dubocr commented 6 years ago

Peux-tu déjà remplacer le bloc par

if(that.obstruction != null) {
    that.obstruction.updateValue(error == 'WHILEEXEC_BLOCKED_BY_HAZARD');
}
lboue commented 6 years ago

Bonjour,

J'ai compris pourquoi on ne passait jamais le test IF, il y'avait une erreur de frappe (this.obtruction au lieu de this.obstruction). Il manquait le "S". Cela explique les erreurs "undefined".

Voilà donc le résultat. On voit bien que la valeur de 'Obstruction Detected'.value passe de false à true. L'alerte apparaît bien dans HomeKit:

[2018-7-3 21:07:17] [Connexoon] [Volet Velux] setClosure[100]
[2018-7-3 21:07:17] [Connexoon] [Volet Velux] setClosure INITIALIZED
[2018-7-3 21:07:17] [Connexoon] Register listener
[2018-7-3 21:07:19] [Connexoon] [Volet Velux] setClosure IN_PROGRESS
[2018-7-3 21:07:29] [Connexoon] [Volet Velux] setClosure WHILEEXEC_BLOCKED_BY_HAZARD
[2018-7-3 21:07:29] [Connexoon] Before that.obstruction != null
[2018-7-3 21:07:29] [Connexoon] IN that.obstruction != null test Characteristic {
  displayName: 'Obstruction Detected',
  UUID: '00000024-0000-1000-8000-0026BB765291',
  iid: 13,
  value: false,
  status: null,
  eventOnlyCharacteristic: false,
  props: 
   { format: 'bool',
     unit: null,
     minValue: null,
     maxValue: null,
     minStep: null,
     perms: [ 'pr', 'ev' ] },
  subscriptions: 1,
  _events: { change: [Function: bound ] },
  _eventsCount: 1 }
[2018-7-3 21:07:29] [Connexoon] IN that.obstruction != null test, that.obstruction=Characteristic {
  displayName: 'Obstruction Detected',
  UUID: '00000024-0000-1000-8000-0026BB765291',
  iid: 13,
  value: true,
  status: null,
  eventOnlyCharacteristic: false,
  props: 
   { format: 'bool',
     unit: null,
     minValue: null,
     maxValue: null,
     minStep: null,
     perms: [ 'pr', 'ev' ] },
  subscriptions: 1,
  _events: { change: [Function: bound ] },
  _eventsCount: 1 }
[2018-7-3 21:07:29] [Connexoon] Unregister listener

L'erreur disparaît si je ré-ouvre le volet et j'attends un peu.

[2018-7-3 21:30:28] [Connexoon] [Volet Velux] setClosure INITIALIZED
[2018-7-3 21:30:28] [Connexoon] Register listener
[2018-7-3 21:30:30] [Connexoon] [Volet Velux] setClosure IN_PROGRESS
[2018-7-3 21:30:38] [Connexoon] [Volet Velux] setClosure COMPLETED
[2018-7-3 21:30:38] [Connexoon] IN that.obstruction != null test Characteristic {
[2018-7-3 21:30:38] [Connexoon] Unregister listener

Ludovic

lboue commented 6 years ago

Par contre si je comprend bien ça veut dire que tout les cas d'erreurs (case ExecutionState.FAILED), cette alerte va être levée ? Exemple le cas où le device ne répond plus (ACTUATORNOANSWER).

lboue commented 6 years ago

J'ai également l'impression qu'au polling suivant de l'API (device states refresh), l'alarme est effacée.

dubocr commented 6 years ago

Non l'alerte sera levée si l'execution échoue et si le retour de l'API esterror == 'WHILEEXEC_BLOCKED_BY_HAZARD' La valeur n'est normalement réinitialisée qu'à la prochaine commande envoyée au volet et correctement exécutée ou au redémarrage d'homebridge.

lboue commented 6 years ago

Effectivement je pensais que c'était la valeur à écrire lors de l'update alors qu'error == 'WHILEEXEC_BLOCKED_BY_HAZARD_' est un test. J'avais mal compris :-)