Skip to content

Vista25IT (20SE) code usage / migration #153

@lorenzodeveloper

Description

@lorenzodeveloper

Hi Alain,

I hope you're doing well! It’s been a while since last time.

I recently tried updating the ESPHome add-on in Home Assistant to version 2025.X, but I can no longer communicate with my panel. It seems the issue stems from:

  1. Breaking changes in ESPHome that affect the old YAML format.
  2. The new code format used for Vista20P, which differs from my setup.

I noticed that the main VistaAlarm.yaml example references the Vista20P code. However, I have a Vista 25IT (we figured together that it's basically the Vista 20SE), and the vista20SE.yaml file is still using the old format. This mismatch prevents my system from working after the update leading to no communication (when using 20P code) or no possibility to update (when using old yaml format).

Could you provide the updated code or migration procedure for vista20SE as well?
For the moment I'm keeping the addon to version 2024.12.4, as it's the last compatible, so there's no rush.

Thanks in advance for your help!
Best regards,

Lorenzo

Setup

  • Vista25IT
  • ESP8266 D1 Mini

Old YAML file I'm using

#for documentation see project at https://github.com/Dilbert66/esphome-VistaECP
substitutions:
  systemName: "vistaalarm"
  accessCode: !secret access_code #Only comes into effect if needed for arming and quickarm is not set
  keypadAddr: "36" #set this to an unused keypad address slot. Make sure to enable it in  your vista panel programming

  rfSerialLookup: "1234567:16:20,..."

  DEBUG_FLAG: "1"

  ##esp8266
  rxPin: "5" #GPIO pin to use for data receive (yellow line) D1
  txPin: "4" #GPIO pin to use for data transmit (green line) D2
  monitorPin: "14" #GPIO pin to use for monitoring module traffic such as RF or Expanders . Set to -1 to disable - D5
  
  # D1 R2 wemos pinout: https://cyaninfinite.com/getting-started-with-the-wemos-d1-esp8266-wifi-board/#Pinouts 
  
  expanderAddr1: "0" # 1st zone expander emulator (4229) address to use . Set to 0 to disable. 
  expanderAddr2: "0" # 2nd expander emulator address to use . Set to 0 to disable. 
  
  relayAddr1: "0" # relay module emulation (4204) addresses. Set to 0 to disable
  relayAddr2: "0"
  relayAddr3: "0"
  relayAddr4: "0"
  
  TTL: "30000"  # time  to live  in ms for zone/fire status before expiring;
  quickArm: "true"
  lrrSupervisor: "true" # set to true if we don't have an LRR monitoring supervisor we can emulate one to get the statuses
  
globals:
       #persistent storage variables
    - id: zoneStates  #persistant storage for zone states in case of reboot
      type: int
      restore_value: yes
    - id: zoneAlarms  #persistant storage for zone states in case of reboot
      type: int
      restore_value: yes
    - id: zoneBypass  #persistant storage for zone states in case of reboot
      type: int
      restore_value: yes
    - id: zoneChecks  #persistant storage for zone states in case of reboot
      type: int
      restore_value: yes      
    - id: lrrCode  #persistant storage for last lrr message in case of reboot
      type: int
      restore_value: yes      
  
      
esphome:
  name: $systemName
  includes:
    - vista20SE/

esp8266:
  board: d1_mini

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

  ap:
    ssid: "$systemName"
    password: !secret ap_wifi_password

logger:
  baud_rate: 115200
  level: DEBUG
  
api:
   encryption:
     key: !secret encryption_key   
   
ota:
   platform: esphome
   password: !secret ota_password
   on_begin:
    - lambda: |-
        disconnectVista();


custom_component:
- lambda: |-
    auto VistaECP = new vistaECPHome($keypadAddr,$rxPin,$txPin,$monitorPin);
    VistaECP->rfSerialLookup="$rfSerialLookup";
    VistaECP->accessCode="$accessCode";
    VistaECP->quickArm=$quickArm;
    VistaECP->expanderAddr1=$expanderAddr1; //zone expander
    VistaECP->expanderAddr2=$expanderAddr2;
    VistaECP->relayAddr1=$relayAddr1; //relay module 
    VistaECP->relayAddr2=$relayAddr2;
    VistaECP->relayAddr3=$relayAddr3; 
    VistaECP->relayAddr4=$relayAddr4;     
    VistaECP->lrrSupervisor=$lrrSupervisor;
    VistaECP->TTL=$TTL;
    VistaECP->debug=$DEBUG_FLAG;
    VistaECP->onSystemStatusChange([&](std::string statusCode) {
       id(system_status).publish_state(statusCode);
    });
    VistaECP->onLrrMsgChange([&](std::string msg) {
        id(m1).publish_state(msg); 
    }); 
    VistaECP->onRfMsgChange([&](std::string msg) {
        id(rf1).publish_state(msg); 
    });    
    VistaECP->onLine1DisplayChange([&](std::string msg) {
        id(l1).publish_state(msg); 
    });  
    VistaECP->onLine2DisplayChange([&](std::string msg) {
        id(l2).publish_state(msg); 
    }); 
    VistaECP->onBeepsChange([&](std::string beeps) {
        id(beep1).publish_state(beeps); 
    });      
    VistaECP->onStatusChange([&](sysState led,bool open) {
      switch(led) {
        case sfire: id(fire).publish_state(open);break;
        case salarm: id(alarm1).publish_state(open);break;
        case strouble: id(trouble).publish_state(open);break;
        case sarmedstay: id(stay).publish_state(open);break;
        case sarmedaway: id(away).publish_state(open);break;
        case sinstant: id(instant).publish_state(open);break; 
        case sready: id(ready).publish_state(open);break; 
        case sac: id(ac).publish_state(open);break;          
        case sbypass: id(bypass).publish_state(open);break;  
        case schime: id(chime).publish_state(open);break;
        case sbat: id(bat).publish_state(open);break;
        case scheck: id(check).publish_state(open);break;
        case sarmednight: id(night).publish_state(open);break;   
        case sarmed: id(armed).publish_state(open);break;       
        default: break;
        }
    });
    VistaECP->onZoneStatusChange([&](uint8_t zone, std::string open) {
      switch (zone) {
        
        case 3: id(z3).publish_state(open); break;
        case 4: id(z4).publish_state(open); break;
        case 8: id(z8).publish_state(open); break;

        case 10: id(z10).publish_state(open); break;
        //...
      }
    }); //you can add more zones above . Also add the text sensor entry below
    
    VistaECP->onRelayStatusChange([&](uint8_t addr,uint8_t zone,bool open) {
     switch(addr) {
     case 12: switch (zone) {
                case 1: id(r1).publish_state(open); break;
                case 2: id(r2).publish_state(open); break;
              }
              break;
      case 13: break;
      }
    });  //add as many case and switch statements as needed to control your binary sensor outputs      
    return {VistaECP};

binary_sensor:
   
    #system status indicator definitions
  - platform: template
    id: trouble
    name: "$systemName Trouble"
    #device_class: problem
    
  - platform: template
    id: bypass
    name: "$systemName Bypass"
    
  - platform: template
    id: away
    name: "$systemName Away"
    
  - platform: template
    id: armed
    name: "$systemName Armed"    
    
  - platform: template
    id: stay
    name: "$systemName Stay"
    
  - platform: template
    id: instant
    name: "$systemName Instant"
    
  - platform: template
    id: night
    name: "$systemName Night"
    
  - platform: template
    id: ac
    name: "$systemName AC"
    device_class: plug  
    
  - platform: template
    id: chime
    name: "$systemName Chime"
    
  - platform: template
    id: check
    name: "$systemName Check"
    device_class: problem  

  - platform: template
    id: alarm1
    name: "$systemName Alarm"
    
  - platform: template
    id: bat
    name: "$systemName Battery"
    device_class: problem
    
  - platform: template
    id: fire
    device_class: smoke
    name: "$systemName Fire"

  - platform: template
    id: ready
    name: "$systemName Ready"

    
    #relay module channels add as many as you need.  To hide, comment out the name: attribute
  - platform: template
    id: r1
    name: "$systemName Relay1"

  - platform: template
    id: r2
    name: "$systemName Relay2"   
   
    #zone definitions.  Add more (also add to the switch statment above). To hide, comment out the name: attribute
text_sensor:
    #zone definitions
  - platform: template
    id: z8
    name: "$systemName Manomissione"

  - platform: template
    id: z10
    name: "$systemName ..."


    #system status 
  - platform: template
    id: system_status
    name: "$systemName System Status"
    icon: "mdi:shield"

  - platform: template
    id: m1
    name: "$systemName Lrr Msg"
    icon: "mdi:alert-box"
    
  - platform: template
    id: rf1
    name: "$systemName RF Msg"
    icon: "mdi:alert-box"    

  - platform: template
    id: l1
    name: "$systemName Line1"
 

  - platform: template
    id: l2
    name: "$systemName Line2"
    
  - platform: template
    id: beep1
    name: "$systemName Beeps"    

switch:
  - platform: template
    name: "$systemName Connection"
    id: connection_status_switch
    lambda: |-
      return vista.keybusConnected;
    icon: "mdi:shield-link-variant"
    turn_on_action:
      - switch.toggle: restart_switch
    turn_off_action:
      - lambda: |-
          disconnectVista();
  - platform: restart
    id: restart_switch

Conversion attempt

#for documentation see project at https://github.com/Dilbert66/esphome-VistaECP
substitutions:
  name: "vistaalarm" #unique network name, system name
  friendlyName: "Vista Alarm"  #used as the friendly name of your application in HomeAssistant
  panelId: "VistaAlarm"         #used as the service variable name.
  
vista_alarm_panel:
  id: $panelId
  accesscode: !secret access_code #Only comes into effect if needed for arming and quickarm is not set
  maxzones: "48" # ?
  maxpartitions: "1" # ?

  rfseriallookup: "1234567:16:20,..." # serial1:loop#:zone1,serial2:loop#:zone2
 
  defaultpartition: "1" #set to your main partition
  vistadebuglevel: "3" #component debug level for messages

  #assign a new virtual keypad address to each active partition using programs *190 - *196
  #and enter it below.  For unused partitions, use 0 as the keypad address.
  keypadaddr1: "36" #partition 1 virtual keyapd
  keypadaddr2: "0" #partition 2 virtual keypad. set to 0 to disable
  keypadaddr3: "0" #partition 3 virtual keypad. set to 0 to disable
  
  autopopulate: true # auto populate seen active zones
  
  ##esp8266
  rxpin: "5" #GPIO pin to use for data receive (yellow line) 
  txpin: "4" #GPIO pin to use for data transmit (green line)
  monitorpin: "14" #GPIO pin to use for monitoring module traffic such as RF or Expanders . Set to -1 to disable
  
  
  expanderaddr1: "0" # 1st zone expander emulator (4229) address to use . Set to 0 to disable. 
  expanderaddr2: "0" # 2nd expander emulator address to use . Set to 0 to disable. 
  
  relayaddr1: "0" # relay module emulation (4204) addresses. Set to 0 to disable
  relayaddr2: "0"
  relayaddr3: "0"
  relayaddr4: "0"
  
  ttl: "30000"  # time  to live  in ms for zone/fire status before expiring;
  quickarm: "true"
  lrrsupervisor: "true" # set to true if we don't have an LRR monitoring supervisor  we can emulate one to get the statuses
  
  clean_build: "false" #default is false.  only set to true if getting duplication errors in linking step. Once you compile, reset it back to false.  

esp8266:    
  board: d1_mini
  framework:
    version: recommended

#location of alarm panel code.  You can use the github release version  or 
#copy the code to directory "my_components" in your main esphome directory
# see here for more info: https://esphome.io/components/external_components    
external_components:
  - source: github://Dilbert66/esphome-components@main # vista20P
  #- source:  my_components #uncomment to use local directory  
    components: [vista_alarm_panel,binary_sensor,text_sensor] 
    refresh: 10min
  
esphome:
  name: $name
  friendly_name: $friendlyName
  includes: # probably not working
    - vista20SE/ 
    
# output sympols to output.map for debugging. you can remove if not needed
  platformio_options:
    build_flags: 
        - "-Wl,-Map,output.map"  

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

  ap:
    ssid: "$name"
    password: !secret wifi_password

logger:
  baud_rate: 115200
  level: debug

api:
   encryption:
     key: !secret encryption_key   

       
safe_mode: 

ota:
   password: !secret ota_password
   platform: esphome
   #on_begin: #disabled due to bug in esphome
       #switch.turn_off: connection_status_switch 

time:
 - platform: sntp


######################################################################## 
# Converted binary and text sensors to new format
binary_sensor:

### zone sensors ###
# Open/close status for each zone
  - platform: template
    id_code: z8
    name: "... (z8)"
    publish_initial_state: true       

  - platform: template
    id_code: z10
    name: "... (z10)"
    publish_initial_state: true    

### Non-zone sensors ###
  - platform: template
    id_code: trbl_1
    name: "Trouble (trbl_1)"
    device_class: problem
    publish_initial_state: true

  - platform: template
    id_code: byp_1
    name: "Bypass (byp_1)"
    publish_initial_state: true

  - platform: template
    id_code: arma_1
    name: "Away (arma_1)"
    publish_initial_state: true

  - platform: template
    id_code: arm_1
    name: "Armed (arm_1)"
    publish_initial_state: true

  - platform: template
    id_code: arms_1
    name: "Stay (arms_1)"
    publish_initial_state: true

  - platform: template
    id_code: armi_1
    name: "Instant (armi_1)"
    publish_initial_state: true

  - platform: template
    id_code: armn_1
    name: "Night (armn_1)"
    publish_initial_state: true

  - platform: template
    id_code: ac
    name: "AC (ac)"
    device_class: plug
    publish_initial_state: true

  - platform: template
    id_code: chm_1
    name: "Chime (chm_1)"
    publish_initial_state: true

  - platform: template
    id_code: chk_1
    name: "Check (chk_1)"
    device_class: problem
    publish_initial_state: true

  - platform: template
    id_code: alm_1
    name: "Alarm (alm_1)"
    publish_initial_state: true

  - platform: template
    id_code: bat
    name: "Battery (bat)"
    device_class: problem
    publish_initial_state: true

  - platform: template
    id_code: fire_1
    name: "Fire (fire_1)"
    device_class: smoke
    publish_initial_state: true

  - platform: template
    id_code: r121
    name: "Relay1 (r121)"
    publish_initial_state: true

  - platform: template
    id_code: r122
    name: "Relay2 (r122)"
    publish_initial_state: true

#### Text Sensors ####
text_sensor:

  - platform: template
    id_code: ss_1
    name: "System Status (ss_1)"
    icon: "mdi:shield"

  - platform: template
    id_code: lrr_1
    name: "Lrr Msg (lrr_1)"
    icon: "mdi:alert-box"

  - platform: template
    id_code: rf_1
    name: "RF Msg (rf_1)"
    icon: "mdi:alert-box"

  - platform: template
    id_code: l1
    name: "Line1 (l1)"

  - platform: template
    id_code: l2
    name: "Line2 (l2)"

  - platform: template
    id_code: beep_1
    name: "Beeps (beep_1)"
   
  - platform: template
    name: "Zone Status (zs)" 
    id_code: zs  


 # end of panel sensor setup - no need to edit anything below.
##############################################################################
switch:
  - platform: template
    name: "$name Connection"
    id: connection_status_switch
    lambda: |-
      return vista.keybusConnected;
    icon: "mdi:shield-link-variant"
    turn_on_action:
      - switch.toggle: restart_switch
    turn_off_action:
      - lambda: |-
          disconnectVista();
  - platform: restart
    id: restart_switch
  - platform: safe_mode
    name: "Safe Mode"   

debug:
  update_interval: 300s

sensor:
  - platform: debug
    free:
      name: "Heap Free"
    block:
      name: "Heap Max Block"
    loop_time:
      name: "Loop Time"   
    #fragmentation: #esp8266 only
     # name: "Heap Fragmentation"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions