Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding new switches (multibyte commands) #17 #18

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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