Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
samoswall authored Sep 14, 2024
1 parent 3ddaf1d commit d606e28
Show file tree
Hide file tree
Showing 4 changed files with 430 additions and 160 deletions.
231 changes: 103 additions & 128 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,168 +1,143 @@
# esphome-apc-ups

![GitHub actions](https://github.com/syssi/esphome-apc-ups/actions/workflows/ci.yaml/badge.svg)
![GitHub stars](https://img.shields.io/github/stars/syssi/esphome-apc-ups)
![GitHub forks](https://img.shields.io/github/forks/syssi/esphome-apc-ups)
![GitHub watchers](https://img.shields.io/github/watchers/syssi/esphome-apc-ups)
[!["Buy Me A Coffee"](https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg)](https://www.buymeacoffee.com/syssi)
ESPHome component to monitor and control a APC UPS via RS232 with MQTT

ESPHome component to monitor and control a APC UPS via RS232
* Fixed switches. They're working now.
* When power is lost or restored, an external command (Q-status flag) is sent to update the status (on_line and on_battery)
* Added a record of the date of battery replacement
* Added switches: shutdown with grace period, soft shutdown, shutdown immediately, turn on

## Supported devices
## Tested on the device

* APC SU420INET (firmware `21.3.I`)
* APC SUVS420I (firmware `42.L.I`)
* APC SUA1000I (firmware `652.13.I`)

## Requirements

* [ESPHome 2024.6.0 or higher](https://github.com/esphome/esphome/releases).
* [ESPHome 2024.5.0 or higher](https://github.com/esphome/esphome/releases).
* Generic ESP32/ESP8266 board

## Schematics

```
RS232 UART-TTL
┌───────────┐ ┌──────────┐ ┌─────────┐
│ │ │ │<----- RX ----->│ │
│ │<---- TX ---->│ RS232 │<----- TX ----->│ ESP32/ │
│ APC UPS │<---- RX ---->│ to TTL │<----- GND ---->│ ESP8266 │
│ │<---- GND --->│ module │<-- 3.3V VCC -->│ │<--- VCC
│ │ │ │ │ │<--- GND
└───────────┘ └──────────┘ └─────────┘
┌───────────┐ ┌──────────┐ ┌─────────┐
│ │<--- TX -----│ RS232 │<---- TX ------│ │
│ │---- RX ---->│ to TTL │----- RX ----->│ ESP32/ │
│ APC UPS │<--- GND --->│ module │<---- GND ---->│ ESP8266 │
│ │ | |<-- 3.3V VCC --│ │
│ │ └──────────┘ │ │
│ │ ┌──────────┐ │ │
│ │<--- GND --->│ DC-DC │<---- GND ---->│ │
│ │---- 24V --->| XL1509 │-- 3.3V VCC -->│ │
└───────────┘ └──────────┘ └─────────┘
```

### D-SUB 9P connector

| Pin | Purpose | MAX3232 pin |
|:---:| :----------- | :---------------- |
| 1 | RX | P14 (DOUT1) |
| 2 | TX | P13 (RIN1) |
| 3 | | |
| 4 | | |
| 5 | | |
| 6 | | |
| 7 | | |
| 8 | | |
| 9 | GND | P15 (GND) |
| UPS pin | RS232 to TTL pin | MAX3232 pin |
| :----------------- | :--------------- | :----------------- |
| RX (pin 1) | RX (pin 2) | P14 (DOUT1) |
| TX (pin 2) | TX (pin 3) | P13 (RIN1) |
| GND (pin 4, 9) | GND (pin 5) | P15 (GND) |
| 24V battery (pin8) | 24V (free pin 9) | connected to DC-DC |

### MAX3232

| Pin | Label | ESPHome | ESP8266 example | ESP32 example |
| :----------- | :----------- | :---------- | :--------------- | :------------ |
| P11 (DIN1) | TXD | `tx_pin` | `GPIO4` | `GPIO16` |
| P12 (ROUT1) | RXD | `rx_pin` | `GPIO5` | `GPIO17` |
| P16 (VCC) | VCC | | | |
| P15 (GND) | GND | | | |
| Pin | Label | ESPHome | ESP8266 | ESP32 | ESP-01 |
| :----------- | :----------- | :---------- | :------ | :------- | :--- |
| P11 (DIN1) | TXD | `tx_pin` | `GPIO4` | `GPIO16` | `GPIO1` |
| P12 (ROUT1) | RXD | `rx_pin` | `GPIO5` | `GPIO17` | `GPIO3` |
| P16 (VCC) | VCC | | | | |
| P15 (GND) | GND | | | | |

## Installation

You can install this component with [ESPHome external components feature](https://esphome.io/components/external_components.html) like this:
```yaml
external_components:
- source: github://syssi/esphome-apc-ups@main
- source: github://samoswall/esphome-apc-ups@main
```
or just use the `esp32-example.yaml` as proof of concept:

```bash
# Install esphome
pip3 install esphome
# Clone this external component
git clone https://github.com/syssi/esphome-apc-ups.git
cd esphome-apc-ups
# Create a secrets.yaml containing some setup specific secrets
cat > secrets.yaml <<EOF
wifi_ssid: MY_WIFI_SSID
wifi_password: MY_WIFI_PASSWORD
mqtt_host: MY_MQTT_HOST
mqtt_username: MY_MQTT_USERNAME
mqtt_password: MY_MQTT_PASSWORD
EOF
# Validate the configuration, create a binary, upload it, and start logs
# If you use a esp8266 run the esp8266-examle.yaml
esphome run esp32-example.yaml
```

## Example response all sensors enabled

```
[apc_ups:286]: Sending polling command : Y with length 1
[apc_ups:112]: Decode Y
[apc_ups:286]: Sending polling command : Q with length 1
[apc_ups:153]: Decode Q
[sensor:094]: 'apc-ups status bitmask': Sending state 8.00000 with 0 decimals of accuracy
[binary_sensor:036]: 'apc-ups runtime calibration': Sending state OFF
[binary_sensor:036]: 'apc-ups smart trim': Sending state OFF
[binary_sensor:036]: 'apc-ups smart boost': Sending state OFF
[binary_sensor:036]: 'apc-ups on line': Sending state ON
[binary_sensor:036]: 'apc-ups on battery': Sending state OFF
[binary_sensor:036]: 'apc-ups output overloaded': Sending state OFF
[binary_sensor:036]: 'apc-ups battery low': Sending state OFF
[binary_sensor:036]: 'apc-ups replace battery': Sending state OFF
[apc_ups:286]: Sending polling command : B with length 1
[apc_ups:117]: Decode B
[sensor:094]: 'apc-ups battery voltage': Sending state 13.61000 V with 2 decimals of accuracy
[apc_ups:286]: Sending polling command : F with length 1
[apc_ups:123]: Decode F
[sensor:094]: 'apc-ups grid frequency': Sending state 50.00000 Hz with 2 decimals of accuracy
[apc_ups:286]: Sending polling command : L with length 1
[apc_ups:135]: Decode L
[sensor:094]: 'apc-ups grid voltage': Sending state 231.80000 V with 1 decimals of accuracy
[apc_ups:286]: Sending polling command : O with length 1
[apc_ups:141]: Decode O
[sensor:094]: 'apc-ups ac output voltage': Sending state 231.80000 V with 1 decimals of accuracy
[apc_ups:286]: Sending polling command : P with length 1
[apc_ups:147]: Decode P
[sensor:094]: 'apc-ups ac output load': Sending state 9.10000 % with 1 decimals of accuracy
[apc_ups:286]: Sending polling command : f with length 1
[apc_ups:171]: Decode f
[sensor:094]: 'apc-ups state of charge': Sending state 100.00000 % with 1 decimals of accuracy
[apc_ups:286]: Sending polling command : j with length 1
[apc_ups:177]: Decode j
[sensor:094]: 'apc-ups estimated runtime': Sending state 42.00000 min with 0 decimals of accuracy
[apc_ups:286]: Sending polling command : G with length 1
[apc_ups:129]: Decode G
[text_sensor:064]: 'apc-ups cause of last transfer': Sending state 'S'
```
## Configuration info
| Type | Symbol | Variable | Info
|-|-|-|-
| Binary_Sensor | Y | smart_mode | Enable smart mode
| Switch | A | front_panel_test | Front panel test
| Sensor | B | battery_voltage | Battery voltage
| Sensor | C | internal_temperature | Internal temperature
| Switch | D | start_runtime_calibration | Start runtime calibration
| Text_Sensor (writable) | E | | Automatic self test interval @TODO
| Sensor | F | grid_frequency | Input line frequency
| Text_Sensor | G | cause_of_last_transfer | Cause of last transfer to battery
| Text_Sensor | I | | Measure-UPS alarm enable @TODO (no decode)
| Text_Sensor | J | | Measure-UPS alarm status @TODO (no decode)
| Switch | K | shutdown_with_grace_period | Shutdown with grace period
| Sensor | L | grid_voltage | Input line voltage
| Sensor | M | max_grid_voltage | Maximum line voltage
| Sensor | N | min_grid_voltage | Minimum line voltage
| Sensor | O | ac_output_voltage | Output voltage
| Sensor | P | ac_output_load | Power load in %
| Sensor | Q | status_bitmask | Status flags. (See table)
| Switch | R | | Turn dumb @TODO
| Switch | S | soft_shutdown | Soft shutdown
| Switch | U | simulate_power_failure | Simulate power failure
| Text_Sensor | V | old_firmware_version | Old firmware version
| Switch | W | self_test | Self test
| Text_Sensor | X | self_test_results | Self test results
| Switch | Z | shutdown_immediately | Shutdown immediately
| Text_Sensor | a | protocol_info | Protocol info
| Text_Sensor | b | firmware_revision | Firmware revision
| Text_Sensor | c | local_identifier | UPS local identifier
| Sensor | e | return_threshold | Return threshold
| Sensor | f | state_of_charge | Battery level
| Sensor | g | nominal_battery_voltage | Nominal battery voltage
| Sensor | h | ambient_humidity | Measure-UPS ambient humidity
| Text_Sensor | i | | Measure-UPS dry contacts @TODO
| Sensor | j | estimated_runtime | Estimated runtime
| Text_Sensor | k | alarm_delay | Alarm delay
| Sensor | l | low_transfer_voltage | Low transfer voltage
| Text_Sensor | m | manufacture_date | Manufacture date
| Text_Sensor | n | serial_number | Serial number
| Sensor | o | nominal_output_voltage | Nominal Output Voltage
| Text_Sensor (writable) | p | | Shutdown grace delay @TODO
| Text_Sensor (writable) | q | | Low battery warning @TODO
| Text_Sensor (writable) | r | | Wakeup delay @TODO
| Text_Sensor (writable) | s | | Sensitivity @TODO
| Sensor | t | ambient_temperature | Measure-UPS ambient temperature
| Sensor | u | upper_transfer_voltage | Upper transfer voltage
| Text_Sensor | v | measure_upc_firmware | Measure-UPS firmware
| Text_Sensor | x | last_battery_change_date | Last battery change date
| Switch | x | save_last_battery_change_date | Save last battery change date
| Text_Sensor | y | copyright_notice | Copyright notice
| Switch | z | | Reset to factory settings @TODO
| Text_Sensor | 9 | line_quality | Line quality @TODO
| Text_Sensor | 0x01 | model_name | Model name
| Switch | 0x0E | turn_on | Turn ON UPS
## Status flags
| Type | Bit | Variable
|-|-|-
| Binary_Sensor | 0 | runtime_calibration
| Binary_Sensor | 1 | smart_trim
| Binary_Sensor | 2 | smart_boost
| Binary_Sensor | 3 | on_line
| Binary_Sensor | 4 | on_battery
| Binary_Sensor | 5 | output_overloaded
| Binary_Sensor | 6 | battery_low
| Binary_Sensor | 7 | replace_battery
## Protocol
See [kirbah.github.io/apc-ups/](https://kirbah.github.io/apc-ups/).
## Known issues
None.
## Debugging
If this component doesn't work out of the box for your device please update your configuration to increase the log level to see details about the UART traffic:
```
logger:
level: DEBUG

uart:
- id: uart_0
baud_rate: 2400
tx_pin: ${tx_pin}
rx_pin: ${rx_pin}
debug:
direction: BOTH
dummy_receiver: false
after:
delimiter: "\r"
sequence:
- lambda: UARTDebug::log_string(direction, bytes);
```
## References
* https://github.com/kirbah/apc-ups
* http://www.apcupsd.org/manual/#apc-smart-protocol
* https://github.com/ssieb/custom_components/tree/master/components/apcups
## Forked from
[https://github.com/syssi/esphome-apc-ups](https://github.com/syssi/esphome-apc-ups)
Loading

0 comments on commit d606e28

Please sign in to comment.