Electrolyseur E-Pool Technologie Justsalt

Bonjour Ricky,

Merci pour l’énorme travail fourni. C’est avec grand plaisir que je vais essayer de te fournir les données dont tu as besoin.

Mais, depuis l’abandon de ESPhome, je suis perdu et ca dépasse de loin mes compétences relativement limitées. je me souviens avoir vu passer un post de ta part avec la procédure pour installer ton nouveau code. est ce toujours la bonne marche a suivre ?

la procédure ci dessus est toujours la bonne ?

oui et je viens de mettre le Github a jour

Pour info, je suis en train d essayer de refaire une version Esphome avec les valeurs identifier
donc si c’st trop compliquer a compiler tu auras toujours cette solution

1 « J'aime »

À c’est cool moi aussi le code ça dépasse un peu mes compétence, la version esphome tourne nicquel j’ai juste reassocier une fois avec la maj esphome 2025.5.

bonjour
pour ceux qui préfère utiliser ESPhome , j ai mis le code a jour avec toutes les avancées depuis le passage en c++
vous devriez voir pas mal de changement dont la possibilité de voir les consignes

@starpom je compte sur toi pour les valeur du volet si tu veux un bouton pour le piloter :slight_smile:

#  JustSalt
substitutions:
  mac_justsalt: "94:DE:B8:A1:1A:AC"
  service_uuid: '09912756-7b32-4629-aeb1-b309d9a338ae'
  characteristic_uuid: 'ef785c24-22bb-463d-b651-0b7445ba091c'
  characteristic_uuid_write: '4d32c5e5-2bb5-45c6-8c89-6f59bb3930d2'

esphome:
  name: esphome-web-ecc470
  friendly_name: ESPHome Web ecc470

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "bLk/RiUyxLzXjb42FYKAhRU9WmN3iuyB3uiKMbovaMo="

ota:


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-Ecc470"
    password: "eEzs1d6LU1bH"

captive_portal:

bluetooth_proxy:
  active: true

time:
  - platform: homeassistant
    id: homeassistant_time_5m
    on_time:
      - seconds: 0
        minutes: /5
        then:
          - switch.turn_off: ble_switch_com
          - delay: 20s
          - switch.turn_on: ble_switch_com

ble_client:
  - mac_address:  ${mac_justsalt}
    auto_connect: true
    id: JustSaltPro
    on_connect:
      then:
        - ble_client.numeric_comparison_reply:
            id: JustSaltPro
            accept: True


binary_sensor:
  - platform: ble_presence
    mac_address: ${mac_justsalt}
    name: Electolyseur

  - platform: template  
    id: InjPHM
    name: "Injection PH-"
  
  - platform: template  
    id: InjPHP
    name: "Injection PH+"

number:
  - platform: template
    id: orp_consigne_new
    name: "ORP Consigne"
    icon: "mdi:flash-triangle-outline"
    unit_of_measurement: "mV"
    min_value: 200
    max_value: 900
    step: 10
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              //float state = std::stof(id(orp_consigne_new).state);
              ESP_LOGD("ORPconsigne", "Option consigne change:  %f", id(orp_consigne_new).state);   
              uint8_t statehex = id(orp_consigne_new).state / 10;
              return {0x00, 0x06, 0x03, 0x35, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: orp_alarme_consigne
    name: "ORP Alarme Consigne"
    icon: "mdi:alarm"
    unit_of_measurement: "h"
    min_value: 12
    max_value: 96
    step: 6
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              //float state = std::stof(id(orp_consigne_new).state);
              ESP_LOGD("ORPalarmeconsigne", "Option consigne change:  %f", id(orp_alarme_consigne).state);   
              uint8_t statehex = id(orp_alarme_consigne).state;
              return {0x00, 0x06, 0x03, 0x37, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
         
  - platform: template
    id: ph_consigne
    name: "PH Consigne"
    icon: "mdi:ph"
    unit_of_measurement: "ph"
    min_value: 6.8
    max_value: 7.6
    step: 0.1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("PHconsigne", "Option consigne change:  %f", id(ph_consigne).state);   
              uint8_t statehex = id(ph_consigne).state * 10;
              return {0x00, 0x06, 0x03, 0x30, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        
  - platform: template
    id: vol_consigne
    name: "Volume Consigne"
    icon: "mdi:cup-water"
    unit_of_measurement: "m3"
    min_value: 10
    max_value: 200
    step: 10
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("volconsigne", "Option consigne change:  %f", id(vol_consigne).state);   
              uint8_t statehex = id(vol_consigne).state;
              return {0x00, 0x06, 0x03, 0x11, 0x02, 0x00, statehex, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: acide_consigne
    name: "acide Consigne"
    icon: "mdi:skull-crossbones-outline"
    unit_of_measurement: "%"
    min_value: 5
    max_value: 55
    step: 1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("acideconsigne", "Option consigne change:  %f", id(acide_consigne).state);   
              uint8_t statehex = id(acide_consigne).state;
              return {0x00, 0x06, 0x03, 0x32, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: production_consigne
    name: "production Consigne"
    icon: "mdi:cog-outline"
    unit_of_measurement: "%"
    min_value: 10
    max_value: 100
    step: 1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("productionconsigne", "Option consigne change:  %f", id(production_consigne).state);   
              uint8_t statehex = id(production_consigne).state;
              return {0x00, 0x06, 0x03, 0x33, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: inversion_consigne
    name: "inversion Consigne"
    icon: "mdi:alarm"
    unit_of_measurement: "h"
    min_value: 2
    max_value: 24
    step: 1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("inversionconsigne", "Option consigne change:  %f", id(inversion_consigne).state);   
              uint8_t statehex = id(inversion_consigne).state;
              return {0x00, 0x06, 0x03, 0x39, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


text_sensor:
  - platform: version
    name: ESPHome Version
  
  - platform: wifi_info
    ssid:
      name: WiFi
  
  - id: ble_name2
    name: "Name"
    platform: template 

  - id: version_logiciel
    name: "version logiciel"
    platform: template 
  
  - id: slave
    name: "Slave"
    platform: template 
   
  - id: idcode
    name: "ID Code"
    platform: template  

  - platform: template
    name: "MAC bt"
    id: JustSalt_macbt_textsensor
  
  - platform: template
    name: "nom bt"
    id: JustSalt_nombt_textsensor
  
  - platform: template
    name: "SN"
    id: JustSalt_sn_textsensor

  - platform: template
    name: "temp90"
    id: JustSalt_90_textsensor
  
  - platform: template
    name: "temp91"
    id: JustSalt_91_textsensor

  - platform: template
    name: "temp9D"
    id: JustSalt_9d_textsensor
  
  - platform: template
    name: "tempD0"
    id: JustSalt_d0_textsensor

  - platform: template
    name: "tempE1"
    id: JustSalt_e1_textsensor

  - platform: template
    name: "tempE2"
    id: JustSalt_e2_textsensor
      
  - platform: template
    name: "tempE4"
    id: JustSalt_e4_textsensor
  
  - platform: template
    name: "tempA3"
    id: JustSalt_a3_textsensor

  - platform: template
    name: "Date etalonage PH"
    id: JustSalt_temp12_textsensor

  - platform: template
    name: "Date etalonage ORP"
    id: JustSalt_temp13_textsensor
    

sensor:
  - platform: wifi_signal
    name: Wifi signal
    update_interval: 60s

  - platform: uptime
    name: Uptime
  
  - platform: template
    name: "temp02"
    id: JustSalt_temp02_sensor
    accuracy_decimals: 0
    on_value:
      then:
        - lambda: |- 
            if (id(sensor_state).state == 1) {
              uint16_t temphex02 = id(JustSalt_temp02_sensor).raw_state;
              //ESP_LOGD(" --- temp 02 str", "%d", temphex02);
              id(InjPHM).publish_state((bool)((temphex02 & 0x000A) ));
              id(InjPHP).publish_state((bool)((temphex02 & 0x000C) ));
              }

  - platform: template
    name: "temp03"
    id: JustSalt_temp03_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp08"
    id: JustSalt_temp08_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp0B"
    id: JustSalt_temp0b_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp0C"
    id: JustSalt_temp0c_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp0D"
    id: JustSalt_temp0d_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "Compteur Heure total de fonctionnement"
    id: JustSalt_temp0e_sensor
    accuracy_decimals: 0
    unit_of_measurement: "h"
  
  - platform: template
    name: "minutes de fonctionement"
    id: JustSalt_temp0f_sensor
    unit_of_measurement: "min"
    accuracy_decimals: 0

  - platform: template
    name: "temp10"
    id: JustSalt_temp10_sensor
    accuracy_decimals: 0
 
  - platform: template
    name: "temp1f"
    id: JustSalt_temp1f_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp28"
    id: JustSalt_temp28_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp29"
    id: JustSalt_temp29_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp2A"
    id: JustSalt_temp2a_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp31"
    id: JustSalt_temp31_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp50"
    id: JustSalt_temp50_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp51"
    id: JustSalt_temp51_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp5F"
    id: JustSalt_temp5f_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp69"
    id: JustSalt_temp69_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp6A"
    id: JustSalt_temp6a_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp8F"
    id: JustSalt_temp8f_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp92"
    id: JustSalt_temp92_sensor
    accuracy_decimals: 0
      
  - platform: template
    name: "temp93"
    id: JustSalt_temp93_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp94"
    id: JustSalt_temp94_sensor
    accuracy_decimals: 0
      
  - platform: template
    name: "temp9B"
    id: JustSalt_temp9b_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp9C"
    id: JustSalt_temp9c_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp9D"
    id: JustSalt_temp9d_sensor
    accuracy_decimals: 0

  - platform: template
    name: "tempB0"
    id: JustSalt_tempb0_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "tempD1"
    id: JustSalt_tempd1_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "tempFE"
    id: JustSalt_tempfe_sensor
    accuracy_decimals: 0

  - platform: ble_rssi
    mac_address:  ${mac_justsalt}
    name: "JustSalt RSSI"  

  - platform: template
    name: "Temperature eau"
    id: JustSalt_temperature_sensor
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    state_class: measurement
    device_class: temperature
  
  - platform: template
    name: "pH"
    id: JustSalt_ph_sensor
    unit_of_measurement: "pH"
    accuracy_decimals: 1
    state_class: measurement
    icon: mdi:ph
  
  - platform: template
    name: "ORP"
    id: JustSalt_orp_sensor
    unit_of_measurement: "mV"
    accuracy_decimals: 0
    state_class: measurement
    device_class: voltage
  
  - platform: template
    name: "TDS"
    id: JustSalt_tds_sensor
    unit_of_measurement: "g/L"
    accuracy_decimals: 1
    state_class: measurement
    icon: mdi:water-opacity

  - platform: ble_client
    ble_client_id: JustSaltPro
    name: "traitement"
    id: sensor_state    
    service_uuid: ${service_uuid} #'09912756-7b32-4629-aeb1-b309d9a338ae'
    characteristic_uuid: ${characteristic_uuid} #'ef785c24-22bb-463d-b651-0b7445ba091c'
    type: characteristic
    # update_interval: 2m
    notify: True
    lambda: |-     
      std::string value2(x.begin(), x.end());
      std::string rawhex = format_hex_pretty((uint8_t *) value2.c_str(), value2.size()).c_str();
      //ESP_LOGW("raw_hex_boucle", "-- Recep Debut --");
      //ESP_LOGD("raw_hex", "%s", rawhex.c_str());
      rawhex.erase(std::remove(rawhex.begin(), rawhex.end(), '.'), rawhex.end());
      
      int index = 3;

      while (index +2 < x.size()) {
        uint8_t idvaleur = x[index];
        int taillevaleur = x[index + 1 ];
      
        switch (idvaleur) {
          case 0x00: { 
            }break;
      
          case 0x01: {
            uint8_t phhex = x[index + 2];
            float ph = static_cast<float>(phhex)/10;
            id(JustSalt_ph_sensor).publish_state(ph);
            }break;

          case 0x02: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp02_sensor).publish_state(temp);
            }break;

          case 0x03: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp03_sensor).publish_state(temp);
            }break;

          case 0x06: {
            uint16_t orphex = ((x[index + 2]<< 8) + (x[index +3]));
            float orp = static_cast<float>(orphex);
            id(JustSalt_orp_sensor).publish_state(orp);
            }break;

          case 0x08: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp08_sensor).publish_state(temp);
            }break;

          case 0x09: {
            uint16_t tempeauhex = ((x[index + 2]<< 8) + (x[index +3]));
            float tempeau = static_cast<float>(tempeauhex)/10;
            id(JustSalt_temperature_sensor).publish_state(tempeau);
            }break;
          
          case 0x0A: {
            uint8_t selhex = x[index + 2] ;
            float sel = static_cast<float>(selhex)/10;
            id(JustSalt_tds_sensor).publish_state(sel);
            }break;

          case 0x0B: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0b_sensor).publish_state(temp);
            }break;
          
          case 0x0C: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0c_sensor).publish_state(temp);
            }break;

          case 0x0D: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0d_sensor).publish_state(temp);
            }break;

          case 0x0E: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0e_sensor).publish_state(temp);
            }break;

          case 0x0F: {
            uint8_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0f_sensor).publish_state(temp);
            }break;
          
          case 0x10: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp10_sensor).publish_state(temp);
            }break;

          case 0x11: {
            uint16_t volhex = ((x[index + 2]<< 8) + (x[index +3]));
            float vol = static_cast<float>(volhex);
            id(vol_consigne).publish_state(vol);
            }break;
          
          case 0x12: {
            uint8_t dayphex = (x[index + 3]);
            uint8_t monthphex = (x[index + 4]);
            uint8_t yearphex = (x[index +5]);
            int dayf = static_cast<int>(dayphex);
            int monthf = static_cast<int>(monthphex);
            int yearf = static_cast<int>(yearphex);
            std::string datestr =  std::to_string(dayf) + "/" + std::to_string(monthf) + "/20" + std::to_string(yearf);
            id(JustSalt_temp12_textsensor ).publish_state(datestr);
            }break;

          case 0x13: {
            uint8_t dayphex = (x[index + 3]);
            uint8_t monthphex = (x[index + 4]);
            uint8_t yearphex = (x[index +5]);
            int dayf = static_cast<int>(dayphex);
            int monthf = static_cast<int>(monthphex);
            int yearf = static_cast<int>(yearphex);
            std::string datestr =  std::to_string(dayf) + "/" + std::to_string(monthf) + "/20" + std::to_string(yearf);
            id(JustSalt_temp13_textsensor ).publish_state(datestr);
            }break;

          case 0x1F: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp1f_sensor).publish_state(temp);
            }break;
          
          case 0x28: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp28_sensor).publish_state(temp);
            }break;
          
          case 0x29: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp29_sensor).publish_state(temp);
            }break;
        
          case 0x2A: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp2a_sensor).publish_state(temp);
            }break;
          
          case 0x30: {
            uint8_t phchex = x[index + 2] ;
            float phc = static_cast<float>(phchex)/10;
            auto phcstr = value_accuracy_to_string (phc,1);
            id(ph_consigne).publish_state(phc);
            }break;
          
          case 0x31: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp31_sensor).publish_state(temp);
            }break;         

          case 0x32: {
            uint8_t acidehex = x[index + 2] ;
            float acide = static_cast<float>(acidehex);
            id(acide_consigne).publish_state(acide);
            }break;
          
          case 0x33: {
            uint8_t prodhex = x[index + 2] ;
            float prod = static_cast<float>(prodhex);
            id(production_consigne).publish_state(prod);
            }break;

          case 0x35: {
            uint8_t orpchex = x[index + 2] ;
            float orpc = static_cast<float>(orpchex)*10;
            id(orp_consigne_new).publish_state(orpc);
            }break;
          
          case 0x37: {
            uint8_t alarmeorphex = x[index + 2] ;
            float alarmeorp = static_cast<float>(alarmeorphex);
            id(orp_alarme_consigne).publish_state(alarmeorp);
            }break;
 
          case 0x39: {
            uint8_t inversionhex = x[index + 2] ;
            float inversionval = static_cast<float>(inversionhex);
            id(inversion_consigne).publish_state(inversionval);
            }break;

          case 0x50: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp50_sensor).publish_state(temp);
            }break;

          case 0x51: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp51_sensor).publish_state(temp);
            }break;

          case 0x5F: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp5f_sensor).publish_state(temp);
            }break;
          
          case 0x69: {
            uint32_t temphex = (x[index + 2]<< 24) + (x[index + 3]<< 16)+ (x[index + 4]<< 8) + (x[index +5]);
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp69_sensor).publish_state(temp);
            }break;

          case 0x6A: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp6a_sensor).publish_state(temp);
            }break;

          case 0x8F: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp8f_sensor).publish_state(temp);
            }break;
            
          case 0x90: {
            // 90.08.00.00.00.00.00.00.00.14.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            id(JustSalt_90_textsensor).publish_state(tempstring.c_str());
            }break;

          case 0x91: {
            //  91.08.00.00.00.00.00.06.6F.C3.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            id(JustSalt_91_textsensor).publish_state(tempstring.c_str());
            }break;
          
          case 0x92: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp92_sensor).publish_state(temp);
            }break;

          case 0x93: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp93_sensor).publish_state(temp);
            }break;

          case 0x94: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp94_sensor).publish_state(temp);
            }break;

          case 0x95: {
            uint32_t idcodehex = (x[index + 2]<< 24) + (x[index + 3]<< 16)+ (x[index + 4]<< 8) + (x[index +5]);
            float idcodefloat = static_cast<float>(idcodehex);
            std::string idcodestr = value_accuracy_to_string (idcodefloat,0);
            id(idcode).publish_state(idcodestr);
            }break;
          
          case 0x96: {
            std::string verlog = rawhex.substr((index + 2 )* 2, 2) + "." + rawhex.substr((index + 2 )* 2 + 2, 2);
            id(version_logiciel).publish_state(verlog);
            }break;
          
          case 0x97: {
            std::string slaveval = rawhex.substr((index + 2 )* 2, 2) + "." + rawhex.substr((index + 2 )* 2 + 2, 2);
            id(slave).publish_state(slaveval);
            }break;

          case 0x99: {
            //99.16.47.45.4E.5F.30.35.32.32.2D.30.34.33.39.35.33.2D.30.30.33.00.00.00.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            id(JustSalt_nombt_textsensor).publish_state(tempstring.c_str());
            }break;

          case 0x9A: {
            //9A.10.30.35.32.32.2D.30.34.33.39.35.33.2D.30.30.33.00.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            id(JustSalt_sn_textsensor).publish_state(tempstring.c_str());
            }break;

          case 0x9B: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp9b_sensor).publish_state(temp);
            }break;

          case 0x9C: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp9c_sensor).publish_state(temp);
            }break;

          case 0x9D: {
            //  9D.08.00.00.00.00.00.00.01.FF
            std::string tempstring = rawhex.substr((index + 2 )* 2, 8);
            id(JustSalt_9d_textsensor).publish_state(tempstring);
            }break;
          
          case 0xA3: {
            //  E1.0F.18.04.11.11.00.33.00.00.88.00.F8.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 15);
            id(JustSalt_a3_textsensor).publish_state(tempstring);
            }break;
          
          case 0xB0: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_tempb0_sensor).publish_state(temp);
            }break;
  
          case 0xB1: {
            std::string tempstring = rawhex.substr((index + 2 )* 2, 12);
            id(JustSalt_macbt_textsensor).publish_state(tempstring);
            }break;
          
          case 0xD0: {
            //D0.06.30.00.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 6);
            id(JustSalt_d0_textsensor).publish_state(tempstring);
            }break;

          case 0xD1: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_tempd1_sensor).publish_state(temp);
            }break;
   
          case 0xFE: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_tempfe_sensor).publish_state(temp);
            }break;
  
          case 0xE1: {
            //  E1.0F.18.04.11.11.00.33.00.00.88.00.F8.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 30);
            id(JustSalt_e1_textsensor).publish_state(tempstring);
            }break;
            
          case 0xE2: {
            // E2.0F.18.04.16.0A.22.10.00.00.00.41.3E.DC.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 30);
            id(JustSalt_e2_textsensor).publish_state(tempstring);
            }break;

          case 0xE4: {
            // E4.0F.18.04.12.15.00.00.46.00.0B.13.00.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 30);
            id(JustSalt_e4_textsensor).publish_state(tempstring);
            }break;

          default: {
              ESP_LOGW("raw_hex_boucle", "idvaleur Non implementee %d", idvaleur);
            };
          }
        index = index + 2 + taillevaleur ;
      }
      //ESP_LOGW("raw_hex_boucle", "-- Recep FIN --");
      return 1;


switch:      
  - platform: restart
    name: JustSalt_Gatway restart    

  - platform: ble_client
    id: ble_switch_com
    ble_client_id: JustSaltPro
    name: "Enable com JustSalt"

1 « J'aime »

Je vais essayer de faire ça ce wk mais je ne promets rien, c’est hyper chargé.

Pour info, ce n’est pas l’électrolyseur qui pilote le volet. C’est juste une entrée qui permet de diminuer la production de chlore.

Je ne sais plus si je te l’ai déjà dit mais j’ai aussi connecté le capteur de débit.

ok donc ca a moins d importance , c est juste un retour d’état
bon alors les seul truc important qui nous manque ce sont les alarmes !
le reste c est sympa mais plus indispensable :slight_smile:

je suis en train de tester différente façon de travailler le code dans ESPHome afin d’essayer de gagner en efficacité sur la lecture de trame !

car a la connexion BLE il y a 4 trames séparé de 30 ms environs chacune, l ensemble comporte toutes les données !
le traitement actuelle ne permet pas de traiter l intégralité de chaque trames, a la première connexion car l envois de chaque valeur dans HA prend trop de temps !
aujourd’hui, il faut pour le moment 2 a 3 cycle de redémarrage Bt pour que ca fonctionne !

j’en ai profité pour mettre des icones plus représentative !

1 « J'aime »

Bonjour ,

J’ajoute un electrolyseur dans la liste , je viens de recevoir mon RACER 17/80 (pas de PH , c’est le boitier complémentaire qui viendra un peu plus tard)
Pour les premiers test avec ESPHome ou en Mqtt j’ai les infos .
Je finaliserais dès que je l’aurais installé .
Encore merci @Ricky_D ainsi qu’aux autres participant pour tout le boulot .

autre info pour cet electrolyseur , il y a aussi la com en modbus .
Un développeur sous Jeedom avait commencé à interpreter les infos :

Cool un nouveau model :slight_smile:
voici la dernière version en ESPHome !
j ai réussi a contourné les pb de ralentissement du a l envois de donné a ha !
pour ceux que ca intéresse je stock les valeur dans des variables global !
j ai aussi créer un tableau pour savoir lesquelles ont été modifié , et je les envois a fur et a mesure des traitement ! résultat les valeurs remonte plus rapidement !

#  JustSalt
substitutions:
  mac_justsalt: "94:DE:B8:A1:1A:AC"
  service_uuid: '09912756-7b32-4629-aeb1-b309d9a338ae'
  characteristic_uuid: 'ef785c24-22bb-463d-b651-0b7445ba091c'
  characteristic_uuid_write: '4d32c5e5-2bb5-45c6-8c89-6f59bb3930d2'

esphome:
  name: esphome-web-ecc470
  friendly_name: ESPHome Web ecc470

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:
  encryption:
    key: "bLk/RiUyxLzXjb42FYKAhRU9WmN3iuyB3uiKMbovaMo="

ota:


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-Ecc470"
    password: "eEzs1d6LU1bH"

captive_portal:

bluetooth_proxy:
  active: true

globals:
  - id: valforexport
    type: bool[255]

  - id: val01
    type: float
  - id: val02
    type: float
  - id: val03
    type: float
  - id: val06
    type: float
  - id: val08
    type: float
  - id: val09
    type: float
  - id: val0A
    type: float
  - id: val0B
    type: float
  - id: val0C
    type: float
  - id: val0D
    type: float
  - id: val0E
    type: float
  - id: val0F
    type: float
  - id: val10
    type: float
  - id: val11
    type: float
  - id: val12
    type: String
  - id: val13
    type: String
  - id: val1F
    type: float
  - id: val28
    type: float
  - id: val29
    type: float
  - id: val2A
    type: float
  - id: val30
    type: float
  - id: val31
    type: float
  - id: val32
    type: float
  - id: val33
    type: float  
  - id: val35
    type: float
  - id: val37
    type: float
  - id: val39
    type: float
  - id: val50
    type: float
  - id: val51
    type: float
  - id: val5F
    type: float
  - id: val69
    type: float
  - id: val6A
    type: float
  - id: val8F
    type: float 
  - id: val90
    type: String
  - id: val91
    type: String
  - id: val92
    type: float
  - id: val93
    type: float
  - id: val94
    type: float
  - id: val95
    type: float
  - id: val96
    type: String
  - id: val97
    type: String 
  - id: val99
    type: String
  - id: val9A
    type: String
  - id: val9B
    type: float
  - id: val9C
    type: float
  - id: val9D
    type: String
  - id: valA3
    type: String
  - id: valB0
    type: float 
  - id: valB1
    type: String
  - id: valD0
    type: String
  - id: valD1
    type: float
  - id: valE1
    type: String
  - id: valE2
    type: String 
  - id: valE4
    type: String
  - id: valFE
    type: float
  
time:
  - platform: homeassistant
    id: homeassistant_time_5m
    on_time:
      - seconds: 0
        minutes: /5
        then:
          - switch.turn_off: ble_switch_com
          - delay: 20s
          - switch.turn_on: ble_switch_com

ble_client:
  - mac_address:  ${mac_justsalt}
    auto_connect: true
    id: JustSaltPro
    on_connect:
      then:
        - ble_client.numeric_comparison_reply:
            id: JustSaltPro
            accept: True

binary_sensor:
  - platform: ble_presence
    mac_address: ${mac_justsalt}
    name: Electolyseur

  - platform: template  
    id: InjPHM
    name: "Injection PH-"
  
  - platform: template  
    id: InjPHP
    name: "Injection PH+"

number:
  - platform: template
    id: orp_consigne
    name: "ORP Consigne"
    icon: "mdi:flash-triangle-outline"
    unit_of_measurement: "mV"
    min_value: 200
    max_value: 900
    step: 10
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("ORPconsigne", "Option consigne change:  %f", id(orp_consigne).state);   
              uint8_t statehex = id(orp_consigne).state / 10;
              return {0x00, 0x06, 0x03, 0x35, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: orp_alarme_consigne
    name: "ORP Alarme Consigne"
    icon: "mdi:alarm"
    unit_of_measurement: "h"
    min_value: 12
    max_value: 96
    step: 6
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("ORPalarmeconsigne", "Option consigne change:  %f", id(orp_alarme_consigne).state);   
              uint8_t statehex = id(orp_alarme_consigne).state;
              return {0x00, 0x06, 0x03, 0x37, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
         
  - platform: template
    id: ph_consigne
    name: "PH Consigne"
    icon: "mdi:ph"
    unit_of_measurement: "ph"
    min_value: 6.8
    max_value: 7.6
    step: 0.1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("PHconsigne", "Option consigne change:  %f", id(ph_consigne).state);   
              uint8_t statehex = id(ph_consigne).state * 10;
              return {0x00, 0x06, 0x03, 0x30, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        
  - platform: template
    id: vol_consigne
    name: "Volume Consigne"
    icon: "mdi:cup-water"
    unit_of_measurement: "m3"
    min_value: 10
    max_value: 200
    step: 10
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("volconsigne", "Option consigne change:  %f", id(vol_consigne).state);   
              uint8_t statehex = id(vol_consigne).state;
              return {0x00, 0x06, 0x03, 0x11, 0x02, 0x00, statehex, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: acide_consigne
    name: "acide Consigne"
    icon: "mdi:skull-crossbones-outline"
    unit_of_measurement: "%"
    min_value: 5
    max_value: 55
    step: 1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("acideconsigne", "Option consigne change:  %f", id(acide_consigne).state);   
              uint8_t statehex = id(acide_consigne).state;
              return {0x00, 0x06, 0x03, 0x32, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: production_consigne
    name: "production Consigne"
    icon: "mdi:cog-outline"
    unit_of_measurement: "%"
    min_value: 10
    max_value: 100
    step: 1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("productionconsigne", "Option consigne change:  %f", id(production_consigne).state);   
              uint8_t statehex = id(production_consigne).state; 
              return {0x00, 0x06, 0x03, 0x33, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
              //return {0x00, 0x06, 0x03, 0x33, 0x01, 0x63, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: inversion_consigne
    name: "inversion Consigne"
    icon: "mdi:alarm"
    unit_of_measurement: "h"
    min_value: 2
    max_value: 24
    step: 1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("inversionconsigne", "Option consigne change:  %f", id(inversion_consigne).state);   
              uint8_t statehex = id(inversion_consigne).state;
              return {0x00, 0x06, 0x03, 0x39, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


text_sensor:
  - platform: version
    name: ESPHome Version
  
  - platform: wifi_info
    ssid:
      name: WiFi

  - id: version_logiciel
    name: "version logiciel"
    platform: template 
    icon: "mdi:qrcode"
  
  - id: slave
    name: "Slave"
    platform: template 
    icon: "mdi:qrcode-edit"

  - platform: template
    name: "MAC bt"
    id: JustSalt_macbt_textsensor
    icon: "mdi:network-outline"
  
  - platform: template
    name: "nom bt"
    id: JustSalt_nombt_textsensor
    icon: "mdi:card-account-details-outline"
  
  - platform: template
    name: "SN"
    id: JustSalt_sn_textsensor
    icon: "mdi:barcode"

  - platform: template
    name: "temp90"
    id: JustSalt_90_textsensor
  
  - platform: template
    name: "temp91"
    id: JustSalt_91_textsensor

  - platform: template
    name: "temp9D"
    id: JustSalt_9d_textsensor
  
  - platform: template
    name: "tempD0"
    id: JustSalt_d0_textsensor

  - platform: template
    name: "tempE1"
    id: JustSalt_e1_textsensor

  - platform: template
    name: "tempE2"
    id: JustSalt_e2_textsensor
      
  - platform: template
    name: "tempE4"
    id: JustSalt_e4_textsensor
  
  - platform: template
    name: "tempA3"
    id: JustSalt_a3_textsensor

  - platform: template
    name: "Date etalonage PH"
    id: JustSalt_temp12_textsensor
    icon: "mdi:calendar-star-four-points"

  - platform: template
    name: "Date etalonage ORP"
    id: JustSalt_temp13_textsensor
    icon: "mdi:calendar-star-four-points"

sensor:
  - platform: wifi_signal
    name: Wifi signal
    update_interval: 60s

  - platform: uptime
    name: Uptime
  
  - platform: template
    name: "temp02"
    id: JustSalt_temp02_sensor
    accuracy_decimals: 0
    on_value:
      then:
        - lambda: |- 
            if (id(sensor_state).state == 1) {
              uint16_t temphex02 = id(JustSalt_temp02_sensor).raw_state;
              //ESP_LOGD(" --- temp 02 str", "%d", temphex02);
              id(InjPHM).publish_state((bool)((temphex02 & 0x000A) ));
              id(InjPHP).publish_state((bool)((temphex02 & 0x000C) ));
              }

  - id: idcode
    name: "ID Code"
    platform: template  
    icon: "mdi:barcode"
    accuracy_decimals: 0

  - platform: template
    name: "temp03"
    id: JustSalt_temp03_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp08"
    id: JustSalt_temp08_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp0B"
    id: JustSalt_temp0b_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp0C"
    id: JustSalt_temp0c_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp0D"
    id: JustSalt_temp0d_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "Compteur Heure total de fonctionnement"
    id: JustSalt_temp0e_sensor
    accuracy_decimals: 0
    unit_of_measurement: "h"
    icon: "mdi:timer-sand"
  
  - platform: template
    name: "minutes de fonctionement"
    id: JustSalt_temp0f_sensor
    unit_of_measurement: "min"
    accuracy_decimals: 0
    icon: "mdi:counter"

  - platform: template
    name: "temp10"
    id: JustSalt_temp10_sensor
    accuracy_decimals: 0
 
  - platform: template
    name: "temp1f"
    id: JustSalt_temp1f_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp28"
    id: JustSalt_temp28_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp29"
    id: JustSalt_temp29_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp2A"
    id: JustSalt_temp2a_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp31"
    id: JustSalt_temp31_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp50"
    id: JustSalt_temp50_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp51"
    id: JustSalt_temp51_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp5F"
    id: JustSalt_temp5f_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp69"
    id: JustSalt_temp69_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp6A"
    id: JustSalt_temp6a_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp8F"
    id: JustSalt_temp8f_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp92"
    id: JustSalt_temp92_sensor
    accuracy_decimals: 0
      
  - platform: template
    name: "temp93"
    id: JustSalt_temp93_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp94"
    id: JustSalt_temp94_sensor
    accuracy_decimals: 0
      
  - platform: template
    name: "temp9B"
    id: JustSalt_temp9b_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp9C"
    id: JustSalt_temp9c_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp9D"
    id: JustSalt_temp9d_sensor
    accuracy_decimals: 0

  - platform: template
    name: "tempB0"
    id: JustSalt_tempb0_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "tempD1"
    id: JustSalt_tempd1_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "tempFE"
    id: JustSalt_tempfe_sensor
    accuracy_decimals: 0

  - platform: ble_rssi
    mac_address:  ${mac_justsalt}
    name: "JustSalt RSSI"  

  - platform: template
    name: "Temperature eau"
    id: JustSalt_temperature_sensor
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    state_class: measurement
    device_class: temperature
  
  - platform: template
    name: "pH"
    id: JustSalt_ph_sensor
    unit_of_measurement: "pH"
    accuracy_decimals: 1
    state_class: measurement
    icon: mdi:ph
  
  - platform: template
    name: "ORP"
    id: JustSalt_orp_sensor
    unit_of_measurement: "mV"
    accuracy_decimals: 0
    state_class: measurement
    device_class: voltage
  
  - platform: template
    name: "TDS"
    id: JustSalt_tds_sensor
    unit_of_measurement: "g/L"
    accuracy_decimals: 1
    state_class: measurement
    icon: mdi:water-opacity

  - platform: ble_client
    ble_client_id: JustSaltPro
    name: "traitement"
    id: sensor_state    
    service_uuid: ${service_uuid} #'09912756-7b32-4629-aeb1-b309d9a338ae'
    characteristic_uuid: ${characteristic_uuid} #'ef785c24-22bb-463d-b651-0b7445ba091c'
    type: characteristic
    # update_interval: 2m
    notify: True
    lambda: |-     
      std::string value2(x.begin(), x.end());
      std::string rawhex = format_hex_pretty((uint8_t *) value2.c_str(), value2.size()).c_str();
      //ESP_LOGW("raw_hex_boucle", "-- Recep Debut --");
      //ESP_LOGD("raw_hex", "%s", rawhex.c_str());
      rawhex.erase(std::remove(rawhex.begin(), rawhex.end(), '.'), rawhex.end());
 
      int index = 3;
      while (index +2 < x.size()) {
        uint8_t idvaleur = x[index];
        int taillevaleur = x[index + 1 ];
        //ESP_LOGW("recep", "-- Recep value -- %d", idvaleur);
        switch (idvaleur) {
          case 0x00: { 
            }break;
      
          case 0x01: {
            id(val01) = static_cast<float>( x[index + 2])/10;
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x02: {
            id(val02) = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x03: {
            id(val03)  = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x06: {
            id(val06)  = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x08: {
            id(val08) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x09: {
            id(val09)  = static_cast<float>( x[index + 2]<< 8) + (x[index +3]) /10;
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x0A: {
            id(val0A) = static_cast<float>( x[index + 2])/10;
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x0B: {
            id(val0B) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x0C: {
            id(val0C) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x0D: {
            id(val0D)  = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x0E: {
            id(val0E)  = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x0F: {
            id(val0F)  = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x10: {
            id(val10)  = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x11: {
            id(val11)  = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x12: {
            uint8_t dayphex = (x[index + 3]);
            uint8_t monthphex = (x[index + 4]);
            uint8_t yearphex = (x[index +5]);
            int dayf = static_cast<int>(dayphex);
            int monthf = static_cast<int>(monthphex);
            int yearf = static_cast<int>(yearphex);
            std::string datestr =  std::to_string(dayf) + "/" + std::to_string(monthf) + "/20" + std::to_string(yearf);
            //id(JustSalt_temp12_textsensor ).publish_state(datestr);
            id(val12)  = datestr.c_str();
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x13: {
            uint8_t dayphex = (x[index + 3]);
            uint8_t monthphex = (x[index + 4]);
            uint8_t yearphex = (x[index +5]);
            int dayf = static_cast<int>(dayphex);
            int monthf = static_cast<int>(monthphex);
            int yearf = static_cast<int>(yearphex);
            std::string datestr =  std::to_string(dayf) + "/" + std::to_string(monthf) + "/20" + std::to_string(yearf);
            //id(JustSalt_temp13_textsensor ).publish_state(datestr);
            id(val13)  = datestr.c_str();
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x1F: {
            //ESP_LOGW("1f", "-- taille -- %d", taillevaleur);
            id(val1F)  = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x28: {
            id(val28)  = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x29: {
            id(val29)  = static_cast<float>( x[index + 2] );
            id(valforexport)[idvaleur] = true;
            }break;
        
          case 0x2A: {
            id(val2A)  = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x30: {
            id(val30) = static_cast<float>( x[index + 2])/10;
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x31: {
            id(val31) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;         

          case 0x32: {
            id(val32) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x33: {
            id(val33) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x35: {
            id(val35) = static_cast<float>( x[index + 2])*10;
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x37: {
            id(val37) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;
 
          case 0x39: {
            id(val39) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x50: {
            id(val50) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x51: {
            id(val51) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x5F: {
            id(val5F) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x69: {
            id(val69) = static_cast<float>( x[index + 2]<< 24) + (x[index + 3]<< 16)+ (x[index + 4]<< 8) + (x[index +5]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x6A: {
            id(val6A) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x8F: {
            id(val8F) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;
            
          case 0x90: {
            // 90.08.00.00.00.00.00.00.00.14.
            std::string tempstring = rawhex.substr((index + 2 )* 2,taillevaleur * 2);
            id(val90) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x91: {
            //  91.08.00.00.00.00.00.06.6F.C3.
            std::string tempstring = rawhex.substr((index + 2 )* 2,taillevaleur * 2);
            id(val91) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;

            }break;
          
          case 0x92: {
            id(val92) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x93: {
            id(val93) = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x94: {
            id(val94) = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x95: {        
            id(val95) = static_cast<float>( x[index + 2]<< 24) + (x[index + 3]<< 16)+ (x[index + 4]<< 8) + (x[index +5]);
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0x96: {
            std::string verlog = rawhex.substr((index + 2 )* 2, 2) + "." + rawhex.substr((index + 2 )* 2 + 2, 2);
            id(val96) = verlog.c_str();
            }break;
          
          case 0x97: {
            std::string slaveval = rawhex.substr((index + 2 )* 2, 2) + "." + rawhex.substr((index + 2 )* 2 + 2, 2);
            id(val97) = slaveval.c_str();
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x99: {
            //99.16.47.45.4E.5F.30.35.32.32.2D.30.34.33.39.35.33.2D.30.30.33.00.00.00.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            //id(JustSalt_nombt_textsensor).publish_state(tempstring.c_str());
            id(val99) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x9A: {
            //9A.10.30.35.32.32.2D.30.34.33.39.35.33.2D.30.30.33.00.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            //id(JustSalt_sn_textsensor).publish_state(tempstring.c_str());
            id(val9A) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x9B: {
            id(val9B) = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x9C: {
            id(val9C) = static_cast<float>( x[index + 2]<< 8) + (x[index +3]);
            id(valforexport)[idvaleur] = true;
            }break;

          case 0x9D: {
            //  9D.08.00.00.00.00.00.00.01.FF
            std::string tempstring = rawhex.substr((index + 2 )* 2, taillevaleur * 2);
            //id(JustSalt_9d_textsensor).publish_state(tempstring);
            id(val9D) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0xA3: {
            //  E1.0F.18.04.11.11.00.33.00.00.88.00.F8.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, taillevaleur * 2);
            //id(JustSalt_a3_textsensor).publish_state(tempstring);
            id(valA3) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0xB0: {
            id(valB0) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;
  
          case 0xB1: {
            String tempstring; //= rawhex.substr((index + 2 )* 2, taillevaleur *2);
            for ( int i = index + 2; i < index + 2 + taillevaleur ; i++ ) {
              tempstring += String(x[i],HEX) ;
                if (i != index + 1 + taillevaleur){
                    tempstring += ":" ; 
                }
            }
            tempstring.toUpperCase();
            id(valB1) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0xD0: {
            //D0.06.30.00.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, taillevaleur *2 );
            //id(JustSalt_d0_textsensor).publish_state(tempstring);
            id(valD0) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;

          case 0xD1: {
            id(valD1) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;
            }break;
   
          case 0xE1: {
            //  E1.0F.18.04.11.11.00.33.00.00.88.00.F8.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, taillevaleur *2);
            //id(JustSalt_e1_textsensor).publish_state(tempstring);
            id(valE1) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;
            
          case 0xE2: {
            // E2.0F.18.04.16.0A.22.10.00.00.00.41.3E.DC.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, taillevaleur *2);
            //id(JustSalt_e2_textsensor).publish_state(tempstring);
            id(valE2) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;

          case 0xE4: {
            // E4.0F.18.04.12.15.00.00.46.00.0B.13.00.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, taillevaleur *2);
            //id(JustSalt_e4_textsensor).publish_state(tempstring);
            id(valE4) = tempstring.c_str();
            id(valforexport)[idvaleur] = true;
            }break;
          
          case 0xFE: {
            id(valFE) = static_cast<float>( x[index + 2]);
            id(valforexport)[idvaleur] = true;;
            }break;

          default: {
              ESP_LOGW("raw_hex_boucle", "idvaleur Non implementee %d", idvaleur);
            };
          }
        index = index + 2 + taillevaleur ;
      }
      //ESP_LOGW("raw_hex_boucle", "-- Recep FIN --> debut export");
      int i=1;
      for ( i = 1; i<= 254; i++) {
        // ESP_LOGW("SendValue", "value send: %i ", i  ); 
        if (id(valforexport)[i] == true){
          //ESP_LOGI("SendValue", "value send: %d - %i", i,i); 
          switch (i) {
            case 0x01: { 
              id(JustSalt_ph_sensor).publish_state(id(val01));
              id(valforexport)[i] = "false";
              }break;
            
            case 0x02: { 
              id(JustSalt_temp02_sensor).publish_state(id(val02));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x03: { 
              id(JustSalt_temp03_sensor).publish_state(id(val03));
              id(valforexport)[i] = "false";
              }break;

            case 0x06: { 
              id(JustSalt_orp_sensor).publish_state(id(val06));
              id(valforexport)[i] = "false";
              }break;

            case 0x08: { 
              id(JustSalt_temp08_sensor).publish_state(id(val08));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x09: { 
              id(JustSalt_temperature_sensor).publish_state(id(val09));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x0A: { 
              id(JustSalt_tds_sensor).publish_state(id(val0A));
              id(valforexport)[i] = "false";
              }break;

            case 0x0B: { 
              id(JustSalt_temp0b_sensor).publish_state(id(val0B));
              id(valforexport)[i] = "false";
              }break;

            case 0x0C: { 
              id(JustSalt_temp0c_sensor).publish_state(id(val0C));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x0D: { 
              id(JustSalt_temp0d_sensor).publish_state(id(val0D));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x0E: { 
              id(JustSalt_temp0e_sensor).publish_state(id(val0E));
              id(valforexport)[i] = "false";
              }break;
            
            case 0x0F: { 
              id(JustSalt_temp0f_sensor).publish_state(id(val0F));
              id(valforexport)[i] = "false";
              }break;

            case 0x10: { 
              id(JustSalt_temp10_sensor).publish_state(id(val10));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x11: { 
              id(vol_consigne).publish_state(id(val11));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x12: { 
              id(JustSalt_temp12_textsensor).publish_state(id(val12).c_str());
              id(valforexport)[i] = "false";
              }break;
            
            case 0x13: { 
              id(JustSalt_temp13_textsensor).publish_state(id(val13).c_str());
              id(valforexport)[i] = "false";
              }break;

            case 0x1F: { 
              id(JustSalt_temp1f_sensor).publish_state(id(val1F));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x28: { 
              id(JustSalt_temp28_sensor).publish_state(id(val28));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x29: { 
              id(JustSalt_temp29_sensor).publish_state(id(val29));
              id(valforexport)[i] = "false";
              }break;      
            
            case 0x2A: { 
              id(JustSalt_temp2a_sensor).publish_state(id(val2A));
              id(valforexport)[i] = "false";
              }break;  

            case 0x30: { 
              if(id(val30) != id(ph_consigne).state ){
                ESP_LOGI("compPHC", "value=  %d - consigne = %i", id(val30),id(ph_consigne).state); 
                id(ph_consigne).publish_state(id(val30));
                id(valforexport)[i] = "false";
                }
              }break;
      
            case 0x31: { 
              id(JustSalt_temp31_sensor).publish_state(id(val31));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x32: { 
              if(id(val32) != id(acide_consigne).state ){
                ESP_LOGI("compAcideC", "value=  %d - consigne = %i", id(val32),id(acide_consigne).state); 
                id(acide_consigne).publish_state(id(val32));
                id(valforexport)[i] = "false";
                }
              }break;      
            
            case 0x33: { 
              if(id(val33) != id(production_consigne).state ){
                ESP_LOGI("compProdC", "value=  %d - consigne = %i", id(val33),id(production_consigne).state); 
                id(production_consigne).publish_state(id(val33));
                id(valforexport)[i] = "false";
                }
              }break;      
            
            case 0x35: { 
              if(id(val35) != id(orp_consigne).state ){
                ESP_LOGI("compORPC", "value=  %d - consigne = %i", id(val35),id(orp_consigne).state); 
                id(orp_consigne).publish_state(id(val35));
                id(valforexport)[i] = "false";
                }
              }break;
      
            case 0x37: { 
              if(id(val37) != id(orp_alarme_consigne).state ){
                ESP_LOGI("compORPAlarmeC", "value=  %d - consigne = %i", id(val37),id(orp_alarme_consigne).state); 
                id(orp_alarme_consigne).publish_state(id(val37));
                id(valforexport)[i] = "false";
                }
              }break;
      
            case 0x39: { 
              if(id(val39) != id(inversion_consigne).state ){
                ESP_LOGI("compinversionC", "value=  %d - consigne = %i", id(val39),id(inversion_consigne).state); 
                id(inversion_consigne).publish_state(id(val39));
                id(valforexport)[i] = "false";
                }
              }break;      
            
            case 0x50: { 
              id(JustSalt_temp50_sensor).publish_state(id(val50));
              id(valforexport)[i] = "false";
              }break;      
      
            case 0x51: { 
              id(JustSalt_temp51_sensor).publish_state(id(val51));
              id(valforexport)[i] = "false";
              }break;      
            
            case 0x5F: { 
              id(JustSalt_temp5f_sensor).publish_state(id(val5F));
              id(valforexport)[i] = "false";
              }break; 

            case 0x69: { 
              id(JustSalt_temp69_sensor).publish_state(id(val69));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x6A: { 
              id(JustSalt_temp6a_sensor).publish_state(id(val6A));
              id(valforexport)[i] = "false";
              }break;
      
            case 0x8F: { 
              id(JustSalt_temp8f_sensor).publish_state(id(val8F));
              id(valforexport)[i] = "false";
              }break;      
            
            case 0x90: { 
              id(JustSalt_90_textsensor).publish_state(id(val90).c_str());
              id(valforexport)[i] = "false";
              }break;      
      
            case 0x91: { 
              id(JustSalt_91_textsensor).publish_state(id(val91).c_str());
              id(valforexport)[i] = "false";
              }break;      
            
            case 0x92: { 
              id(JustSalt_temp92_sensor).publish_state(id(val92));
              id(valforexport)[i] = "false";
              }break;   

            case 0x93: { 
              id(JustSalt_temp93_sensor).publish_state(id(val93));
              id(valforexport)[i] = "false";
              }break;  

            case 0x94: { 
              id(JustSalt_temp94_sensor).publish_state(id(val94));
              id(valforexport)[i] = "false";
              }break;  
            
            case 0x95: { 
              id(idcode).publish_state(id(val95));
              id(valforexport)[i] = "false";
              }break;  

            case 0x96: { 
              id(version_logiciel).publish_state(id(val96).c_str());
              id(valforexport)[i] = "false";
              }break;  

            case 0x97: { 
              id(slave).publish_state(id(val97).c_str());
              id(valforexport)[i] = "false";
              }break;  

            case 0x99: { 
              id(JustSalt_nombt_textsensor).publish_state(id(val99).c_str());
              id(valforexport)[i] = "false";
              }break;

            case 0x9A: { 
              id(JustSalt_sn_textsensor).publish_state(id(val9A).c_str());
              id(valforexport)[i] = "false";
              }break;  

            case 0x9B: { 
              id(JustSalt_temp9b_sensor).publish_state(id(val9B));
              id(valforexport)[i] = "false";
              }break;  

            case 0x9C: { 
              id(JustSalt_temp9c_sensor).publish_state(id(val9C));
              id(valforexport)[i] = "false";
              }break;  

            case 0x9D: { 
              id(JustSalt_9d_textsensor).publish_state(id(val9D).c_str());
              id(valforexport)[i] = "false";
              }break;  
            
            case 0xA3: { 
              id(JustSalt_a3_textsensor).publish_state(id(valA3).c_str());
              id(valforexport)[i] = "false";
              }break;  
            
            case 0xB0: { 
              id(JustSalt_tempb0_sensor).publish_state(id(valB0));
              id(valforexport)[i] = "false";
              }break;  
                            
            case 0xB1: { 
              id(JustSalt_macbt_textsensor).publish_state(id(valB1).c_str());
              id(valforexport)[i] = "false";
              }break;  
          
            case 0xD0: { 
              id(JustSalt_d0_textsensor).publish_state(id(valD0).c_str());
              id(valforexport)[i] = "false";
              }break;  
            
            case 0xD1: { 
              id(JustSalt_tempd1_sensor).publish_state(id(valD1));
              id(valforexport)[i] = "false";
              }break; 

            case 0xE1: { 
              id(JustSalt_e1_textsensor).publish_state(id(valE1).c_str());
              id(valforexport)[i] = "false";
              }break; 

            case 0xE2: { 
              id(JustSalt_e2_textsensor).publish_state(id(valE2).c_str());
              id(valforexport)[i] = "false";
              }break; 

            case 0xE4: { 
              id(JustSalt_e4_textsensor).publish_state(id(valE4).c_str());
              id(valforexport)[i] = "false";
              }break; 

            case 0xFE: { 
              id(JustSalt_tempfe_sensor).publish_state(id(valFE));
              id(valforexport)[i] = "false";
              }break;  

          }
        }
        
      }
      //ESP_LOGW("raw_hex_boucle", "-- send export Fin --");
      return 1;


switch:      
  - platform: restart
    name: JustSalt_Gatway restart    

  - platform: ble_client
    id: ble_switch_com
    ble_client_id: JustSaltPro
    name: "Enable com JustSalt"

Bonjour ,

Lorsqu’il y a des modifications de code pour ESPHome , y en a t il aussi pour la version MQTT ,?

En théorie oui.
Mais la j adaptai le code esphome au niveau du code mqtt
Donc pas de changement pour la version compilé

1 « J'aime »

Bonjour ,
La version ESPHome fonctionne bien .
Je voudrais utiliser pleinement la version MQTT , mais cela ne fonctionne pas .

Explication : ESPHome , connection bluetooth , appairage OK , les infos communique dans les 2 sens pas de soucis .
Je passe sur la version MQTT , enregistrement de mes valeurs , broker , adresse mac , les uuid …
je n’arrive pas à appairer en bluetooth

Alors :
Je test l’appairage avec l’API E-pool sur Iphone = ok
Je test l’appairage avec l’API E-pool sur Android = ok
Je re -test l’appairage avec ESPHome = ok ,

Je me dis c’est bon , je re test avec MQTT = impossible à appairer , l’appairage tourne en boucle sur l’electrolyseur , pas de connexion

J’ai constaté que pour les API cela ne fonctionne que si la localisation du telephone est active ( pour l’electrolyseur Racer )
Je suppose que pour ESPHome c’est natif avec HA .
Je ne sais pas pourquoi avec la version MQTT l’electrolyseur ne peux s’appairer ,
la version MQTT aurais elle besoin de la localisation pour mon electrolyseur …

J’ai testé avec un autre ESP32 , meme résultat .

J’ai reçu 1 ESP32-C6 , je galère pour le faire accepter par VScode et PlatformIO ,pour mes nouveaux test .
As tu réussi à intégrer l’ESP32-C6 ?

Non pas besoin de la localisation sur autre chose qu’un téléphone. C’est devenu un abus de language pour dire donne moi accès pleinement au ‹ bluetooth ›.

1 « J'aime »

@Ricky_D

avec pas mal de retard, j’ai enfin pris le temps de remettre a jour le code de mon esp32 avec ta dernière version.

quelle sont les valeurs dont tu voudrais l’historique ?

je rappelle la configuration de mon installation :

  • electrolyseur duo (pas d’orp)
  • marque distributeur (majestic)
  • branché h24
  • production de chlore pilotée par :
    • un capteur de débit (pas de débit, pas de production)
    • entrée volet :
      • volet ouvert : production de chlore selon consigne
      • volet fermé : production de chlore consigne /5

De ce que j’ai pu voir pendant mes tests hier, lorsque mon volet est fermé, la consigne reste bien à 100% mais la production est bien diminuée à 20%.

Il doit certainement avoir une valeur que indique la production réelle mais laquelle ???

temp0B doit être une température (interne au boitier ou autre) car on voit bien quelle monte dans les 47 en production à 100% et redescend à 24 en production à 20% (d’ailleurs le ventilo interne ne se déclenche pas à 20%)

L’électrolyseur est enfin remis en marche de mon côté. Ma configuration est :

  • Arboral Salt Next duo : Pas d’orp
  • Régulation au sel.
  • J’utilise la dernière version du code ESPHome

La récupération des constantes semble fonctionner parfaitement, j’ai une mise à jour régulière de celles-ci sans reconnexion manuel, (Température de l’eau, TDS, pH, Consigne Production, Consigne pH).
Cependant, j’ai un bug pour modifier les consignes de pH et de Production. Quand je les modifie, j’ai HA qui m’affiche un compte à rebours « Dans 30s » et au bout de ces 30s j’ai une déco/reco à l’électrolyseur et la valeur de consigne revient à ce qu’elle était à la base.
Rencontrez vous aussi le même pb ?

Salut
Déjà merci pour les retours très constructif
J apprécie vraiment !
Je tiens aussi à m excuser pour le manque de réactivité ou de réponse !
La semaine dernière je préparerai le baptême de mes filles et là je range, je pense reprendre l activité sur le l électrolyseur fin de semaine, mais très légèrement car le boulot professionnel s accumule après 15 jours de congés,mais promis je compilerai toutes vos informations des que possible.
Pour le esp c6 je galère aussi ! (Pas sûr que ce soit la bonne piste)
Par contre j ai aussi reçu des esp32 qui fonctionnent bien pour le portail captif les travaux dessus sont initiés, mais loin d êtres complètement opérationnel
Le point accès fonctionne,la saisie du réseau wifi et du serveur mqtt est opérationnel mais il faut que j adapte le code précédemment fait car les librairies ne sont pas compatibles entre elle,bref un peut bcp de boulot d adaptation :scream:
Et j aussi remarqué une déco reco intempestives sur la version compilé

2 « J'aime »

Bonjour,
Je viens de créer un compte pour vous remercier. La version en ESPHome fonctionne bien avec mon électrolyseur.

@Ricky_D j’ai utilisé une Esp32-C6. ça a été bien le bazar pour trouver la bonne config avec HA mais ça fonctionne. J’ai plus qu’à attendre que le zigbee soit pris en charge.

Bonjour,
Peux tu partager ta config/méthode pour l’ESP32-C6
Je n’ai pas réussi avec Platformio .

Hello voila le code.
Il faut que je trouve une commande pour rebooter l’ESP toutes les 24h.

esphome:
  name: esp
  friendly_name: esp

esp32:
  board: esp32-c6-devkitc-1
  flash_size: 8MB
  variant: esp32c6
  framework:
    type: esp-idf
    version: "5.2.1"
    platform_version: 6.6.0
    sdkconfig_options:
      CONFIG_OPENTHREAD_ENABLED: n
      CONFIG_ENABLE_WIFI_STATION: y
      CONFIG_USE_MINIMAL_MDNS: y
      CONFIG_ESPTOOLPY_FLASHSIZE_8MB: y

# fix for logger from luar123 (thanks!)
external_components:
    - source: github://luar123/esphome@fix_logger
      components: [ logger ]
      refresh: never

#  JustSalt
substitutions:
  mac_justsalt: "mets la tienne"
  service_uuid: '09912756-7b32-4629-aeb1-b309d9a338ae'
  characteristic_uuid: 'ef785c24-22bb-463d-b651-0b7445ba091c'
  characteristic_uuid_write: '4d32c5e5-2bb5-45c6-8c89-6f59bb3930d2'  

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "mets la tienne"

ota:
  password: "je sais pas si tu as le tiens"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp Fallback Hotspot"
    password: "eobDwqbh6t9e"

captive_portal:

bluetooth_proxy:
  active: true

time:
  - platform: homeassistant
    id: homeassistant_time_5m
    on_time:
      - seconds: 0
        minutes: /5
        then:
          - switch.turn_off: ble_switch_com
          - delay: 20s
          - switch.turn_on: ble_switch_com

ble_client:
  - mac_address:  ${mac_justsalt}
    auto_connect: true
    id: JustSaltPro
    on_connect:
      then:
        - ble_client.numeric_comparison_reply:
            id: JustSaltPro
            accept: True


binary_sensor:
  - platform: ble_presence
    mac_address: ${mac_justsalt}
    name: Electolyseur

  - platform: template  
    id: InjPHM
    name: "Injection PH-"
  
  - platform: template  
    id: InjPHP
    name: "Injection PH+"

number:
  - platform: template
    id: orp_consigne_new
    name: "ORP Consigne"
    icon: "mdi:flash-triangle-outline"
    unit_of_measurement: "mV"
    min_value: 200
    max_value: 900
    step: 10
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              //float state = std::stof(id(orp_consigne_new).state);
              ESP_LOGD("ORPconsigne", "Option consigne change:  %f", id(orp_consigne_new).state);   
              uint8_t statehex = id(orp_consigne_new).state / 10;
              return {0x00, 0x06, 0x03, 0x35, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: orp_alarme_consigne
    name: "ORP Alarme Consigne"
    icon: "mdi:alarm"
    unit_of_measurement: "h"
    min_value: 12
    max_value: 96
    step: 6
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              //float state = std::stof(id(orp_consigne_new).state);
              ESP_LOGD("ORPalarmeconsigne", "Option consigne change:  %f", id(orp_alarme_consigne).state);   
              uint8_t statehex = id(orp_alarme_consigne).state;
              return {0x00, 0x06, 0x03, 0x37, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
         
  - platform: template
    id: ph_consigne
    name: "PH Consigne"
    icon: "mdi:ph"
    unit_of_measurement: "ph"
    min_value: 6.8
    max_value: 7.6
    step: 0.1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("PHconsigne", "Option consigne change:  %f", id(ph_consigne).state);   
              uint8_t statehex = id(ph_consigne).state * 10;
              return {0x00, 0x06, 0x03, 0x30, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        
  - platform: template
    id: vol_consigne
    name: "Volume Consigne"
    icon: "mdi:cup-water"
    unit_of_measurement: "m3"
    min_value: 10
    max_value: 200
    step: 10
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("volconsigne", "Option consigne change:  %f", id(vol_consigne).state);   
              uint8_t statehex = id(vol_consigne).state;
              return {0x00, 0x06, 0x03, 0x11, 0x02, 0x00, statehex, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: acide_consigne
    name: "acide Consigne"
    icon: "mdi:skull-crossbones-outline"
    unit_of_measurement: "%"
    min_value: 5
    max_value: 55
    step: 1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("acideconsigne", "Option consigne change:  %f", id(acide_consigne).state);   
              uint8_t statehex = id(acide_consigne).state;
              return {0x00, 0x06, 0x03, 0x32, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: production_consigne
    name: "production Consigne"
    icon: "mdi:cog-outline"
    unit_of_measurement: "%"
    min_value: 10
    max_value: 100
    step: 1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("productionconsigne", "Option consigne change:  %f", id(production_consigne).state);   
              uint8_t statehex = id(production_consigne).state;
              return {0x00, 0x06, 0x03, 0x33, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  - platform: template
    id: inversion_consigne
    name: "inversion Consigne"
    icon: "mdi:alarm"
    unit_of_measurement: "h"
    min_value: 2
    max_value: 24
    step: 1
    optimistic: true
    on_value: 
      then:
        - ble_client.ble_write:
            id: JustSaltPro
            service_uuid: ${service_uuid}
            characteristic_uuid: ${characteristic_uuid_write}
            value: !lambda |-
              ESP_LOGD("inversionconsigne", "Option consigne change:  %f", id(inversion_consigne).state);   
              uint8_t statehex = id(inversion_consigne).state;
              return {0x00, 0x06, 0x03, 0x39, 0x01, statehex, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


text_sensor:
  - platform: version
    name: ESPHome Version
  
  - platform: wifi_info
    ssid:
      name: WiFi
  
  - id: ble_name2
    name: "Name"
    platform: template 

  - id: version_logiciel
    name: "version logiciel"
    platform: template 
  
  - id: slave
    name: "Slave"
    platform: template 
   
  - id: idcode
    name: "ID Code"
    platform: template  

  - platform: template
    name: "MAC bt"
    id: JustSalt_macbt_textsensor
  
  - platform: template
    name: "nom bt"
    id: JustSalt_nombt_textsensor
  
  - platform: template
    name: "SN"
    id: JustSalt_sn_textsensor

  - platform: template
    name: "temp90"
    id: JustSalt_90_textsensor
  
  - platform: template
    name: "temp91"
    id: JustSalt_91_textsensor

  - platform: template
    name: "temp9D"
    id: JustSalt_9d_textsensor
  
  - platform: template
    name: "tempD0"
    id: JustSalt_d0_textsensor

  - platform: template
    name: "tempE1"
    id: JustSalt_e1_textsensor

  - platform: template
    name: "tempE2"
    id: JustSalt_e2_textsensor
      
  - platform: template
    name: "tempE4"
    id: JustSalt_e4_textsensor
  
  - platform: template
    name: "tempA3"
    id: JustSalt_a3_textsensor

  - platform: template
    name: "Date etalonage PH"
    id: JustSalt_temp12_textsensor

  - platform: template
    name: "Date etalonage ORP"
    id: JustSalt_temp13_textsensor
    

sensor:
  - platform: wifi_signal
    name: Wifi signal
    update_interval: 60s

  - platform: uptime
    name: Uptime
  
  - platform: template
    name: "temp02"
    id: JustSalt_temp02_sensor
    accuracy_decimals: 0
    on_value:
      then:
        - lambda: |- 
            if (id(sensor_state).state == 1) {
              uint16_t temphex02 = id(JustSalt_temp02_sensor).raw_state;
              //ESP_LOGD(" --- temp 02 str", "%d", temphex02);
              id(InjPHM).publish_state((bool)((temphex02 & 0x000A) ));
              id(InjPHP).publish_state((bool)((temphex02 & 0x000C) ));
              }

  - platform: template
    name: "temp03"
    id: JustSalt_temp03_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp08"
    id: JustSalt_temp08_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp0B"
    id: JustSalt_temp0b_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp0C"
    id: JustSalt_temp0c_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp0D"
    id: JustSalt_temp0d_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "Compteur Heure total de fonctionnement"
    id: JustSalt_temp0e_sensor
    accuracy_decimals: 0
    unit_of_measurement: "h"
  
  - platform: template
    name: "minutes de fonctionement"
    id: JustSalt_temp0f_sensor
    unit_of_measurement: "min"
    accuracy_decimals: 0

  - platform: template
    name: "temp10"
    id: JustSalt_temp10_sensor
    accuracy_decimals: 0
 
  - platform: template
    name: "temp1f"
    id: JustSalt_temp1f_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp28"
    id: JustSalt_temp28_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp29"
    id: JustSalt_temp29_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp2A"
    id: JustSalt_temp2a_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp31"
    id: JustSalt_temp31_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp50"
    id: JustSalt_temp50_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp51"
    id: JustSalt_temp51_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp5F"
    id: JustSalt_temp5f_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp69"
    id: JustSalt_temp69_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp6A"
    id: JustSalt_temp6a_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp8F"
    id: JustSalt_temp8f_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "temp92"
    id: JustSalt_temp92_sensor
    accuracy_decimals: 0
      
  - platform: template
    name: "temp93"
    id: JustSalt_temp93_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp94"
    id: JustSalt_temp94_sensor
    accuracy_decimals: 0
      
  - platform: template
    name: "temp9B"
    id: JustSalt_temp9b_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp9C"
    id: JustSalt_temp9c_sensor
    accuracy_decimals: 0

  - platform: template
    name: "temp9D"
    id: JustSalt_temp9d_sensor
    accuracy_decimals: 0

  - platform: template
    name: "tempB0"
    id: JustSalt_tempb0_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "tempD1"
    id: JustSalt_tempd1_sensor
    accuracy_decimals: 0
  
  - platform: template
    name: "tempFE"
    id: JustSalt_tempfe_sensor
    accuracy_decimals: 0

  - platform: ble_rssi
    mac_address:  ${mac_justsalt}
    name: "JustSalt RSSI"  

  - platform: template
    name: "Temperature eau"
    id: JustSalt_temperature_sensor
    unit_of_measurement: "°C"
    accuracy_decimals: 1
    state_class: measurement
    device_class: temperature
  
  - platform: template
    name: "pH"
    id: JustSalt_ph_sensor
    unit_of_measurement: "pH"
    accuracy_decimals: 1
    state_class: measurement
    icon: mdi:ph
  
  - platform: template
    name: "ORP"
    id: JustSalt_orp_sensor
    unit_of_measurement: "mV"
    accuracy_decimals: 0
    state_class: measurement
    device_class: voltage
  
  - platform: template
    name: "TDS"
    id: JustSalt_tds_sensor
    unit_of_measurement: "g/L"
    accuracy_decimals: 1
    state_class: measurement
    icon: mdi:water-opacity

  - platform: ble_client
    ble_client_id: JustSaltPro
    name: "traitement"
    id: sensor_state    
    service_uuid: ${service_uuid} #'09912756-7b32-4629-aeb1-b309d9a338ae'
    characteristic_uuid: ${characteristic_uuid} #'ef785c24-22bb-463d-b651-0b7445ba091c'
    type: characteristic
    # update_interval: 2m
    notify: True
    lambda: |-     
      std::string value2(x.begin(), x.end());
      std::string rawhex = format_hex_pretty((uint8_t *) value2.c_str(), value2.size()).c_str();
      //ESP_LOGW("raw_hex_boucle", "-- Recep Debut --");
      //ESP_LOGD("raw_hex", "%s", rawhex.c_str());
      rawhex.erase(std::remove(rawhex.begin(), rawhex.end(), '.'), rawhex.end());
      
      int index = 3;

      while (index +2 < x.size()) {
        uint8_t idvaleur = x[index];
        int taillevaleur = x[index + 1 ];
      
        switch (idvaleur) {
          case 0x00: { 
            }break;
      
          case 0x01: {
            uint8_t phhex = x[index + 2];
            float ph = static_cast<float>(phhex)/10;
            id(JustSalt_ph_sensor).publish_state(ph);
            }break;

          case 0x02: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp02_sensor).publish_state(temp);
            }break;

          case 0x03: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp03_sensor).publish_state(temp);
            }break;

          case 0x06: {
            uint16_t orphex = ((x[index + 2]<< 8) + (x[index +3]));
            float orp = static_cast<float>(orphex);
            id(JustSalt_orp_sensor).publish_state(orp);
            }break;

          case 0x08: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp08_sensor).publish_state(temp);
            }break;

          case 0x09: {
            uint16_t tempeauhex = ((x[index + 2]<< 8) + (x[index +3]));
            float tempeau = static_cast<float>(tempeauhex)/10;
            id(JustSalt_temperature_sensor).publish_state(tempeau);
            }break;
          
          case 0x0A: {
            uint8_t selhex = x[index + 2] ;
            float sel = static_cast<float>(selhex)/10;
            id(JustSalt_tds_sensor).publish_state(sel);
            }break;

          case 0x0B: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0b_sensor).publish_state(temp);
            }break;
          
          case 0x0C: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0c_sensor).publish_state(temp);
            }break;

          case 0x0D: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0d_sensor).publish_state(temp);
            }break;

          case 0x0E: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0e_sensor).publish_state(temp);
            }break;

          case 0x0F: {
            uint8_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp0f_sensor).publish_state(temp);
            }break;
          
          case 0x10: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp10_sensor).publish_state(temp);
            }break;

          case 0x11: {
            uint16_t volhex = ((x[index + 2]<< 8) + (x[index +3]));
            float vol = static_cast<float>(volhex);
            id(vol_consigne).publish_state(vol);
            }break;
          
          case 0x12: {
            uint8_t dayphex = (x[index + 3]);
            uint8_t monthphex = (x[index + 4]);
            uint8_t yearphex = (x[index +5]);
            int dayf = static_cast<int>(dayphex);
            int monthf = static_cast<int>(monthphex);
            int yearf = static_cast<int>(yearphex);
            std::string datestr =  std::to_string(dayf) + "/" + std::to_string(monthf) + "/20" + std::to_string(yearf);
            id(JustSalt_temp12_textsensor ).publish_state(datestr);
            }break;

          case 0x13: {
            uint8_t dayphex = (x[index + 3]);
            uint8_t monthphex = (x[index + 4]);
            uint8_t yearphex = (x[index +5]);
            int dayf = static_cast<int>(dayphex);
            int monthf = static_cast<int>(monthphex);
            int yearf = static_cast<int>(yearphex);
            std::string datestr =  std::to_string(dayf) + "/" + std::to_string(monthf) + "/20" + std::to_string(yearf);
            id(JustSalt_temp13_textsensor ).publish_state(datestr);
            }break;

          case 0x1F: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp1f_sensor).publish_state(temp);
            }break;
          
          case 0x28: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp28_sensor).publish_state(temp);
            }break;
          
          case 0x29: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp29_sensor).publish_state(temp);
            }break;
        
          case 0x2A: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp2a_sensor).publish_state(temp);
            }break;
          
          case 0x30: {
            uint8_t phchex = x[index + 2] ;
            float phc = static_cast<float>(phchex)/10;
            auto phcstr = value_accuracy_to_string (phc,1);
            id(ph_consigne).publish_state(phc);
            }break;
          
          case 0x31: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp31_sensor).publish_state(temp);
            }break;         

          case 0x32: {
            uint8_t acidehex = x[index + 2] ;
            float acide = static_cast<float>(acidehex);
            id(acide_consigne).publish_state(acide);
            }break;
          
          case 0x33: {
            uint8_t prodhex = x[index + 2] ;
            float prod = static_cast<float>(prodhex);
            id(production_consigne).publish_state(prod);
            }break;

          case 0x35: {
            uint8_t orpchex = x[index + 2] ;
            float orpc = static_cast<float>(orpchex)*10;
            id(orp_consigne_new).publish_state(orpc);
            }break;
          
          case 0x37: {
            uint8_t alarmeorphex = x[index + 2] ;
            float alarmeorp = static_cast<float>(alarmeorphex);
            id(orp_alarme_consigne).publish_state(alarmeorp);
            }break;
 
          case 0x39: {
            uint8_t inversionhex = x[index + 2] ;
            float inversionval = static_cast<float>(inversionhex);
            id(inversion_consigne).publish_state(inversionval);
            }break;

          case 0x50: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp50_sensor).publish_state(temp);
            }break;

          case 0x51: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp51_sensor).publish_state(temp);
            }break;

          case 0x5F: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp5f_sensor).publish_state(temp);
            }break;
          
          case 0x69: {
            uint32_t temphex = (x[index + 2]<< 24) + (x[index + 3]<< 16)+ (x[index + 4]<< 8) + (x[index +5]);
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp69_sensor).publish_state(temp);
            }break;

          case 0x6A: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp6a_sensor).publish_state(temp);
            }break;

          case 0x8F: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp8f_sensor).publish_state(temp);
            }break;
            
          case 0x90: {
            // 90.08.00.00.00.00.00.00.00.14.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            id(JustSalt_90_textsensor).publish_state(tempstring.c_str());
            }break;

          case 0x91: {
            //  91.08.00.00.00.00.00.06.6F.C3.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            id(JustSalt_91_textsensor).publish_state(tempstring.c_str());
            }break;
          
          case 0x92: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp92_sensor).publish_state(temp);
            }break;

          case 0x93: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp93_sensor).publish_state(temp);
            }break;

          case 0x94: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp94_sensor).publish_state(temp);
            }break;

          case 0x95: {
            uint32_t idcodehex = (x[index + 2]<< 24) + (x[index + 3]<< 16)+ (x[index + 4]<< 8) + (x[index +5]);
            float idcodefloat = static_cast<float>(idcodehex);
            std::string idcodestr = value_accuracy_to_string (idcodefloat,0);
            id(idcode).publish_state(idcodestr);
            }break;
          
          case 0x96: {
            std::string verlog = rawhex.substr((index + 2 )* 2, 2) + "." + rawhex.substr((index + 2 )* 2 + 2, 2);
            id(version_logiciel).publish_state(verlog);
            }break;
          
          case 0x97: {
            std::string slaveval = rawhex.substr((index + 2 )* 2, 2) + "." + rawhex.substr((index + 2 )* 2 + 2, 2);
            id(slave).publish_state(slaveval);
            }break;

          case 0x99: {
            //99.16.47.45.4E.5F.30.35.32.32.2D.30.34.33.39.35.33.2D.30.30.33.00.00.00.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            id(JustSalt_nombt_textsensor).publish_state(tempstring.c_str());
            }break;

          case 0x9A: {
            //9A.10.30.35.32.32.2D.30.34.33.39.35.33.2D.30.30.33.00.
            std::string tempstring = value2.substr((index + 2 ), taillevaleur);
            id(JustSalt_sn_textsensor).publish_state(tempstring.c_str());
            }break;

          case 0x9B: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp9b_sensor).publish_state(temp);
            }break;

          case 0x9C: {
            uint16_t temphex = ((x[index + 2]<< 8) + (x[index +3]));
            float temp = static_cast<float>(temphex);
            id(JustSalt_temp9c_sensor).publish_state(temp);
            }break;

          case 0x9D: {
            //  9D.08.00.00.00.00.00.00.01.FF
            std::string tempstring = rawhex.substr((index + 2 )* 2, 8);
            id(JustSalt_9d_textsensor).publish_state(tempstring);
            }break;
          
          case 0xA3: {
            //  E1.0F.18.04.11.11.00.33.00.00.88.00.F8.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 15);
            id(JustSalt_a3_textsensor).publish_state(tempstring);
            }break;
          
          case 0xB0: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_tempb0_sensor).publish_state(temp);
            }break;
  
          case 0xB1: {
            std::string tempstring = rawhex.substr((index + 2 )* 2, 12);
            id(JustSalt_macbt_textsensor).publish_state(tempstring);
            }break;
          
          case 0xD0: {
            //D0.06.30.00.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 6);
            id(JustSalt_d0_textsensor).publish_state(tempstring);
            }break;

          case 0xD1: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_tempd1_sensor).publish_state(temp);
            }break;
   
          case 0xFE: {
            uint8_t temphex = x[index + 2];
            float temp = static_cast<float>(temphex);
            id(JustSalt_tempfe_sensor).publish_state(temp);
            }break;
  
          case 0xE1: {
            //  E1.0F.18.04.11.11.00.33.00.00.88.00.F8.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 30);
            id(JustSalt_e1_textsensor).publish_state(tempstring);
            }break;
            
          case 0xE2: {
            // E2.0F.18.04.16.0A.22.10.00.00.00.41.3E.DC.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 30);
            id(JustSalt_e2_textsensor).publish_state(tempstring);
            }break;

          case 0xE4: {
            // E4.0F.18.04.12.15.00.00.46.00.0B.13.00.00.00.00.00
            std::string tempstring = rawhex.substr((index + 2 )* 2, 30);
            id(JustSalt_e4_textsensor).publish_state(tempstring);
            }break;

          default: {
              ESP_LOGW("raw_hex_boucle", "idvaleur Non implementee %d", idvaleur);
            };
          }
        index = index + 2 + taillevaleur ;
      }
      //ESP_LOGW("raw_hex_boucle", "-- Recep FIN --");
      return 1;


switch:      
  - platform: restart
    name: JustSalt_Gatway restart    

  - platform: ble_client
    id: ble_switch_com
    ble_client_id: JustSaltPro
    name: "Enable com JustSalt"