commit
9238542fb5
252
README.md
252
README.md
@ -4,23 +4,28 @@ Wirelessly control your Mitsubishi Comfort HVAC equipment with an ESP8266 or
|
||||
ESP32 using the [ESPHome](https://esphome.io) framework.
|
||||
|
||||
## Features
|
||||
|
||||
* Instant feedback of command changes via RF Remote to HomeAssistant or MQTT.
|
||||
* Direct control without the remote.
|
||||
* Uses the [SwiCago/HeatPump](https://github.com/SwiCago/HeatPump) Arduino
|
||||
libary to talk to the unit directly via the internal `CN105` connector.
|
||||
|
||||
## Requirements
|
||||
* https://github.com/SwiCago/HeatPump
|
||||
|
||||
* [SwiCago/HeatPump](https://github.com/SwiCago/HeatPump)
|
||||
* ESPHome 1.19.1 or greater
|
||||
|
||||
## Supported Microcontrollers
|
||||
|
||||
This library should work on most ESP8266 or ESP32 platforms. It has been tested
|
||||
with the following MCUs:
|
||||
|
||||
* Generic ESP-01S board (ESP8266)
|
||||
* WeMos D1 Mini (ESP8266)
|
||||
* Generic ESP32 Dev Kit (ESP32)
|
||||
|
||||
## Supported Mitsubishi Climate Units
|
||||
|
||||
The underlying HeatPump library works with a number of Mitsubishi HVAC
|
||||
units. Basically, if the unit has a `CN105` header on the main board, it should
|
||||
work with this library. The [HeatPump
|
||||
@ -34,11 +39,15 @@ available.
|
||||
|
||||
The whole integration with this libary and the underlying HeatPump has been
|
||||
tested by the author on the following units:
|
||||
|
||||
* `MSZ-GL06NA`
|
||||
* `MFZ-KA09NA`
|
||||
* `MSZ-FH35V`
|
||||
* `MSZ-LN35VG2W`
|
||||
|
||||
## Usage
|
||||
### Step 1: Build a control circuit.
|
||||
|
||||
### Step 1: Build a control circuit
|
||||
|
||||
Build a control circuit with your MCU as detailed in the [SwiCago/HeatPump
|
||||
README](https://github.com/SwiCago/HeatPump/blob/master/README.md#demo-circuit).
|
||||
@ -70,6 +79,7 @@ external_components:
|
||||
Version 2.0 and greater of this libary use the ESPHome `external_components`
|
||||
feature, which is a huge step forward in terms of usability. In order to make
|
||||
things compile correctly, you will need to:
|
||||
|
||||
1. Remove the `libraries` section that imports
|
||||
`https://github.com/SwiCago/HeatPump`, as this is handled by the
|
||||
`external_component` section of manifest.
|
||||
@ -90,7 +100,8 @@ and `libraries` lines will likely result in compilation errors complaining
|
||||
about duplicate declarations of `MitsubishiHeatPump::traits()`.
|
||||
|
||||
##### Example error
|
||||
```
|
||||
|
||||
```none
|
||||
Linking /data/bedroom_east_heatpump/.pioenvs/bedroom_east_heatpump/firmware.elf
|
||||
/root/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld: /data/bedroom_east_heatpump/.pioenvs/bedroom_east_heatpump/src/esphome/components/mitsubishi_heatpump/espmhp.cpp.o: in function `MitsubishiHeatPump::traits()':
|
||||
espmhp.cpp:(.text._ZN18MitsubishiHeatPump6traitsEv+0x4): multiple definition of `MitsubishiHeatPump::traits()'; /data/bedroom_east_heatpump/.pioenvs/bedroom_east_heatpump/src/esphome-mitsubishiheatpump/espmhp.cpp.o:espmhp.cpp:(.text._ZN18MitsubishiHeatPump6traitsEv+0x80): first defined here
|
||||
@ -107,11 +118,14 @@ climate:
|
||||
|
||||
# Optional
|
||||
hardware_uart: UART0
|
||||
baud_rate: 4800
|
||||
|
||||
# Optional
|
||||
update_interval: 500ms
|
||||
```
|
||||
|
||||
#### ESP8266 platforms
|
||||
|
||||
On ESP8266 you'll need to disable logging to serial because it conflicts with
|
||||
the heatpump UART:
|
||||
|
||||
@ -120,8 +134,13 @@ logger:
|
||||
baud_rate: 0
|
||||
```
|
||||
|
||||
#### ESP32 platforms
|
||||
|
||||
On ESP32 you can change `hardware_uart` to `UART1` or `UART2` and keep logging
|
||||
enabled on the main serial port.
|
||||
enabled on the main serial port. This may require specifying `baud_rate` on some
|
||||
ESP32 boards.
|
||||
|
||||
#### UART Notes
|
||||
|
||||
*Note:* this component DOES NOT use the ESPHome `uart` component, as it
|
||||
requires direct access to a hardware UART via the Arduino `HardwareSerial`
|
||||
@ -131,13 +150,15 @@ software serial libraries, including the one in ESPHome. There's currently no
|
||||
way to guarantee access to a hardware UART nor retrieve the `HardwareSerial`
|
||||
handle from the `uart` component within the ESPHome framework.
|
||||
|
||||
# Example configuration
|
||||
## Example configurations
|
||||
|
||||
Below is an example configuration which will include wireless strength
|
||||
indicators and permit over the air updates. You'll need to create a
|
||||
`secrets.yaml` file inside of your `esphome` directory with entries for the
|
||||
various items prefixed with `!secret`.
|
||||
|
||||
### ESP8266 Example Configuration
|
||||
|
||||
```yaml
|
||||
substitutions:
|
||||
name: hptest
|
||||
@ -221,13 +242,110 @@ climate:
|
||||
- platform: mitsubishi_heatpump
|
||||
name: "${friendly_name}"
|
||||
|
||||
horizontal_vane_select:
|
||||
name: Horizontal Vane
|
||||
vertical_vane_select:
|
||||
name: Vertical Vane
|
||||
|
||||
# ESP32 only - change UART0 to UART1 or UART2 and remove the
|
||||
# logging:baud_rate above to allow the built-in UART0 to function for
|
||||
# logging.
|
||||
# Some ESP32 boards will require the baud_rate setting if hardware_uart is specified.
|
||||
hardware_uart: UART0
|
||||
baud_rate: 4800
|
||||
```
|
||||
|
||||
# Advanced configuration
|
||||
### ESP32 Example Configuration
|
||||
|
||||
```yaml
|
||||
substitutions:
|
||||
name: hptest
|
||||
friendly_name: Test Heatpump
|
||||
|
||||
|
||||
esphome:
|
||||
name: ${name}
|
||||
|
||||
esp32:
|
||||
board: lolin_s2_mini
|
||||
variant: ESP32S2
|
||||
framework:
|
||||
type: arduino
|
||||
version: 2.0.3
|
||||
platform_version: 5.0.0
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_password
|
||||
|
||||
# Enable fallback hotspot (captive portal) in case wifi connection fails
|
||||
ap:
|
||||
ssid: "${friendly_name} Fallback Hotspot"
|
||||
password: !secret fallback_password
|
||||
|
||||
captive_portal:
|
||||
|
||||
# Enable logging
|
||||
logger:
|
||||
|
||||
# Enable Home Assistant API
|
||||
api:
|
||||
|
||||
ota:
|
||||
|
||||
# Enable Web server.
|
||||
web_server:
|
||||
port: 80
|
||||
|
||||
# Sync time with Home Assistant.
|
||||
time:
|
||||
- platform: homeassistant
|
||||
id: homeassistant_time
|
||||
|
||||
# Text sensors with general information.
|
||||
text_sensor:
|
||||
# Expose ESPHome version as sensor.
|
||||
- platform: version
|
||||
name: ${name} ESPHome Version
|
||||
# Expose WiFi information as sensors.
|
||||
- platform: wifi_info
|
||||
ip_address:
|
||||
name: ${name} IP
|
||||
ssid:
|
||||
name: ${name} SSID
|
||||
bssid:
|
||||
name: ${name} BSSID
|
||||
|
||||
# Sensors with general information.
|
||||
sensor:
|
||||
# Uptime sensor.
|
||||
- platform: uptime
|
||||
name: ${name} Uptime
|
||||
|
||||
# WiFi Signal sensor.
|
||||
- platform: wifi_signal
|
||||
name: ${name} WiFi Signal
|
||||
update_interval: 60s
|
||||
|
||||
external_components:
|
||||
- source: github://geoffdavis/esphome-mitsubishiheatpump
|
||||
|
||||
climate:
|
||||
- platform: mitsubishi_heatpump
|
||||
name: "${friendly_name}"
|
||||
|
||||
horizontal_vane_select:
|
||||
name: Horizontal Vane
|
||||
vertical_vane_select:
|
||||
name: Vertical Vane
|
||||
|
||||
# ESP32 only - change UART0 to UART1 or UART2 and remove the
|
||||
# logging:baud_rate above to allow the built-in UART0 to function for
|
||||
# logging.
|
||||
hardware_uart: UART1
|
||||
```
|
||||
|
||||
### Advanced configuration
|
||||
|
||||
Some models of heat pump require different baud rates or don't support all
|
||||
possible modes of operation. You can configure mulitple climate "traits" in
|
||||
@ -239,10 +357,12 @@ climate:
|
||||
name: "My heat pump"
|
||||
hardware_uart: UART2
|
||||
baud_rate: 9600
|
||||
rx_pin: 9
|
||||
tx_pin: 10
|
||||
supports:
|
||||
mode: [HEAT_COOL, COOL, HEAT, FAN_ONLY]
|
||||
fan_mode: [AUTO, LOW, MEDIUM, HIGH]
|
||||
swing_mode: [OFF, VERTICAL]
|
||||
mode: ["HEAT_COOL", "COOL", "HEAT", "FAN_ONLY"]
|
||||
fan_mode: ["AUTO", "LOW", "MEDIUM", "HIGH"]
|
||||
swing_mode: ["OFF", "VERTICAL", "HORIZONTAL", "BOTH"]
|
||||
visual:
|
||||
min_temperature: 16
|
||||
max_temperature: 31
|
||||
@ -251,40 +371,63 @@ climate:
|
||||
|
||||
## Configuration variables that affect this library directly
|
||||
|
||||
* *hardware\_uart* (_Optional_): the hardware UART instance to use for
|
||||
* `hardware_uart` (_Optional_): the hardware UART instance to use for
|
||||
communcation with the heatpump. On ESP8266, only `UART0` is usable. On ESP32,
|
||||
`UART0`, `UART1`, and `UART2` are all valid choices. Default: `UART0`
|
||||
* *baud\_rate* (_Optional_): Serial BAUD rate used to communicate with the
|
||||
* `baud_rate` (_Optional_): Serial BAUD rate used to communicate with the
|
||||
HeatPump. Most systems use the default value of `4800` baud, but some use
|
||||
`9600`. Default: `4800`
|
||||
* *update\_interval* (_Optional_, range: 0ms to 9000ms): How often this
|
||||
`2400` or `9600`. Check [here](https://github.com/SwiCago/HeatPump/issues/13)
|
||||
to find discussion of whether your particular model requires a non-default baud rate.
|
||||
Some ESP32 boards will require the baud_rate setting if
|
||||
hardware_uart is specified. Default: `4800`.
|
||||
* `rx_pin` (_Optional_): pin number to use as RX for the specified hardware
|
||||
UART (ESP32 only - ESP8266 hardware UART's pins aren't configurable).
|
||||
* `tx_pin` (_Optional_): pin number to use as TX for the specified hardware
|
||||
UART (ESP32 only - ESP8266 hardware UART's pins aren't configurable).
|
||||
* `update_interval` (_Optional_, range: 0ms to 9000ms): How often this
|
||||
component polls the heatpump hardware, in milliseconds. Maximum usable value
|
||||
is 9 seconds due to underlying issues with the HeatPump library. Default: 500ms
|
||||
* *supports* (_Optional_): Supported features for the device. ** *mode*
|
||||
(_Optional_, list): Supported climate modes for the HeatPump. Default:
|
||||
* `supports` (_Optional_): Supported features for the device.
|
||||
* `mode` (_Optional_, list): Supported climate modes for the HeatPump. Default:
|
||||
`['HEAT_COOL', 'COOL', 'HEAT', 'DRY', 'FAN_ONLY']`
|
||||
** *fan_mode* (_Optional_, list):
|
||||
Supported fan speeds for the HeatPump. Default: `['AUTO', 'DIFFUSE', 'LOW',
|
||||
'MEDIUM', 'MIDDLE', 'HIGH']` ** *swing_mode* (_Optional_, list): Supported
|
||||
fan swing modes. Most Mitsubishi units only support the default. Default:
|
||||
`['OFF', 'VERTICAL']`
|
||||
* `fan_mode` (_Optional_, list): Supported fan speeds for the HeatPump.
|
||||
Default: `['AUTO', 'DIFFUSE', 'LOW', 'MEDIUM', 'MIDDLE', 'HIGH']`
|
||||
* `swing_mode` (_Optional_, list): Supported fan swing modes. Most Mitsubishi
|
||||
units only support the default. Default: `['OFF', 'VERTICAL']`
|
||||
* `remote_temperature_operating_timeout_minutes` (_Optional_): The number of
|
||||
minutes before a set_remote_temperature request becomes stale, while the
|
||||
heatpump is heating or cooling. Unless a new set_remote_temperature
|
||||
request was made within the time duration, the heatpump will revert back to it's
|
||||
internal temperature sensor.
|
||||
* `remote_temperature_idle_timeout_minutes` (_Optional_): The number of
|
||||
minutes before a set_remote_temperature request becomes stale while the heatpump
|
||||
is idle. Unless a new set_remote_temperature request is made within the time duration,
|
||||
the heatpump will revert back to it's internal temperature sensor.
|
||||
* `remote_temperature_ping_timeout_minutes` (_Optional_): The number of
|
||||
minutes before a set_remote_temperature request becomes stale, if a ping
|
||||
request wasn't received from your ESPHome controller. This will result
|
||||
in the heatpump reverting to it's internal temperature sensor if the heatpump
|
||||
loses it's WiFi connection.
|
||||
equest.)
|
||||
|
||||
## Other configuration
|
||||
|
||||
* *id* (_Optional_): used to identify multiple instances, e.g. "denheatpump"
|
||||
* *name* (_Required_): The name of the climate component, e.g. "Den Heatpump"
|
||||
* *visual* (_Optional_): The core `Climate` component has several *visual*
|
||||
* `id` (_Optional_): used to identify multiple instances, e.g. "denheatpump"
|
||||
* `name` (_Required_): The name of the climate component, e.g. "Den Heatpump"
|
||||
* `visual` (_Optional_): The core `Climate` component has several *visual*
|
||||
options that can be set. See the [Climate
|
||||
Component](https://esphome.io/components/climate/index.html) documentation for
|
||||
details.
|
||||
|
||||
## Remote temperature
|
||||
### Remote temperature
|
||||
|
||||
It is possible to use an external temperature sensor to tell the heat pump what
|
||||
the room temperature is, rather than relying on its internal temperature
|
||||
sensor. You can do this by calling `set_remote_temperature(float temp)` on the
|
||||
`mitsubishi_heatpump` object in a lambda. Note that you can call
|
||||
`set_remote_temperature(0)` to switch back to the internal temperature sensor.
|
||||
sensor. This is helpful if you want to make sure that a particular room, or part
|
||||
of the room, reaches the desired temperature—rather than just the area near the
|
||||
heat pump or the thermostat. You can do this by calling `set_remote_temperature(float temp)`
|
||||
on the `mitsubishi_heatpump` object in a lambda. (If needed, you can call
|
||||
`set_remote_temperature(0)` to switch back to the internal temperature sensor.)
|
||||
|
||||
There are several ways you could make use of this functionality. One is to use
|
||||
a sensor automation:
|
||||
@ -296,7 +439,7 @@ climate:
|
||||
id: hp
|
||||
|
||||
sensor:
|
||||
# You could use a Bluetooth temperature sensor
|
||||
# You could use a Bluetooth temperature sensor as the source...
|
||||
- platform: atc_mithermometer
|
||||
mac_address: "XX:XX:XX:XX:XX:XX"
|
||||
temperature:
|
||||
@ -305,7 +448,7 @@ sensor:
|
||||
then:
|
||||
- lambda: 'id(hp).set_remote_temperature(x);'
|
||||
|
||||
# Or you could use a HomeAssistant sensor
|
||||
# ...or you could use a Home Assistant sensor as the source
|
||||
- platform: homeassistant
|
||||
name: "Temperature Sensor From Home Assistant"
|
||||
entity_id: sensor.temperature_sensor
|
||||
@ -313,8 +456,15 @@ sensor:
|
||||
then:
|
||||
- lambda: 'id(hp).set_remote_temperature(x);'
|
||||
```
|
||||
One issue that you might have here is that, after some amount of time with no update from the
|
||||
external temperature sensor, the heat pump will revert back to its internal temperature.
|
||||
You can prevent this by [adding a `heartbeat` filter](https://github.com/geoffdavis/esphome-mitsubishiheatpump/issues/31#issuecomment-1207115352)
|
||||
to the sensor, which will keep reminding the heat pump of the external sensor value.
|
||||
|
||||
Alternatively you could define a
|
||||
Also, if your external sensor is in Fahrenheit, you will have to [convert the value to Celsius](https://github.com/geoffdavis/esphome-mitsubishiheatpump/issues/31#issuecomment-1207115352).
|
||||
|
||||
|
||||
Alternatively, you could define a
|
||||
[service](https://www.esphome.io/components/api.html#user-defined-services)
|
||||
that Home Assistant can call:
|
||||
|
||||
@ -332,9 +482,44 @@ api:
|
||||
- lambda: 'id(hp).set_remote_temperature(0);'
|
||||
```
|
||||
|
||||
# See Also
|
||||
It's also possible to configure timeouts which will revert the heatpump
|
||||
back to it's internal temperature sensor in the event that an external sensor
|
||||
becomes unavailable. All three settings are optional, but it's recommended
|
||||
that you configure both operating and idle timeout. Both can be configured to the same
|
||||
value.
|
||||
|
||||
```yaml
|
||||
climate:
|
||||
- platform: mitsubishi_heatpump
|
||||
remote_temperature_operating_timeout_minutes: 65
|
||||
remote_temperature_idle_timeout_minutes: 120
|
||||
remote_temperature_ping_timeout_minutes: 20
|
||||
|
||||
api:
|
||||
services:
|
||||
- service: ping
|
||||
then:
|
||||
- lambda: 'id(hp).ping();'
|
||||
```
|
||||
|
||||
There is an explicit distinction between an operating timeout and an idle timeout.
|
||||
|
||||
* **Operating timeout** The heatpump is currently pumping heat, and the expectation is that
|
||||
the temperature should shift within a certain time period. Recommended value: 60 minutes.
|
||||
* **Idle timeout** The heatpump is not currently pumping heat, so temperature shifts are expected
|
||||
to happen less frequently. Recommended value depends on the implementation details of your temperature
|
||||
sensor. Some will only provide updates on temperature changes, others such as Aqara will provide
|
||||
an update at least once every hour.
|
||||
* **Ping timeout** Detects if a connection is lost between HomeAssistant and the heatpump, or if your
|
||||
home assistant instance is down. Recommended value is 20 minutes, with a ping being sent every 5 minutes.
|
||||
|
||||
Do not enable ping timeout until you have the logic in place to call the ping service at a regular interval. You
|
||||
can view the ESPHome logs to ensure this is taking place.
|
||||
|
||||
## See Also
|
||||
|
||||
### Other Implementations
|
||||
|
||||
## Other Implementations
|
||||
The [gysmo38/mitsubishi2MQTT](https://github.com/gysmo38/mitsubishi2MQTT)
|
||||
Arduino sketch also uses the `SwiCago/HeatPump`
|
||||
library, and works with MQTT directly. The author of this implementation found
|
||||
@ -351,9 +536,10 @@ repository and it's underlying `HeatPump` library allows bi-directional
|
||||
communication with the Mitsubishi system, and can detect when someone changes
|
||||
the settings via an IR remote.
|
||||
|
||||
## Reference documentation
|
||||
### Reference documentation
|
||||
|
||||
The author referred to the following documentation repeatedly:
|
||||
|
||||
* [ESPHome Custom Sensors Reference](https://esphome.io/components/sensor/custom.html)
|
||||
* [ESPHome Custom Climate Components Reference](https://esphome.io/components/climate/custom.html)
|
||||
* [ESPHome External Components Reference](https://esphome.io/components/external_components.html)
|
||||
|
@ -1,11 +1,13 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import climate
|
||||
from esphome.components import climate, select
|
||||
from esphome.components.logger import HARDWARE_UART_TO_SERIAL
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_HARDWARE_UART,
|
||||
CONF_BAUD_RATE,
|
||||
CONF_RX_PIN,
|
||||
CONF_TX_PIN,
|
||||
CONF_UPDATE_INTERVAL,
|
||||
CONF_MODE,
|
||||
CONF_FAN_MODE,
|
||||
@ -13,17 +15,29 @@ from esphome.const import (
|
||||
)
|
||||
from esphome.core import CORE, coroutine
|
||||
|
||||
AUTO_LOAD = ["climate"]
|
||||
AUTO_LOAD = ["climate", "select"]
|
||||
|
||||
CONF_SUPPORTS = "supports"
|
||||
CONF_HORIZONTAL_SWING_SELECT = "horizontal_vane_select"
|
||||
CONF_VERTICAL_SWING_SELECT = "vertical_vane_select"
|
||||
DEFAULT_CLIMATE_MODES = ["HEAT_COOL", "COOL", "HEAT", "DRY", "FAN_ONLY"]
|
||||
DEFAULT_FAN_MODES = ["AUTO", "DIFFUSE", "LOW", "MEDIUM", "MIDDLE", "HIGH"]
|
||||
DEFAULT_SWING_MODES = ["OFF", "VERTICAL"]
|
||||
HORIZONTAL_SWING_OPTIONS = ["auto","left","left_center","center","right_center","right","swing"]
|
||||
VERTICAL_SWING_OPTIONS = ["auto", "up", "up_center", "center", "down_center", "down","swing"]
|
||||
|
||||
# Remote temperature timeout configuration
|
||||
CONF_REMOTE_OPERATING_TIMEOUT = "remote_temperature_operating_timeout_minutes"
|
||||
CONF_REMOTE_IDLE_TIMEOUT = "remote_temperature_idle_timeout_minutes"
|
||||
CONF_REMOTE_PING_TIMEOUT = "remote_temperature_ping_timeout_minutes"
|
||||
|
||||
MitsubishiHeatPump = cg.global_ns.class_(
|
||||
"MitsubishiHeatPump", climate.Climate, cg.PollingComponent
|
||||
)
|
||||
|
||||
MitsubishiACSelect = cg.global_ns.class_(
|
||||
"MitsubishiACSelect", select.Select, cg.Component
|
||||
)
|
||||
|
||||
def valid_uart(uart):
|
||||
if CORE.is_esp8266:
|
||||
@ -36,16 +50,28 @@ def valid_uart(uart):
|
||||
return cv.one_of(*uarts, upper=True)(uart)
|
||||
|
||||
|
||||
SELECT_SCHEMA = select.SELECT_SCHEMA.extend(
|
||||
{cv.GenerateID(CONF_ID): cv.declare_id(MitsubishiACSelect)}
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = climate.CLIMATE_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MitsubishiHeatPump),
|
||||
cv.Optional(CONF_HARDWARE_UART, default="UART0"): valid_uart,
|
||||
cv.Optional(CONF_BAUD_RATE): cv.positive_int,
|
||||
cv.Optional(CONF_REMOTE_OPERATING_TIMEOUT): cv.positive_int,
|
||||
cv.Optional(CONF_REMOTE_IDLE_TIMEOUT): cv.positive_int,
|
||||
cv.Optional(CONF_REMOTE_PING_TIMEOUT): cv.positive_int,
|
||||
cv.Optional(CONF_RX_PIN): cv.positive_int,
|
||||
cv.Optional(CONF_TX_PIN): cv.positive_int,
|
||||
# If polling interval is greater than 9 seconds, the HeatPump library
|
||||
# reconnects, but doesn't then follow up with our data request.
|
||||
cv.Optional(CONF_UPDATE_INTERVAL, default="500ms"): cv.All(
|
||||
cv.update_interval, cv.Range(max=cv.TimePeriod(milliseconds=9000))
|
||||
),
|
||||
# Add selects for vertical and horizontal vane positions
|
||||
cv.Optional(CONF_HORIZONTAL_SWING_SELECT): SELECT_SCHEMA,
|
||||
cv.Optional(CONF_VERTICAL_SWING_SELECT): SELECT_SCHEMA,
|
||||
# Optionally override the supported ClimateTraits.
|
||||
cv.Optional(CONF_SUPPORTS, default={}): cv.Schema(
|
||||
{
|
||||
@ -69,6 +95,22 @@ def to_code(config):
|
||||
if CONF_BAUD_RATE in config:
|
||||
cg.add(var.set_baud_rate(config[CONF_BAUD_RATE]))
|
||||
|
||||
if CONF_RX_PIN in config:
|
||||
cg.add(var.set_rx_pin(config[CONF_RX_PIN]))
|
||||
|
||||
if CONF_TX_PIN in config:
|
||||
cg.add(var.set_tx_pin(config[CONF_TX_PIN]))
|
||||
|
||||
if CONF_REMOTE_OPERATING_TIMEOUT in config:
|
||||
cg.add(var.set_remote_operating_timeout_minutes(config[CONF_REMOTE_OPERATING_TIMEOUT]))
|
||||
|
||||
if CONF_REMOTE_IDLE_TIMEOUT in config:
|
||||
cg.add(var.set_remote_idle_timeout_minutes(config[CONF_REMOTE_IDLE_TIMEOUT]))
|
||||
|
||||
if CONF_REMOTE_PING_TIMEOUT in config:
|
||||
cg.add(var.set_remote_ping_timeout_minutes(config[CONF_REMOTE_PING_TIMEOUT]))
|
||||
|
||||
|
||||
supports = config[CONF_SUPPORTS]
|
||||
traits = var.config_traits()
|
||||
|
||||
@ -85,6 +127,18 @@ def to_code(config):
|
||||
climate.CLIMATE_SWING_MODES[mode]
|
||||
))
|
||||
|
||||
if CONF_HORIZONTAL_SWING_SELECT in config:
|
||||
conf = config[CONF_HORIZONTAL_SWING_SELECT]
|
||||
swing_select = yield select.new_select(conf, options=HORIZONTAL_SWING_OPTIONS)
|
||||
yield cg.register_component(swing_select, conf)
|
||||
cg.add(var.set_horizontal_vane_select(swing_select))
|
||||
|
||||
if CONF_VERTICAL_SWING_SELECT in config:
|
||||
conf = config[CONF_VERTICAL_SWING_SELECT]
|
||||
swing_select = yield select.new_select(conf, options=VERTICAL_SWING_OPTIONS)
|
||||
yield cg.register_component(swing_select, conf)
|
||||
cg.add(var.set_vertical_vane_select(swing_select))
|
||||
|
||||
yield cg.register_component(var, config)
|
||||
yield climate.register_climate(var, config)
|
||||
cg.add_library(
|
||||
|
@ -9,7 +9,8 @@
|
||||
* Author: @am-io on Github.
|
||||
* Author: @nao-pon on Github.
|
||||
* Author: Simon Knopp @sijk on Github
|
||||
* Last Updated: 2021-05-27
|
||||
* Author: Paul Murphy @donutsoft on GitHub
|
||||
* Last Updated: 2023-04-22
|
||||
* License: BSD
|
||||
*
|
||||
* Requirements:
|
||||
@ -40,6 +41,10 @@ MitsubishiHeatPump::MitsubishiHeatPump(
|
||||
this->traits_.set_visual_min_temperature(ESPMHP_MIN_TEMPERATURE);
|
||||
this->traits_.set_visual_max_temperature(ESPMHP_MAX_TEMPERATURE);
|
||||
this->traits_.set_visual_temperature_step(ESPMHP_TEMPERATURE_STEP);
|
||||
|
||||
// Assume a succesful connection was made to the ESPHome controller on
|
||||
// launch.
|
||||
this->ping();
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::check_logger_conflict_() {
|
||||
@ -53,6 +58,11 @@ void MitsubishiHeatPump::check_logger_conflict_() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::banner() {
|
||||
ESP_LOGI(TAG, "ESPHome MitsubishiHeatPump version %s",
|
||||
ESPMHP_VERSION);
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::update() {
|
||||
// This will be called every "update_interval" milliseconds.
|
||||
//this->dump_config();
|
||||
@ -62,12 +72,21 @@ void MitsubishiHeatPump::update() {
|
||||
heatpumpStatus currentStatus = hp->getStatus();
|
||||
this->hpStatusChanged(currentStatus);
|
||||
#endif
|
||||
this->enforce_remote_temperature_sensor_timeout();
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_baud_rate(int baud) {
|
||||
this->baud_ = baud;
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_rx_pin(int rx_pin) {
|
||||
this->rx_pin_ = rx_pin;
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_tx_pin(int tx_pin) {
|
||||
this->tx_pin_ = tx_pin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get our supported traits.
|
||||
*
|
||||
@ -92,6 +111,117 @@ climate::ClimateTraits& MitsubishiHeatPump::config_traits() {
|
||||
return traits_;
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::update_swing_horizontal(const std::string &swing) {
|
||||
this->horizontal_swing_state_ = swing;
|
||||
|
||||
if (this->horizontal_vane_select_ != nullptr &&
|
||||
this->horizontal_vane_select_->state != this->horizontal_swing_state_) {
|
||||
this->horizontal_vane_select_->publish_state(
|
||||
this->horizontal_swing_state_); // Set current horizontal swing
|
||||
// position
|
||||
}
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::update_swing_vertical(const std::string &swing) {
|
||||
this->vertical_swing_state_ = swing;
|
||||
|
||||
if (this->vertical_vane_select_ != nullptr &&
|
||||
this->vertical_vane_select_->state != this->vertical_swing_state_) {
|
||||
this->vertical_vane_select_->publish_state(
|
||||
this->vertical_swing_state_); // Set current vertical swing position
|
||||
}
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_vertical_vane_select(
|
||||
select::Select *vertical_vane_select) {
|
||||
this->vertical_vane_select_ = vertical_vane_select;
|
||||
this->vertical_vane_select_->add_on_state_callback(
|
||||
[this](const std::string &value, size_t index) {
|
||||
if (value == this->vertical_swing_state_) return;
|
||||
this->on_vertical_swing_change(value);
|
||||
});
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_horizontal_vane_select(
|
||||
select::Select *horizontal_vane_select) {
|
||||
this->horizontal_vane_select_ = horizontal_vane_select;
|
||||
this->horizontal_vane_select_->add_on_state_callback(
|
||||
[this](const std::string &value, size_t index) {
|
||||
if (value == this->horizontal_swing_state_) return;
|
||||
this->on_horizontal_swing_change(value);
|
||||
});
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::on_vertical_swing_change(const std::string &swing) {
|
||||
ESP_LOGD(TAG, "Setting vertical swing position");
|
||||
bool updated = false;
|
||||
|
||||
if (swing == "swing") {
|
||||
hp->setVaneSetting("SWING");
|
||||
updated = true;
|
||||
} else if (swing == "auto") {
|
||||
hp->setVaneSetting("AUTO");
|
||||
updated = true;
|
||||
} else if (swing == "up") {
|
||||
hp->setVaneSetting("1");
|
||||
updated = true;
|
||||
} else if (swing == "up_center") {
|
||||
hp->setVaneSetting("2");
|
||||
updated = true;
|
||||
} else if (swing == "center") {
|
||||
hp->setVaneSetting("3");
|
||||
updated = true;
|
||||
} else if (swing == "down_center") {
|
||||
hp->setVaneSetting("4");
|
||||
updated = true;
|
||||
} else if (swing == "down") {
|
||||
hp->setVaneSetting("5");
|
||||
updated = true;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Invalid vertical vane position %s", swing);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Vertical vane - Was HeatPump updated? %s", YESNO(updated));
|
||||
|
||||
// and the heat pump:
|
||||
hp->update();
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::on_horizontal_swing_change(const std::string &swing) {
|
||||
ESP_LOGD(TAG, "Setting horizontal swing position");
|
||||
bool updated = false;
|
||||
|
||||
if (swing == "swing") {
|
||||
hp->setWideVaneSetting("SWING");
|
||||
updated = true;
|
||||
} else if (swing == "auto") {
|
||||
hp->setWideVaneSetting("<>");
|
||||
updated = true;
|
||||
} else if (swing == "left") {
|
||||
hp->setWideVaneSetting("<<");
|
||||
updated = true;
|
||||
} else if (swing == "left_center") {
|
||||
hp->setWideVaneSetting("<");
|
||||
updated = true;
|
||||
} else if (swing == "center") {
|
||||
hp->setWideVaneSetting("|");
|
||||
updated = true;
|
||||
} else if (swing == "right_center") {
|
||||
hp->setWideVaneSetting(">");
|
||||
updated = true;
|
||||
} else if (swing == "right") {
|
||||
hp->setWideVaneSetting(">>");
|
||||
updated = true;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Invalid horizontal vane position %s", swing);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Horizontal vane - Was HeatPump updated? %s", YESNO(updated));
|
||||
|
||||
// and the heat pump:
|
||||
hp->update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement control of a MitsubishiHeatPump.
|
||||
*
|
||||
@ -106,6 +236,24 @@ void MitsubishiHeatPump::control(const climate::ClimateCall &call) {
|
||||
if (has_mode){
|
||||
this->mode = *call.get_mode();
|
||||
}
|
||||
|
||||
if (last_remote_temperature_sensor_update_.has_value()) {
|
||||
// Some remote temperature sensors will only issue updates when a change
|
||||
// in temperature occurs.
|
||||
|
||||
// Assume a case where the idle sensor timeout is 12hrs and operating
|
||||
// timeout is 1hr. If the user changes the HP setpoint after 1.5hrs, the
|
||||
// machine will switch to operating mode, the remote temperature
|
||||
// reading will expire and the HP will revert to it's internal
|
||||
// temperature sensor.
|
||||
|
||||
// This change ensures that if the user changes the machine setpoint,
|
||||
// the remote sensor has an opportunity to issue an update to reflect
|
||||
// the new change in temperature.
|
||||
last_remote_temperature_sensor_update_ =
|
||||
std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
switch (this->mode) {
|
||||
case climate::CLIMATE_MODE_COOL:
|
||||
hp->setModeSetting("COOL");
|
||||
@ -227,10 +375,22 @@ void MitsubishiHeatPump::control(const climate::ClimateCall &call) {
|
||||
switch(*call.get_swing_mode()) {
|
||||
case climate::CLIMATE_SWING_OFF:
|
||||
hp->setVaneSetting("AUTO");
|
||||
hp->setWideVaneSetting("|");
|
||||
updated = true;
|
||||
break;
|
||||
case climate::CLIMATE_SWING_VERTICAL:
|
||||
hp->setVaneSetting("SWING");
|
||||
hp->setWideVaneSetting("|");
|
||||
updated = true;
|
||||
break;
|
||||
case climate::CLIMATE_SWING_HORIZONTAL:
|
||||
hp->setVaneSetting("3");
|
||||
hp->setWideVaneSetting("SWING");
|
||||
updated = true;
|
||||
break;
|
||||
case climate::CLIMATE_SWING_BOTH:
|
||||
hp->setVaneSetting("SWING");
|
||||
hp->setWideVaneSetting("SWING");
|
||||
updated = true;
|
||||
break;
|
||||
default:
|
||||
@ -333,15 +493,52 @@ void MitsubishiHeatPump::hpSettingsChanged() {
|
||||
/* ******** HANDLE MITSUBISHI VANE CHANGES ********
|
||||
* const char* VANE_MAP[7] = {"AUTO", "1", "2", "3", "4", "5", "SWING"};
|
||||
*/
|
||||
if (strcmp(currentSettings.vane, "SWING") == 0) {
|
||||
if (strcmp(currentSettings.vane, "SWING") == 0 &&
|
||||
strcmp(currentSettings.wideVane, "SWING") == 0) {
|
||||
this->swing_mode = climate::CLIMATE_SWING_BOTH;
|
||||
} else if (strcmp(currentSettings.vane, "SWING") == 0) {
|
||||
this->swing_mode = climate::CLIMATE_SWING_VERTICAL;
|
||||
}
|
||||
else {
|
||||
} else if (strcmp(currentSettings.wideVane, "SWING") == 0) {
|
||||
this->swing_mode = climate::CLIMATE_SWING_HORIZONTAL;
|
||||
} else {
|
||||
this->swing_mode = climate::CLIMATE_SWING_OFF;
|
||||
}
|
||||
ESP_LOGI(TAG, "Swing mode is: %i", this->swing_mode);
|
||||
if (strcmp(currentSettings.vane, "SWING") == 0) {
|
||||
this->update_swing_vertical("swing");
|
||||
} else if (strcmp(currentSettings.vane, "AUTO") == 0) {
|
||||
this->update_swing_vertical("auto");
|
||||
} else if (strcmp(currentSettings.vane, "1") == 0) {
|
||||
this->update_swing_vertical("up");
|
||||
} else if (strcmp(currentSettings.vane, "2") == 0) {
|
||||
this->update_swing_vertical("up_center");
|
||||
} else if (strcmp(currentSettings.vane, "3") == 0) {
|
||||
this->update_swing_vertical("center");
|
||||
} else if (strcmp(currentSettings.vane, "4") == 0) {
|
||||
this->update_swing_vertical("down_center");
|
||||
} else if (strcmp(currentSettings.vane, "5") == 0) {
|
||||
this->update_swing_vertical("down");
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Vertical vane mode is: %s", currentSettings.vane);
|
||||
|
||||
if (strcmp(currentSettings.wideVane, "SWING") == 0) {
|
||||
this->update_swing_horizontal("swing");
|
||||
} else if (strcmp(currentSettings.wideVane, "<>") == 0) {
|
||||
this->update_swing_horizontal("auto");
|
||||
} else if (strcmp(currentSettings.wideVane, "<<") == 0) {
|
||||
this->update_swing_horizontal("left");
|
||||
} else if (strcmp(currentSettings.wideVane, "<") == 0) {
|
||||
this->update_swing_horizontal("left_center");
|
||||
} else if (strcmp(currentSettings.wideVane, "|") == 0) {
|
||||
this->update_swing_horizontal("center");
|
||||
} else if (strcmp(currentSettings.wideVane, ">") == 0) {
|
||||
this->update_swing_horizontal("right_center");
|
||||
} else if (strcmp(currentSettings.wideVane, ">>") == 0) {
|
||||
this->update_swing_horizontal("right");
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Horizontal vane mode is: %s", currentSettings.wideVane);
|
||||
|
||||
/*
|
||||
* ******** HANDLE TARGET TEMPERATURE CHANGES ********
|
||||
@ -402,14 +599,71 @@ void MitsubishiHeatPump::hpStatusChanged(heatpumpStatus currentStatus) {
|
||||
this->action = climate::CLIMATE_ACTION_OFF;
|
||||
}
|
||||
|
||||
this->operating_ = currentStatus.operating;
|
||||
|
||||
this->publish_state();
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_remote_temperature(float temp) {
|
||||
ESP_LOGD(TAG, "Setting remote temp: %.1f", temp);
|
||||
if (temp > 0) {
|
||||
last_remote_temperature_sensor_update_ =
|
||||
std::chrono::steady_clock::now();
|
||||
} else {
|
||||
last_remote_temperature_sensor_update_.reset();
|
||||
}
|
||||
|
||||
this->hp->setRemoteTemperature(temp);
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::ping() {
|
||||
ESP_LOGD(TAG, "Ping request received");
|
||||
last_ping_request_ = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_remote_operating_timeout_minutes(int minutes) {
|
||||
ESP_LOGD(TAG, "Setting remote operating timeout time: %d minutes", minutes);
|
||||
remote_operating_timeout_ = std::chrono::minutes(minutes);
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_remote_idle_timeout_minutes(int minutes) {
|
||||
ESP_LOGD(TAG, "Setting remote idle timeout time: %d minutes", minutes);
|
||||
remote_idle_timeout_ = std::chrono::minutes(minutes);
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_remote_ping_timeout_minutes(int minutes) {
|
||||
ESP_LOGD(TAG, "Setting remote ping timeout time: %d minutes", minutes);
|
||||
remote_ping_timeout_ = std::chrono::minutes(minutes);
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::enforce_remote_temperature_sensor_timeout() {
|
||||
// Handle ping timeouts.
|
||||
if (remote_ping_timeout_.has_value() && last_ping_request_.has_value()) {
|
||||
auto time_since_last_ping =
|
||||
std::chrono::steady_clock::now() - last_ping_request_.value();
|
||||
if(time_since_last_ping > remote_ping_timeout_.value()) {
|
||||
ESP_LOGW(TAG, "Ping timeout.");
|
||||
this->set_remote_temperature(0);
|
||||
last_ping_request_.reset();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle set_remote_temperature timeouts.
|
||||
auto remote_set_temperature_timeout =
|
||||
this->operating_ ? remote_operating_timeout_ : remote_idle_timeout_;
|
||||
if (remote_set_temperature_timeout.has_value() &&
|
||||
last_remote_temperature_sensor_update_.has_value()) {
|
||||
auto time_since_last_temperature_update =
|
||||
std::chrono::steady_clock::now() - last_remote_temperature_sensor_update_.value();
|
||||
if (time_since_last_temperature_update > remote_set_temperature_timeout.value()) {
|
||||
ESP_LOGW(TAG, "Set remote temperature timeout, operating=%d", this->operating_);
|
||||
this->set_remote_temperature(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::setup() {
|
||||
// This will be called by App.setup()
|
||||
this->banner();
|
||||
@ -431,6 +685,8 @@ void MitsubishiHeatPump::setup() {
|
||||
this->target_temperature = NAN;
|
||||
this->fan_mode = climate::CLIMATE_FAN_OFF;
|
||||
this->swing_mode = climate::CLIMATE_SWING_OFF;
|
||||
this->vertical_swing_state_ = "auto";
|
||||
this->horizontal_swing_state_ = "auto";
|
||||
|
||||
#ifdef USE_CALLBACKS
|
||||
hp->setSettingsChangedCallback(
|
||||
@ -451,12 +707,11 @@ void MitsubishiHeatPump::setup() {
|
||||
"hw_serial(%p) is &Serial(%p)? %s",
|
||||
this->get_hw_serial_(),
|
||||
&Serial,
|
||||
YESNO(this->get_hw_serial_() == &Serial)
|
||||
YESNO((void *)this->get_hw_serial_() == (void *)&Serial)
|
||||
);
|
||||
|
||||
ESP_LOGCONFIG(TAG, "Calling hp->connect(%p)", this->get_hw_serial_());
|
||||
|
||||
if (hp->connect(this->get_hw_serial_(), this->baud_, -1, -1)) {
|
||||
if (hp->connect(this->get_hw_serial_(), this->baud_, this->rx_pin_, this->tx_pin_)) {
|
||||
hp->sync();
|
||||
}
|
||||
else {
|
||||
|
@ -18,10 +18,11 @@
|
||||
#define USE_CALLBACKS
|
||||
|
||||
#include "esphome.h"
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "esphome/core/preferences.h"
|
||||
#include <chrono>
|
||||
|
||||
#include "HeatPump.h"
|
||||
using namespace esphome;
|
||||
|
||||
#ifndef ESPMHP_H
|
||||
#define ESPMHP_H
|
||||
@ -41,7 +42,7 @@ static const uint8_t ESPMHP_MAX_TEMPERATURE = 31; // degrees C,
|
||||
static const float ESPMHP_TEMPERATURE_STEP = 0.5; // temperature setting step,
|
||||
// in degrees C
|
||||
|
||||
class MitsubishiHeatPump : public PollingComponent, public climate::Climate {
|
||||
class MitsubishiHeatPump : public esphome::PollingComponent, public esphome::climate::Climate {
|
||||
|
||||
public:
|
||||
|
||||
@ -58,14 +59,17 @@ class MitsubishiHeatPump : public PollingComponent, public climate::Climate {
|
||||
);
|
||||
|
||||
// Print a banner with library information.
|
||||
void banner() {
|
||||
ESP_LOGI(TAG, "ESPHome MitsubishiHeatPump version %s",
|
||||
ESPMHP_VERSION);
|
||||
}
|
||||
void banner();
|
||||
|
||||
// Set the baud rate. Must be called before setup() to have any effect.
|
||||
void set_baud_rate(int);
|
||||
|
||||
// Set the RX pin. Must be called before setup() to have any effect.
|
||||
void set_rx_pin(int);
|
||||
|
||||
// Set the TX pin. Must be called before setup() to have any effect.
|
||||
void set_tx_pin(int);
|
||||
|
||||
// print the current configuration
|
||||
void dump_config() override;
|
||||
|
||||
@ -82,27 +86,52 @@ class MitsubishiHeatPump : public PollingComponent, public climate::Climate {
|
||||
void update() override;
|
||||
|
||||
// Configure the climate object with traits that we support.
|
||||
climate::ClimateTraits traits() override;
|
||||
esphome::climate::ClimateTraits traits() override;
|
||||
|
||||
// Get a mutable reference to the traits that we support.
|
||||
climate::ClimateTraits& config_traits();
|
||||
esphome::climate::ClimateTraits& config_traits();
|
||||
|
||||
// Debugging function to print the object's state.
|
||||
void dump_state();
|
||||
|
||||
// Handle a request from the user to change settings.
|
||||
void control(const climate::ClimateCall &call) override;
|
||||
void control(const esphome::climate::ClimateCall &call) override;
|
||||
|
||||
// Use the temperature from an external sensor. Use
|
||||
// set_remote_temp(0) to switch back to the internal sensor.
|
||||
void set_remote_temperature(float);
|
||||
|
||||
void set_vertical_vane_select(esphome::select::Select *vertical_vane_select);
|
||||
void set_horizontal_vane_select(esphome::select::Select *horizontal_vane_select);
|
||||
|
||||
// Used to validate that a connection is present between the controller
|
||||
// and this heatpump.
|
||||
void ping();
|
||||
|
||||
// Number of minutes before the heatpump reverts back to the internal
|
||||
// temperature sensor if the machine is currently operating.
|
||||
void set_remote_operating_timeout_minutes(int);
|
||||
|
||||
// Number of minutes before the heatpump reverts back to the internal
|
||||
// temperature sensor if the machine is currently idle.
|
||||
void set_remote_idle_timeout_minutes(int);
|
||||
|
||||
// Number of minutes before the heatpump reverts back to the internal
|
||||
// temperature sensor if a ping isn't received from the controller.
|
||||
void set_remote_ping_timeout_minutes(int);
|
||||
|
||||
protected:
|
||||
// HeatPump object using the underlying Arduino library.
|
||||
HeatPump* hp;
|
||||
|
||||
// The ClimateTraits supported by this HeatPump.
|
||||
climate::ClimateTraits traits_;
|
||||
esphome::climate::ClimateTraits traits_;
|
||||
|
||||
// Vane position
|
||||
void update_swing_horizontal(const std::string &swing);
|
||||
void update_swing_vertical(const std::string &swing);
|
||||
std::string vertical_swing_state_;
|
||||
std::string horizontal_swing_state_;
|
||||
|
||||
// Allow the HeatPump class to use get_hw_serial_
|
||||
friend class HeatPump;
|
||||
@ -118,21 +147,41 @@ class MitsubishiHeatPump : public PollingComponent, public climate::Climate {
|
||||
|
||||
// various prefs to save mode-specific temperatures, akin to how the IR
|
||||
// remote works.
|
||||
ESPPreferenceObject cool_storage;
|
||||
ESPPreferenceObject heat_storage;
|
||||
ESPPreferenceObject auto_storage;
|
||||
esphome::ESPPreferenceObject cool_storage;
|
||||
esphome::ESPPreferenceObject heat_storage;
|
||||
esphome::ESPPreferenceObject auto_storage;
|
||||
|
||||
optional<float> cool_setpoint;
|
||||
optional<float> heat_setpoint;
|
||||
optional<float> auto_setpoint;
|
||||
esphome::optional<float> cool_setpoint;
|
||||
esphome::optional<float> heat_setpoint;
|
||||
esphome::optional<float> auto_setpoint;
|
||||
|
||||
static void save(float value, ESPPreferenceObject& storage);
|
||||
static optional<float> load(ESPPreferenceObject& storage);
|
||||
static void save(float value, esphome::ESPPreferenceObject& storage);
|
||||
static esphome::optional<float> load(esphome::ESPPreferenceObject& storage);
|
||||
|
||||
esphome::select::Select *vertical_vane_select_ =
|
||||
nullptr; // Select to store manual position of vertical swing
|
||||
esphome::select::Select *horizontal_vane_select_ =
|
||||
nullptr; // Select to store manual position of horizontal swing
|
||||
|
||||
// When received command to change the vane positions
|
||||
void on_horizontal_swing_change(const std::string &swing);
|
||||
void on_vertical_swing_change(const std::string &swing);
|
||||
|
||||
private:
|
||||
void enforce_remote_temperature_sensor_timeout();
|
||||
|
||||
// Retrieve the HardwareSerial pointer from friend and subclasses.
|
||||
HardwareSerial *hw_serial_;
|
||||
int baud_ = 0;
|
||||
int rx_pin_ = -1;
|
||||
int tx_pin_ = -1;
|
||||
bool operating_ = false;
|
||||
|
||||
std::optional<std::chrono::duration<long long, std::ratio<60>>> remote_operating_timeout_;
|
||||
std::optional<std::chrono::duration<long long, std::ratio<60>>> remote_idle_timeout_;
|
||||
std::optional<std::chrono::duration<long long, std::ratio<60>>> remote_ping_timeout_;
|
||||
std::optional<std::chrono::time_point<std::chrono::steady_clock>> last_remote_temperature_sensor_update_;
|
||||
std::optional<std::chrono::time_point<std::chrono::steady_clock>> last_ping_request_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
15
components/mitsubishi_heatpump/mitsubishi_ac_select.h
Normal file
15
components/mitsubishi_heatpump/mitsubishi_ac_select.h
Normal file
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/components/select/select.h"
|
||||
#include "esphome/core/component.h"
|
||||
|
||||
namespace esphome {
|
||||
|
||||
class MitsubishiACSelect : public select::Select, public Component {
|
||||
protected:
|
||||
void control(const std::string &value) override {
|
||||
this->publish_state(value);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome
|
Loading…
Reference in New Issue
Block a user