[Tuto] Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Vous avez créé un script LUA dont vous êtes fier, un .sh génial, un programme Python hors du commun, un Tuto, c'est ici que vous pouvez les partager.
js-martin
Messages : 487
Inscription : 22 mars 2015, 22:08
Contact :

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par js-martin »

Nouvelle version du code : 1.2
Add : check internal Viessmann error log + new widget "Alert"


J'ai fait une petite amélioration : un widget Alert qui donne l'état de la chaudière et remonte les deux derniers défauts (numéro du code d'erreur).

Si tout va bien :
Etat_chaudiere_Green.JPG
Etat_chaudiere_Green.JPG (14.27 Kio) Consulté 14001 fois
S'il y a un défaut constaté dans les logs de la chaudière (ici deux : le dernier est le code erreur 123 et le précédent 456) :
Etat_chaudiere_RED.JPG
Etat_chaudiere_RED.JPG (14.56 Kio) Consulté 14001 fois
La chaudière gère ses erreurs internes. Il est possible de les consulter en appuyant simultanément sur "OK" + "mode chauffage". La chaudière stocke les 10 derniers défauts.

Les codes sont formés de 3 digits. "OOO" indique que tout va bien. La correspondance des codes et des messages d'erreur est dans votre notice de maintenance (cela ressemble à cela pour ma 222-W : http://www.viessmann.com/vires/product_ ... 0001_1.PDF )

La remise à zéro des défauts est possible en appuyant simultanément sur "OK" + "mode chauffage", puis sur la touche ">|<" qui permet d'effacer tous les codes mémorisés.

Sur ce nouveau widget, une notification par email ou autre me semble pertinente. Tiens, pas de notification via Domoticz sur les widget "alert" : bizarre... Je creuserai ce point quand j'aurai un peu de temps => viewtopic.php?f=8&t=2093

Code : Tout sélectionner

#!/usr/bin/python
# domo2vito 
# JS MARTIN - 05/2016
# version 1.2

import telnetlib
import sys     
import os
import time
import requests
from requests.auth import HTTPBasicAuth
import json

############# Parameters ################################# 

#~~~~~~~~~~ Parameters Domoticz ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
domoticz_ip='192.168.10.40'
domoticz_port='8080'
user=''  
password=''
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Commands viTalk
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#autorized commands
commands = ["mode","saving","party","party_soll_temp","outdoor_temp","raum_soll_temp","raum_ist_temp","k_ist_temp","ww_soll_temp","ww_ist_temp","k_abgas_temp","power","errors"]
#write only commands
write_only_commands = ["mode","saving","party","party_soll_temp","ww_soll_temp"]

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IDX de Domoticz
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# remplacer XXX par votre idx de votre widget
dummy_idx={'mode':343, 'saving': 344, 'party':345, 'party_soll_temp':346, 'outdoor_temp':347, 'raum_soll_temp':355, 'raum_ist_temp':349, 'k_ist_temp':350, 'ww_soll_temp':351, 'ww_ist_temp':352, 'k_abgas_temp':353, 'power':354, 'error_log':371}
# mode   : dummy selector switch OFF/Water/Heating (Boiler [FR:chaudiere] stand-by/water only/water+heating)
# saving : dummy switch ON/OFF (Boiler eco ON/OFF)
# party  : dummy switch ON/OFF (party temporary manual control)
# party_soll_temp: dummy thermostat setpoint (party temperature)
# outdoor_temp   : dummy temp (outdoor temperature)
# raum_soll_temp : dummy temp (heating setpoint [FR:consigne] temperature) - note : without vitotronic, use thermostat setpoint 
# raum_ist_temp  : dummy temp (heating current [FR:actuelle] temperature)
# k_ist_temp     : dummy temp (boiler current temperature)
# ww_soll_temp   : dummy temp (hot water setpoint temperature)
# ww_ist_temp    : dummy temp (hot water current temperature)
# k_abgas_temp   : dummy temp (exhaust gas [FR:gaz evacue'] temperature)
# power          : dummy percentage (% boiler power) 

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Mode debug
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# if debug = True => verbose
debug=True

#######################################################################
######  viTalk_connect() : connect to viTalk localhost:83
#######################################################################

def viTalk_connect():
        retry=3
        while retry!=0:
            try:
               tn = telnetlib.Telnet("localhost", 83)
               print "Connected to viTalk telnet !"
               return tn
            except:
               print "Connection ERROR - I try to restart viTalk deamon"
               #I try to restart viTalk
               cmd = 'sudo service vitalk restart'
               os.system(cmd)
               time.sleep(10)
               retry-=1
            else:
               tn.read_until(b"$", 5)
        if retry==0:
           tn.close()
           print "Connection ERROR - I could not restart viTalk deamon"
           sys.exit()
######


#######################################################################
###### viTalk_read(cmd) : read a value  
#######################################################################

def viTalk_read(cmd):
        global debug
        global tn
        retry=3
        value=""
        while retry!=0:
            tn.read_until(b"$", 5)
            tn.write(b"g "+cmd+"\n")
            value=tn.read_until(b"$", 5).strip("\n$")
            if value!="" and value!='NULL':
                break
            retry-=1
        if retry==0:
            print "Connection ERROR - I try to restart viTalk deamon"
            os.system('sudo service vitalk restart')
            #tn.close()
            print(cmd+": "+value+" error")
            sys.exit()
        value = value.strip("\n$")
        if debug:
           print "get "+cmd+" : answer = "+value
        return value
          
######

#######################################################################
###### viTalk_check() : test viTalk and restart it if needed
#######################################################################

def viTalk_check():
        global debug
        global tn
        retry=3
        value=""
        while retry!=0:
            tn.read_until(b"$", 5)
            tn.write(b"g mode \n")
            value=tn.read_until(b"$", 5).strip("\n$")
            if value!="" and value!='NULL':
                if debug:
                   print "Check viTalk data OK ! (no NULL data received)"
                break
            retry-=1
        if retry==0:
            print "Connection ERROR - I try to restart viTalk deamon"
            os.system('sudo service vitalk restart')
            sys.exit()
######

#######################################################################
###### viTalk_set(cmd,val) : unsecured write
#######################################################################
def viTalk_set(cmd,val):
        global debug
        global tn
        tn.write(b"s "+cmd+" "+val+"\n")
        tn.read_until(b"$", 5).strip("\n$")
        if debug:
             print("set "+cmd+" "+val)
          
######

#######################################################################
###### viTalk_write(cmd,val) : secured write (I check if value is 
######                         really updated)
#######################################################################
def viTalk_write(cmd,val):
        global debug
        global tn
        retry=3
        value=""
        while retry!=0:
            viTalk_set(cmd,val)
            tn.read_until(b"$", 5)
            value=viTalk_read(cmd) 
            if val==value:
                break
            retry-=1
        if retry==0:
           tn.close()
           print(cmd+" "+val+" : error")
           sys.exit()
        if debug:
           print "check last command set "+cmd+" "+val+" : OK"

#########

#######################################################################
###### check_command(cmd) : is it an authorized command ?  
#######################################################################
def check_command(cmd):
       global commands
       global debug
       try:
         #check position of cmd in commands list 
         commands.index(cmd)
       except:
          print "command not found"
          return False
       else:
          if debug:
             print "this command "+cmd+" is known"
          return True
####

#######################################################################
###### check_set_command(cmd) : is it an authorized write command ?
#######################################################################
def check_set_command(cmd):
       global commands
       global debug
       try:
         #check position of cmd in write only commands list
         write_only_commands.index(cmd)
       except:
          print "set command not found (I can't write with this command)"
          return False
       else:
          if debug:
             print "this command "+cmd+" is known for writing"
          return True
####

#######################################################################
###### get_setpoint_temp(idx) : get temperature from domoticz setpoint
#######################################################################
def get_setpoint_temp(idx):
    r = requests.get('http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=devices&rid='+str(idx),auth=HTTPBasicAuth(user,password))
    status=r.status_code
    if status == 200:
       r=r.json()
       result={}
       return r['result'][0]['Data']
    else:
       print "Get setpoint temp error - IDX:"+str(idx) 


#-----------------------------------### START ###--------------------------------------------#

# arguments in command line 
nb_arg=len(sys.argv)-1 

if nb_arg==0:
   print "HELP : "
   print "domo2vito update : update all domoticz values"
   print "domo2vito command : get command (e.g. domo2vito mode <=> get mode)"
   print "domo2vito command value : set command value (e.g. domo2vito mode 1 <=> set mode 1)"

if nb_arg==1 and sys.argv[1]!="update":
   if check_command(sys.argv[1]):
       if debug:
          print "get "+sys.argv[1] 
       tn=viTalk_connect()
       viTalk_read(sys.argv[1])
       tn.close()

if nb_arg==1 and sys.argv[1]=="update":   
   tn=viTalk_connect()
   viTalk_check()
   values=[]
   i=0
   tn.read_until(b"$", 5)
   for command in commands:
       tn.write(b"g "+command+"\n")
       value=tn.read_until(b"$", 5).strip("\n$")
       if debug:
          print str(i)+") command : get "+command+ " => "+value
       values.append(value)
       i+=1
   # get setpoint  party_soll_temp and update boiler if needed
   temp=int(float(get_setpoint_temp(dummy_idx['party_soll_temp'])))
   if temp!=int(float(values[3])): #Viessmann ignore decimales
      if debug:
         print "party setpoint has changed : I update it!"
      if temp<12: # party mini temp
         temp=12
      if temp>25: # party maxi temp
         temp=25
      viTalk_set("party_soll_temp",str(temp))
   # get setpoint ww_soll_temp and update boiler if needed
   temp=int(float(get_setpoint_temp(dummy_idx['ww_soll_temp'])))
   if temp!=int(float(values[8])): #Viessmann ignore decimales
      if debug:
         print "hot water setpoint has changed : I update it!"
      if temp<20: # hot water mini temp
         temp=20
      if temp>70: # hot water maxi temp
         temp=70
      viTalk_set("ww_soll_temp",str(temp))
   tn.close() 
   
   #mode (selector level : 0=OFF 10=water 20=heating)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['mode'])+'&switchcmd=Set%20Level&level='+str(int(values[0])*10)
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # saving : dummy switch ON/OFF (Boiler eco ON/OFF) : if a user modify boiler or vitotrol, update Domoticz
   if values[1]=="0":
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['saving'])+'&switchcmd=Off'
   else:
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['saving'])+'&switchcmd=On'
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # party  : dummy switch ON/OFF (party temporary manual control) : if a user modify boiler or vitotrol, update Domoticz
   if values[2]=="0":
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['party'])+'&switchcmd=Off'
   else:
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['party'])+'&switchcmd=On'
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # party_soll_temp: dummy thermostat setpoint (party temperature) note:Domoticz setpoint manage this parameter
   #req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['party_soll_temp'])+'&nvalue=0&svalue='+values[3]
   #requests.get(req,auth=HTTPBasicAuth(user,password))

   # outdoor_temp   : dummy temp (outdoor temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['outdoor_temp'])+'&nvalue=0&svalue='+values[4]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # raum_soll_temp : dummy temp (heating setpoint [FR:consigne] temperature) - note : without vitotronic, use thermostat setpoint
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['raum_soll_temp'])+'&nvalue=0&svalue='+values[5]
   requests.get(req,auth=HTTPBasicAuth(user,password))
 
   # raum_ist_temp  : dummy temp (heating current [FR:actuelle] temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['raum_ist_temp'])+'&nvalue=0&svalue='+values[6]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # k_ist_temp     : dummy temp (boiler current temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['k_ist_temp'])+'&nvalue=0&svalue='+values[7]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # ww_soll_temp   : dummy setpoint (hot water setpoint temperature) note:Domoticz setpoint manage this parameter
   #req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['ww_soll_temp'])+'&nvalue=0&svalue='+values[8]
   #requests.get(req,auth=HTTPBasicAuth(user,password))

   # ww_ist_temp    : dummy temp (hot water current temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['ww_ist_temp'])+'&nvalue=0&svalue='+values[9]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # k_abgas_temp   : dummy temp (exhaust gas [FR:gaz evacue'] temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['k_abgas_temp'])+'&nvalue=0&svalue='+values[10]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # power          : dummy percentage (% boiler power)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['power'])+'&nvalue=0&svalue='+values[11]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # error	    : dummy alert (show the two last log codes) 
   # values[12]="123,456,235,244,244,244,244,244,244,244 ;"
   V_error=values[12][0:3]
   V_previous_error=values[12][4:7]
   if V_error=="000":
      if debug:
          print "no internal error : all it is OK"+"(previous code="+V_previous_error+")"
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['error_log'])+'&nvalue=1&svalue='+'OK (previous='+V_previous_error+')'
   else:
      if debug:
          print "There is an internal error : code="+V_error+"(previous code="+V_previous_error+")"
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['error_log'])+'&nvalue=4&svalue='+'Error '+V_error+' (previous='+V_previous_error+')'
   requests.get(req,auth=HTTPBasicAuth(user,password))

if nb_arg==2:
   if check_set_command(sys.argv[1]):
       print "set "+sys.argv[1]+" "+sys.argv[2]
       tn=viTalk_connect()
       viTalk_write(sys.argv[1],sys.argv[2])
       tn.close()
Domotisation de : mes compteurs EDF, solaire, eau / mon alarme / ma Chaudière Viessamnn / mon congel / ma sonnette. Matériels : Pi2 - RFXTrx433e - Zwave+ Aeotec, ampoules Hue - Détecteur et prises Fibaro - Capteurs Oregon - présentation installation => lien
lanvezhon
Messages : 10
Inscription : 12 mai 2016, 19:10

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par lanvezhon »

Bjr, Merci "Maître" pour ces améliorations, notamment la relance du daemon en vrac. Pour info, sur la vito 300, il y a la mem "0A82" à 0 ou 1 si défaut (état de la lampe rouge). La valeur à 3 digits décimaux est à traduire en HEX pour refléter les codes de la doc (Ex mem=235 > Code=Eb).
js-martin
Messages : 487
Inscription : 22 mars 2015, 22:08
Contact :

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par js-martin »

Tu ne vas pas bien ?? "Maitre" !?! j'ai maintenant mes chaussettes qui se déchirent avec mes chevilles qui enflent :o
Je ne suis pas développeur, mais cela me plaisait quand j'étais plus jeune...

Sérieusement, tu n'as plus de problème avec l'instabilité de viTalk ? De mon côté, cela semble stable maintenant.

Pour les codes d'erreur, je vais m'en occuper pour les passer en hexa.

Pour l'adresse 0A82, tu l'as trouvé où ? Il faudrait voir si c'est commun à plusieurs modèles (ou je le mets en paramètre). Le voyant rouge s'allume dès qu'une erreur est trouvée ou seulement pour certaines erreurs critiques ? Dans ce cas, je pourrais rajouter un niveau d'alerte sur le widget.

Pour les notifications, je peux rajouter un switch virtuel (erreur chaudiere : on/off) ou je fais l'envoi d'un mail depuis le code. Tu as un avis ?
Domotisation de : mes compteurs EDF, solaire, eau / mon alarme / ma Chaudière Viessamnn / mon congel / ma sonnette. Matériels : Pi2 - RFXTrx433e - Zwave+ Aeotec, ampoules Hue - Détecteur et prises Fibaro - Capteurs Oregon - présentation installation => lien
lanvezhon
Messages : 10
Inscription : 12 mai 2016, 19:10

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par lanvezhon »

Le Daemon marche. Pour la lecture de l'état de la lampe, on trouve quelques infos dans les XML OPENV & autre utilisés par le daemon VCONTROLD (quelquefois repéré comme OUTPUT 50). Je crois que chaque erreur génère l'allumage. Dans mon cas le signalement par notification de la présence d'un défaut me suffirait, la lecture du code & son éventuel traitement se faisant au "pied du mur" avec la doc.
js-martin
Messages : 487
Inscription : 22 mars 2015, 22:08
Contact :

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par js-martin »

Nouvelle version du code : 1.3
Add : internal Viessmann errors log are now in hexa
Add : new widget "problem" (set switch to On if there is a internal boiler problem)


Le nouveau switch permet de faire les notifications en cas de défaut.
panne.JPG
panne.JPG (15.13 Kio) Consulté 13927 fois

Code : Tout sélectionner

#!/usr/bin/python
# domo2vito 
# JS MARTIN - 05/2016
# version 1.3

import telnetlib
import sys     
import os
import time
import requests
from requests.auth import HTTPBasicAuth
import json

############# Parameters ################################# 

#~~~~~~~~~~ Parameters Domoticz ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
domoticz_ip='192.168.10.40'
domoticz_port='8080'
user=''  
password=''
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Commands viTalk
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#autorized commands
commands = ["mode","saving","party","party_soll_temp","outdoor_temp","raum_soll_temp","raum_ist_temp","k_ist_temp","ww_soll_temp","ww_ist_temp","k_abgas_temp","power","errors"]
#write only commands
write_only_commands = ["mode","saving","party","party_soll_temp","ww_soll_temp"]

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# IDX de Domoticz
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# remplacer XXX par votre idx de votre widget
dummy_idx={'mode':343, 'saving': 344, 'party':345, 'party_soll_temp':346, 'outdoor_temp':347, 'raum_soll_temp':355, 'raum_ist_temp':349, 'k_ist_temp':350, 'ww_soll_temp':351, 'ww_ist_temp':352, 'k_abgas_temp':353, 'power':354, 'error_log':371, 'problem':416}
# mode   : dummy selector switch OFF/Water/Heating (Boiler [FR:chaudiere] stand-by/water only/water+heating)
# saving : dummy switch ON/OFF (Boiler eco ON/OFF)
# party  : dummy switch ON/OFF (party temporary manual control)
# party_soll_temp: dummy thermostat setpoint (party temperature)
# outdoor_temp   : dummy temp (outdoor temperature)
# raum_soll_temp : dummy temp (heating setpoint [FR:consigne] temperature) - note : without vitotronic, use thermostat setpoint 
# raum_ist_temp  : dummy temp (heating current [FR:actuelle] temperature)
# k_ist_temp     : dummy temp (boiler current temperature)
# ww_soll_temp   : dummy temp (hot water setpoint temperature)
# ww_ist_temp    : dummy temp (hot water current temperature)
# k_abgas_temp   : dummy temp (exhaust gas [FR:gaz evacue'] temperature)
# power          : dummy percentage (% boiler power) 
# error_log          : dummy alert (show the two last log codes) 
# problem        : dummy switch (set switch to On if there is a internal boiler problem)

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Mode debug
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# if debug = True => verbose
debug=True

#######################################################################
######  viTalk_connect() : connect to viTalk localhost:83
#######################################################################

def viTalk_connect():
        retry=3
        while retry!=0:
            try:
               tn = telnetlib.Telnet("localhost", 83)
               print "Connected to viTalk telnet !"
               return tn
            except:
               print "Connection ERROR - I try to restart viTalk deamon"
               #I try to restart viTalk
               cmd = 'sudo service vitalk restart'
               os.system(cmd)
               time.sleep(10)
               retry-=1
            else:
               tn.read_until(b"$", 5)
        if retry==0:
           tn.close()
           print "Connection ERROR - I could not restart viTalk deamon"
           sys.exit()
######


#######################################################################
###### viTalk_read(cmd) : read a value  
#######################################################################

def viTalk_read(cmd):
        global debug
        global tn
        retry=3
        value=""
        while retry!=0:
            tn.read_until(b"$", 5)
            tn.write(b"g "+cmd+"\n")
            value=tn.read_until(b"$", 5).strip("\n$")
            if value!="" and value!='NULL':
                break
            retry-=1
        if retry==0:
            print "Connection ERROR - I try to restart viTalk deamon"
            os.system('sudo service vitalk restart')
            #tn.close()
            print(cmd+": "+value+" error")
            sys.exit()
        value = value.strip("\n$")
        if debug:
           print "get "+cmd+" : answer = "+value
        return value
          
######

#######################################################################
###### viTalk_check() : test viTalk and restart it if needed
#######################################################################

def viTalk_check():
        global debug
        global tn
        retry=3
        value=""
        while retry!=0:
            tn.read_until(b"$", 5)
            tn.write(b"g mode \n")
            value=tn.read_until(b"$", 5).strip("\n$")
            if value!="" and value!='NULL':
                if debug:
                   print "Check viTalk data OK ! (no NULL data received)"
                break
            retry-=1
        if retry==0:
            print "Connection ERROR - I try to restart viTalk deamon"
            os.system('sudo service vitalk restart')
            sys.exit()
######

#######################################################################
###### viTalk_set(cmd,val) : unsecured write
#######################################################################
def viTalk_set(cmd,val):
        global debug
        global tn
        tn.write(b"s "+cmd+" "+val+"\n")
        tn.read_until(b"$", 5).strip("\n$")
        if debug:
             print("set "+cmd+" "+val)
          
######

#######################################################################
###### viTalk_write(cmd,val) : secured write (I check if value is 
######                         really updated)
#######################################################################
def viTalk_write(cmd,val):
        global debug
        global tn
        retry=3
        value=""
        while retry!=0:
            viTalk_set(cmd,val)
            tn.read_until(b"$", 5)
            value=viTalk_read(cmd) 
            if val==value:
                break
            retry-=1
        if retry==0:
           tn.close()
           print(cmd+" "+val+" : error")
           sys.exit()
        if debug:
           print "check last command set "+cmd+" "+val+" : OK"

#########

#######################################################################
###### check_command(cmd) : is it an authorized command ?  
#######################################################################
def check_command(cmd):
       global commands
       global debug
       try:
         #check position of cmd in commands list 
         commands.index(cmd)
       except:
          print "command not found"
          return False
       else:
          if debug:
             print "this command "+cmd+" is known"
          return True
####

#######################################################################
###### check_set_command(cmd) : is it an authorized write command ?
#######################################################################
def check_set_command(cmd):
       global commands
       global debug
       try:
         #check position of cmd in write only commands list
         write_only_commands.index(cmd)
       except:
          print "set command not found (I can't write with this command)"
          return False
       else:
          if debug:
             print "this command "+cmd+" is known for writing"
          return True
####

#######################################################################
###### get_setpoint_temp(idx) : get temperature from domoticz setpoint
#######################################################################
def get_setpoint_temp(idx):
    r = requests.get('http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=devices&rid='+str(idx),auth=HTTPBasicAuth(user,password))
    status=r.status_code
    if status == 200:
       r=r.json()
       result={}
       return r['result'][0]['Data']
    else:
       print "Get setpoint temp error - IDX:"+str(idx) 

####


########################################################################
###### get_boiler_state(idx) : get boiler state(OK or not) from domoticz 
########################################################################
def get_boiler_state(idx):
    r = requests.get('http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=devices&rid='+str(idx),auth=HTTPBasicAuth(user,password))
    status=r.status_code
    if status == 200:
       r=r.json()
       result={}
       return r['result'][0]['Data']
    else:
       print "Get state error - IDX:"+str(idx)

####

#-----------------------------------### START ###--------------------------------------------#

# arguments in command line 
nb_arg=len(sys.argv)-1 

if nb_arg==0:
   print "HELP : "
   print "domo2vito update : update all domoticz values"
   print "domo2vito command : get command (e.g. domo2vito mode <=> get mode)"
   print "domo2vito command value : set command value (e.g. domo2vito mode 1 <=> set mode 1)"

if nb_arg==1 and sys.argv[1]!="update":
   if check_command(sys.argv[1]):
       if debug:
          print "get "+sys.argv[1] 
       tn=viTalk_connect()
       viTalk_read(sys.argv[1])
       tn.close()

if nb_arg==1 and sys.argv[1]=="update":   
   tn=viTalk_connect()
   viTalk_check()
   values=[]
   i=0
   tn.read_until(b"$", 5)
   for command in commands:
       tn.write(b"g "+command+"\n")
       value=tn.read_until(b"$", 5).strip("\n$")
       if debug:
          print str(i)+") command : get "+command+ " => "+value
       values.append(value)
       i+=1
   # get setpoint  party_soll_temp and update boiler if needed
   temp=int(float(get_setpoint_temp(dummy_idx['party_soll_temp'])))
   if temp!=int(float(values[3])): #Viessmann ignore decimales
      if debug:
         print "party setpoint has changed : I update it!"
      if temp<12: # party mini temp
         temp=12
      if temp>25: # party maxi temp
         temp=25
      viTalk_set("party_soll_temp",str(temp))
   # get setpoint ww_soll_temp and update boiler if needed
   temp=int(float(get_setpoint_temp(dummy_idx['ww_soll_temp'])))
   if temp!=int(float(values[8])): #Viessmann ignore decimales
      if debug:
         print "hot water setpoint has changed : I update it!"
      if temp<20: # hot water mini temp
         temp=20
      if temp>70: # hot water maxi temp
         temp=70
      viTalk_set("ww_soll_temp",str(temp))
   tn.close() 
   
   #mode (selector level : 0=OFF 10=water 20=heating)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['mode'])+'&switchcmd=Set%20Level&level='+str(int(values[0])*10)
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # saving : dummy switch ON/OFF (Boiler eco ON/OFF) : if a user modify boiler or vitotrol, update Domoticz
   if values[1]=="0":
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['saving'])+'&switchcmd=Off'
   else:
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['saving'])+'&switchcmd=On'
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # party  : dummy switch ON/OFF (party temporary manual control) : if a user modify boiler or vitotrol, update Domoticz
   if values[2]=="0":
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['party'])+'&switchcmd=Off'
   else:
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['party'])+'&switchcmd=On'
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # party_soll_temp: dummy thermostat setpoint (party temperature) note:Domoticz setpoint manage this parameter
   #req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['party_soll_temp'])+'&nvalue=0&svalue='+values[3]
   #requests.get(req,auth=HTTPBasicAuth(user,password))

   # outdoor_temp   : dummy temp (outdoor temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['outdoor_temp'])+'&nvalue=0&svalue='+values[4]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # raum_soll_temp : dummy temp (heating setpoint [FR:consigne] temperature) - note : without vitotronic, use thermostat setpoint
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['raum_soll_temp'])+'&nvalue=0&svalue='+values[5]
   requests.get(req,auth=HTTPBasicAuth(user,password))
 
   # raum_ist_temp  : dummy temp (heating current [FR:actuelle] temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['raum_ist_temp'])+'&nvalue=0&svalue='+values[6]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # k_ist_temp     : dummy temp (boiler current temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['k_ist_temp'])+'&nvalue=0&svalue='+values[7]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # ww_soll_temp   : dummy setpoint (hot water setpoint temperature) note:Domoticz setpoint manage this parameter
   #req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['ww_soll_temp'])+'&nvalue=0&svalue='+values[8]
   #requests.get(req,auth=HTTPBasicAuth(user,password))

   # ww_ist_temp    : dummy temp (hot water current temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['ww_ist_temp'])+'&nvalue=0&svalue='+values[9]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # k_abgas_temp   : dummy temp (exhaust gas [FR:gaz evacue'] temperature)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['k_abgas_temp'])+'&nvalue=0&svalue='+values[10]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # power          : dummy percentage (% boiler power)
   req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['power'])+'&nvalue=0&svalue='+values[11]
   requests.get(req,auth=HTTPBasicAuth(user,password))

   # error_log	    : dummy alert (show the two last log codes) 
   # problem    : dummy switch (set switch to On if there is a internal boiler problem)
   #values[12]="123,255,235,244,244,244,244,244,244,244 ;"
   V_error=values[12][0:3]
   V_previous_error=values[12][4:7]
   V_error_hexa=str(hex(int(V_error)))[2:4] # hexa convertion
   V_previous_error_hexa=str(hex(int(V_previous_error)))[2:4]  # hexa convertion
   V_previous_problem_state=get_boiler_state(str(dummy_idx['problem']))
   if V_error=="000":
      if debug:
          print "no internal error : all it is OK"+" (previous code="+V_previous_error_hexa+")"
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['error_log'])+'&nvalue=1&svalue='+'OK (previous='+V_previous_error_hexa+')'
      requests.get(req,auth=HTTPBasicAuth(user,password))
      if V_previous_problem_state=="On": # I update problem switch only if state is modified 
          if debug:
             print "State of boiler error status changed (no problem): I update the Domotics boiler problem switch"
          req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['problem'])+'&switchcmd=Off'
          requests.get(req,auth=HTTPBasicAuth(user,password))
   else:
      if debug:
          print "There is an internal error : code="+V_error_hexa+" ( previous ="+V_previous_error_hexa+")"
      req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['error_log'])+'&nvalue=4&svalue='+'Error '+V_error_hexa+' (previous='+V_previous_error_hexa+')'
      requests.get(req,auth=HTTPBasicAuth(user,password))
      if V_previous_problem_state=="Off": # I update problem switch only if state is modified
          if debug:
             print "State of boiler error status changed (problem): I update the Domotics boiler problem switch"
          req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=switchlight&idx='+str(dummy_idx['problem'])+'&switchcmd=On'
          requests.get(req,auth=HTTPBasicAuth(user,password))


if nb_arg==2:
   if check_set_command(sys.argv[1]):
       print "set "+sys.argv[1]+" "+sys.argv[2]
       tn=viTalk_connect()
       viTalk_write(sys.argv[1],sys.argv[2])
       tn.close()
Domotisation de : mes compteurs EDF, solaire, eau / mon alarme / ma Chaudière Viessamnn / mon congel / ma sonnette. Matériels : Pi2 - RFXTrx433e - Zwave+ Aeotec, ampoules Hue - Détecteur et prises Fibaro - Capteurs Oregon - présentation installation => lien
Neutrino
Messages : 2662
Inscription : 10 juil. 2015, 15:42
Localisation : Les Herbiers(85)

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par Neutrino »

Salut js-martin
Bravo pour ce 'hack' ! Je n'ai pas de chaudière, mais j'ai suivi ce topic avec plaisir :) !
Petite question : où as-tu trouvé le câble blanc de ton émetteur/récepteur IR ?
Image

J'essaye d'augmenter le WAF de mes bidouillages :mrgreen:
Ma maison à plein d'IP ! :mrgreen:
SAV Bonjour. Vous avez vidé le cache ?
js-martin
Messages : 487
Inscription : 22 mars 2015, 22:08
Contact :

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par js-martin »

Merci pour ton commentaire. J'ai repris pas mal de briques fabriquées par d'autres...

Pour mes câbles, c'est souvent de la recup... J'ai un carton où j'entasse mes restes de fils...Le 4 fils blanc vient d'une rallonge de strip led IKEA...

J'utilise pas mal le fil téléphone ou réseau ethernet.

Il y a des bobines de 100m pas trop chère : un exemple http://www.cdiscount.com/informatique/c ... 73348.html
Domotisation de : mes compteurs EDF, solaire, eau / mon alarme / ma Chaudière Viessamnn / mon congel / ma sonnette. Matériels : Pi2 - RFXTrx433e - Zwave+ Aeotec, ampoules Hue - Détecteur et prises Fibaro - Capteurs Oregon - présentation installation => lien
Neutrino
Messages : 2662
Inscription : 10 juil. 2015, 15:42
Localisation : Les Herbiers(85)

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par Neutrino »

J'utilise aussi du câble réseau (multibrins) ou téléphonique (monobrins).
Mais ils sont multicolores une fois mis à nu, et ça ce voit. :mrgreen:
Merci pour ton lien ;)
Vous pouvez reprendre le cour normal de ce topic.
Ma maison à plein d'IP ! :mrgreen:
SAV Bonjour. Vous avez vidé le cache ?
lanvezhon
Messages : 10
Inscription : 12 mai 2016, 19:10

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par lanvezhon »

Retour d'expérience sur le duo Viessmann - Domoticz. Je ne dirai qu'un mot: BRAVO.
Départ en vacances en Sardaigne: Arrêt de l'ECS
Pendant les vacances: (Juste pour narguer), accès aux courbes de températures extérieures bretonnes de mi-juin via la sonde ext!!
Retour: Relance production ECS à l'arrivée du zinc.
Chapeau bas Maître Es Python pour ce super code.
js-martin
Messages : 487
Inscription : 22 mars 2015, 22:08
Contact :

Re: Contrôler sa chaudière Viessmann avec Domoticz via une interface infrarouge

Message par js-martin »

Super, merci pour ton retour !

C'est un travail à plusieurs... Ceux qui ont décodé le protocole, le développeur de vitalk, les tuto... J'ai juste fait la partie finale pour le lien avec Domoticz ;)
Domotisation de : mes compteurs EDF, solaire, eau / mon alarme / ma Chaudière Viessamnn / mon congel / ma sonnette. Matériels : Pi2 - RFXTrx433e - Zwave+ Aeotec, ampoules Hue - Détecteur et prises Fibaro - Capteurs Oregon - présentation installation => lien
Répondre