Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Heiman WarningDevice (8804) #240

Open
pickwick86 opened this issue Dec 22, 2019 · 25 comments
Open

Heiman WarningDevice (8804) #240

pickwick86 opened this issue Dec 22, 2019 · 25 comments
Labels
bug Something isn't working

Comments

@pickwick86
Copy link

Description du bug
Toutes les commandes gérées par la sirène Heiman ne sont pas reconnues.
Les commandes détectées ne fonctionnent pas toutes

Pour Reproduire
Etapes pour reproduire le problème:
Sur un jeedom à jour (dernière version stable + dernier plugin zigate stable), j'ai mis le plugin en mode inclusion et appuyé sur le bouton de ma sirène pour l’appairer.

Toutes les commandes ne sont pas affichées (pas de gestion du strobe alors que lors d'une précédente tentative elles étaient là).
Les commandes de type "Buzzer X secondes" ne fonctionnent pas. (Seule la commande "Armed" fait buzzer pendant une seconde)

Screenshots
image

Informations:

@pickwick86
Copy link
Author

Après un peu de gratouille dans l'histo Git, c'est le commit 1bd04fa qui pose problème.

Les commandes strobe_ON_Buzzer_ON et STROBE_ON marchaient bien, mais elles ont été supprimées dans la dernière version du plugin.

Je ne connais pas les dessous de la lib et je suis une buse en PHP mais est-ce qu'il serait possible de faire en sorte que ce pilotage du device redevienne possible ?

Fonctions de bases attendues :

  • Strobe ON
  • Strobe OFF
  • Buzzer ON
  • Buzzer OFF

Si on a ces 4 commandes, on peut ensuite faire faire ce qu'on veut au device et recréer d'éventuels "buzzer_2sec" via un scenario.

@doudz
Copy link
Member

doudz commented Dec 24, 2019

Il faut supprimer les commandes qui ne fonctionnent plus à l'aide du bouton "-" à droite de la ligne de commande.
Puis faire une synchronisation pour que les nouvelles commandes soient créées correctement

@pickwick86
Copy link
Author

Ça c'est effectivement la solution si j'avais créé mon équipement avec l'ancienne version et si j'essayais de m'en servir avec la nouvelle, mais là c'est pas le cas. J'ai bien recréé mon équipement "from scratch" avec la nouvelle version.
Ce que je cherche à obtenir, c'est un moyen de faire clignoter mon alarme (un temps donné, pour prévenir qu'elle va bientôt sonner) et un moyen de la faire sonner (idéalement, jusqu'à ce qu'on lui dise Stop)

J'ai regardé un peu le contenu de la zigate.class.php et les specs Zigbee, est-ce que tu peux me confirmer 2-3 trucs ?

D'après ce que je comprends, la commande zigbee est créée à l'aide de la méthode "public function _create_action($endpoint_id, $action, $name, $subtype, $value = null)" et les valeurs "utiles" sont :

  • $action : qui indique au device si on appelle une commande Warning ('ias_warning') ou Alerte ('ias_squawk')
  • $value : qui constitue la payload de la commande.

Suivant si on est warning ou squawk, le struct utilisé comme payload n'est pas le même :

En warning, les huits premiers bits définissent le signal (mode, clignotement, volume sonore), les 16 suivants la durée en secondes, les 8 d'après je sais pas trop ( uStrobeDutyCycle) et les 8 derniers le niveau de clignotement :

typedef struct
{
uint8 u8WarningModeStrobeAndSirenLevel;
uint16 u16WarningDuration;
uint8 uStrobeDutyCycle;
enum8 eStrobeLevel;
}tsCLD_IASWD_StartWarningReqPayload;

En alerte c'est plus simple, la payload est sur 8 bits :

typedef struct
{
uint8 u8SquawkModeStrobeAndLevel;
}tsCLD_IASWD_SquawkReqPayload;

Le premier bit correspond au On/Off de la sirène, le bits 4 au On/Off du clignotement et les bits 6 et 7 au volume sonore.

C'est bien sur ce principe là que tu t'es basé aussi ?

Si c'est bien le cas je ne comprends pas trop les lignes (surtout les $value 'armed' et 'disarmed') :
_create_action($endpoint_id, 'ias_squawk', 'Disarmed', 'other', 'disarmed');
_create_action($endpoint_id, 'ias_squawk', 'Armed', 'other', 'armed');

Je m'attendrais plutôt une payload de type 11010001 pour Armed et 00000000 pour Disarmed

Et pour les commandes de type warning, on dirait que tu ne passes en $value que la durée (60 pour 'buzzer_60sec' par exemple) alors que je m'attendais à y voir une payload plus complexe.

Du coup j'y comprends rien :)
Pour info, j'ai basé mon raisonnement sur la spec JN-UG-3115-1 (pages 879 à 881)

@doudz
Copy link
Member

doudz commented Dec 28, 2019

Ce n'est pas directement le payload de la zigate qui est utilisé par le plugin, on utilise une bibliothèque intermédiaire pour simplifier les choses.
pour la fonction ias_squawk par exemple

 def action_ias_squawk(self, addr, endpoint,
                          mode='armed',
                          strobe=True,
                          level='low',
                          direction=0, manufacturer_code=0):
        '''
        mode: armed or disarmed
        strobe: True or False
        level: low, medium, high, veryhigh
        '''

https://github.com/doudz/zigate/blob/master/zigate/core.py#L2213-L2222

pour le warning

def action_ias_warning(self, addr, endpoint,
                           mode='burglar', strobe=True, level='low',
                           duration=60, strobe_cycle=10, strobe_level='low',
                           direction=0, manufacturer_code=0):
        '''
        mode: stop, burglar, fire, emergency, policepanic, firepanic, emergencypanic
        duration: seconds
        level: low, medium, high, veryhigh
        strobe_cycle: duty-cycle of the strobe pulse, expressed as a percentage in 10% steps
        strobe_level: level of the strobe (pulse) low, medium, high, veryhigh
        '''

@pickwick86
Copy link
Author

OK, au temps pour moi, j'avais zappé la bibliothèque intermédiaire.
Mais par contre vous avez validé le fonctionnement sur quel modèle de sirène ? Je n'ai trouvé que la Heiman en zigbee et elle ne réagit pas du tout aux commandes comme attendu :

  • buzzer_10sec : rien ne se passe
  • buzzer_2sec : rien ne se passe
  • buzzer_60sec : rien ne se passe
  • Armed : La sirène se met en route un court instant (1 seconde ou 2)
  • Disarmed : rien ne se passe (mais pas choquant)
  • off : rien ne se passe (mais pas choquant)

@doudz
Copy link
Member

doudz commented Dec 28, 2019

J'ai ce même modèle de sirène.
Je ferai des tests

@doudz
Copy link
Member

doudz commented Dec 28, 2019

ça pourrait m'aider de lancer les commandes et de me fournir le log en mettant le démon en mode debug

@doudz
Copy link
Member

doudz commented Dec 28, 2019

Je confirme la présence d'un bug

@doudz doudz added the bug Something isn't working label Dec 28, 2019
@doudz
Copy link
Member

doudz commented Dec 28, 2019

doudz/zigate#157

@pickwick86
Copy link
Author

OK ça me rassure, je comprenais plus rien.

Tant qu'à mettre le nez dedans, est-ce qu'il serait possible :

  1. d'avoir une commande qui ne fait que clignoter l'alarme un temps donné (sans son), du genre ias_warning avec la payload qui va bien. (Mode = Stop, Strobe = UseStrobe)

  2. de pouvoir choisir l'intensité sonore du squawk (une commande différente par niveau Low / Medium / High / VeryHigh), ou a minima s'il n'y en a qu'une seule qu'elle soit en VeryHigh histoire de faire le plus de bruit possible

@doudz
Copy link
Member

doudz commented Dec 29, 2019

Après vérif pour squawk
Armed : Sirène + Flash pendant 2 sec
Disarmed : Flash uniquement pendant 2 sec
dans les 2 cas, le volume est sur low mais la sirène Heiman ne semble pas avoir de réglage de volume car pas de différence, peut importe la valeur

@pickwick86
Copy link
Author

Moi j'ai pas tout à fait ça :
Disarmed : la sirène se met à clignoter rapidement et longtemps (potentiellement sans fin).
Et si ensuite j'envoie la commande Off elle se met à clignoter plus lentement pendant une dizaine de secondes avant de s'arrêter.
Ce que tu décris c'est le résultat de tes tests en l'état actuel du code ?

@pickwick86
Copy link
Author

Bonjour,

une idée (à la louche) d'une date de résolution ?

@doudz
Copy link
Member

doudz commented Feb 24, 2020

Le code de base fonctionne, mais ce que je souhaiterai faire c'est donner la possibilité à l'utilisateur de modifier les commandes proposées par défaut pour ajuster par exemple le durée de fonctionnement de la sirène, etc.
Je n'ai pas trop le temps en ce moment pour me consacrer à ce projet donc à la louche je dirais dans un mois
Je suis désolé pour le délai, toute aide est la bienvenue

@sytosoim
Copy link

sytosoim commented May 28, 2020

Bonjour, j'ai également cette sirène utilisée avec la Zigate et Jeedom sur Raspberry Pi3B+. En effet, j'ai les mêmes résultats de commande que @pickwick86 . Est-ce qu'il y a eu une correction du code depuis ? J'ai essayé de faire une boucle afin que la sirène clignote x fois plus longtemps. Eh bien ça clignote beaucoup plus longtemps que ça ne devrait selon le nombre de répétition spécifiée.

@fredericbcv
Copy link

Hello,
Je suis pas sur Jeedom mais sur Home Assistant, je pense pas que ça change grand chose au final. Avant de commencer l'intégration dans Home Assistant, j'ai voulu jouer avec le python pour essayer de faire sonner l'alarme. Une fois l'alarme appairé. voici ce que je fais:

import zigate
z = zigate.connect('/dev/ttyUSB0')
z.devices

[Device (5d4a) 00158d0003a4077f, Device (1ec5) 00158d0003fb74dd, Heiman WarningDevice (5d95) 000d6f0014f70d33]

Il me retourne une liste de devices, je suis content :D

z.devices[-1]

Heiman WarningDevice (5d95) 000d6f0014f70d33

import inspect
inspect.getmembers(z.devices[-1])

En regardant les méthodes du device, je suis tombé sur action_ias_warning et action_ias_squawk

z.devices[-1].action_ias_warning()

Il se passe rien...

z.devices[-1].action_ias_squawk()

Outch mes oreilles !

J'essaye de faire clignoter la lumière sans la sirène avec action_ias_warning

z.devices[-1].action_ias_warning('stop',1,'low',3,30,'low')

Il se passe rien encore une fois, je cherche sur google et je tombe sur le forum zigate.fr, cette sirène est évoqué et un patch du firmware rend possible son utilisation la version 3.1a. J'imagine que mon firmware est à jour sinon la sirène n'aurait pas sonnée. Mais lorsqu'on regarde les derniers post, ils parlent que cela est fonctionnel sur Domoticz.

lien: https://zigate.fr/forum/topic/sirene-compatible-zigate-zigbee/?part=4

Je regarde le code de Domoticz en me disant que les fonctions doivent être proche et c'est le cas effectivement !

lien: https://github.com/pipiche38/Domoticz-Zigate/blob/e4af40c771657b6afd3397e5a80ace6ac76f18a5/Classes/IAS.py

Et effectivement y'as des fonctions cool, dont strobe_only, qui fait appel à

warningmode( nwkid, ep, 'stop' )

qui lui même appel à

self._write_IASWD( nwkid, ep, warning_mode, warning_duration, strobe_duty, strobe_level)

Par contre si on regarde le code de la fonction warningMode le calcul de warning_mode est différent que celui dont fait référence @doudz. Si notre device est un WarningDevice le calcul est différent:

if self.ListOfDevices[nwkid]['Model'] == 'WarningDevice':
strobe_duty = 0x00
strobe_level = 0x01
if mode == 'both':
warning_mode = 0b00010111
elif mode == 'siren':
warning_mode = 0b00010011
elif mode == 'strobe':
warning_mode = 0b00000100
elif mode == 'stop':
warning_mode = 0b00000000

Dans les autres cas le calcul est celui qui est fait par @doudz

STROBE_LEVEL = { 'Low':0x00, 'Medium': 0x01 }

WARNING_MODE = { 'Stop': 0b00000000,
'Burglar': 0b00000001,
'Fire': 0b00000010,
'Emergency': 0b00000011,
'Police Panic': 0b00000100,
'Fire Panic': 0b00000101,
'Emergency': 0b00000110 }
STROBE_MODE = { 'No Strobe':0b00000000,
'Use Strobe':0b00010000 }

SIRENE_MODE = ( 'both', 'siren', 'strobe', 'stop')

warning_duration = 0x00
strobe_duty = 0x00
strobe_level = 0x00
warning_duration = 0x01 # 1 seconde

elif mode in SIRENE_MODE:
if mode == 'both':
warning_mode = WARNING_MODE['Fire'] + STROBE_MODE['Use Strobe']
strobe_duty = 0x1E # % duty cycle in 10% steps
strobe_level = STROBE_LEVEL['Low']
elif mode == 'siren':
warning_mode = WARNING_MODE['Fire'] + STROBE_MODE['No Strobe']
elif mode == 'strobe':
warning_mode = WARNING_MODE['Stop'] + STROBE_MODE['Use Strobe']
strobe_duty = 0x1E # % duty cycle in 10% steps
strobe_level = STROBE_LEVEL['Low']
elif mode == 'stop':
warning_mode = WARNING_MODE['Stop']

Alors je tente, je met un gros magic number dans le code pour tester. Et miracle, ça clignote sans que ça sonne. On peut jouer sur la durée du clignotement, son rapport cyclique, etc.

Voici ma modif en crade pour tester:

@register_actions(ACTIONS_IAS)
def action_ias_warning(self, addr, endpoint,
mode='burglar', strobe=True, level='low',
duration=60, strobe_cycle=10, strobe_level='low',
direction=0, manufacturer_code=0):
'''
mode: stop, burglar, fire, emergency, policepanic, firepanic, emergencypanic
duration: seconds
level: low, medium, high, veryhigh
strobe_cycle: duty-cycle of the strobe pulse, expressed as a percentage in 10% steps
strobe_level: level of the strobe (pulse) low, medium, high, veryhigh
'''
addr = self._translate_addr(addr)
addr_mode, addr_fmt = self._choose_addr_mode(addr)
addr = self.__addr(addr)
manufacturer_specific = int(manufacturer_code != 0)
mode = {'stop': '0000', 'burglar': '1000', 'fire': '0100', 'emergency': '1100',
'policepanic': '0010', 'firepanic': '1010', 'emergencypanic': '0110'
}.get(mode, '0000')
strobe = '10' if strobe else '00'
level = {'low': '00', 'medium': '10', 'high': '01', 'veryhigh': '11'}.get(level, '00')
warning_mode_strobe_level = int(mode + strobe + level, 2)
warning_mode_strobe_level = 4
strobe_level = {'low': 0, 'medium': 1, 'high': 2, 'veryhigh': 3}.get(strobe_level, 0)
data = struct.pack('!B' + addr_fmt + 'BBBBHBHBB', addr_mode, addr, 1,
endpoint,
direction, manufacturer_specific, manufacturer_code,
warning_mode_strobe_level, duration, strobe_cycle, strobe_level)
print('###############')
print(addr_fmt)
print(addr_mode)
print(addr)
print(endpoint)
print(direction)
print(manufacturer_specific)
print(manufacturer_code)
print(warning_mode_strobe_level)
print(duration)
print(strobe_cycle)
print(strobe_level)
print('###############')

self.send_data(0x0111, data)

Petite explication pour les arguments de la fonctions

z.devices[-1].action_ias_warning(mode,strobe,level,duration,strobe_cycle,strobe_level)

J'essayerais pour l'alarme plus tard y'as pas de raison. Si jamais, j'ai un code propre qui fonctionne correctement, je proposerais l'évol à @doudz

@doudz
Copy link
Member

doudz commented Jun 29, 2020

Merci pour les essais
warning_mode_strobe_level = 4
4 en binaire c'est 00000100
soit 0000 : stop sirène
01 : ? strobe ?
00 : level low (pas d'importance puisqu'on dit pas de sirène)

mais le code actuel dit
stop : 0000
strobe : 10
level low : 00
soit 8 et non 4, l'erreur est peut être là
il faudrait tester en modifiant la ligne strobe = '10' if strobe else '00'

comme ceci strobe = '01' if strobe else '00'

@fredericbcv
Copy link

En effet, je teste ça ce soir ^^

Par contre pour ceux qui se pose la question, c'est normal que l'alarme se coupe avec la fonction action_ias_squawk. Voici ce que dit la doc de NXP:

The IAS WD cluster allows a device which detects warning conditions (e.g. fire) to trigger a warning on an IAS Warning Device which, in turn, initiates a physical alarm such as a siren and/or strobe. The IAS Warning Device hosts the cluster server and the triggering device hosts the cluster client. Two types of warning can be initiated:

  • Warning mode: This mode indicates a genuine emergency, such as a fire or an intruder. On detection of the emergency condition, the application on the triggering device must call the eCLD_IASWDStartWarningReqSend() function, which sends a Start Warning command to the Warning Device. The payload of this command contains the time-duration for which the Warning Device must remain in warning mode. The specified duration must not exceed the maximum duration defined in the u16MaxDuration attribute on the Warning Device (see Section 28.2). The payload also contains details of the warning and the strobe requirements, if any. On receiving this command, an E_CLD_IASWD_CMD_WD_START_WARNING event is generated on the Warning Device (see Section 28.4) for the attention of the application.

  • Squawk mode: This mode indicates a change of state of the IAS system - that is, armed or disarmed. Thus, this is typically a short audible beep or ‘squawk’ that is emitted when the system is armed or disarmed. To initiate a squawk, the application on the triggering device must call the function eCLD_IASWDSquawkReqSend(), which sends a Squawk command to the Warning Device. The payload also contains details of the squawk and the strobe requirements, if any. On receiving this command, an E_CLD_IASWD_CMD_WD_SQUAWK event is generated on the Warning Device (see Section 28.4) for the attention of the application.

Pour ceux qui ont la flemme de lire Squawk mode c'est pour émettre un son court typiquement lorsqu'on active ou désactive l'alarme. Et Warning c'est pour la faire sonner en continue, la durée est un uint_16 en secondes ce qui fait pratiquement 18h à sonner. Je pense que tu auras eu le temps de rentrer chez toi.

@fredericbcv
Copy link

fredericbcv commented Jun 29, 2020

@doudz Je viens de tester en effet ceci corrige le strobe strobe = '01' if strobe else '00'

Par contre, je n'arrive pas à activer l'alarme. J'ai refais une passe sur la datasheet de NXP JN-UG-3077 v2.1 chapitre 28 page 558 dans le tableau, on voit les valeurs suivantes :

  • 0 - Stop
  • 1 - Burglar
  • 2 - Fire
  • 3 - Emergency
  • 4 - Police panic
  • 5 - Fire panic
  • 6 - Emergency panic
    All other values are reserved

Par rapport à ce qu'on voit dans le code je pense que les msb et lsb ont été inversés.

En modifiant la ligne
mode = {'stop': '0000', 'burglar': '1000', 'fire': '0100', 'emergency': '1100', 'policepanic': '0010', 'firepanic': '1010', 'emergencypanic': '0110' }.get(mode, '0000')
par
mode = {'stop': '0000', 'burglar': '0001', 'fire': '0010', 'emergency': '0011', 'policepanic': '0100', 'firepanic': '0101', 'emergencypanic': '0110' }.get(mode, '0000')

J'ai les modes burglar, fire, emergency qui font bien sonner l'alarme, c'est gagné :). Par contre, c'est la même à chaque fois, j'ai pas vu de différence. Les modes panic ne font pas sonner l'alarme, je pense que c'est pas implémenté dans la sirène tout comme le niveau sonore qui n'a aucun effet.

Il me reste plus qu'a faire le faire marcher dans home assistant :s

@fredericbcv
Copy link

En faite c'est assez simple, voici ce que j'ai fais si ça intéresse du monde:

  • Créez un nouveau script
  • Dans type d'action, choissez Appeler un service
  • Dans service, selectionner zigate.ias_warning
  • Puis cliquez sur les trois petits points à droite et cliquez sur modifier en tant que YAML et remplissez les champs comme ceci
data:
  addr: 5d95 (verifiez l'adresse dans la partie administration du zigate)
  duration: 1
  endpoint: '1'
  entity_id: zigate.0000000000000000 (verifiez l'id dans la partie administration du zigate)
  level: low
  mode: fire
  strobe: true
  strobe_cycle: 10
  strobe_level: low
service: zigate.ias_warning

Et voilà, je peux me créer autant de script que je veux avec des valeurs prédéfinies.

Merci @doudz pour ton taff c'est cool 👍

@doudz
Copy link
Member

doudz commented Jun 30, 2020

@fredericbcv c'est un peu off topic puisque ça concerne home assistant, mais tu ne peux pas indiquer le paramètre addr et le paramètre entity_id
Le plus efficace est d'indiquer uniquement entity_id, ainsi l'adresse addr sera récupérée en interne.

@fredericbcv
Copy link

Ok c'est bon à savoir, merci

@pickwick86
Copy link
Author

Et du coup pour utiliser la sirène dans Jeedom ?

@fredericbcv
Copy link

fredericbcv commented Aug 17, 2020

J'utilise pas Jeedom mais Home Assistant, mais je pense que si tu appliques les même modifs que moi, il y'a moyen que cela corriges tes commandes prédéfinies dans Jeedom.

@fredericbcv
Copy link

@pickwick86 Hello, j'ai regardé doudz à pris en compte le correctif que j'avais proposé. Il manquait une partie sur ias_sqwak et warning mais c'est mineur. Si ça se trouve si tu met à jour le package python zigate, tu corriges ton problème.

@doudz J'ai créé une pull request sur le reste de la modif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants