Ligação Solzaima

Rafael, É como quiseres, se pretenderes ter esses comandos especialmente o da temperatura no HA a aproximação é a mesma. O sensor mycezajson já traz tudo e podes ter apenas para visualização sem criar os inputs e os rest commands caso não pretendas o control.
O que referes do refresh é quando inicias o HA. A solução do Fernando em node-red é uma boa alternativa embora eu nunca tenha usado. Em breve vou fazer uma automação para verficar o estado depois do arranque do HA e forçar o refresh caso não tenha funcionado.

Sobre o consumo de pellets tenho que abrir um topico novo pois senão vai ficar aqui uma confusão ainda maior.
Farei isso para a semana depois da pascoa.

Muito Obrigado Fernando
:ok_hand: :clap:

Fernando, tinha um erro no ponto 2 pois faltavam umas aspas no payload mas já corriji. Eu presumo que seja assim mas caso não funcione eu digo-te como fazes o recording no chrome para captarmos o payload.

malta eu sou um lammer nisto, mas pretendia integrar no HA o meu recuperador de calor da marca l´artistico, que tenho acesso pelo app e pela pagina da https://cloudwinet.it/.
ao entrar na pagina, e apos fazer o login aparece isto:


E depois de clicar na mao verde isto:

Sei a api key e ha este manual que dá para ver o status atraves de links com a api key.


Com esta info que aparece ai consigo meter isso no HA?

João, muito obrigado pela ajuda mas infelizmente ainda não funciona, não consigo controlar nem a chama nem a ventoinha. Podes me ensinar como fazer o recording no chrome para captar o payload por favor?

Olha que eu tinha um erro no presumivel payload pois faltava umas aspas e agora descobri outro…
por favor modifica para isto,

{"value":"{{states.input_number.stove_fire_temperature_sel.state | int }}","code":"E600"}

e experimenta os serviços individualmente.
(entretanto já modifiquei o post anterior):

Ola Tiago. Não parece nada dificil.
Tu dizes que sabes qual a api key logo a primeira coisa que tens de testar é o que está no ponto 3)

Para começares abres o chrome e na barra de endereços escreves a URL que está no manual juntando a tua api key e confirma que obtens uma resposta em formato json semelhante ao que está aqui:

image

Se sim então isso é um GET htpp que é facil de implementar usando os conectores nativos do HA. Para depois criares os comandos vais precisar de fazer uns POST com a mesma logica.

Sim, recebo a informação certa do estado do recuperador.

E como faço isso que dizes no HA?
Há algum tutorial?

Tiago, é hora da leitura: Para teres os sensores, como por exemplo o que acabaste de testar (ou então o da temperatura descrito no ponto 9) vais precisar varios rest sensors em função da URL a utilizar:

O rest full sensor vai retornar extamente o que ves no chrome e prescisaras de um sensor template para extrair o estado (nesta caso será “0” ou"1" caso uses “Status” ou “On” e “Off” caso uses o “StatusDescription”

Para os comandos usas o rest_command descrito aqui:

A logica é a mesma so que no URL alem da api key precisas de passar o parametro. Exemplo no ponto 8) onde será na URL …/a_tua_api_key:23 se quiseres 23 graus.

os rest commands ficam como um serviço que podes invocar diretamente num card ou então num script.

1 Curtiu

Como não tenho node red como o @Fernmac partilho aqui a automação que após o restart do HA verifica passado 60 segundos se os tokens foram extraidos e senão vai insistir de 15 em 15 segundos até conseguir:

- id: myceza_session_ha_restart_delay
  alias: Myceza Session HA Restart Delay
  initial_state: true
  trigger:
    - platform: homeassistant
      event: start
  action:
    - delay:
        seconds: 60
    - repeat:
        while:
          - condition: template
            value_template: >
              {{ states.sensor.mycezajson.state != 'Recuperador Sala' }}
        sequence:      
          - service: rest_command.myceza_session_logout
            data: {}
          - service: multiscrape.trigger_solzaima_ha_integration
            data: {}
          - delay:
              seconds: 15
  mode: single

Caso queiram usar só tem que alterar o nome ‘Recuperador Sala’ para o nome do vosso aparelho que definiram na myceza app e eventualmente adaptarem os delays conforme pretendido.

Estou a ponderar comprar uma caldeira para aquecimento central Solzaima SZM A PLUS 32 ou a SZM A 30 KW, mas uma das premissas obrigatórias é que consiga controlar (pelo menos parcialmente) via HomeAssistant.

Este método ainda funciona para estas caldeiras/salamandras?

Conseguem por aqui controlar o mesmo que via site ou app?

Funciona, continuo a utilizar. Nunca mais usei a app da Solzaima.

1 Curtiu

@Joao_Sousa já passou algum tempo desde esta integração mas de facto parabens por ela.

Em relação á “gestão de utilização e consumo de Pellets” chegou abrir algum topico?

Obrigado pela partilha

Os meus dados estão “intermitentes” ora tenho valores ora tenho desconhecido.
O que estará mal?

Sim visto que há pessoal interessado vou abrir um tópico com isso:

2 Curtiram

Qual é a versão do multiscrape que estás a usar?
Podes partilhar a configuração?

@Joao_Sousa
Multiscrape 7.0.0

automations.yaml:

- id: myceza_session_reconnect
  alias: Myceza Session Reconnect
  trigger:
    platform: state
    entity_id: sensor.mycezajson
    from: 'Casa'
    to: 'unknown'
  action:
    - service: rest_command.myceza_session_logout
      data: {}
    - service: multiscrape.trigger_solzaima_ha_integration
      data: {}
  mode: single

- id: myceza_session_refresh
  alias: Myceza Session Refresh
  trigger:
    - platform: time_pattern
      # Isto faz com que o multiscrape renove os tokens a cada 11 horas pois expiram a cada 12
      hours: '/11'
      minutes: 0
      seconds: 0
  action:
    - service: rest_command.myceza_session_logout
      data: {}
    - service: multiscrape.trigger_solzaima_ha_integration
      data: {}
  mode: single
  
  # Recuperador stove_mode_sel
- id: stove_load_myceza_settings
  alias: stove_load_myceza_settings
  trigger:
  - entity_id: input_boolean.stove_control_settings
    platform: state
  condition:
  action:
  - data_template:
      entity_id: input_number.stove_temp_sel
      value: '{{ states.sensor.stove_ambient_temperature.state }}'
    service: input_number.set_value
  - data_template:
      entity_id: input_select.stove_mode_sel
      option: '{{ states.sensor.stove_mode_desc.state }}'
    service: input_select.select_option
  - data_template:
      entity_id: input_select.stove_fan_speed_sel
      option: '{{ states.sensor.stove_fan_one_desc.state }}'
    service: input_select.select_option```


configurations.yaml:


# Loads default set of integrations. Do not remove.
default_config:

#group: !include groups.yaml
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
switch: !include switch.yaml

# Load frontend themes from the themes folder
frontend:
  themes: !include_dir_merge_named themes

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

multiscrape:
  - name: solzaima ha integration  
    resource: 'https://myceza.it/en'
    scan_interval: 86400 # isto sao 24h embora este token expira as 12h e uma automacao faz o reload
    log_response: True # apenas na Release 6
    form_submit:
      submit_once: False
      resubmit_on_error: True
      resource: 'https://myceza.it/en/login'
      select: '#main > div > div.panel-body > form'
      input:
        username: pedronetop@gmail.com
        password: 'salixsalve'
    sensor:
      - unique_id: mycezadatatoken
        select: 'div#app-meta'
        name: Myceza Data Token
        attribute: 'data-token'
        value_template: '{{ value }}'
        on_error:
          log: error
      - unique_id: mycezacsrftoken
        select: 'head > meta:nth-child(3)'
        name: Myceza CSRF Token
        attribute: 'content'
        value_template: '{{ value }}'        
        on_error:
          log: error

rest_command:
  myceza_session_logout:
    url: https://myceza.it/en/logout
    method: POST
    headers:
      Host: myceza.it
      Connection: keep-alive
      Cache-Control: max-age=0
      Content-Length: 47
      Upgrade-Insecure-Requests: 1
      Content-Type: application/x-www-form-urlencoded
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
      Origin: https://myceza.it
      Sec-Fetch-Site: same-origin
      Sec-Fetch-Mode: navigate
      Sec-Fetch-User: ?1
      Sec-Fetch-Dest: document
      Referer: https://myceza.it/en/logout
      Accept-Encoding: gzip, deflate, br
      Accept-Language: en-US,en;q=0.9
      Cookie: >
        XSRF-TOKEN={{ states('sensor.mycezaxsrftoken')}}; myceza_session={{ states('sensor.mycezasession') }}
    payload: >    
      _token={{states.sensor.mycezacsrftoken.state}}
      
homeassistant:
    allowlist_external_dirs:
      - /config
      
resources:
  url: /local/stack-in-card.js
  type: module
  
sensor: !include sensor.yaml

input_number: !include inputnumber.yaml
input_datetime: !include inputdatetime.yaml
input_boolean: !include inputboolean.yaml
input_select: !include inputselect.yaml

rest_command:
  myceza_stove_set_temperature:
    url: https://myceza.it/api/stove/command/en/00:80:E1:BE:59:38
    method: POST
    headers:
      Host: myceza.it
      Connection: keep-alive
      X-XSRF-TOKEN: >
        {{ states('sensor.mycezaxsrftoken') | replace("%3D","=") }}
      Authorization: >
        Bearer {{ states('sensor.mycezadatatoken_actual_ks') }}
      Content-Type: application/json;charset=UTF-8
      Accept: application/json, */*
      Origin: https://myceza.it
      Sec-Fetch-Site: same-origin
      Sec-Fetch-Mode: cors
      Sec-Fetch-Dest: empty
      Referer: https://myceza.it/en/stove/00:80:E1:BE:59:38
      Accept-Encoding: gzip, deflate, br
      Accept-Language: en-US,en;q=0.9
      Cookie: >
        XSRF-TOKEN={{ states('sensor.mycezaxsrftoken')}}; myceza_session={{ states('sensor.mycezasession') }}
    payload: >
      {"value":"{{states.input_number.stove_temp_sel.state | int}}","code":"E001"}
  myceza_stove_set_mode:
    url: https://myceza.it/api/stove/command/en/00:80:E1:BE:59:38
    method: POST
    headers:
      Host: myceza.it
      Connection: keep-alive
      X-XSRF-TOKEN: >
        {{ states('sensor.mycezaxsrftoken') | replace("%3D","=") }}
      Authorization: >
        Bearer {{ states('sensor.mycezadatatoken_actual_ks') }}
      Content-Type: application/json;charset=UTF-8
      Accept: application/json, */*
      Origin: https://myceza.it
      Sec-Fetch-Site: same-origin
      Sec-Fetch-Mode: cors
      Sec-Fetch-Dest: empty
      Referer: https://myceza.it/en/stove/00:80:E1:BE:59:38
      Accept-Encoding: gzip, deflate, br
      Accept-Language: en-US,en;q=0.9
      Cookie: >
        XSRF-TOKEN={{ states('sensor.mycezaxsrftoken')}}; myceza_session={{ states('sensor.mycezasession') }}
    payload: >      
      {"value":{{states.input_select.stove_mode_sel.state | replace("Manual",0) | replace ("Auto",1)}},"code":"F001"}
  myceza_stove_set_fan_speed:
    url: https://myceza.it/api/stove/command/en/00:80:E1:BE:59:38
    method: POST
    headers:
      Host: myceza.it
      Connection: keep-alive
      X-XSRF-TOKEN: >
        {{ states('sensor.mycezaxsrftoken') | replace("%3D","=") }}
      Authorization: >
        Bearer {{ states('sensor.mycezadatatoken_actual_ks') }}
      Content-Type: application/json;charset=UTF-8
      Accept: application/json, */*
      Origin: https://myceza.it
      Sec-Fetch-Site: same-origin
      Sec-Fetch-Mode: cors
      Sec-Fetch-Dest: empty
      Referer: https://myceza.it/en/stove/00:80:E1:BE:59:38
      Accept-Encoding: gzip, deflate, br
      Accept-Language: en-US,en;q=0.9
      Cookie: >
        XSRF-TOKEN={{ states('sensor.mycezaxsrftoken')}}; myceza_session={{ states('sensor.mycezasession') }}
    payload: >    
      {"value":{{states.input_select.stove_fan_speed_sel.state | replace ("Auto",6)}},"code":"E601"}
  myceza_stove_power:
    url: https://myceza.it/api/stove/command/en/00:80:E1:BE:59:38
    method: POST
    headers:
      Host: myceza.it
      Connection: keep-alive
      X-XSRF-TOKEN: >
        {{ states('sensor.mycezaxsrftoken') | replace("%3D","=") }}
      Authorization: >
        Bearer {{ states('sensor.mycezadatatoken_actual_ks') }}
      Content-Type: application/json;charset=UTF-8
      Accept: application/json, */*
      Origin: https://myceza.it
      Sec-Fetch-Site: same-origin
      Sec-Fetch-Mode: cors
      Sec-Fetch-Dest: empty
      Referer: https://myceza.it/en/stove/00:80:E1:BE:59:38
      Accept-Encoding: gzip, deflate, br
      Accept-Language: en-US,en;q=0.9
      Cookie: >
        XSRF-TOKEN={{ states('sensor.mycezaxsrftoken')}}; myceza_session={{ states('sensor.mycezasession') }}
    payload: >    
      {"value":{{powercommand}},"code":"F000"} 



scripts.yaml
myceza_set_stove_definitions:
 alias: myceza_set_stove_definitions
 sequence:
 - service: rest_command.myceza_stove_set_temperature
   data: {}
 - service: rest_command.myceza_stove_set_mode
   data: {}
 - service: rest_command.myceza_stove_set_fan_speed
   data: {}
 - delay:
     seconds: 10
 - service: homeassistant.update_entity
   entity_id: sensor.mycezajson  
 mode: single

sensors.yaml
- platform: file
  scan_interval: 30
  name: mycezaxsrftoken
  file_path: /config/multiscrape/solzaima_ha_integration/page_response_headers.txt
  value_template: '{{ (value.split("=")[2]).split(";")[0] }}'

- platform: file
  scan_interval: 30
  name: mycezasession
  file_path: /config/multiscrape/solzaima_ha_integration/page_response_headers.txt
  value_template: '{{ (value.split("=")[6]).split(";")[0] }}' 

- platform: template
  scan_interval: 5
  sensors:
# Recuperador Keep last Valid Token
      mycezadatatoken_actual_ks:
        unique_id: 'mycezadatatoken_actual_ks'
        value_template: >-
          {% set datatoken_actual = states('sensor.mycezadatatoken') %}
          {{ datatoken_actual if datatoken_actual != 'unknown' else states('sensor.mycezadatatoken_actual_ks') }}     
# Recuperador de Calor sensors based on JSON Dict
      stove_status:
        value_template: >       
          {% if is_state('sensor.mycezajson', 'Casa') %}
            {{ (state_attr('sensor.mycezajson','stoves'))['00:80:E1:BE:59:38']['statuses']['status'].label }}
          {% else %}
            {{'None'}} 
          {% endif %}   
        unique_id: 'stove_status'
      stove_active: # 1 = Off , 3=On , 2= Starting, 4 = Shutdown
        unique_id: stove_ative
        value_template: >
          {% if is_state('sensor.mycezajson', 'Casa') %}
            {{ (state_attr('sensor.mycezajson','stoves'))['00:80:E1:BE:59:38']['statuses']['status'].value }}
          {% else %}
            {{'None'}}
          {% endif %}        
      stove_fumes_temperature:
        unique_id: 'stove_fumes_temperature'
        icon_template: mdi:thermometer-alert
        friendly_name: "Recuperador Calor Temperatura Fumos"
        unit_of_measurement: "°C"
        value_template: >
          {% if is_state('sensor.mycezajson', 'Casa') %}
            {{ (state_attr('sensor.mycezajson','stoves'))['00:80:E1:BE:59:38']['statuses']['fumes_temperature'].value }}
          {% else %}
            {{'None'}}
          {% endif %}
      stove_room_temperature:
        unique_id: 'stove_room_temperature'
        icon_template: mdi:home-thermometer-outline
        friendly_name: "Recuperador Calor Temperatura Sala"
        unit_of_measurement: "°C"
        value_template: >
          {% if is_state('sensor.mycezajson', 'Casa') %}
            {{ (state_attr('sensor.mycezajson','stoves'))['00:80:E1:BE:59:38']['statuses']['room_temperature'].value }}
          {% else %}
            {{'None'}}
          {% endif %}
      stove_ambient_temperature:
        unique_id: 'stove_ambient_temperature'
        icon_template: mdi:home-thermometer-outline
        friendly_name: "Recuperador Calor Temperatura Selecionada"
        unit_of_measurement: "°C"
        value_template: >
          {% if is_state('sensor.mycezajson', 'Casa') %}
            {{ (state_attr('sensor.mycezajson','stoves'))['00:80:E1:BE:59:38']['statuses']['ambient_temperature'].value }}
          {% else %}
            {{'None'}}
          {% endif %}
      stove_mode: # 1 = Auto
        unique_id: 'stove_mode'
        icon_template: mdi:autorenew
        value_template: >
          {% if is_state('sensor.mycezajson', 'Casa') %}
            {{ (state_attr('sensor.mycezajson','stoves'))['00:80:E1:BE:59:38']['statuses']['mode'].value }}
          {% else %}
            {{'None'}}
          {% endif %}        
      stove_fan_one: # 1 to 5 and 6 = Auto
        unique_id: 'stove_fan_one'
        icon_template: mdi:fan
        value_template: >
          {% if is_state('sensor.mycezajson', 'Casa') %}
            {{ (state_attr('sensor.mycezajson','stoves'))['00:80:E1:BE:59:38']['statuses']['fan_one'].value }}
          {% else %}
            {{'None'}}
          {% endif %}    
      # Sensors to use in Front-end control
      stove_status_desc:
        unique_id: 'stove_status_desc'
        icon_template: mdi:fireplace
        friendly_name: Recuperador Calor Estado
        value_template: >-
          {{ states('sensor.stove_status') | replace('Stove on', 'Ligado') | replace('Stove off', 'Desligado') | replace('In startup', 'Ativacao') | replace('In shutdown', 'Desativacao')}}      
      stove_mode_desc:
        unique_id: 'stove_mode_desc'
        icon_template: mdi:autorenew
        friendly_name: "Recuperador Calor Modo"
        value_template: >-
          {{ states('sensor.stove_mode') | replace('1', 'Auto') | replace('0', 'Manual')}}
      stove_fan_one_desc:
        unique_id: 'stove_fan_one_desc'
        icon_template: mdi:fan
        friendly_name: "Recuperador Calor Ventoinha"
        value_template: >-
          {{ states('sensor.stove_fan_one') | replace('6', 'Auto') }}
      # Sensors to keep last state    
      stove_active_ks:
        unique_id: 'stove_active_ks'
        value_template: >-
          {% set stative = states('sensor.stove_active') %}
          {{ stative if stative != 'unknown' else states('sensor.stove_active_ks') }}
      stove_active_all_on_states:
        unique_id: 'stove_active_all_on_states'
        value_template: |
          {% if states('sensor.stove_active_ks') == '2' or states('sensor.stove_active_ks') == '3' %}1{% else %}0{% endif %}

- platform: rest
  name: mycezajson
  json_attributes:
    - stoves
  value_template: '{{ value_json.stoves["00:80:E1:BE:59:38"].name}}' 
  resource: https://myceza.it/api/user/en
  scan_interval: 30 # este tempo pode ser ajustado para ter updates mais ou menos frequentes
  headers:
    Host: myceza.it
    Connection: keep-alive
    Authorization: >
      Bearer {{ states('sensor.mycezadatatoken_actual_ks') }}
    Accept: application/json, */*  
    X-XSRF-TOKEN: >
      {{ states('sensor.mycezaxsrftoken') | replace("%3D","=") }}
    Referer: https://myceza.it/en
    Accept-Encoding: gzip, deflate, br
    Accept-Language: en-US,en;q=0.9
    Cookie: >
      XSRF-TOKEN={{ states('sensor.mycezaxsrftoken')}}; myceza_session={{ states('sensor.mycezasession') }}	

- platform: history_stats
  name: Recuperador Calor On Time
  entity_id: sensor.stove_active_all_on_states
  state: '1'
  type: time
  start: '{{ now().replace(hour=0, minute=0, second=0) }}'
  end: '{{ now() }}'

switch.yaml
- platform: template
  switches:
    # Recuperador Calor Interruptor
    stove_power:
      friendly_name: "Interruptor Recuperador Calor"
      icon_template: mdi:power-settings
      value_template: "{{ is_state('sensor.stove_active_all_on_states','1')}}"
      turn_on: 
        - service: rest_command.myceza_stove_power
          data: >
            {"powercommand": "1"}
        - service: homeassistant.update_entity
          target:
            entity_id: sensor.mycezajson
      turn_off:
        - service: rest_command.myceza_stove_power
          data: >
            {"powercommand": "0"}
        - service: homeassistant.update_entity
          entity_id: sensor.mycezajson  

![Captura de ecrã 2024-10-01 101340|421x309](upload://6fgNxq6GvMbe7lMZKaPsVGHfDtk.jpeg)

Captura de ecrã 2024-10-01 101340

Com a versão 7 do Multiscrape podes ter um erro quando inicias o HA pois os ficheiro debug ainda não estão criados quando os sensores “file” tentam abrir para retirar os tokens. Acho que com a versão 6.4 não tens esse problema e depois explico como resolver com as versões atuais mas para já vamos tentar perceber o que está a acontecer. Podes por favor experimentar essa versão anterior e verificar se a intermitência desaparece?

Com a 6.4 não consigo de todo sequer obter uma leitura.


Copyright © 2017-. Todos os direitos reservados
CPHA.pt - info@cpha.pt


FAQ | Termos de Serviço/Regras | Política de Privacidade