Forum dédié aux problématiques concernant les scripts pour DomoticZ.
Entourez votre code et les logs avec les balises nommées code grâce au bouton <\>.
J'utilise le canal I2C pour mes carpteurs d'ouverture de mon alarme.
On peut dire que cela fonctionne à 99%, mais quand comment et pourquoi? quand une carte PCF8574 ne répond pas un message d'erreur arrive dans le log
2024-10-01 06:58:35.314 Error: I2C_0x21_33: I2C_PCF8574: Failed to read from the i2c bus with address 33
Ca fait pas mal de temps que je cherche, mais comme ces erreurs sont rares il m'est impossible de trouver la raison.
Par contre, quelques fois les erreurs sont empiriques et au bout d'un certain temps toutes les cartes de même type ne répondent plus et le plus important, domoticz sera tellement occupé qu'il ne répondra plus et il plante.
pour réinitialiser le canal I2C dans un script Lua quand l'erreur est dans le log car évidement cela se produit le plus souvent quand je ne suis pas chez moi.
Est ce possible?
Merci de votre aide.
Cordialement.
commandArray = {}
-- Chemin du fichier log de Domoticz
local logFilePath = "/tmp/domoticz.txt"
-- Fonction pour lire la dernière ligne d'un fichier
local function readLastLine(filename)
local file = io.open(filename, "r")
if not file then return nil end
local lastLine
for line in file:lines() do
lastLine = line
end
file:close()
return lastLine
end
-- Lire la dernière ligne du fichier log
local lastLogLine = readLastLine(logFilePath)
-- Vérifier que la dernière ligne n'est pas nil
if lastLogLine then
-- Vérifier la présence de l'erreur "Error: I2C"
if string.find(lastLogLine, "Error: I2C") then
-- Redémarrer le canal I2C
os.execute("sudo modprobe -r i2c-dev")
os.execute("sudo modprobe i2c-dev")
-- Afficher un message dans la console
print('Canal I2C redémarré suite à l\'erreur.')
end
else
print('Le fichier log est vide ou inaccessible.')
end
return commandArray
Ce qui est ici fait, c'est un redémarrage de l'I2C du PI par déchargement/rechargement du module noyau (les lignes avec "modprobe", éventuellement assortie de l'option "-r" pour remove).
Pourtant, la trace suggèrerait plutôt qu'une trame n'a pas été reçue en face (pas d'acknowledge)...
Attention, car bien que simple l'I2C pose souvent des problèmes, parmi lesquels:
1)Non support de son mode contrôle de flux dit "clock stretching": Le récepteur tiens la ligne SCL à 0 pour signifier qu'il ne peut plus rien recevoir... Mais si côté émetteur on s'en fout, perte/désynchronisation au programme!
2)Violations du protocole, en particulier sur les repeated-start.
3)Sensibilité au bruit: Avec de la logique rapide, une perturbation même de l'ordre de la ns (bon scope et sonde pour la voir, à l'analyseur logique on passera au travers) de la ligne d'horloge (SCL) peut causer un double échantillonnage d'un bit de donnée sur SDA côté récepteur. On peut donc se retrouver désynchronisé côté émetteur pour le ack final et avoir une substitution de commande/donnée côté récepteur (attention aux FPGA Mach XO2 qui avaient la commande de lecture de statut simplifié ayant 1 bit de différence avec la fonction de blocage définitif de l'interface de programmation du composant, à des fins de protection! Y'avait plus qu'a remplacer le composant et du BGA c'est pas simple): En face, ça peut vite mettre un composant dans un état tordu.
Pour 1, la solution serait de baisser la vitesse (probablement via un paramètre du module) afin d'éviter que du controle de flux ne soit nécéssaire.
Pour 2, rien de simple: J'ai parfois dû configurer des IO I2C en véritables IO pour les gérer par programme (driver/module I2C fonctionnant en mode dit "bit-banging", il en existe peut-être utilisable sur PI) sans les affecter à un un contrôleur I2C ne sachant pas générer des trames hors norme.
Pour 3, soigner la connectique (blindage, parfois un réglage d'impédance de terminaison est dispo).
Si c'était chez moi, pour un IO extender I2C qui doit a priori être poolé pour voir si un état alarme monte à un rythme qui pourrait être à la seconde, je commencerait par baisser la vitesse.
Merci pour ces éclaircissements.
Le protocole I2C est bien délicat je le confirme, mais tellement pratique, un module PCF8574 et 8I/O ou le MCP23017 16I/O que j'utilise en sortie uniquement.
Le PCF8574 qui me fait défaut est souvent le même celui qui est le plus loin, je me suis acharné avec un oscillo pour que ses signaux soient le plus propre possible baissé la vitesse de transmission comme tu l'as suggéré mais quelques fois et pas souvent moins de 10 fois par an, il ne répond plus et au bout d'un certain temps tous les autres font pareils jusqu'au système 1Wire qui lâche aussi.
Après un reboot du raspberry tout revient dans l'ordre, je pense tout comme toi que les parasites y sont pour quelque chose, j'ai dû changer un télérupteur ancien qui quand actionné foutait le canal I2C en rideau changer des modules relais méca par des SSR également.
Mais quand ça se produit la nuit à 3h00 du matin ou quand il n'y a personne à la maison je suis bien embarrassé pour en définir la cause.
A+