Page 7 sur 55

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

Publié : 23 juil. 2016, 23:46
par cr1cr1
Une question : est-il possible de n'ajouter des événements "défaut chaudière" qu'en cas de changements d'événements / défauts ?
Car dans le code présent, j'ai un ajout systématique d'événement "OK" dans le switch Domoticz correspondant à chaque lancement par le cron du script Domo2vito.py !

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

Publié : 25 juil. 2016, 23:51
par js-martin
Super que tout marche bien ! Non, pas besoin de la béta. Il suffit d'utiliser une version stable après mars 2016.

Voici la MAJ demandée :

je n'ai pas beaucoup de temps pour tester, alors je compte sur toi ;)

Nouvelle version du code : 1.4
Add : update internal Viessmann error log into Domotics only if it is necessary

Code : Tout sélectionner

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

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_error_state=get_boiler_state(str(dummy_idx['error_log']))[0:2]
   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+")"
      if V_previous_error_state!="OK":  # I update error_log alert only if state is modified
          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+")"
      if V_previous_error_state!=V_error_hexa: # I update error_log alert only if state is modified
          req='http://'+domoticz_ip+':'+domoticz_port+'/json.htm?type=command&param=udevice&idx='+str(dummy_idx['error_log'])+'&nvalue=4&svalue='+V_error_hexa+' error (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()
OK,j'ai donc effacé mes "dummy switches" et recréé des "Dummy Thermostat Setpoint" pour la consigne ECS, consigne chauffage et consigne mode Party. J'ai réglé les consigne...
D'autre part, j'avais créé les selector switches dans le mauvais ordre : j'avais déjà créé des "switch" dont j'avais modifié le subtype en selector. La fenêtre d'édition du switch est alors bizarre et on ne peut pas mettre d'actions. J'ai recommencé et je me suis rendu compte que l'on pouvait directement préciser des "selector switch" lors de la création des dummy devices...
Je dois changer quelque chose pour que cela soit plus clair d'après toi ?

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

Publié : 26 juil. 2016, 00:17
par cr1cr1
Merci :-) Je n'en demandais pas tant !
Impec, ça marche ! Je n'ai pas été jusqu'à créer une erreur (je ferai ça au retour de mes vacances si j'y pense!) mais c'est top : les événements ne s'accumulent plus dans le log.

Pour te répondre dans les commentaires en début de code, je mettrai pour ces deux lignes :

Code : Tout sélectionner

# raum_soll_temp : dummy thermostat setpoint (heating setpoint [FR:consigne] temperature) - note : without vitotronic, use thermostat setpoint
# ww_soll_temp   : dummy thermostat setpoint (hot water setpoint temperature)
Mais en lisant la fin du commentaire pour raum_soll_temp, j'ai un doute ! J'ai créé des dummy "thermostat setpoint" pour ces 3 paramètres dans le menu [Setup]/[Hardware]/[Create Virtual Sensors]. Il fallait faire autre chose ?

Sinon, afin d'enrichir le tuto, on peut préciser :
- créer le Selector Switch dès la création du virtual sensor, et pas un switch dont on change le sub-type après.
- effacer l'historique des defauts de la chaudière en allant dans le menu de service (appui 4s sur touches OK et Menu simultanées)

Merci pour tout encore une fois !
En parallèle, j'ai fait un montage pour récupérer les téléinfos de mon compteur Linky....

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

Publié : 26 juil. 2016, 00:39
par js-martin
Lorsque j'ai vu que j'avais 221 pages de log, je me suis dit qu'il fallait faire quelque chose !

Pour l'erreur, je n'ai pas touché cette partie du code. Es-tu certain d'avoir bien réglé le numéro du widget domoticz pour "party_soll_temp" ? C'est un setpoint domoticz.

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

Publié : 26 juil. 2016, 00:49
par cr1cr1
Désolé, j'ai édité mon message mais tu étais déjà à l'affût ! J'avais simplement oublié de préciser à nouveau mes idx ... :?
Et j'ai passé un peu de temps pour partager des suggestions pour le tuto.
Tout marche bien :)

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

Publié : 26 juil. 2016, 01:09
par js-martin
Ok. Merci pour les commentaires qui peuvent aider les suivants... Il faut que je pense à les intégrer.

Pour le compteur linky, il a les deux sortie serie (I1/I2) comme sur les compteurs digitaux ?

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

Publié : 26 juil. 2016, 01:16
par cr1cr1
Oui, le linky a I1 et I2, qui sont configurés en mode "historique" par défaut, c'est à dire compatible avec les anciens protocoles.
En plus, il y a une sortie "A" qui veut dire "Alimentation". Mais il faut la filtrer (ça sort du 50kHz...) et l'utiliser de paire avec I1 pour l'alim.
Ça marche impec avec Domoticz., comme ce que tu dois avoir.

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

Publié : 26 juil. 2016, 08:59
par js-martin
Oui... Cela aura ete mon premier montage maison qui fonctionne toujours.

J'ai meme utilisé une machine pour graver mon circuit imprimé :

viewtopic.php?f=7&t=185&hilit=teleinfo&start=10#p3213

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

Publié : 31 juil. 2016, 19:34
par js-martin
Tu as remarqué que tu avais de nombreux démarrages de brûleur par rapport à ta durée de fonctionnement ? il y a des discussions autour de ce sujet sur certains forums Viessmann...
Non, je n'ai pas remarqué : tu peux m'en dire plus ?

J'en suis à 95036 démarrages brûleur.

J'ai commencé à lire cela et ce ne semble pas si simple :
https://www.bricozone.fr/t/arret-bruleu ... 2-f.12105/

Je peux tenter de baisser la puissance de ma chaudière. Tu en penses quoi ?

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

Publié : 06 août 2016, 10:11
par damolc
Bonjour
Savez vous si on peux utiliser Le module Vitocom pour l intégration avec Domoticz ?