Table of Contents

2006-09-01 J'ai hacké mon onduleur ou le reverse engineering de protocoles de communication (part 8)

J'ai donc continuer de développer ma solution de gestion d'onduleur. J'ai profité de mon retour à la maison pour continuer les tests physiques sur mes onduleurs. Oui, j'ai bien dit mes onduleurs. En fait, j'en possède 3 du même modèle. Ce qui a aussi motivé l'écriture de ce service de gestion…

La suite des tests m'a permis de compléter le protocole de communication et de déterminer à quoi servent la plupart des bits :

00001000 = statut. 1 bit par info.

b0b1b2b3b4b5b6b7

  • b0 = passe à 1 lorsqu'une panne de courant arrive, lorsque l'alimentation est coupée
  • b1 = passe à 1 lorsque la batterie est faible
  • b2 = ??? pas encore déterminé. Impossible en utilisation normale de le faire passer à 1. Il reste à 0.
  • b3 = ??? Idem
  • b4 = est à 1 en fonctionnement normal. Il indique que les sorties sont alimentées
  • b5= passe à 1 quand on est en mode test. Le mode test est déclenché par l'envoie de la commande T
  • b6 = ??? pas non plus réussit à déterminer à quoi ce bit sert
  • b7 = passe à 1 quand l'alimentation est sur batterie Cela m'a également permis d'étalonner les niveau de la batterie. Le niveau haut varie de 14 à 10,7. L'échelle de consommation est quasi linéaire.

Côté code, j'ai décidé d'implémenter des événements. Ainsi, lorsqu'un de ces bits change, j'envoie l'événement correspondant. Cela permet de gérer avec de la souplesse ce qui peut arriver. Il faut d'abord dans le code déclarer les événements :

'se déclenche lorsque le secteur est coupé, en général va avec l'événement FonctionnementBatterie 
Public Event ArretAlimSecteur() 

'se déclenche lorsque le secteur est remis (et qu'il était coupé) 
Public Event RetourAlimSecteur() 

'lorsque l'onduleur fonctionne sur batterie 
Public Event FonctionnementBatterie() 

'ou lorsqu'il fonctionne de nouveau normalement 
Public Event ArretFonctionnementBatterie() 

'Lorsque la batterie est faible 
Public Event BatterieFaible() 

'lorsque l'onduleur est arrêté 
Public Event OnduleurArrete() 

Puis, pour chaque bit, on vérifie si un changement d'état s'est passé. Ca donne cela :

'position 0 = panne secteur 
Dim BoolTemp As Boolean 
' récupère la valeur (0 ou 1) du bit 0 de la chaîne de 8 bits 
BoolTemp = Val(mc.Item(7).Value.Substring(0, 1)) 
If BoolTemp <> myOnduleurPanneSecteur Then 
  If BoolTemp Then 
    RaiseEvent ArretAlimSecteur() 
  Else 
    RaiseEvent RetourAlimSecteur() 
  End If 
myOnduleurPanneSecteur = BoolTemp 
End If 

Le principe est simple, il faut récupérer la valeur dans une variable temporaire. Puis on compare à la valeur actuelle. Si la valeur est la même, alors pas de changement d'état et on ne fait rien. Si les valeurs sont différentes, alors on regarde la valeur de la variable.

Dans le cas où le bit est à 1, alors cela signifie que le courant a été coupé. On envoie donc l'événement ArretAlimSecteur. Dans le cas où il passe à 0, on peut signifier que le courant est revenu en envoyant l'événement RetourAlimSecteur. Le mot magic RaiseEvent permet d'envoyer l'événement.

Ne pas oublier à la fin d'attribuer la nouvelle valeur à la variable privée stockant cette information.

Côté du code qui intercepte les événements, ce n'est pas plus compliqué. Il faut déclarer une variable avec le mot clé WithEvents.

Public WithEvents myOnduleur As New Onduleur 

On se retrouve ensuite avec une fonction de ce type qui permet d'intercepter l'événement et de le traiter :

Private Sub myOnduleur_ArretAlimSecteur() Handles myOnduleur.ArretAlimSecteur 
'Faire quelque chose ici :-) 
End Sub 

S'il y a des paramètres à passer, cela se passe de la même façon. Il suffit de les décrire dans la définition puis de les envoyer ans le RaiseEvent et de les récupérer comme avec n'importe quel événement dans la fonction Handles.

L'utilisation des événements est donc très simple. Un vrai bonheur.

Avec cela, j'ai fini d'écrire ma classe de gestion de l'onduleur. Elle permet de se connecter à l'onduleur, de récupérer les informations, en cas de panne de courant ou autre, d'envoyer l'événement correspondant.

Je récupère les données de façon régulière à l'aide d'un timer. Le fonctionnement d'un timer au prochain post…