Automating a Westinghouse generator to work with the EG4 18kPV

For those managing solar inverters like the EG4 18kPV that utilizes a two wire contact closure and looking to streamline wireless generator backup functionality, here’s how I set up my Westinghouse WGen9500DF to work seamlessly with my EG4 inverter. By using Home Assistant, an ESP32, and a Broadlink 433MHz transmitter, I can automatically trigger my generator based on the inverter’s contact closure output, creating a fully automated power backup system. This solution can be used by any inverter with a generator input and a two wire dry contact closure.

Option 1

Screenshot

Equipment Needed

  1. EG4 18kPV Hybrid Inverter – Provides a contact closure output. SanTan Solar link
  2. Westinghouse WGen9500DF Generator – A dual-fuel generator that’s powerful enough to sustain a home’s essential circuits. Amazon link
  3. ESP32 Board – Monitors the EG4’s contact closure and wirelessly communicates with Home Assistant over WiFi. Amazon link
  4. Broadlink 433MHz Transmitter – Sends start and stop commands to the generator. Amazon link
  5. Home Assistant – A Raspberry Pi-based smart home hub that hosts automation scripts. Amazon link
  6. 18650 Battery UPS – For uninterrupted power to the ESP32. Amazon link
  7. Enclosure – ESP and 18650 battery case. Amazon link
  8. Terminal Block Connector – The connector to connect the two wire from the EG4 to the ESP32. Amazon link
  9. Micro USB
  10. USB – power adapter. Amazon link
  11. APC UPS – Powers the Broadlink transmitter, WiFi and Raspberry Pi, keeping the system resilient during outages. (When dark starts are critical) Amazon link
  12. Cat5 cable – you can use what you have but I would recommend solid copper. Amazon link
  13. Optional Raspberry Pi dev kit – This includes LEDs and a bread board to validate everything on. Amazon link

Guide

Prerequisite: There a plenty of guides out there for basic setups for Home Assistant and ESPHome.

Before diving into Step 1, make sure you have the following components set up and functioning:

  1. Home Assistant Instance
    • You’ll need a working instance of Home Assistant, preferably on a Raspberry Pi or any compatible device. Home Assistant will be the central hub for automation, controlling the start and stop scripts for the generator based on the EG4 inverter’s output.

Step 1: Configure the Broadlink 433MHz Transmitter

To start and stop the Westinghouse generator wirelessly, use a Broadlink 433MHz transmitter:

  1. Install Home Assistant Broadlink integration to send start and stop signals via the Broadlink transmitter when the ESP32 initiates a trigger event.
  2. Pair the Broadlink transmitter with your generator’s wireless remote start functionality. Test this to ensure reliable communication. You can do this by using learning the RF commands following the Broadlink integration guide.

Step 2: Create Home Assistant Automations

In Home Assistant, set up two scripts:

  • Start Generator Script: Runs when the ESP32 detects a closed contact from the EG4, instructing Home Assistant to send the start command. Settings, automation, scripts.
alias: Generator Start
sequence:
  - data:
      num_repeats: 2
      delay_secs: 10
      hold_secs: 0
      device: Generator
      command: Start
    target:
      device_id: 69067c3eb22ffb2384cc92313bf8a262
    action: remote.send_command
  - action: notify.mobile_app_titan
    metadata: {}
    data:
      message: Generator START script, ran.
  - target:
      entity_id: input_boolean.generator_status
    action: input_boolean.turn_on
    data: {}
mode: single
icon: mdi:power
  • Stop Generator Script: Executes when the contact opens, stopping the generator.
alias: Generator Stop
sequence:
  - data:
      num_repeats: 1
      delay_secs: 0.4
      hold_secs: 0
      device: Generator
      command: Stop
    target:
      device_id: 69067c3eb22ffb2384cc92313bf8a262
    action: remote.send_command
  - action: notify.mobile_app_titan
    metadata: {}
    data:
      message: Generator STOP script, ran.
  - action: input_boolean.turn_off
    target:
      entity_id:
        - input_boolean.generator_status
    data: {}
mode: single
icon: mdi:stop-circle

Step 3: Integrate ESPHome with Home Assistant

To wirelessly control the generator, set up the ESP32 in Home Assistant:

  1. Install ESPHome integration in Home Assistant.
  2. Once you create the device you will need to add it in the integration page (settings, devices and services, ESPHome, configure on generator-control) select the check box “Allow the device to perform Home Assistant actions.” to allow the api calls to function.
  3. Make sure you have a secrets.yaml config in ESPHome, this can store your WiFi credentials. Alternatively you can put these details in the ESP32 yaml itself.
# Your Wi-Fi SSID and password
wifi_ssid: "Some network name"
wifi_password: "password_4_u_wifi"

Step 4: Set up the ESP32 to Monitor the Contact Closure

Program your ESP32 to detect the EG4’s contact closure output. This output acts as a API call that when conditions have met the criteria for the generator to start, the call will be sent to home assistant to run the start generator script. Here’s an overview of the steps:

  • Program the ESP32 to monitor the contact closure using GPIO pins.
    • In home assistant browse to the integration ESPHome
      • Click the new device button
        • Use name “Generator Control”
          • Select device ESP32
          • Click Install and then manual download the configuration
    • Got to https://web.esphome.io in chrome browser.
      • Plugin the ESP32 to your computer with the USB cable that came with the ESP32s (to make sure that data and power pins are connected).
      • Click connect and select the ESP32 via USB.
      • Choose the downloaded zip that home assistant generated and load it. This will take a few minutes.
    • The ESP32 will have joined your wireless home network and you should now see your device show up in home assistant under ESPHome.
      • Click edit, and load the config below (careful not to overwrite your encryption key and ESP OTA password)
esphome:
  name: generator-control
  friendly_name: generator-control

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API with encryption
api:
  encryption:
    key: ""
  services:
    - service: generator_start
      then:
        - homeassistant.service:
            service: script.generator_stop  # Call Home Assistant script
    - service: generator_stop
      then:
        - homeassistant.service:
            service: script.generator_start  # Call Home Assistant script

ota:
  - platform: esphome
    password: ""

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Generator-Control"
    password: ""

captive_portal:

# Use GPIO13 for relay input (safe pin on ESP32)
binary_sensor:
  - platform: gpio
    pin:
      number: GPIO13
      mode: INPUT_PULLUP
    name: "Inverter Relay"
    id: inverter_relay
    filters:
      - delayed_on: 50ms
      - delayed_off: 50ms
    on_press:
      then:
        - homeassistant.service:
            service: script.generator_stop  # Directly trigger Home Assistant script
    on_release:
      then:
        - homeassistant.service:
            service: script.generator_start  # Directly trigger Home Assistant script

# Optional: Status LED using GPIO4
status_led:
  pin:
    number: GPIO4
    inverted: yes
  • Power the ESP32 using an 18650 battery, creating a mini UPS setup to ensure it remains operational during power interruptions.
    • Use GND and pin D4 for the LED
    • Use GND and pin D13 for the contact closure
Board pinout
Connecting to the normally open contact on the EG4. (NO1 and CO1)

Step 5: Testing & Fine-Tuning

After setting up the components, thoroughly test your system. Ensure:

  • The ESP32 consistently detects contact closures.
  • Home Assistant reliably sends commands through the Broadlink transmitter.
  • Your APC UPS provides sufficient runtime for the critical components (ESP32, Broadlink, and Raspberry Pi) during power outages.
  • You can mock a power outage scenario by increase the Generator start SOC to 50% and shutting off grid-power input. For instance in your battery drops below that state of charge (50% SOC) the generator contact will close and the generator will start and begin providing power to your system. When grid power is returned the contact will open and the generator will shutoff.

Option 2 (Optional) no ESP32

Equipment Needed:

  1. EG4 18kPV Hybrid Inverter – Provides a contact closure output. SanTan Solar link
  2. Westinghouse WGen9500DF Generator – A dual-fuel generator that’s powerful enough to sustain a home’s essential circuits. Amazon link
  3. Broadlink 433MHz Transmitter – Sends start and stop commands to the generator. Amazon link
  4. Home Assistant – A Raspberry Pi-based smart home hub that hosts automation scripts. Amazon link
  5. SolarAssistant – Software for monitoring and managing the EG4 inverter.
  6. MQTT Broker – For communication between SolarAssistant and Home Assistant (can be hosted on Home Assistant or separately).

Prerequisite: Home Assistant.

Before diving into Step 1, make sure you have the following components set up and functioning:

  1. Home Assistant Instance

Steps:

1. Set Up SolarAssistant with MQTT

  • Install SolarAssistant on a Raspberry Pi or compatible device and configure it to monitor your EG4 inverter.
  • Enable the MQTT feature in SolarAssistant:
    • Navigate to SolarAssistant’s settings and enable MQTT integration.
    • Configure the MQTT broker settings, pointing to your Home Assistant’s MQTT broker.

2. Set Up MQTT Integration in Home Assistant

  • Install the MQTT integration in Home Assistant:
    • Go to Settings > Devices & Services > Add Integration and search for “MQTT.”
    • Enter your broker details to connect.
  • Confirm that data from SolarAssistant is being received in Home Assistant. For instance:
    • Topic: solar_assistant/total/battery_state_of_charge
      • sensor.luxpower_lxp_battery_state_of_charge (Battery state of charge).
    • Topic: solar_assistant/inverter_1/grid_voltage
      • sensor.luxpower_lxp_grid_voltage (Grid voltage).

Add this to your configuration.yaml or sensors.yaml (depending on your setup)

mqtt:
  sensor:
# solar_assistant
    - name: "Shutdown Battery Capacity"
      unique_id: "shutdown_battery_capacity"
      state_topic: "solar_assistant/inverter_1/shutdown_battery_capacity"
      unit_of_measurement: "%"
  
    - name: "Serial Number"
      unique_id: "serial_number"
      state_topic: "solar_assistant/inverter_1/serial_number"
      unit_of_measurement: ""
  
    - name: "Shutdown Battery Voltage"
      unique_id: "shutdown_battery_voltage"
      state_topic: "solar_assistant/inverter_1/shutdown_battery_voltage"
      unit_of_measurement: "V"
  
    - name: "Load Power Essential"
      unique_id: "load_power_essential"
      state_topic: "solar_assistant/inverter_1/load_power_essential"
      unit_of_measurement: "W"
  
    - name: "Load Power Essential 2"
      unique_id: "load_power_essential_2"
      state_topic: "solar_assistant/inverter_1/load_power_essential_2"
      unit_of_measurement: "W"
  
    - name: "Grid Frequency"
      unique_id: "grid_frequency"
      state_topic: "solar_assistant/inverter_1/grid_frequency"
      unit_of_measurement: "Hz"
  
    - name: "PV Current 1"
      unique_id: "pv_current_1"
      state_topic: "solar_assistant/inverter_1/pv_current_1"
      unit_of_measurement: "A"
  
    - name: "Grid Power CT"
      unique_id: "grid_power_ct"
      state_topic: "solar_assistant/inverter_1/grid_power_ct"
      unit_of_measurement: "W"
  
    - name: "Battery Voltage"
      unique_id: "battery_voltage"
      state_topic: "solar_assistant/inverter_1/battery_voltage"
      unit_of_measurement: "V"
  
    - name: "PV Power 3"
      unique_id: "pv_power_3"
      state_topic: "solar_assistant/inverter_1/pv_power_3"
      unit_of_measurement: "W"
  
    - name: "PV Current 2"
      unique_id: "pv_current_2"
      state_topic: "solar_assistant/inverter_1/pv_current_2"
      unit_of_measurement: "A"
  
    - name: "Temperature"
      unique_id: "temperature"
      state_topic: "solar_assistant/inverter_1/temperature"
      unit_of_measurement: "°C"
  
    - name: "Battery Current"
      unique_id: "battery_current"
      state_topic: "solar_assistant/inverter_1/battery_current"
      unit_of_measurement: "A"
  
    - name: "Grid Power"
      unique_id: "grid_power"
      state_topic: "solar_assistant/inverter_1/grid_power"
      unit_of_measurement: "W"
  
    - name: "PV Voltage 1"
      unique_id: "pv_voltage_1"
      state_topic: "solar_assistant/inverter_1/pv_voltage_1"
      unit_of_measurement: "V"
  
    - name: "PV Voltage 2"
      unique_id: "pv_voltage_2"
      state_topic: "solar_assistant/inverter_1/pv_voltage_2"
      unit_of_measurement: "V"
  
    - name: "PV Power 1"
      unique_id: "pv_power_1"
      state_topic: "solar_assistant/inverter_1/pv_power_1"
      unit_of_measurement: "W"
  
    - name: "PV Current 3"
      unique_id: "pv_current_3"
      state_topic: "solar_assistant/inverter_1/pv_current_3"
      unit_of_measurement: "A"
  
    - name: "Device Mode"
      unique_id: "device_mode"
      state_topic: "solar_assistant/inverter_1/device_mode"
      unit_of_measurement: ""
  
    - name: "Load Power Essential 1"
      unique_id: "load_power_essential_1"
      state_topic: "solar_assistant/inverter_1/load_power_essential_1"
      unit_of_measurement: "W"
  
    - name: "Grid Voltage"
      unique_id: "grid_voltage"
      state_topic: "solar_assistant/inverter_1/grid_voltage"
      unit_of_measurement: "V"
  
    - name: "AC Output Frequency"
      unique_id: "ac_output_frequency"
      state_topic: "solar_assistant/inverter_1/ac_output_frequency"
      unit_of_measurement: "Hz"
  
    - name: "Grid Power LD"
      unique_id: "grid_power_ld"
      state_topic: "solar_assistant/inverter_1/grid_power_ld"
      unit_of_measurement: "W"
  
    - name: "Load Power Non-Essential"
      unique_id: "load_power_non_essential"
      state_topic: "solar_assistant/inverter_1/load_power_non-essential"
      unit_of_measurement: "W"
  
    - name: "PV Voltage 3"
      unique_id: "pv_voltage_3"
      state_topic: "solar_assistant/inverter_1/pv_voltage_3"
      unit_of_measurement: "V"
  
    - name: "AC Output Voltage"
      unique_id: "ac_output_voltage"
      state_topic: "solar_assistant/inverter_1/ac_output_voltage"
      unit_of_measurement: "V"
  
    - name: "Load Power"
      unique_id: "load_power"
      state_topic: "solar_assistant/inverter_1/load_power"
      unit_of_measurement: "W"
  
    - name: "PV Power 2"
      unique_id: "pv_power_2"
      state_topic: "solar_assistant/inverter_1/pv_power_2"
      unit_of_measurement: "W"
      

3. Create Automations for Generator Control

Automation 1: Start Generator When SOC is Low and Grid Power is Out

  • In Home Assistant, create a new helper:
input_boolean.generator_status
  • In Home Assistant, create a new automation:
    • Start generator at 3% SOC (change to what you need)
alias: Generator Start SOC 3%
description: "When house batteries are below 3% SOC and grid is down start the generator. "
triggers:
  - trigger: numeric_state
    entity_id:
      - sensor.luxpower_lxp_battery_state_of_charge
    below: 3
conditions:
  - condition: numeric_state
    entity_id: sensor.luxpower_lxp_grid_voltage
    below: 100
actions:
  - action: script.generator_start
    metadata: {}
    data: {}
mode: single
  • In Home Assistant, create a new automation:
    • Stop generator at 20% SOC (change to what you need)
alias: Generator Stop SOC 20%
description: "When house batteries are above 20% SOC and grid is down start the generator. "
triggers:
  - trigger: numeric_state
    entity_id:
      - sensor.luxpower_lxp_battery_state_of_charge
    above: 20
conditions:
  - condition: state
    entity_id: input_boolean.generator_status
    state: "on"
actions:
  - action: script.generator_stop
    data: {}
mode: single

I set my system at these low SOCs to minimize the time the generator is running and to not charge too deep into the battery pack at any given time to leave plenty of room for solar charing to take place. Solar energy is free, gasoline is not. Be sure to set your generator start and stop SOC percentage to match on your EG4 inverter.

Final Thoughts

This setup gives you a robust and automatic system, allowing your EG4 18kPV inverter to seamlessly control the Westinghouse generator during power outages. The beauty of this solution is its adaptability—it can work with any wirelessly controlled generator, making it highly versatile for various off-grid or backup power systems. Enjoy the peace of mind that comes with automated backup power management!

Additionally you can setup a script to run weekly generator exercise test and home assistant can let you know how it went. Here is my weekly test automation.

alias: Generator Weekly Test
description: Run a weekly generator test with validation and notifications.
triggers:
  - entity_id: calendar.generator
    event: start
    offset: "-0:0:20"
    trigger: calendar
conditions: []
actions:
  - action: script.generator_start
    data: {}
  - data:
      message: Starting weekly generator test ⚡
    action: notify.notify
  - delay:
      hours: 0
      minutes: 2
      seconds: 0
      milliseconds: 0
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.luxpower_lxp_auxiliary_pv_voltage
            above: 20
        sequence:
          - delay:
              hours: 0
              minutes: 9
              seconds: 0
              milliseconds: 0
          - action: script.generator_stop
            data: {}
          - delay:
              hours: 0
              minutes: 1
              seconds: 30
              milliseconds: 0
          - choose:
              - conditions:
                  - condition: numeric_state
                    entity_id: sensor.luxpower_lxp_auxiliary_pv_voltage
                    below: 19
                sequence:
                  - data:
                      message: Generator test completed successfully ⚡
                    action: notify.notify
          - data:
              message: >-
                Generator test stopped, but voltage did not drop to 0. Please
                inspect ⚠️
            action: notify.notify
    default:
      - data:
          message: >-
            Generator test failed! Voltage did not reach the expected level.
            Please check the generator ⚠️
        action: notify.notify
mode: single

Have questions? Find me on DIY Solar Forum