mirror of
https://github.com/geoffdavis/esphome-mitsubishiheatpump
synced 2024-08-30 18:12:13 +00:00
Merge pull request #28 from sijk/external_component
Make this usable as an `external_component`
This commit is contained in:
commit
c53dbc6e4b
3
.gitignore
vendored
3
.gitignore
vendored
@ -30,3 +30,6 @@
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Python cache
|
||||
__pycache__
|
||||
|
111
README.md
111
README.md
@ -11,7 +11,7 @@ ESP32 using the [ESPHome](https://esphome.io) framework.
|
||||
|
||||
## Requirements
|
||||
* https://github.com/SwiCago/HeatPump
|
||||
* ESPHome 1.15.0 or greater
|
||||
* ESPHome 1.18.0 or greater
|
||||
|
||||
## Supported Microcontrollers
|
||||
This library should work on most ESP8266 or ESP32 platforms. It has been tested
|
||||
@ -50,53 +50,47 @@ to the control
|
||||
board](https://github.com/SwiCago/HeatPump/issues/13#issuecomment-457897457)
|
||||
via CN105.
|
||||
|
||||
### Step 2: Use ESPHome 1.15.0 or higher
|
||||
### Step 2: Use ESPHome 1.18.0 or higher
|
||||
|
||||
The code in this repository makes use of a number of features in the 1.15.0 version of ESPHome, including various Fan modes.
|
||||
The code in this repository makes use of a number of features in the 1.18.0
|
||||
version of ESPHome, including various Fan modes and external components.
|
||||
|
||||
### Step 3: Clone this repository into your ESPHome configuration directory
|
||||
### Step 3: Add this repository as an external component
|
||||
|
||||
This repository needs to live in your ESPHome configuration directory, as it
|
||||
doesn't work correctly when used as a Platform.IO library, and there doesn't
|
||||
seem to be an analog for that functionality for ESPHome code.
|
||||
Add this repository to your ESPHome config:
|
||||
|
||||
On Hass.IO, you'll want to do something like:
|
||||
```yaml
|
||||
external_components:
|
||||
- source: github://geoffdavis/esphome-mitsubishiheatpump
|
||||
```
|
||||
|
||||
* Change directories to your esphome configuration directory.
|
||||
* `mkdir -p src`
|
||||
* `cd src`
|
||||
* `git clone https://github.com/geoffdavis/esphome-mitsubishiheatpump.git`
|
||||
### Step 4: Configure the heatpump
|
||||
|
||||
### Step 4: Configure your ESPHome device with YAML
|
||||
|
||||
Create an ESPHome YAML configuration with the following sections:
|
||||
* `esphome: libraries: [https://github.com/SwiCago/HeatPump]`
|
||||
* `esphome: includes: [src/esphome-mitsubishiheatpump]`
|
||||
* `climate:` - set up a custom climate entry, change the Serial port as needed.
|
||||
* ESP8266 only: `logger: baud_rate: 0` - disable serial port logging on the
|
||||
sole ESP8266 hardware UART
|
||||
|
||||
The custom climate definition should use `platform: custom` and contain a
|
||||
`lambda` block, where you instanciate an instance of the MitsubishiHeatPump
|
||||
class, and then register it with ESPHome. It should allso contain a "climates"
|
||||
entry. On ESP32 you
|
||||
can change `&Serial` to `&Serial1` or `&Serial2` and re-enable logging to the
|
||||
main serial port.
|
||||
|
||||
If that's all greek to you, here's an example. Change "My Heat Pump" to
|
||||
whatever you want.
|
||||
Add a `mitsubishi_heatpump` to your ESPHome config:
|
||||
|
||||
```yaml
|
||||
climate:
|
||||
- platform: custom
|
||||
lambda: |-
|
||||
auto my_heatpump = new MitsubishiHeatPump(&Serial);
|
||||
App.register_component(my_heatpump);
|
||||
return {my_heatpump};
|
||||
climates:
|
||||
- name: "My Heat Pump"
|
||||
- platform: mitsubishi_heatpump
|
||||
name: "My Heat Pump"
|
||||
|
||||
# Optional
|
||||
hardware_uart: UART0
|
||||
|
||||
# Optional
|
||||
update_period: 500ms
|
||||
```
|
||||
|
||||
On ESP8266 you'll need to disable logging to serial because it conflicts with
|
||||
the heatpump UART:
|
||||
|
||||
```yaml
|
||||
logger:
|
||||
baud_rate: 0
|
||||
```
|
||||
|
||||
On ESP32 you can change `hardware_uart` to `UART1` or `UART2` and keep logging
|
||||
enabled on the main serial port.
|
||||
|
||||
Note: this component DOES NOT use the ESPHome `uart` component, as it requires
|
||||
direct access to a hardware UART via the Arduino `HardwareSerial` class. The
|
||||
Mitsubishi Heatpump units use an atypical serial port setting ("even parity").
|
||||
@ -119,12 +113,6 @@ esphome:
|
||||
board: esp01_1m
|
||||
# Boards tested: ESP-01S (ESP8266), Wemos D1 Mini (ESP8266); ESP32 Wifi-DevKit2
|
||||
|
||||
libraries:
|
||||
- https://github.com/SwiCago/HeatPump
|
||||
|
||||
includes:
|
||||
- src/esphome-mitsubishiheatpump
|
||||
|
||||
wifi:
|
||||
ssid: !secret wifi_ssid
|
||||
password: !secret wifi_password
|
||||
@ -181,18 +169,39 @@ sensor:
|
||||
name: denheatpump WiFi Signal
|
||||
update_interval: 60s
|
||||
|
||||
external_components:
|
||||
- source: github://geoffdavis/esphome-mitsubishiheatpump
|
||||
|
||||
climate:
|
||||
- platform: custom
|
||||
# ESP32 only - change &Serial to &Serial1 or &Serial2 and remove the
|
||||
- platform: mitsubishi_heatpump
|
||||
name: "Den Heat Pump"
|
||||
|
||||
# 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.
|
||||
lambda: |-
|
||||
auto my_heatpump = new MitsubishiHeatPump(&Serial);
|
||||
App.register_component(my_heatpump);
|
||||
return {my_heatpump};
|
||||
climates:
|
||||
- name: "Den Heat Pump"
|
||||
hardware_uart: UART0
|
||||
```
|
||||
|
||||
# Advanced
|
||||
|
||||
Some models of heat pump require different baud rates or don't support all
|
||||
possible modes of operation. You can configure pretty much everything in YAML
|
||||
to match what your hardware supports. For example:
|
||||
|
||||
```yaml
|
||||
climate:
|
||||
- platform: mitsubishi_heatpump
|
||||
name: "My heat pump"
|
||||
hardware_uart: UART2
|
||||
baud_rate: 9600
|
||||
supports:
|
||||
mode: [AUTO, COOL, HEAT, FAN_ONLY]
|
||||
fan_mode: [AUTO, LOW, MEDIUM, HIGH]
|
||||
swing_mode: [OFF, VERTICAL]
|
||||
visual:
|
||||
min_temperature: 16
|
||||
max_temperature: 31
|
||||
temperature_step: 1.0
|
||||
```
|
||||
|
||||
# See Also
|
||||
|
0
components/mitsubishi_heatpump/__init__.py
Normal file
0
components/mitsubishi_heatpump/__init__.py
Normal file
88
components/mitsubishi_heatpump/climate.py
Normal file
88
components/mitsubishi_heatpump/climate.py
Normal file
@ -0,0 +1,88 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import climate
|
||||
from esphome.components.logger import HARDWARE_UART_TO_SERIAL
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_HARDWARE_UART,
|
||||
CONF_BAUD_RATE,
|
||||
CONF_UPDATE_INTERVAL,
|
||||
CONF_MODE,
|
||||
CONF_FAN_MODE,
|
||||
CONF_SWING_MODE,
|
||||
)
|
||||
from esphome.core import CORE, coroutine
|
||||
|
||||
AUTO_LOAD = ["climate"]
|
||||
|
||||
CONF_SUPPORTS = "supports"
|
||||
DEFAULT_CLIMATE_MODES = ['AUTO', 'COOL', 'HEAT', 'DRY', 'FAN_ONLY']
|
||||
DEFAULT_FAN_MODES = ['AUTO', 'DIFFUSE', 'LOW', 'MEDIUM', 'MIDDLE', 'HIGH']
|
||||
DEFAULT_SWING_MODES = ['OFF', 'VERTICAL']
|
||||
|
||||
MitsubishiHeatPump = cg.global_ns.class_("MitsubishiHeatPump", climate.Climate, cg.PollingComponent)
|
||||
|
||||
|
||||
def valid_uart(uart):
|
||||
if CORE.is_esp8266:
|
||||
uarts = ["UART0"] # UART1 is tx-only
|
||||
elif CORE.is_esp32:
|
||||
uarts = ["UART0", "UART1", "UART2"]
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
return cv.one_of(*uarts, upper=True)(uart)
|
||||
|
||||
|
||||
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,
|
||||
|
||||
# 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))
|
||||
),
|
||||
|
||||
# Optionally override the supported ClimateTraits.
|
||||
cv.Optional(CONF_SUPPORTS, default={}): cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_MODE, default=DEFAULT_CLIMATE_MODES):
|
||||
cv.ensure_list(climate.validate_climate_mode),
|
||||
cv.Optional(CONF_FAN_MODE, default=DEFAULT_FAN_MODES):
|
||||
cv.ensure_list(climate.validate_climate_fan_mode),
|
||||
cv.Optional(CONF_SWING_MODE, default=DEFAULT_SWING_MODES):
|
||||
cv.ensure_list(climate.validate_climate_swing_mode),
|
||||
}
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
@coroutine
|
||||
def to_code(config):
|
||||
serial = HARDWARE_UART_TO_SERIAL[config[CONF_HARDWARE_UART]]
|
||||
var = cg.new_Pvariable(config[CONF_ID], cg.RawExpression(f'&{serial}'))
|
||||
|
||||
if CONF_BAUD_RATE in config:
|
||||
cg.add(var.set_baud_rate(config[CONF_BAUD_RATE]))
|
||||
|
||||
traits = []
|
||||
for mode in config[CONF_SUPPORTS][CONF_MODE]:
|
||||
if mode == 'OFF':
|
||||
continue
|
||||
traits.append(f'set_supports_{mode.lower()}_mode')
|
||||
for mode in config[CONF_SUPPORTS][CONF_FAN_MODE]:
|
||||
traits.append(f'set_supports_fan_mode_{mode.lower()}')
|
||||
for mode in config[CONF_SUPPORTS][CONF_SWING_MODE]:
|
||||
traits.append(f'set_supports_swing_mode_{mode.lower()}')
|
||||
for trait in traits:
|
||||
cg.add(getattr(var.config_traits(), trait)(True))
|
||||
|
||||
yield cg.register_component(var, config)
|
||||
yield climate.register_climate(var, config)
|
||||
cg.add_library("https://github.com/SwiCago/HeatPump", None)
|
||||
|
@ -32,7 +32,15 @@ MitsubishiHeatPump::MitsubishiHeatPump(
|
||||
) :
|
||||
PollingComponent{poll_interval}, // member initializers list
|
||||
hw_serial_{hw_serial}
|
||||
{ }
|
||||
{
|
||||
this->traits_.set_supports_action(true);
|
||||
this->traits_.set_supports_current_temperature(true);
|
||||
this->traits_.set_supports_two_point_target_temperature(false);
|
||||
this->traits_.set_supports_away(false);
|
||||
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);
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::check_logger_conflict_() {
|
||||
#ifdef USE_LOGGER
|
||||
@ -56,8 +64,12 @@ void MitsubishiHeatPump::update() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void MitsubishiHeatPump::set_baud_rate(int baud) {
|
||||
this->baud_ = baud;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define our supported traits.
|
||||
* Get our supported traits.
|
||||
*
|
||||
* Note:
|
||||
* Many of the following traits are only available in the 1.5.0 dev train of
|
||||
@ -67,33 +79,17 @@ void MitsubishiHeatPump::update() {
|
||||
* This class' supported climate::ClimateTraits.
|
||||
*/
|
||||
climate::ClimateTraits MitsubishiHeatPump::traits() {
|
||||
auto traits = climate::ClimateTraits();
|
||||
traits.set_supports_action(true);
|
||||
traits.set_supports_current_temperature(true);
|
||||
traits.set_supports_auto_mode(true);
|
||||
traits.set_supports_cool_mode(true);
|
||||
traits.set_supports_heat_mode(true);
|
||||
traits.set_supports_dry_mode(true);
|
||||
traits.set_supports_fan_only_mode(true);
|
||||
traits.set_supports_two_point_target_temperature(false);
|
||||
traits.set_supports_away(false);
|
||||
traits.set_visual_min_temperature(ESPMHP_MIN_TEMPERATURE);
|
||||
traits.set_visual_max_temperature(ESPMHP_MAX_TEMPERATURE);
|
||||
traits.set_visual_temperature_step(ESPMHP_TEMPERATURE_STEP);
|
||||
traits.set_supports_fan_mode_on(false);
|
||||
traits.set_supports_fan_mode_off(false);
|
||||
traits.set_supports_fan_mode_auto(true);
|
||||
traits.set_supports_fan_mode_focus(false);
|
||||
traits.set_supports_fan_mode_diffuse(true);
|
||||
traits.set_supports_fan_mode_low(true);
|
||||
traits.set_supports_fan_mode_medium(true);
|
||||
traits.set_supports_fan_mode_middle(true);
|
||||
traits.set_supports_fan_mode_high(true);
|
||||
traits.set_supports_swing_mode_off(true);
|
||||
traits.set_supports_swing_mode_both(false);
|
||||
traits.set_supports_swing_mode_vertical(true);
|
||||
traits.set_supports_swing_mode_horizontal(false);
|
||||
return traits;
|
||||
return traits_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify our supported traits.
|
||||
*
|
||||
* Returns:
|
||||
* A reference to this class' supported climate::ClimateTraits.
|
||||
*/
|
||||
climate::ClimateTraits& MitsubishiHeatPump::config_traits() {
|
||||
return traits_;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -451,7 +447,7 @@ void MitsubishiHeatPump::setup() {
|
||||
|
||||
ESP_LOGCONFIG(TAG, "Calling hp->connect(%p)", this->get_hw_serial_());
|
||||
|
||||
if (hp->connect(this->get_hw_serial_())) {
|
||||
if (hp->connect(this->get_hw_serial_(), this->baud_)) {
|
||||
hp->sync();
|
||||
}
|
||||
else {
|
@ -62,6 +62,9 @@ class MitsubishiHeatPump : public PollingComponent, public climate::Climate {
|
||||
ESPMHP_VERSION);
|
||||
}
|
||||
|
||||
// Set the baud rate. Must be called before setup() to have any effect.
|
||||
void set_baud_rate(int);
|
||||
|
||||
// print the current configuration
|
||||
void dump_config() override;
|
||||
|
||||
@ -80,6 +83,9 @@ class MitsubishiHeatPump : public PollingComponent, public climate::Climate {
|
||||
// Configure the climate object with traits that we support.
|
||||
climate::ClimateTraits traits() override;
|
||||
|
||||
// Get a mutable reference to the traits that we support.
|
||||
climate::ClimateTraits& config_traits();
|
||||
|
||||
// Debugging function to print the object's state.
|
||||
void dump_state();
|
||||
|
||||
@ -90,6 +96,9 @@ class MitsubishiHeatPump : public PollingComponent, public climate::Climate {
|
||||
// HeatPump object using the underlying Arduino library.
|
||||
HeatPump* hp;
|
||||
|
||||
// The ClimateTraits supported by this HeatPump.
|
||||
climate::ClimateTraits traits_;
|
||||
|
||||
// Allow the HeatPump class to use get_hw_serial_
|
||||
friend class HeatPump;
|
||||
|
||||
@ -118,7 +127,7 @@ class MitsubishiHeatPump : public PollingComponent, public climate::Climate {
|
||||
private:
|
||||
// Retrieve the HardwareSerial pointer from friend and subclasses.
|
||||
HardwareSerial *hw_serial_;
|
||||
|
||||
int baud_ = 0;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user