Added component panasonic heatpump
This commit is contained in:
parent
8e8464dd27
commit
6419fd80a7
|
|
@ -1 +1,2 @@
|
||||||
**/__pycache__/**
|
**/__pycache__/**
|
||||||
|
**.DS_Store
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import uart
|
||||||
|
from esphome.const import CONF_ID, CONF_ADDRESS
|
||||||
|
|
||||||
|
CODEOWNERS = ['@elvit']
|
||||||
|
MULTICONF = True
|
||||||
|
DEPENDENCIES = ['uart']
|
||||||
|
|
||||||
|
CONF_PANASONIC_HEATPUMP_ID = "panasonic_heatpump"
|
||||||
|
CONF_UART_HP = "uart_hp"
|
||||||
|
CONF_UART_WM = "uart_wm"
|
||||||
|
|
||||||
|
panasonic_heatpump_ns = cg.esphome_ns.namespace('panasonic_heatpump')
|
||||||
|
PanasonicHeatpumpComponent = panasonic_heatpump_ns.class_('PanasonicHeatpumpComponent', cg.Component)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = (
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(): cv.declare_id(PanasonicHeatpumpComponent),
|
||||||
|
|
||||||
|
cv.Required(CONF_UART_HP): cv.use_id(uart.UARTComponent),
|
||||||
|
cv.Required(CONF_UART_WM): cv.use_id(uart.UARTComponent),
|
||||||
|
}
|
||||||
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
await cg.register_component(var, config)
|
||||||
|
|
||||||
|
uart_hp = await cg.get_variable(config[CONF_UART_HP])
|
||||||
|
cg.add(var.set_uart_hp(uart_hp))
|
||||||
|
|
||||||
|
uart_wm = await cg.get_variable(config[CONF_UART_WM])
|
||||||
|
cg.add(var.set_uart_wm(uart_wm))
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import binary_sensor
|
||||||
|
from esphome.const import (
|
||||||
|
DEVICE_CLASS_HEAT,
|
||||||
|
)
|
||||||
|
from . import PanasonicHeatpumpComponent, CONF_PANASONIC_HEATPUMP_ID
|
||||||
|
|
||||||
|
CONF_BIN_SENS_TOP0 = "top0"
|
||||||
|
CONF_BIN_SENS_TOP2 = "top2"
|
||||||
|
CONF_BIN_SENS_TOP3 = "top3"
|
||||||
|
CONF_BIN_SENS_TOP13 = "top13"
|
||||||
|
CONF_BIN_SENS_TOP26 = "top26"
|
||||||
|
CONF_BIN_SENS_TOP60 = "top60"
|
||||||
|
CONF_BIN_SENS_TOP61 = "top61"
|
||||||
|
CONF_BIN_SENS_TOP68 = "top68"
|
||||||
|
CONF_BIN_SENS_TOP69 = "top69"
|
||||||
|
CONF_BIN_SENS_TOP99 = "top99"
|
||||||
|
CONF_BIN_SENS_TOP100 = "top100"
|
||||||
|
CONF_BIN_SENS_TOP108 = "top108"
|
||||||
|
CONF_BIN_SENS_TOP109 = "top109"
|
||||||
|
CONF_BIN_SENS_TOP110 = "top110"
|
||||||
|
|
||||||
|
TYPES = [
|
||||||
|
CONF_BIN_SENS_TOP0,
|
||||||
|
CONF_BIN_SENS_TOP2,
|
||||||
|
CONF_BIN_SENS_TOP3,
|
||||||
|
CONF_BIN_SENS_TOP13,
|
||||||
|
CONF_BIN_SENS_TOP26,
|
||||||
|
CONF_BIN_SENS_TOP60,
|
||||||
|
CONF_BIN_SENS_TOP61,
|
||||||
|
CONF_BIN_SENS_TOP68,
|
||||||
|
CONF_BIN_SENS_TOP69,
|
||||||
|
CONF_BIN_SENS_TOP99,
|
||||||
|
CONF_BIN_SENS_TOP100,
|
||||||
|
CONF_BIN_SENS_TOP108,
|
||||||
|
CONF_BIN_SENS_TOP109,
|
||||||
|
CONF_BIN_SENS_TOP110,
|
||||||
|
]
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.All(
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(PanasonicHeatpumpComponent),
|
||||||
|
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP0): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP2): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP3): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP13): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP26): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP60): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP61): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP68): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP69): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP99): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP100): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP108): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP109): binary_sensor.binary_sensor_schema(),
|
||||||
|
cv.Optional(CONF_BIN_SENS_TOP110): binary_sensor.binary_sensor_schema(),
|
||||||
|
}
|
||||||
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def setup_conf(config, key, hub):
|
||||||
|
if sensor_config := config.get(key):
|
||||||
|
var = await binary_sensor.new_binary_sensor(sensor_config)
|
||||||
|
cg.add(getattr(hub, f"set_{key}_binary_sensor")(var))
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
hub = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID])
|
||||||
|
for key in TYPES:
|
||||||
|
await setup_conf(config, key, hub)
|
||||||
|
|
@ -0,0 +1,256 @@
|
||||||
|
#include "decode.h"
|
||||||
|
|
||||||
|
|
||||||
|
constexpr const char* const PanasonicDecode::DisabledEnabled[];
|
||||||
|
constexpr const char* const PanasonicDecode::BlockedFree[];
|
||||||
|
constexpr const char* const PanasonicDecode::OffOn[];
|
||||||
|
constexpr const char* const PanasonicDecode::InactiveActive[];
|
||||||
|
constexpr const char* const PanasonicDecode::PumpFlowRateMode[];
|
||||||
|
constexpr const char* const PanasonicDecode::HolidayState[];
|
||||||
|
constexpr const char* const PanasonicDecode::OpModeDesc[];
|
||||||
|
constexpr const char* const PanasonicDecode::Powerfulmode[];
|
||||||
|
constexpr const char* const PanasonicDecode::Quietmode[];
|
||||||
|
constexpr const char* const PanasonicDecode::Valve[];
|
||||||
|
constexpr const char* const PanasonicDecode::MixingValve[];
|
||||||
|
constexpr const char* const PanasonicDecode::ZonesState[];
|
||||||
|
constexpr const char* const PanasonicDecode::HeatCoolModeDesc[];
|
||||||
|
constexpr const char* const PanasonicDecode::SolarModeDesc[];
|
||||||
|
constexpr const char* const PanasonicDecode::ZonesSensorType[];
|
||||||
|
constexpr const char* const PanasonicDecode::LiquidType[];
|
||||||
|
constexpr const char* const PanasonicDecode::ExtPadHeaterType[];
|
||||||
|
constexpr const char* const PanasonicDecode::Bivalent[];
|
||||||
|
constexpr const char* const PanasonicDecode::ModelNames[];
|
||||||
|
|
||||||
|
|
||||||
|
int PanasonicDecode::getBit1(uint8_t input)
|
||||||
|
{
|
||||||
|
return (input >> 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getBit1and2(uint8_t input)
|
||||||
|
{
|
||||||
|
return ((input >> 6) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getBit3and4(uint8_t input)
|
||||||
|
{
|
||||||
|
return (((input >> 4) & 0b11) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getBit5and6(uint8_t input)
|
||||||
|
{
|
||||||
|
return (((input >> 2) & 0b11) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getBit7and8(uint8_t input)
|
||||||
|
{
|
||||||
|
return ((input & 0b11) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getBit3and4and5(uint8_t input)
|
||||||
|
{
|
||||||
|
return (((input >> 3) & 0b111) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getLeft5bits(uint8_t input)
|
||||||
|
{
|
||||||
|
return ((input >> 3) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getRight3bits(uint8_t input)
|
||||||
|
{
|
||||||
|
return ((input & 0b111) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getIntMinus1(uint8_t input)
|
||||||
|
{
|
||||||
|
int value = (int)input - 1;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getIntMinus128(uint8_t input)
|
||||||
|
{
|
||||||
|
int value = (int)input - 128;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
float PanasonicDecode::getIntMinus1Div5(uint8_t input)
|
||||||
|
{
|
||||||
|
return ((((float)input - 1) / 5), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
float PanasonicDecode::getIntMinus1Div50(uint8_t input)
|
||||||
|
{
|
||||||
|
return ((((float)input - 1) / 50), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getIntMinus1Times10(uint8_t input)
|
||||||
|
{
|
||||||
|
int value = (int)input - 1;
|
||||||
|
return (value * 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getIntMinus1Times50(uint8_t input)
|
||||||
|
{
|
||||||
|
int value = (int)input - 1;
|
||||||
|
return (value * 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getFirstByte(uint8_t input)
|
||||||
|
{
|
||||||
|
return ((input >> 4) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getSecondByte(uint8_t input)
|
||||||
|
{
|
||||||
|
return ((input & 0b1111) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getWord(uint8_t low, uint8_t hi)
|
||||||
|
{
|
||||||
|
return ((hi << 8) + low) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PanasonicDecode::getUintt16(uint8_t input1, uint8_t input2)
|
||||||
|
{
|
||||||
|
uint16_t value = static_cast<uint16_t>((input2 << 8) | input1);
|
||||||
|
return (value - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOP15, TOP16, TOP38, TOP39, TOP40, TOP41 //
|
||||||
|
int PanasonicDecode::getPower(uint8_t input)
|
||||||
|
{
|
||||||
|
int value = ((int)input - 1) * 200;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOP4 //
|
||||||
|
int PanasonicDecode::getOpMode(uint8_t input)
|
||||||
|
{
|
||||||
|
switch ((int)(input & 0b111111))
|
||||||
|
{
|
||||||
|
case 18:
|
||||||
|
return 0;
|
||||||
|
case 19:
|
||||||
|
return 1;
|
||||||
|
case 25:
|
||||||
|
return 2;
|
||||||
|
case 33:
|
||||||
|
return 3;
|
||||||
|
case 34:
|
||||||
|
return 4;
|
||||||
|
case 35:
|
||||||
|
return 5;
|
||||||
|
case 41:
|
||||||
|
return 6;
|
||||||
|
case 26:
|
||||||
|
return 7;
|
||||||
|
case 42:
|
||||||
|
return 8;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOP124 //
|
||||||
|
int PanasonicDecode::getBivalent(uint8_t input)
|
||||||
|
{
|
||||||
|
switch ((int)input)
|
||||||
|
{
|
||||||
|
case 0x55:
|
||||||
|
return 0;
|
||||||
|
case 0x56:
|
||||||
|
return 1;
|
||||||
|
case 0x57:
|
||||||
|
return 2;
|
||||||
|
case 0x58:
|
||||||
|
return 3;
|
||||||
|
case 0x59:
|
||||||
|
return 4;
|
||||||
|
case 0x5A:
|
||||||
|
return 5;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOP92 //
|
||||||
|
int PanasonicDecode::getModel(std::vector<uint8_t>& data, uint8_t index)
|
||||||
|
{
|
||||||
|
uint8_t model[10] = { data[index], data[index+1], data[index+2], data[index+3], data[index+4], data[index+5], data[index+6], data[index+7], data[index+8], data[index+9] };
|
||||||
|
int result = -1;
|
||||||
|
int size = sizeof(KnownModels) / sizeof(KnownModels[0]);
|
||||||
|
|
||||||
|
for (unsigned int i = 0 ; i < size; i++)
|
||||||
|
{
|
||||||
|
if (memcmp(model, KnownModels[i], 10) == 0)
|
||||||
|
{
|
||||||
|
result = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOP1 //
|
||||||
|
// input1 = data[169]
|
||||||
|
// input2 = data[170]
|
||||||
|
float PanasonicDecode::getPumpFlow(uint8_t input1, uint8_t input2)
|
||||||
|
{
|
||||||
|
int PumpFlow2 = (int)input2;
|
||||||
|
float PumpFlow1 = (((float)input1 - 1) / 256);
|
||||||
|
float PumpFlow = PumpFlow2 + PumpFlow1;
|
||||||
|
return PumpFlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOP5, TOP6 //
|
||||||
|
float PanasonicDecode::getFractional(uint8_t input, uint8_t shift)
|
||||||
|
{
|
||||||
|
float result;
|
||||||
|
int fractional = (int)((input >> shift) & 0b111) - 1;
|
||||||
|
result = fractional * 0.25;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TOP44 //
|
||||||
|
// errorType = data[113]
|
||||||
|
// errorNumber = data[114]
|
||||||
|
std::string PanasonicDecode::getErrorInfo(uint8_t errorType, uint8_t errorNumber)
|
||||||
|
{
|
||||||
|
int error_type = (int)(errorType);
|
||||||
|
int error_number = ((int)(errorNumber)) - 17;
|
||||||
|
char error_string[10];
|
||||||
|
|
||||||
|
switch (error_type)
|
||||||
|
{
|
||||||
|
case 177: // B1=F type error
|
||||||
|
sprintf(error_string, "F%02X", error_number);
|
||||||
|
break;
|
||||||
|
case 161: // A1=H type error
|
||||||
|
sprintf(error_string, "H%02X", error_number);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sprintf(error_string, "No error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PanasonicDecode::getBoolState(uint8_t input)
|
||||||
|
{
|
||||||
|
return input != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PanasonicDecode::getTextState(const char* const array[], int index)
|
||||||
|
{
|
||||||
|
int size = atoi(array[0]);
|
||||||
|
|
||||||
|
if ((index < 0) || (index >= size))
|
||||||
|
{
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
|
return array[index + 1];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define NUMBER_OF_MODELS 51
|
||||||
|
#define NUMBER_OF_TOPICS 127
|
||||||
|
#define NUMBER_OF_TOPICS_EXTRA 6
|
||||||
|
#define NUMBER_OF_OPT_TOPICS 7
|
||||||
|
#define MAX_TOPIC_LEN 42
|
||||||
|
|
||||||
|
|
||||||
|
class PanasonicDecode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PanasonicDecode() = delete;
|
||||||
|
|
||||||
|
static int getBit1(uint8_t input);
|
||||||
|
static int getBit1and2(uint8_t input);
|
||||||
|
static int getBit3and4(uint8_t input);
|
||||||
|
static int getBit5and6(uint8_t input);
|
||||||
|
static int getBit7and8(uint8_t input);
|
||||||
|
static int getBit3and4and5(uint8_t input);
|
||||||
|
static int getLeft5bits(uint8_t input);
|
||||||
|
static int getRight3bits(uint8_t input);
|
||||||
|
static int getIntMinus1(uint8_t input);
|
||||||
|
static int getIntMinus128(uint8_t input);
|
||||||
|
static float getIntMinus1Div5(uint8_t input);
|
||||||
|
static float getIntMinus1Div50(uint8_t input);
|
||||||
|
static int getIntMinus1Times10(uint8_t input);
|
||||||
|
static int getIntMinus1Times50(uint8_t input);
|
||||||
|
static int getFirstByte(uint8_t input);
|
||||||
|
static int getSecondByte(uint8_t input);
|
||||||
|
static int getWord(uint8_t hi, uint8_t low);
|
||||||
|
static int getUintt16(uint8_t input1, uint8_t input2);
|
||||||
|
|
||||||
|
static int getPower(uint8_t input);
|
||||||
|
static int getOpMode(uint8_t input);
|
||||||
|
static int getModel(std::vector<uint8_t>& data, uint8_t index);
|
||||||
|
static int getBivalent(uint8_t input);
|
||||||
|
static float getPumpFlow(uint8_t input1, uint8_t input2);
|
||||||
|
static float getFractional(uint8_t input, uint8_t shift);
|
||||||
|
static std::string getErrorInfo(uint8_t errorType, uint8_t errorNumber);
|
||||||
|
|
||||||
|
static bool getBoolState(uint8_t input);
|
||||||
|
static std::string getTextState(const char* const array[], int index);
|
||||||
|
|
||||||
|
|
||||||
|
static const constexpr char* const DisabledEnabled[] = {"2", "Disabled", "Enabled"};
|
||||||
|
static const constexpr char* const BlockedFree[] = {"2", "Blocked", "Free"};
|
||||||
|
static const constexpr char* const OffOn[] = {"2", "Off", "On"};
|
||||||
|
static const constexpr char* const InactiveActive[] = {"2", "Inactive", "Active"};
|
||||||
|
static const constexpr char* const PumpFlowRateMode[] = {"2", "DeltaT", "Max flow"};
|
||||||
|
static const constexpr char* const HolidayState[] = {"3", "Off", "Scheduled", "Active"};
|
||||||
|
static const constexpr char* const OpModeDesc[] = {"9", "Heat", "Cool", "Auto(heat)", "DHW", "Heat+DHW", "Cool+DHW", "Auto(heat)+DHW", "Auto(cool)", "Auto(cool)+DHW"};
|
||||||
|
static const constexpr char* const Powerfulmode[] = {"4", "Off", "30min", "60min", "90min"};
|
||||||
|
static const constexpr char* const Quietmode[] = {"4", "Off", "Level 1", "Level 2", "Level 3"};
|
||||||
|
static const constexpr char* const Valve[] = {"2", "Room", "DHW"};
|
||||||
|
static const constexpr char* const MixingValve[] = {"4", "Off", "Increase","Nothing","Decrease"};
|
||||||
|
static const constexpr char* const ZonesState[] = {"3", "Zone1 active", "Zone2 active", "Zone1 and zone2 active"};
|
||||||
|
static const constexpr char* const HeatCoolModeDesc[] = {"2", "Comp. Curve", "Direct"};
|
||||||
|
static const constexpr char* const SolarModeDesc[] = {"3", "Disabled", "Buffer", "DHW"};
|
||||||
|
static const constexpr char* const ZonesSensorType[] = {"4", "Water Temperature", "External Thermostat", "Internal Thermostat", "Thermistor"};
|
||||||
|
static const constexpr char* const LiquidType[] = {"2", "Water", "Glycol"};
|
||||||
|
static const constexpr char* const ExtPadHeaterType[] = {"3", "Disabled", "Type-A","Type-B"};
|
||||||
|
static const constexpr char* const Bivalent[] = {"6", "Off", "Alternativ", "A-Off", "Parallel", "P-Off", "Parallel Advanced"};
|
||||||
|
|
||||||
|
static const constexpr char* const ModelNames[] =
|
||||||
|
{
|
||||||
|
"51", //string representation of number of known models (last model number + 1)
|
||||||
|
"WH-MDC05H3E5", //0
|
||||||
|
"WH-MDC07H3E5", //1
|
||||||
|
"IDU:WH-SXC09H3E5, ODU:WH-UX09HE5", //2
|
||||||
|
"IDU:WH-SDC09H3E8, ODU:WH-UD09HE8", //3
|
||||||
|
"IDU:WH-SXC09H3E8, ODU:WH-UX09HE8", //4
|
||||||
|
"IDU:WH-SXC12H9E8, ODU:WH-UX12HE8", //5
|
||||||
|
"IDU:WH-SXC16H9E8, ODU:WH-UX16HE8", //6
|
||||||
|
"IDU:WH-SDC05H3E5, ODU:WH-UD05HE5", //7
|
||||||
|
"IDU:WH-SDC0709J3E5, ODU:WH-UD09JE5", //8
|
||||||
|
"WH-MDC05J3E5", //9
|
||||||
|
"WH-MDC09H3E5", //10
|
||||||
|
"WH-MXC09H3E5", //11
|
||||||
|
"IDU:WH-ADC0309J3E5, ODU:WH-UD09JE5", //12
|
||||||
|
"IDU:WH-ADC0916H9E8, ODU:WH-UX12HE8", //13
|
||||||
|
"IDU:WH-SQC09H3E8, ODU:WH-UQ09HE8", //14
|
||||||
|
"IDU:WH-SDC09H3E5, ODU:WH-UD09HE5", //15
|
||||||
|
"IDU:WH-ADC0309H3E5, ODU:WH-UD09HE5", //16
|
||||||
|
"IDU:WH-ADC0309J3E5, ODU:WH-UD05JE5", //17
|
||||||
|
"IDU:WH-SDC0709J3E5, ODU:WH-UD07JE5", //18
|
||||||
|
"IDU:WH-SDC07H3E5-1, ODU:WH-UD07HE5-1", //19
|
||||||
|
"WH-MDC07J3E5", //20
|
||||||
|
"WH-MDC09J3E5", //21
|
||||||
|
"IDU:WH-SDC0305J3E5, ODU:WH-UD05JE5", //22
|
||||||
|
"WH-MXC09J3E8", //23
|
||||||
|
"WH-MXC12J9E8", //24
|
||||||
|
"IDU:WH-ADC1216H6E5, ODU:WH-UD12HE5", //25
|
||||||
|
"IDU:WH-ADC0309J3E5C, ODU:WH-UD07JE5", //26
|
||||||
|
"WH-MDC07J3E5", //27
|
||||||
|
"WH-MDC05J3E5", //28
|
||||||
|
"IDU:WH-UQ12HE8, ODU:WH-SQC12H9E8", //29
|
||||||
|
"IDU:WH-SXC12H6E5, ODU:WH-UX12HE5", //30
|
||||||
|
"WH-MDC09J3E5", //31
|
||||||
|
"WH-MXC09J3E5", //32
|
||||||
|
"IDU:WH-ADC1216H6E5C ODU:WH-UD12HE5", //33
|
||||||
|
"IDU:WH-ADC0509L3E5 ODU:WH-WDG07LE5", //34
|
||||||
|
"IDU:WH-SXC09H3E8 ODU:WH-UX09HE8", //35
|
||||||
|
"IDU:WH-ADC0309K3E5AN ODU:WH-UDZ07KE5", //36
|
||||||
|
"IDU:WH-SDC0309K3E5 ODU:WH-UDZ05KE5", //37
|
||||||
|
"IDU:WH-SDC0509L3E5 ODU:WH-WDG09LE5", //38
|
||||||
|
"IDU:WH-SDC12H9E8 ODU:WH-UD12HE8", //39
|
||||||
|
"IDU:WH-SDC0309K3E5, ODU:WH-UDZ07KE5", //40
|
||||||
|
"IDU:WH-ADC0916H9E8, ODU:WH-UX16HE8", //41
|
||||||
|
"IDU:WH-ADC0912H9E8, ODU:WH-UX12HE8", //42
|
||||||
|
"WH-MXC16J9E8", //43
|
||||||
|
"WH-MXC12J6E5", //44
|
||||||
|
"IDU:WH-SQC09H3E8, ODU:WH-UQ09HE8", //45
|
||||||
|
"IDU:WH-ADC0309K3E5 ODU:WH-UDZ09KE5", //46
|
||||||
|
"IDU:WH-ADC0916H9E8, ODU:WH-UX12HE8", //47
|
||||||
|
"IDU:WH-SDC0509L3E5 ODU:WH-WDG07LE5", //48
|
||||||
|
"IDU:WH-SXC09H3E5, ODU:WH-UX09HE5", //49
|
||||||
|
"IDU:WH-SXC12H9E8, ODU:WH-UX12HE8", //50
|
||||||
|
};
|
||||||
|
|
||||||
|
// stores the bytes #129 to #138 of known models in the same order as the ModelNames above
|
||||||
|
static constexpr uint8_t KnownModels[NUMBER_OF_MODELS][10] =
|
||||||
|
{
|
||||||
|
0xE2, 0xCF, 0x0B, 0x13, 0x33, 0x32, 0xD1, 0x0C, 0x16, 0x33, //0
|
||||||
|
0xE2, 0xCF, 0x0B, 0x14, 0x33, 0x42, 0xD1, 0x0B, 0x17, 0x33, //1
|
||||||
|
0xE2, 0xCF, 0x0D, 0x77, 0x09, 0x12, 0xD0, 0x0B, 0x05, 0x11, //2
|
||||||
|
0xE2, 0xCF, 0x0C, 0x88, 0x05, 0x12, 0xD0, 0x0B, 0x97, 0x05, //3
|
||||||
|
0xE2, 0xCF, 0x0D, 0x85, 0x05, 0x12, 0xD0, 0x0C, 0x94, 0x05, //4
|
||||||
|
0xE2, 0xCF, 0x0D, 0x86, 0x05, 0x12, 0xD0, 0x0C, 0x95, 0x05, //5
|
||||||
|
0xE2, 0xCF, 0x0D, 0x87, 0x05, 0x12, 0xD0, 0x0C, 0x96, 0x05, //6
|
||||||
|
0xE2, 0xCE, 0x0D, 0x71, 0x81, 0x72, 0xCE, 0x0C, 0x92, 0x81, //7
|
||||||
|
0x62, 0xD2, 0x0B, 0x43, 0x54, 0x42, 0xD2, 0x0B, 0x72, 0x66, //8
|
||||||
|
0xC2, 0xD3, 0x0B, 0x33, 0x65, 0xB2, 0xD3, 0x0B, 0x94, 0x65, //9
|
||||||
|
0xE2, 0xCF, 0x0B, 0x15, 0x33, 0x42, 0xD1, 0x0B, 0x18, 0x33, //10
|
||||||
|
0xE2, 0xCF, 0x0B, 0x41, 0x34, 0x82, 0xD1, 0x0B, 0x31, 0x35, //11
|
||||||
|
0x62, 0xD2, 0x0B, 0x45, 0x54, 0x42, 0xD2, 0x0B, 0x47, 0x55, //12
|
||||||
|
0xE2, 0xCF, 0x0C, 0x74, 0x09, 0x12, 0xD0, 0x0D, 0x95, 0x05, //13
|
||||||
|
0xE2, 0xCF, 0x0B, 0x82, 0x05, 0x12, 0xD0, 0x0C, 0x91, 0x05, //14
|
||||||
|
0xE2, 0xCF, 0x0C, 0x55, 0x14, 0x12, 0xD0, 0x0B, 0x15, 0x08, //15
|
||||||
|
0xE2, 0xCF, 0x0C, 0x43, 0x00, 0x12, 0xD0, 0x0B, 0x15, 0x08, //16
|
||||||
|
0x62, 0xD2, 0x0B, 0x45, 0x54, 0x32, 0xD2, 0x0C, 0x45, 0x55, //17
|
||||||
|
0x62, 0xD2, 0x0B, 0x43, 0x54, 0x42, 0xD2, 0x0C, 0x46, 0x55, //18
|
||||||
|
0xE2, 0xCF, 0x0C, 0x54, 0x14, 0x12, 0xD0, 0x0B, 0x14, 0x08, //19
|
||||||
|
0xC2, 0xD3, 0x0B, 0x34, 0x65, 0xB2, 0xD3, 0x0B, 0x95, 0x65, //20
|
||||||
|
0xC2, 0xD3, 0x0B, 0x35, 0x65, 0xB2, 0xD3, 0x0B, 0x96, 0x65, //21
|
||||||
|
0x62, 0xD2, 0x0B, 0x41, 0x54, 0x32, 0xD2, 0x0C, 0x45, 0x55, //22
|
||||||
|
0x32, 0xD4, 0x0B, 0x87, 0x84, 0x73, 0x90, 0x0C, 0x84, 0x84, //23
|
||||||
|
0x32, 0xD4, 0x0B, 0x88, 0x84, 0x73, 0x90, 0x0C, 0x85, 0x84, //24
|
||||||
|
0xE2, 0xCF, 0x0B, 0x75, 0x09, 0x12, 0xD0, 0x0C, 0x06, 0x11, //25
|
||||||
|
0x42, 0xD4, 0x0B, 0x83, 0x71, 0x42, 0xD2, 0x0C, 0x46, 0x55, //26
|
||||||
|
0xC2, 0xD3, 0x0C, 0x34, 0x65, 0xB2, 0xD3, 0x0B, 0x95, 0x65, //27
|
||||||
|
0xC2, 0xD3, 0x0C, 0x33, 0x65, 0xB2, 0xD3, 0x0B, 0x94, 0x65, //28
|
||||||
|
0xE2, 0xCF, 0x0B, 0x83, 0x05, 0x12, 0xD0, 0x0D, 0x92, 0x05, //29
|
||||||
|
0xE2, 0xCF, 0x0C, 0x78, 0x09, 0x12, 0xD0, 0x0B, 0x06, 0x11, //30
|
||||||
|
0xC2, 0xD3, 0x0C, 0x35, 0x65, 0xB2, 0xD3, 0x0B, 0x96, 0x65, //31
|
||||||
|
0x32, 0xD4, 0x0B, 0x99, 0x77, 0x62, 0x90, 0x0B, 0x01, 0x78, //32
|
||||||
|
0x42, 0xD4, 0x0B, 0x15, 0x76, 0x12, 0xD0, 0x0B, 0x10, 0x11, //33
|
||||||
|
0xE2, 0xD5, 0x0C, 0x29, 0x99, 0x83, 0x92, 0x0C, 0x28, 0x98, //34
|
||||||
|
0xE2, 0xCF, 0x0D, 0x85, 0x05, 0x12, 0xD0, 0x0E, 0x94, 0x05, //35
|
||||||
|
0xE2, 0xD5, 0x0D, 0x36, 0x99, 0x02, 0xD6, 0x0F, 0x67, 0x95, //36
|
||||||
|
0xE2, 0xD5, 0x0B, 0x08, 0x95, 0x02, 0xD6, 0x0E, 0x66, 0x95, //37
|
||||||
|
0xE2, 0xD5, 0x0B, 0x34, 0x99, 0x83, 0x92, 0x0C, 0x29, 0x98, //38
|
||||||
|
0xE2, 0xCF, 0x0C, 0x89, 0x05, 0x12, 0xD0, 0x0C, 0x98, 0x05, //39
|
||||||
|
0xE2, 0xD5, 0x0B, 0x08, 0x95, 0x02, 0xD6, 0x0E, 0x67, 0x95, //40
|
||||||
|
0xE2, 0xCF, 0x0C, 0x74, 0x09, 0x12, 0xD0, 0x0C, 0x96, 0x05, //41
|
||||||
|
0xE2, 0xCF, 0x0C, 0x74, 0x09, 0x12, 0xD0, 0x0E, 0x95, 0x05, //42
|
||||||
|
0x32, 0xD4, 0x0B, 0x89, 0x84, 0x73, 0x90, 0x0C, 0x86, 0x84, //43
|
||||||
|
0x32, 0xD4, 0x0B, 0x00, 0x78, 0x62, 0x90, 0x0B, 0x02, 0x78, //44
|
||||||
|
0xE2, 0xCF, 0x0B, 0x82, 0x05, 0x12, 0xD0, 0x0D, 0x91, 0x05, //45
|
||||||
|
0xE2, 0xD5, 0x0D, 0x99, 0x94, 0x02, 0xD6, 0x0D, 0x68, 0x95, //46
|
||||||
|
0xE2, 0xCF, 0x0C, 0x74, 0x09, 0x12, 0xD0, 0x0C, 0x95, 0x05, //47
|
||||||
|
0xE2, 0xD5, 0x0B, 0x34, 0x99, 0x83, 0x92, 0x0C, 0x28, 0x98, //48
|
||||||
|
0xE2, 0xCF, 0x0D, 0x77, 0x09, 0x12, 0xD0, 0x0C, 0x05, 0x11, //49
|
||||||
|
0xE2, 0xCF, 0x0D, 0x86, 0x05, 0x12, 0xD0, 0x0E, 0x95, 0x05, //50
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,293 @@
|
||||||
|
#include "panasonic_heatpump.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace esphome
|
||||||
|
{
|
||||||
|
namespace panasonic_heatpump
|
||||||
|
{
|
||||||
|
static const char *const TAG = "panasonic_heatpump";
|
||||||
|
|
||||||
|
static const uint8_t RESPONSE_DATA_SIZE = 203;
|
||||||
|
static const uint8_t REQUEST_DATA_SIZE = 111;
|
||||||
|
|
||||||
|
void PanasonicHeatpumpComponent::dump_config()
|
||||||
|
{
|
||||||
|
ESP_LOGCONFIG(TAG, "Panasonic Heatpump");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanasonicHeatpumpComponent::loop()
|
||||||
|
{
|
||||||
|
uint8_t byte_hp;
|
||||||
|
uint8_t byte_wm;
|
||||||
|
|
||||||
|
while (this->uart_hp_->available())
|
||||||
|
{
|
||||||
|
this->uart_hp_->read_byte(&byte_hp);
|
||||||
|
this->uart_wm_->write_byte(byte_hp);
|
||||||
|
|
||||||
|
if (!this->response_receiving_)
|
||||||
|
{
|
||||||
|
// Message shall start with 0x71, if not skip this byte
|
||||||
|
if (byte_hp != 0x71)
|
||||||
|
continue;
|
||||||
|
this->response_receiving_ = true;
|
||||||
|
}
|
||||||
|
// Add current byte to message buffer
|
||||||
|
this->response_data_.push_back(byte_hp);
|
||||||
|
// 2. bytes contains the payload size
|
||||||
|
if (this->response_data_.size() == 2)
|
||||||
|
this->response_payload_length_ = byte_hp;
|
||||||
|
// Discard message if 3. and 4. byte are not as expected
|
||||||
|
if (this->response_data_.size() == 3 && byte_hp != 0x01 ||
|
||||||
|
this->response_data_.size() == 4 && byte_hp != 0x10)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Invalid response message: %d. byte is 0x%02X but expexted is 0x%02X",
|
||||||
|
response_data_.size(), byte_hp, response_data_.size() == 3 ? "01" : "10");
|
||||||
|
delay(10);
|
||||||
|
this->response_data_.clear();
|
||||||
|
this->response_receiving_ = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Decode message if message is complete
|
||||||
|
if (this->response_data_.size() > 2 && this->response_data_.size() == this->response_payload_length_ + 3)
|
||||||
|
{
|
||||||
|
this->log_uart_hex("<<<", this->response_data_, ',');
|
||||||
|
this->decode_response_(this->response_data_);
|
||||||
|
this->response_data_.clear();
|
||||||
|
this->response_receiving_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (this->uart_wm_->available())
|
||||||
|
{
|
||||||
|
this->uart_wm_->read_byte(&byte_wm);
|
||||||
|
this->uart_hp_->write_byte(byte_wm);
|
||||||
|
|
||||||
|
if (!this->request_receiving_)
|
||||||
|
{
|
||||||
|
// Message shall start with 0x71, if not skip this byte
|
||||||
|
if (byte_wm != 0x71)
|
||||||
|
continue;
|
||||||
|
this->request_receiving_ = true;
|
||||||
|
}
|
||||||
|
// Add current byte to message buffer
|
||||||
|
this->request_data_.push_back(byte_wm);
|
||||||
|
// 2. bytes contains the payload size
|
||||||
|
if (this->request_data_.size() == 2)
|
||||||
|
this->request_payload_length_ = byte_wm;
|
||||||
|
// Discard message if 3. and 4. byte are not as expected
|
||||||
|
if (this->request_data_.size() == 3 && byte_wm != 0x01 ||
|
||||||
|
this->request_data_.size() == 4 && byte_wm != 0x10)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Invalid request message: %d. byte is 0x%02X but expexted is 0x%02X",
|
||||||
|
request_data_.size(), byte_wm, request_data_.size() == 3 ? "01" : "10");
|
||||||
|
delay(10);
|
||||||
|
this->request_data_.clear();
|
||||||
|
this->request_receiving_ = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Decode message if message is complete
|
||||||
|
if (this->request_data_.size() > 2 && this->request_data_.size() == this->request_payload_length_ + 3)
|
||||||
|
{
|
||||||
|
this->log_uart_hex(">>>", this->request_data_, ',');
|
||||||
|
this->request_data_.clear();
|
||||||
|
this->request_receiving_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanasonicHeatpumpComponent::decode_response_(std::vector<uint8_t> bytes)
|
||||||
|
{
|
||||||
|
// Read response message:
|
||||||
|
// format: 0x71 [payload_length] 0x01 0x10 [[TOP0 - TOP114] ...] 0x00 [checksum]
|
||||||
|
// payload_length: payload_length + 3 = packet_length
|
||||||
|
// checksum: if (sum(all bytes) & 0xFF == 0) ==> valid packet
|
||||||
|
|
||||||
|
if (bytes.size() != RESPONSE_DATA_SIZE)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Invalid response message length: recieved %d - expected %d", bytes.size(), RESPONSE_DATA_SIZE);
|
||||||
|
delay(10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t checksum = 0;
|
||||||
|
for (int i = 0; i < bytes.size(); i++)
|
||||||
|
{
|
||||||
|
checksum += bytes[i];
|
||||||
|
}
|
||||||
|
// checksum = checksum & 0xFF;
|
||||||
|
if (checksum != 0)
|
||||||
|
{
|
||||||
|
ESP_LOGW(TAG, "Invalid response message: checksum = 0x%02X, last_byte = 0x%02X", checksum, bytes[202]);
|
||||||
|
delay(10);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
if (this->top1_sensor_) this->top1_sensor_->publish_state(PanasonicDecode::getPumpFlow(bytes[169], bytes[170]));
|
||||||
|
if (this->top5_sensor_) this->top5_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[143]) + PanasonicDecode::getFractional(bytes[118], 0));
|
||||||
|
if (this->top6_sensor_) this->top6_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[144]) + PanasonicDecode::getFractional(bytes[118], 3));
|
||||||
|
if (this->top7_sensor_) this->top7_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[153]));
|
||||||
|
if (this->top8_sensor_) this->top8_sensor_->publish_state(PanasonicDecode::getIntMinus1(bytes[166]));
|
||||||
|
if (this->top9_sensor_) this->top9_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[42]));
|
||||||
|
if (this->top10_sensor_) this->top10_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[141]));
|
||||||
|
if (this->top11_sensor_) this->top11_sensor_->publish_state(PanasonicDecode::getWord(bytes[182], bytes[183]));
|
||||||
|
if (this->top12_sensor_) this->top12_sensor_->publish_state(PanasonicDecode::getWord(bytes[179], bytes[180]));
|
||||||
|
if (this->top14_sensor_) this->top14_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[142]));
|
||||||
|
if (this->top15_sensor_) this->top15_sensor_->publish_state(PanasonicDecode::getPower(bytes[194]));
|
||||||
|
if (this->top16_sensor_) this->top16_sensor_->publish_state(PanasonicDecode::getPower(bytes[193]));
|
||||||
|
if (this->top21_sensor_) this->top21_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[158]));
|
||||||
|
if (this->top22_sensor_) this->top22_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[99]));
|
||||||
|
if (this->top23_sensor_) this->top23_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[84]));
|
||||||
|
if (this->top24_sensor_) this->top24_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[94]));
|
||||||
|
if (this->top25_sensor_) this->top25_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[44]));
|
||||||
|
if (this->top27_sensor_) this->top27_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[38]));
|
||||||
|
if (this->top28_sensor_) this->top28_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[39]));
|
||||||
|
if (this->top29_sensor_) this->top29_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[75]));
|
||||||
|
if (this->top30_sensor_) this->top30_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[76]));
|
||||||
|
if (this->top31_sensor_) this->top31_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[78]));
|
||||||
|
if (this->top32_sensor_) this->top32_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[77]));
|
||||||
|
if (this->top33_sensor_) this->top33_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[156]));
|
||||||
|
if (this->top34_sensor_) this->top34_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[40]));
|
||||||
|
if (this->top35_sensor_) this->top35_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[41]));
|
||||||
|
if (this->top36_sensor_) this->top36_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[145]));
|
||||||
|
if (this->top37_sensor_) this->top37_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[146]));
|
||||||
|
if (this->top38_sensor_) this->top38_sensor_->publish_state(PanasonicDecode::getPower(bytes[196]));
|
||||||
|
if (this->top39_sensor_) this->top39_sensor_->publish_state(PanasonicDecode::getPower(bytes[195]));
|
||||||
|
if (this->top40_sensor_) this->top40_sensor_->publish_state(PanasonicDecode::getPower(bytes[198]));
|
||||||
|
if (this->top41_sensor_) this->top41_sensor_->publish_state(PanasonicDecode::getPower(bytes[197]));
|
||||||
|
if (this->top42_sensor_) this->top42_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[147]));
|
||||||
|
if (this->top43_sensor_) this->top43_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[148]));
|
||||||
|
if (this->top45_sensor_) this->top45_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[43]));
|
||||||
|
if (this->top46_sensor_) this->top46_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[149]));
|
||||||
|
if (this->top47_sensor_) this->top47_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[150]));
|
||||||
|
if (this->top48_sensor_) this->top48_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[151]));
|
||||||
|
if (this->top49_sensor_) this->top49_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[154]));
|
||||||
|
if (this->top50_sensor_) this->top50_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[155]));
|
||||||
|
if (this->top51_sensor_) this->top51_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[157]));
|
||||||
|
if (this->top52_sensor_) this->top52_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[159]));
|
||||||
|
if (this->top53_sensor_) this->top53_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[160]));
|
||||||
|
if (this->top54_sensor_) this->top54_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[161]));
|
||||||
|
if (this->top55_sensor_) this->top55_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[162]));
|
||||||
|
if (this->top56_sensor_) this->top56_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[139]));
|
||||||
|
if (this->top57_sensor_) this->top57_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[140]));
|
||||||
|
if (this->top62_sensor_) this->top62_sensor_->publish_state(PanasonicDecode::getIntMinus1Times10(bytes[173]));
|
||||||
|
if (this->top63_sensor_) this->top63_sensor_->publish_state(PanasonicDecode::getIntMinus1Times10(bytes[174]));
|
||||||
|
if (this->top64_sensor_) this->top64_sensor_->publish_state(PanasonicDecode::getIntMinus1Div5(bytes[163]));
|
||||||
|
if (this->top65_sensor_) this->top65_sensor_->publish_state(PanasonicDecode::getIntMinus1Times50(bytes[171]));
|
||||||
|
if (this->top66_sensor_) this->top66_sensor_->publish_state(PanasonicDecode::getIntMinus1Times50(bytes[164]));
|
||||||
|
if (this->top67_sensor_) this->top67_sensor_->publish_state(PanasonicDecode::getIntMinus1Div5(bytes[165]));
|
||||||
|
if (this->top70_sensor_) this->top70_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[100]));
|
||||||
|
if (this->top71_sensor_) this->top71_sensor_->publish_state(PanasonicDecode::getIntMinus1(bytes[101]));
|
||||||
|
if (this->top72_sensor_) this->top72_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[86]));
|
||||||
|
if (this->top73_sensor_) this->top73_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[87]));
|
||||||
|
if (this->top74_sensor_) this->top74_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[89]));
|
||||||
|
if (this->top75_sensor_) this->top75_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[88]));
|
||||||
|
if (this->top77_sensor_) this->top77_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[83]));
|
||||||
|
if (this->top78_sensor_) this->top78_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[85]));
|
||||||
|
if (this->top79_sensor_) this->top79_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[95]));
|
||||||
|
if (this->top80_sensor_) this->top80_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[96]));
|
||||||
|
if (this->top82_sensor_) this->top82_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[79]));
|
||||||
|
if (this->top83_sensor_) this->top83_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[80]));
|
||||||
|
if (this->top84_sensor_) this->top84_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[82]));
|
||||||
|
if (this->top85_sensor_) this->top85_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[81]));
|
||||||
|
if (this->top86_sensor_) this->top86_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[90]));
|
||||||
|
if (this->top87_sensor_) this->top87_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[91]));
|
||||||
|
if (this->top88_sensor_) this->top88_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[93]));
|
||||||
|
if (this->top89_sensor_) this->top89_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[92]));
|
||||||
|
if (this->top90_sensor_) this->top90_sensor_->publish_state(PanasonicDecode::getWord(bytes[185], bytes[186]));
|
||||||
|
if (this->top91_sensor_) this->top91_sensor_->publish_state(PanasonicDecode::getWord(bytes[188], bytes[189]));
|
||||||
|
if (this->top93_sensor_) this->top93_sensor_->publish_state(PanasonicDecode::getIntMinus1(bytes[172]));
|
||||||
|
if (this->top95_sensor_) this->top95_sensor_->publish_state(PanasonicDecode::getIntMinus1(bytes[45]));
|
||||||
|
if (this->top96_sensor_) this->top96_sensor_->publish_state(PanasonicDecode::getIntMinus1(bytes[104]));
|
||||||
|
if (this->top97_sensor_) this->top97_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[105]));
|
||||||
|
if (this->top98_sensor_) this->top98_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[106]));
|
||||||
|
if (this->top102_sensor_) this->top102_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[61]));
|
||||||
|
if (this->top103_sensor_) this->top103_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[62]));
|
||||||
|
if (this->top104_sensor_) this->top104_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[63]));
|
||||||
|
if (this->top105_sensor_) this->top105_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[64]));
|
||||||
|
if (this->top113_sensor_) this->top113_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[59]));
|
||||||
|
if (this->top115_sensor_) this->top115_sensor_->publish_state(PanasonicDecode::getIntMinus1Div50(bytes[125]));
|
||||||
|
if (this->top116_sensor_) this->top116_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[126]));
|
||||||
|
if (this->top117_sensor_) this->top117_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[127]));
|
||||||
|
if (this->top118_sensor_) this->top118_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[128]));
|
||||||
|
if (this->top119_sensor_) this->top119_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[65]));
|
||||||
|
if (this->top120_sensor_) this->top120_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[66]));
|
||||||
|
if (this->top121_sensor_) this->top121_sensor_->publish_state(PanasonicDecode::getIntMinus128(bytes[68]));
|
||||||
|
if (this->top122_sensor_) this->top122_sensor_->publish_state(PanasonicDecode::getIntMinus1(bytes[67]));
|
||||||
|
if (this->top123_sensor_) this->top123_sensor_->publish_state(PanasonicDecode::getIntMinus1(bytes[69]));
|
||||||
|
if (this->top125_sensor_) this->top125_sensor_->publish_state(PanasonicDecode::getIntMinus1(bytes[177]));
|
||||||
|
if (this->top126_sensor_) this->top126_sensor_->publish_state(PanasonicDecode::getIntMinus1(bytes[178]));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
if (this->top0_binary_sensor_) this->top0_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit7and8(bytes[4])));
|
||||||
|
if (this->top2_binary_sensor_) this->top2_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit1and2(bytes[4])));
|
||||||
|
if (this->top3_binary_sensor_) this->top3_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit1and2(bytes[7])));
|
||||||
|
if (this->top13_binary_sensor_) this->top13_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit1and2(bytes[5])));
|
||||||
|
if (this->top26_binary_sensor_) this->top26_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit5and6(bytes[111])));
|
||||||
|
if (this->top60_binary_sensor_) this->top60_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit7and8(bytes[112])));
|
||||||
|
if (this->top61_binary_sensor_) this->top61_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit5and6(bytes[112])));
|
||||||
|
if (this->top68_binary_sensor_) this->top68_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit5and6(bytes[5])));
|
||||||
|
if (this->top69_binary_sensor_) this->top69_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit5and6(bytes[117])));
|
||||||
|
if (this->top99_binary_sensor_) this->top99_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit5and6(bytes[24])));
|
||||||
|
if (this->top100_binary_sensor_) this->top100_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit7and8(bytes[24])));
|
||||||
|
if (this->top108_binary_sensor_) this->top108_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit3and4(bytes[20])));
|
||||||
|
if (this->top109_binary_sensor_) this->top109_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit5and6(bytes[20])));
|
||||||
|
if (this->top110_binary_sensor_) this->top110_binary_sensor_->publish_state(PanasonicDecode::getBoolState(PanasonicDecode::getBit7and8(bytes[20])));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
if (this->top4_text_sensor_) this->top4_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::OpModeDesc, PanasonicDecode::getOpMode(bytes[6])));
|
||||||
|
if (this->top17_text_sensor_) this->top17_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Powerfulmode, PanasonicDecode::getRight3bits(bytes[7])));
|
||||||
|
if (this->top18_text_sensor_) this->top18_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Quietmode, PanasonicDecode::getBit3and4and5(bytes[7])));
|
||||||
|
if (this->top19_text_sensor_) this->top19_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::HolidayState, PanasonicDecode::getBit3and4(bytes[5])));
|
||||||
|
if (this->top20_text_sensor_) this->top20_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Valve, PanasonicDecode::getBit7and8(bytes[111])));
|
||||||
|
if (this->top44_text_sensor_) this->top44_text_sensor_->publish_state(PanasonicDecode::getErrorInfo(bytes[113], bytes[114]));
|
||||||
|
if (this->top58_text_sensor_) this->top58_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit5and6(bytes[9])));
|
||||||
|
if (this->top59_text_sensor_) this->top59_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::BlockedFree, PanasonicDecode::getBit7and8(bytes[9])));
|
||||||
|
if (this->top76_text_sensor_) this->top76_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::HeatCoolModeDesc, PanasonicDecode::getBit7and8(bytes[28])));
|
||||||
|
if (this->top81_text_sensor_) this->top81_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::HeatCoolModeDesc, PanasonicDecode::getBit5and6(bytes[28])));
|
||||||
|
// if (this->top92_text_sensor_) this->top92_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ModelNames, PanasonicDecode::getModel(bytes, 129)));
|
||||||
|
if (this->top94_text_sensor_) this->top94_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZonesState, PanasonicDecode::getBit1and2(bytes[6])));
|
||||||
|
if (this->top101_text_sensor_) this->top101_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::SolarModeDesc, PanasonicDecode::getBit3and4(bytes[24])));
|
||||||
|
if (this->top106_text_sensor_) this->top106_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::PumpFlowRateMode, PanasonicDecode::getBit3and4(bytes[29])));
|
||||||
|
if (this->top107_text_sensor_) this->top107_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::LiquidType, PanasonicDecode::getBit1(bytes[20])));
|
||||||
|
if (this->top111_text_sensor_) this->top111_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZonesSensorType, PanasonicDecode::getSecondByte(bytes[22])));
|
||||||
|
if (this->top112_text_sensor_) this->top112_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ZonesSensorType, PanasonicDecode::getFirstByte(bytes[22])));
|
||||||
|
if (this->top114_text_sensor_) this->top114_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::ExtPadHeaterType, PanasonicDecode::getBit3and4(bytes[25])));
|
||||||
|
if (this->top124_text_sensor_) this->top124_text_sensor_->publish_state(PanasonicDecode::getTextState(PanasonicDecode::Bivalent, PanasonicDecode::getBivalent(bytes[26])));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanasonicHeatpumpComponent::send_request_()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PanasonicHeatpumpComponent::log_uart_hex(std::string prefix, std::vector<uint8_t> bytes, uint8_t separator)
|
||||||
|
{
|
||||||
|
std::string logStr;
|
||||||
|
logStr = "[" + std::to_string(bytes.size()) + "]";
|
||||||
|
ESP_LOGD(TAG, "%s %s", prefix.c_str(), logStr.c_str());
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
logStr = "";
|
||||||
|
char buffer[5];
|
||||||
|
for (size_t i = 0; i < bytes.size(); i++)
|
||||||
|
{
|
||||||
|
if (i > 0) logStr += separator;
|
||||||
|
sprintf(buffer, "%02X", bytes[i]);
|
||||||
|
logStr += buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t chunkSize = 90;
|
||||||
|
for (size_t i = 0; i < logStr.length(); i += chunkSize)
|
||||||
|
{
|
||||||
|
ESP_LOGD(TAG, "%s %s", prefix.c_str(), logStr.substr(i, chunkSize).c_str());
|
||||||
|
delay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace panasonic_heatpump
|
||||||
|
} // namespace esphome
|
||||||
|
|
@ -0,0 +1,188 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/core/defines.h"
|
||||||
|
#include "esphome/components/uart/uart.h"
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
#include "esphome/components/sensor/sensor.h"
|
||||||
|
#endif
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
#include "esphome/components/text_sensor/text_sensor.h"
|
||||||
|
#endif
|
||||||
|
#include "decode.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
namespace esphome
|
||||||
|
{
|
||||||
|
namespace panasonic_heatpump
|
||||||
|
{
|
||||||
|
class PanasonicHeatpumpComponent : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PanasonicHeatpumpComponent() = default;
|
||||||
|
|
||||||
|
#ifdef USE_SENSOR
|
||||||
|
SUB_SENSOR(top1);
|
||||||
|
SUB_SENSOR(top5);
|
||||||
|
SUB_SENSOR(top6);
|
||||||
|
SUB_SENSOR(top7);
|
||||||
|
SUB_SENSOR(top8);
|
||||||
|
SUB_SENSOR(top9);
|
||||||
|
SUB_SENSOR(top10);
|
||||||
|
SUB_SENSOR(top11);
|
||||||
|
SUB_SENSOR(top12);
|
||||||
|
SUB_SENSOR(top14);
|
||||||
|
SUB_SENSOR(top15);
|
||||||
|
SUB_SENSOR(top16);
|
||||||
|
SUB_SENSOR(top21);
|
||||||
|
SUB_SENSOR(top22);
|
||||||
|
SUB_SENSOR(top23);
|
||||||
|
SUB_SENSOR(top24);
|
||||||
|
SUB_SENSOR(top25);
|
||||||
|
SUB_SENSOR(top27);
|
||||||
|
SUB_SENSOR(top28);
|
||||||
|
SUB_SENSOR(top29);
|
||||||
|
SUB_SENSOR(top30);
|
||||||
|
SUB_SENSOR(top31);
|
||||||
|
SUB_SENSOR(top32);
|
||||||
|
SUB_SENSOR(top33);
|
||||||
|
SUB_SENSOR(top34);
|
||||||
|
SUB_SENSOR(top35);
|
||||||
|
SUB_SENSOR(top36);
|
||||||
|
SUB_SENSOR(top37);
|
||||||
|
SUB_SENSOR(top38);
|
||||||
|
SUB_SENSOR(top39);
|
||||||
|
SUB_SENSOR(top40);
|
||||||
|
SUB_SENSOR(top41);
|
||||||
|
SUB_SENSOR(top42);
|
||||||
|
SUB_SENSOR(top43);
|
||||||
|
SUB_SENSOR(top45);
|
||||||
|
SUB_SENSOR(top46);
|
||||||
|
SUB_SENSOR(top47);
|
||||||
|
SUB_SENSOR(top48);
|
||||||
|
SUB_SENSOR(top49);
|
||||||
|
SUB_SENSOR(top50);
|
||||||
|
SUB_SENSOR(top51);
|
||||||
|
SUB_SENSOR(top52);
|
||||||
|
SUB_SENSOR(top53);
|
||||||
|
SUB_SENSOR(top54);
|
||||||
|
SUB_SENSOR(top55);
|
||||||
|
SUB_SENSOR(top56);
|
||||||
|
SUB_SENSOR(top57);
|
||||||
|
SUB_SENSOR(top62);
|
||||||
|
SUB_SENSOR(top63);
|
||||||
|
SUB_SENSOR(top64);
|
||||||
|
SUB_SENSOR(top65);
|
||||||
|
SUB_SENSOR(top66);
|
||||||
|
SUB_SENSOR(top67);
|
||||||
|
SUB_SENSOR(top70);
|
||||||
|
SUB_SENSOR(top71);
|
||||||
|
SUB_SENSOR(top72);
|
||||||
|
SUB_SENSOR(top73);
|
||||||
|
SUB_SENSOR(top74);
|
||||||
|
SUB_SENSOR(top75);
|
||||||
|
SUB_SENSOR(top77);
|
||||||
|
SUB_SENSOR(top78);
|
||||||
|
SUB_SENSOR(top79);
|
||||||
|
SUB_SENSOR(top80);
|
||||||
|
SUB_SENSOR(top82);
|
||||||
|
SUB_SENSOR(top83);
|
||||||
|
SUB_SENSOR(top84);
|
||||||
|
SUB_SENSOR(top85);
|
||||||
|
SUB_SENSOR(top86);
|
||||||
|
SUB_SENSOR(top87);
|
||||||
|
SUB_SENSOR(top88);
|
||||||
|
SUB_SENSOR(top89);
|
||||||
|
SUB_SENSOR(top90);
|
||||||
|
SUB_SENSOR(top91);
|
||||||
|
SUB_SENSOR(top93);
|
||||||
|
SUB_SENSOR(top95);
|
||||||
|
SUB_SENSOR(top96);
|
||||||
|
SUB_SENSOR(top97);
|
||||||
|
SUB_SENSOR(top98);
|
||||||
|
SUB_SENSOR(top102);
|
||||||
|
SUB_SENSOR(top103);
|
||||||
|
SUB_SENSOR(top104);
|
||||||
|
SUB_SENSOR(top105);
|
||||||
|
SUB_SENSOR(top113);
|
||||||
|
SUB_SENSOR(top115);
|
||||||
|
SUB_SENSOR(top116);
|
||||||
|
SUB_SENSOR(top117);
|
||||||
|
SUB_SENSOR(top118);
|
||||||
|
SUB_SENSOR(top119);
|
||||||
|
SUB_SENSOR(top120);
|
||||||
|
SUB_SENSOR(top121);
|
||||||
|
SUB_SENSOR(top122);
|
||||||
|
SUB_SENSOR(top123);
|
||||||
|
SUB_SENSOR(top125);
|
||||||
|
SUB_SENSOR(top126);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BINARY_SENSOR
|
||||||
|
SUB_BINARY_SENSOR(top0);
|
||||||
|
SUB_BINARY_SENSOR(top2);
|
||||||
|
SUB_BINARY_SENSOR(top3);
|
||||||
|
SUB_BINARY_SENSOR(top13);
|
||||||
|
SUB_BINARY_SENSOR(top26);
|
||||||
|
SUB_BINARY_SENSOR(top60);
|
||||||
|
SUB_BINARY_SENSOR(top61);
|
||||||
|
SUB_BINARY_SENSOR(top68);
|
||||||
|
SUB_BINARY_SENSOR(top69);
|
||||||
|
SUB_BINARY_SENSOR(top99);
|
||||||
|
SUB_BINARY_SENSOR(top100);
|
||||||
|
SUB_BINARY_SENSOR(top108);
|
||||||
|
SUB_BINARY_SENSOR(top109);
|
||||||
|
SUB_BINARY_SENSOR(top110);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_TEXT_SENSOR
|
||||||
|
SUB_TEXT_SENSOR(top4);
|
||||||
|
SUB_TEXT_SENSOR(top17);
|
||||||
|
SUB_TEXT_SENSOR(top18);
|
||||||
|
SUB_TEXT_SENSOR(top19);
|
||||||
|
SUB_TEXT_SENSOR(top20);
|
||||||
|
SUB_TEXT_SENSOR(top44);
|
||||||
|
SUB_TEXT_SENSOR(top58);
|
||||||
|
SUB_TEXT_SENSOR(top59);
|
||||||
|
SUB_TEXT_SENSOR(top76);
|
||||||
|
SUB_TEXT_SENSOR(top81);
|
||||||
|
// SUB_TEXT_SENSOR(top92);
|
||||||
|
SUB_TEXT_SENSOR(top94);
|
||||||
|
SUB_TEXT_SENSOR(top101);
|
||||||
|
SUB_TEXT_SENSOR(top106);
|
||||||
|
SUB_TEXT_SENSOR(top107);
|
||||||
|
SUB_TEXT_SENSOR(top111);
|
||||||
|
SUB_TEXT_SENSOR(top112);
|
||||||
|
SUB_TEXT_SENSOR(top114);
|
||||||
|
SUB_TEXT_SENSOR(top124);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float get_setup_priority() const override { return setup_priority::LATE; }
|
||||||
|
void loop() override;
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
void set_uart_hp(uart::UARTComponent *uart) { this->uart_hp_ = uart; }
|
||||||
|
void set_uart_wm(uart::UARTComponent *uart) { this->uart_wm_ = uart; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
uart::UARTComponent *uart_hp_;
|
||||||
|
uart::UARTComponent *uart_wm_;
|
||||||
|
|
||||||
|
std::vector<uint8_t> response_data_;
|
||||||
|
uint8_t response_payload_length_;
|
||||||
|
bool response_receiving_{false};
|
||||||
|
std::vector<uint8_t> request_data_;
|
||||||
|
uint8_t request_payload_length_;
|
||||||
|
bool request_receiving_{false};
|
||||||
|
|
||||||
|
void decode_response_(std::vector<uint8_t> data);
|
||||||
|
void send_request_();
|
||||||
|
void log_uart_hex(std::string prefix, std::vector<uint8_t> bytes, uint8_t separator);
|
||||||
|
};
|
||||||
|
} // namespace panasonic_heatpump
|
||||||
|
} // namespace esphome
|
||||||
|
|
@ -0,0 +1,327 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import sensor
|
||||||
|
from esphome.const import (
|
||||||
|
UNIT_AMPERE,
|
||||||
|
UNIT_CELSIUS,
|
||||||
|
UNIT_HERTZ,
|
||||||
|
UNIT_HOUR,
|
||||||
|
UNIT_KELVIN,
|
||||||
|
UNIT_MINUTE,
|
||||||
|
UNIT_WATT,
|
||||||
|
)
|
||||||
|
from . import PanasonicHeatpumpComponent, CONF_PANASONIC_HEATPUMP_ID
|
||||||
|
|
||||||
|
UNIT_LITRE_PER_MINUTE = "l/min"
|
||||||
|
UNIT_ROTATIONS_PER_MINUTE = "r/min"
|
||||||
|
UNIT_PRESSURE_KGFCM2 = "kgf/cm²"
|
||||||
|
UNIT_BAR = "bar"
|
||||||
|
|
||||||
|
CONF_SENS_TOP1 = "top1"
|
||||||
|
CONF_SENS_TOP5 = "top5"
|
||||||
|
CONF_SENS_TOP6 = "top6"
|
||||||
|
CONF_SENS_TOP7 = "top7"
|
||||||
|
CONF_SENS_TOP8 = "top8"
|
||||||
|
CONF_SENS_TOP9 = "top9"
|
||||||
|
CONF_SENS_TOP10 = "top10"
|
||||||
|
CONF_SENS_TOP11 = "top11"
|
||||||
|
CONF_SENS_TOP12 = "top12"
|
||||||
|
CONF_SENS_TOP14 = "top14"
|
||||||
|
CONF_SENS_TOP15 = "top15"
|
||||||
|
CONF_SENS_TOP16 = "top16"
|
||||||
|
CONF_SENS_TOP21 = "top21"
|
||||||
|
CONF_SENS_TOP22 = "top22"
|
||||||
|
CONF_SENS_TOP23 = "top23"
|
||||||
|
CONF_SENS_TOP24 = "top24"
|
||||||
|
CONF_SENS_TOP25 = "top25"
|
||||||
|
CONF_SENS_TOP27 = "top27"
|
||||||
|
CONF_SENS_TOP28 = "top28"
|
||||||
|
CONF_SENS_TOP29 = "top29"
|
||||||
|
CONF_SENS_TOP30 = "top30"
|
||||||
|
CONF_SENS_TOP31 = "top31"
|
||||||
|
CONF_SENS_TOP32 = "top32"
|
||||||
|
CONF_SENS_TOP33 = "top33"
|
||||||
|
CONF_SENS_TOP34 = "top34"
|
||||||
|
CONF_SENS_TOP35 = "top35"
|
||||||
|
CONF_SENS_TOP36 = "top36"
|
||||||
|
CONF_SENS_TOP37 = "top37"
|
||||||
|
CONF_SENS_TOP38 = "top38"
|
||||||
|
CONF_SENS_TOP39 = "top39"
|
||||||
|
CONF_SENS_TOP40 = "top40"
|
||||||
|
CONF_SENS_TOP41 = "top41"
|
||||||
|
CONF_SENS_TOP42 = "top42"
|
||||||
|
CONF_SENS_TOP43 = "top43"
|
||||||
|
CONF_SENS_TOP45 = "top45"
|
||||||
|
CONF_SENS_TOP46 = "top46"
|
||||||
|
CONF_SENS_TOP47 = "top47"
|
||||||
|
CONF_SENS_TOP48 = "top48"
|
||||||
|
CONF_SENS_TOP49 = "top49"
|
||||||
|
CONF_SENS_TOP50 = "top50"
|
||||||
|
CONF_SENS_TOP51 = "top51"
|
||||||
|
CONF_SENS_TOP52 = "top52"
|
||||||
|
CONF_SENS_TOP53 = "top53"
|
||||||
|
CONF_SENS_TOP54 = "top54"
|
||||||
|
CONF_SENS_TOP55 = "top55"
|
||||||
|
CONF_SENS_TOP56 = "top56"
|
||||||
|
CONF_SENS_TOP57 = "top57"
|
||||||
|
CONF_SENS_TOP62 = "top62"
|
||||||
|
CONF_SENS_TOP63 = "top63"
|
||||||
|
CONF_SENS_TOP64 = "top64"
|
||||||
|
CONF_SENS_TOP65 = "top65"
|
||||||
|
CONF_SENS_TOP66 = "top66"
|
||||||
|
CONF_SENS_TOP67 = "top67"
|
||||||
|
CONF_SENS_TOP70 = "top70"
|
||||||
|
CONF_SENS_TOP71 = "top71"
|
||||||
|
CONF_SENS_TOP72 = "top72"
|
||||||
|
CONF_SENS_TOP73 = "top73"
|
||||||
|
CONF_SENS_TOP74 = "top74"
|
||||||
|
CONF_SENS_TOP75 = "top75"
|
||||||
|
CONF_SENS_TOP77 = "top77"
|
||||||
|
CONF_SENS_TOP78 = "top78"
|
||||||
|
CONF_SENS_TOP79 = "top79"
|
||||||
|
CONF_SENS_TOP80 = "top80"
|
||||||
|
CONF_SENS_TOP82 = "top82"
|
||||||
|
CONF_SENS_TOP83 = "top83"
|
||||||
|
CONF_SENS_TOP84 = "top84"
|
||||||
|
CONF_SENS_TOP85 = "top85"
|
||||||
|
CONF_SENS_TOP86 = "top86"
|
||||||
|
CONF_SENS_TOP87 = "top87"
|
||||||
|
CONF_SENS_TOP88 = "top88"
|
||||||
|
CONF_SENS_TOP89 = "top89"
|
||||||
|
CONF_SENS_TOP90 = "top90"
|
||||||
|
CONF_SENS_TOP91 = "top91"
|
||||||
|
CONF_SENS_TOP93 = "top93"
|
||||||
|
CONF_SENS_TOP95 = "top95"
|
||||||
|
CONF_SENS_TOP96 = "top96"
|
||||||
|
CONF_SENS_TOP97 = "top97"
|
||||||
|
CONF_SENS_TOP98 = "top98"
|
||||||
|
CONF_SENS_TOP102 = "top102"
|
||||||
|
CONF_SENS_TOP103 = "top103"
|
||||||
|
CONF_SENS_TOP104 = "top104"
|
||||||
|
CONF_SENS_TOP105 = "top105"
|
||||||
|
CONF_SENS_TOP113 = "top113"
|
||||||
|
CONF_SENS_TOP115 = "top115"
|
||||||
|
CONF_SENS_TOP116 = "top116"
|
||||||
|
CONF_SENS_TOP117 = "top117"
|
||||||
|
CONF_SENS_TOP118 = "top118"
|
||||||
|
CONF_SENS_TOP119 = "top119"
|
||||||
|
CONF_SENS_TOP120 = "top120"
|
||||||
|
CONF_SENS_TOP121 = "top121"
|
||||||
|
CONF_SENS_TOP122 = "top122"
|
||||||
|
CONF_SENS_TOP123 = "top123"
|
||||||
|
CONF_SENS_TOP125 = "top125"
|
||||||
|
CONF_SENS_TOP126 = "top126"
|
||||||
|
|
||||||
|
TYPES = [
|
||||||
|
CONF_SENS_TOP1,
|
||||||
|
CONF_SENS_TOP5,
|
||||||
|
CONF_SENS_TOP6,
|
||||||
|
CONF_SENS_TOP7,
|
||||||
|
CONF_SENS_TOP8,
|
||||||
|
CONF_SENS_TOP9,
|
||||||
|
CONF_SENS_TOP10,
|
||||||
|
CONF_SENS_TOP11,
|
||||||
|
CONF_SENS_TOP12,
|
||||||
|
CONF_SENS_TOP14,
|
||||||
|
CONF_SENS_TOP15,
|
||||||
|
CONF_SENS_TOP16,
|
||||||
|
CONF_SENS_TOP21,
|
||||||
|
CONF_SENS_TOP22,
|
||||||
|
CONF_SENS_TOP23,
|
||||||
|
CONF_SENS_TOP24,
|
||||||
|
CONF_SENS_TOP25,
|
||||||
|
CONF_SENS_TOP27,
|
||||||
|
CONF_SENS_TOP28,
|
||||||
|
CONF_SENS_TOP29,
|
||||||
|
CONF_SENS_TOP30,
|
||||||
|
CONF_SENS_TOP31,
|
||||||
|
CONF_SENS_TOP32,
|
||||||
|
CONF_SENS_TOP33,
|
||||||
|
CONF_SENS_TOP34,
|
||||||
|
CONF_SENS_TOP35,
|
||||||
|
CONF_SENS_TOP36,
|
||||||
|
CONF_SENS_TOP37,
|
||||||
|
CONF_SENS_TOP38,
|
||||||
|
CONF_SENS_TOP39,
|
||||||
|
CONF_SENS_TOP40,
|
||||||
|
CONF_SENS_TOP41,
|
||||||
|
CONF_SENS_TOP42,
|
||||||
|
CONF_SENS_TOP43,
|
||||||
|
CONF_SENS_TOP45,
|
||||||
|
CONF_SENS_TOP46,
|
||||||
|
CONF_SENS_TOP47,
|
||||||
|
CONF_SENS_TOP48,
|
||||||
|
CONF_SENS_TOP49,
|
||||||
|
CONF_SENS_TOP50,
|
||||||
|
CONF_SENS_TOP51,
|
||||||
|
CONF_SENS_TOP52,
|
||||||
|
CONF_SENS_TOP53,
|
||||||
|
CONF_SENS_TOP54,
|
||||||
|
CONF_SENS_TOP55,
|
||||||
|
CONF_SENS_TOP56,
|
||||||
|
CONF_SENS_TOP57,
|
||||||
|
CONF_SENS_TOP62,
|
||||||
|
CONF_SENS_TOP63,
|
||||||
|
CONF_SENS_TOP64,
|
||||||
|
CONF_SENS_TOP65,
|
||||||
|
CONF_SENS_TOP66,
|
||||||
|
CONF_SENS_TOP67,
|
||||||
|
CONF_SENS_TOP70,
|
||||||
|
CONF_SENS_TOP71,
|
||||||
|
CONF_SENS_TOP72,
|
||||||
|
CONF_SENS_TOP73,
|
||||||
|
CONF_SENS_TOP74,
|
||||||
|
CONF_SENS_TOP75,
|
||||||
|
CONF_SENS_TOP77,
|
||||||
|
CONF_SENS_TOP78,
|
||||||
|
CONF_SENS_TOP79,
|
||||||
|
CONF_SENS_TOP80,
|
||||||
|
CONF_SENS_TOP82,
|
||||||
|
CONF_SENS_TOP83,
|
||||||
|
CONF_SENS_TOP84,
|
||||||
|
CONF_SENS_TOP85,
|
||||||
|
CONF_SENS_TOP86,
|
||||||
|
CONF_SENS_TOP87,
|
||||||
|
CONF_SENS_TOP88,
|
||||||
|
CONF_SENS_TOP89,
|
||||||
|
CONF_SENS_TOP90,
|
||||||
|
CONF_SENS_TOP91,
|
||||||
|
CONF_SENS_TOP93,
|
||||||
|
CONF_SENS_TOP95,
|
||||||
|
CONF_SENS_TOP96,
|
||||||
|
CONF_SENS_TOP97,
|
||||||
|
CONF_SENS_TOP98,
|
||||||
|
CONF_SENS_TOP102,
|
||||||
|
CONF_SENS_TOP103,
|
||||||
|
CONF_SENS_TOP104,
|
||||||
|
CONF_SENS_TOP105,
|
||||||
|
CONF_SENS_TOP113,
|
||||||
|
CONF_SENS_TOP115,
|
||||||
|
CONF_SENS_TOP116,
|
||||||
|
CONF_SENS_TOP117,
|
||||||
|
CONF_SENS_TOP118,
|
||||||
|
CONF_SENS_TOP119,
|
||||||
|
CONF_SENS_TOP120,
|
||||||
|
CONF_SENS_TOP121,
|
||||||
|
CONF_SENS_TOP122,
|
||||||
|
CONF_SENS_TOP123,
|
||||||
|
CONF_SENS_TOP125,
|
||||||
|
CONF_SENS_TOP126,
|
||||||
|
]
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.All(
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(PanasonicHeatpumpComponent),
|
||||||
|
|
||||||
|
cv.Optional(CONF_SENS_TOP1): sensor.sensor_schema(
|
||||||
|
accuracy_decimals = 1,
|
||||||
|
unit_of_measurement = UNIT_LITRE_PER_MINUTE),
|
||||||
|
cv.Optional(CONF_SENS_TOP5): sensor.sensor_schema(
|
||||||
|
accuracy_decimals = 1,
|
||||||
|
unit_of_measurement = UNIT_CELSIUS),
|
||||||
|
cv.Optional(CONF_SENS_TOP6): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP7): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP8): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP9): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP10): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP11): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP12): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP14): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP15): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP16): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP21): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP22): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP23): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP24): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP25): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP27): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP28): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP29): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP30): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP31): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP32): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP33): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP34): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP35): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP36): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP37): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP38): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP39): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP40): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP41): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP42): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP43): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP45): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP46): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP47): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP48): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP49): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP50): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP51): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP52): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP53): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP54): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP55): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP56): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP57): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP62): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP63): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP64): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP65): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP66): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP67): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP70): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP71): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP72): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP73): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP74): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP75): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP77): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP78): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP79): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP80): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP82): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP83): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP84): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP85): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP86): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP87): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP88): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP89): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP90): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP91): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP93): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP95): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP96): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP97): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP98): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP102): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP103): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP104): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP105): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP113): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP115): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP116): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP117): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP118): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP119): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP120): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP121): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP122): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP123): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP125): sensor.sensor_schema(),
|
||||||
|
cv.Optional(CONF_SENS_TOP126): sensor.sensor_schema(),
|
||||||
|
}
|
||||||
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def setup_conf(config, key, hub):
|
||||||
|
if sensor_config := config.get(key):
|
||||||
|
sens = await sensor.new_sensor(sensor_config)
|
||||||
|
cg.add(getattr(hub, f"set_{key}_sensor")(sens))
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
hub = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID])
|
||||||
|
for key in TYPES:
|
||||||
|
await setup_conf(config, key, hub)
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome.components import text_sensor
|
||||||
|
from esphome.const import (
|
||||||
|
DEVICE_CLASS_HEAT,
|
||||||
|
)
|
||||||
|
from . import PanasonicHeatpumpComponent, CONF_PANASONIC_HEATPUMP_ID
|
||||||
|
|
||||||
|
CONF_TEXT_SENS_TOP4 = "top4"
|
||||||
|
CONF_TEXT_SENS_TOP17 = "top17"
|
||||||
|
CONF_TEXT_SENS_TOP18 = "top18"
|
||||||
|
CONF_TEXT_SENS_TOP19 = "top19"
|
||||||
|
CONF_TEXT_SENS_TOP20 = "top20"
|
||||||
|
CONF_TEXT_SENS_TOP44 = "top44"
|
||||||
|
CONF_TEXT_SENS_TOP58 = "top58"
|
||||||
|
CONF_TEXT_SENS_TOP59 = "top59"
|
||||||
|
CONF_TEXT_SENS_TOP76 = "top76"
|
||||||
|
CONF_TEXT_SENS_TOP81 = "top81"
|
||||||
|
CONF_TEXT_SENS_TOP92 = "top92"
|
||||||
|
CONF_TEXT_SENS_TOP94 = "top94"
|
||||||
|
CONF_TEXT_SENS_TOP101 = "top101"
|
||||||
|
CONF_TEXT_SENS_TOP106 = "top106"
|
||||||
|
CONF_TEXT_SENS_TOP107 = "top107"
|
||||||
|
CONF_TEXT_SENS_TOP111 = "top111"
|
||||||
|
CONF_TEXT_SENS_TOP112 = "top112"
|
||||||
|
CONF_TEXT_SENS_TOP114 = "top114"
|
||||||
|
CONF_TEXT_SENS_TOP124 = "top124"
|
||||||
|
|
||||||
|
TYPES = [
|
||||||
|
CONF_TEXT_SENS_TOP4,
|
||||||
|
CONF_TEXT_SENS_TOP17,
|
||||||
|
CONF_TEXT_SENS_TOP18,
|
||||||
|
CONF_TEXT_SENS_TOP19,
|
||||||
|
CONF_TEXT_SENS_TOP20,
|
||||||
|
CONF_TEXT_SENS_TOP44,
|
||||||
|
CONF_TEXT_SENS_TOP58,
|
||||||
|
CONF_TEXT_SENS_TOP59,
|
||||||
|
CONF_TEXT_SENS_TOP76,
|
||||||
|
CONF_TEXT_SENS_TOP81,
|
||||||
|
CONF_TEXT_SENS_TOP92,
|
||||||
|
CONF_TEXT_SENS_TOP94,
|
||||||
|
CONF_TEXT_SENS_TOP101,
|
||||||
|
CONF_TEXT_SENS_TOP106,
|
||||||
|
CONF_TEXT_SENS_TOP107,
|
||||||
|
CONF_TEXT_SENS_TOP111,
|
||||||
|
CONF_TEXT_SENS_TOP112,
|
||||||
|
CONF_TEXT_SENS_TOP114,
|
||||||
|
CONF_TEXT_SENS_TOP124,
|
||||||
|
]
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.All(
|
||||||
|
cv.Schema(
|
||||||
|
{
|
||||||
|
cv.GenerateID(CONF_PANASONIC_HEATPUMP_ID): cv.use_id(PanasonicHeatpumpComponent),
|
||||||
|
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP4): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP17): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP18): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP19): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP20): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP44): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP58): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP59): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP76): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP81): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP92): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP94): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP101): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP106): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP107): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP111): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP112): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP114): text_sensor.text_sensor_schema(),
|
||||||
|
cv.Optional(CONF_TEXT_SENS_TOP124): text_sensor.text_sensor_schema(),
|
||||||
|
}
|
||||||
|
).extend(cv.COMPONENT_SCHEMA)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def setup_conf(config, key, hub):
|
||||||
|
if sensor_config := config.get(key):
|
||||||
|
sens = await text_sensor.new_text_sensor(sensor_config)
|
||||||
|
cg.add(getattr(hub, f"set_{key}_text_sensor")(sens))
|
||||||
|
|
||||||
|
async def to_code(config):
|
||||||
|
hub = await cg.get_variable(config[CONF_PANASONIC_HEATPUMP_ID])
|
||||||
|
for key in TYPES:
|
||||||
|
await setup_conf(config, key, hub)
|
||||||
|
|
@ -0,0 +1,431 @@
|
||||||
|
substitutions:
|
||||||
|
mdns_name: panasonic-heatpump
|
||||||
|
device_name: Panasonic Heatpump
|
||||||
|
|
||||||
|
pin_rx_hp: GPIO4 # heatpump reads data (RX) on this pin
|
||||||
|
pin_tx_hp: GPIO3 # heatpump sends data (TX) on this pin
|
||||||
|
pin_tx_cz: GPIO1 # WiFi module sends data (TX) on this pin
|
||||||
|
pin_rx_cz: GPIO0 # WiFi module reads data (RX) on this pin
|
||||||
|
|
||||||
|
# CN-CNT Pinout (from top to bottom)
|
||||||
|
# 1 - +5V (250mA)
|
||||||
|
# 2 - 0-5V TX (from heatpump)
|
||||||
|
# 3 - 0-5V RX (to heatpump)
|
||||||
|
# 4 - +12V (250mA)
|
||||||
|
# 5 - GND
|
||||||
|
|
||||||
|
esp32:
|
||||||
|
board: esp32-c3-devkitm-1
|
||||||
|
variant: ESP32C3
|
||||||
|
framework:
|
||||||
|
type: arduino
|
||||||
|
|
||||||
|
esphome:
|
||||||
|
name: $mdns_name
|
||||||
|
friendly_name: $device_name
|
||||||
|
|
||||||
|
ota:
|
||||||
|
platform: esphome
|
||||||
|
password: !secret ota_password
|
||||||
|
id: ota_pass
|
||||||
|
|
||||||
|
api:
|
||||||
|
encryption:
|
||||||
|
key: !secret ha_api_key
|
||||||
|
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
ap:
|
||||||
|
ssid: "${device_name} Fallback"
|
||||||
|
password: !secret fallback_password
|
||||||
|
|
||||||
|
web_server:
|
||||||
|
port: 80
|
||||||
|
auth:
|
||||||
|
username: !secret webserver_username
|
||||||
|
password: !secret webserver_password
|
||||||
|
|
||||||
|
captive_portal:
|
||||||
|
|
||||||
|
improv_serial:
|
||||||
|
|
||||||
|
logger:
|
||||||
|
|
||||||
|
uart:
|
||||||
|
- id: uart_heat
|
||||||
|
tx_pin: $pin_rx_hp
|
||||||
|
rx_pin: $pin_tx_hp
|
||||||
|
baud_rate: 9600
|
||||||
|
data_bits: 8
|
||||||
|
parity: EVEN
|
||||||
|
stop_bits: 1
|
||||||
|
- id: uart_wifi
|
||||||
|
tx_pin: $pin_rx_cz
|
||||||
|
rx_pin: $pin_tx_cz
|
||||||
|
baud_rate: 9600
|
||||||
|
data_bits: 8
|
||||||
|
parity: EVEN
|
||||||
|
stop_bits: 1
|
||||||
|
|
||||||
|
external_components:
|
||||||
|
- source:
|
||||||
|
type: git
|
||||||
|
url: https://github.com/ElVit/esphome_components/
|
||||||
|
components: [ panasonic_heatpump ]
|
||||||
|
|
||||||
|
panasonic_heatpump:
|
||||||
|
uart_hp: uart_heat
|
||||||
|
uart_wm: uart_wifi
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: panasonic_heatpump
|
||||||
|
top1:
|
||||||
|
name: "Pump Flow"
|
||||||
|
unit_of_measurement: l/min"
|
||||||
|
top5:
|
||||||
|
name: "Main Inlet Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top6:
|
||||||
|
name: "Main Outlet Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top7:
|
||||||
|
name: "Main Target Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top8:
|
||||||
|
name: "Compressor Freq"
|
||||||
|
unit_of_measurement: Hz"
|
||||||
|
top9:
|
||||||
|
name: "DHW Target Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top10:
|
||||||
|
name: "DHW Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top11:
|
||||||
|
name: "Operations Hours"
|
||||||
|
unit_of_measurement: h"
|
||||||
|
top12:
|
||||||
|
name: "Operations Counter"
|
||||||
|
top14:
|
||||||
|
name: "Outside Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top15:
|
||||||
|
name: "Heat Power Production"
|
||||||
|
unit_of_measurement: W"
|
||||||
|
top16:
|
||||||
|
name: "Heat Power Consumption"
|
||||||
|
unit_of_measurement: W"
|
||||||
|
top21:
|
||||||
|
name: "Outside Pipe Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top22:
|
||||||
|
name: "DHW Heat Delta"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top23:
|
||||||
|
name: "Heat Delta"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top24:
|
||||||
|
name: "Cool Delta"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top25:
|
||||||
|
name: "DHW Holiday Shift Temp"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top27:
|
||||||
|
name: "Z1 Heat Request Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top28:
|
||||||
|
name: "Z1 Cool Request Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top29:
|
||||||
|
name: "Z1 Heat Curve Target High Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top30:
|
||||||
|
name: "Z1 Heat Curve Target Low Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top31:
|
||||||
|
name: "Z1 Heat Curve Outside High Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top32:
|
||||||
|
name: "Z1 Heat Curve Outside Low Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top33:
|
||||||
|
name: "Room Thermostat Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top34:
|
||||||
|
name: "Z2 Heat Request Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top35:
|
||||||
|
name: "Z2 Cool Request Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top36:
|
||||||
|
name: "Z1 Water Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top37:
|
||||||
|
name: "Z2 Water Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top38:
|
||||||
|
name: "Cool Power Production"
|
||||||
|
unit_of_measurement: W"
|
||||||
|
top39:
|
||||||
|
name: "Cool Power Consumption"
|
||||||
|
unit_of_measurement: W"
|
||||||
|
top40:
|
||||||
|
name: "DHW Power Production"
|
||||||
|
unit_of_measurement: W"
|
||||||
|
top41:
|
||||||
|
name: "DHW Power Consumption"
|
||||||
|
unit_of_measurement: W"
|
||||||
|
top42:
|
||||||
|
name: "Z1 Water Target Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top43:
|
||||||
|
name: "Z2 Water Target Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top45:
|
||||||
|
name: "Room Holiday Shift Temp"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top46:
|
||||||
|
name: "Buffer Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top47:
|
||||||
|
name: "Solar Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top48:
|
||||||
|
name: "Pool Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top49:
|
||||||
|
name: "Main Hex Outlet Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top50:
|
||||||
|
name: "Discharge Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top51:
|
||||||
|
name: "Inside Pipe Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top52:
|
||||||
|
name: "Defrost Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top53:
|
||||||
|
name: "Eva Outlet Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top54:
|
||||||
|
name: "Bypass Outlet Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top55:
|
||||||
|
name: "Ipm Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top56:
|
||||||
|
name: "Z1 Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top57:
|
||||||
|
name: "Z2 Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top62:
|
||||||
|
name: "Fan1 Motor Speed"
|
||||||
|
unit_of_measurement: r/min"
|
||||||
|
top63:
|
||||||
|
name: "Fan2 Motor Speed"
|
||||||
|
unit_of_measurement: r/min"
|
||||||
|
top64:
|
||||||
|
name: "High Pressure"
|
||||||
|
unit_of_measurement: kgf/cm²"
|
||||||
|
top65:
|
||||||
|
name: "Pump Speed"
|
||||||
|
unit_of_measurement: r/min"
|
||||||
|
top66:
|
||||||
|
name: "Low Pressure"
|
||||||
|
unit_of_measurement: kgf/cm²"
|
||||||
|
top67:
|
||||||
|
name: "Compressor Current"
|
||||||
|
unit_of_measurement: A"
|
||||||
|
top70:
|
||||||
|
name: "Sterilization Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top71:
|
||||||
|
name: "Sterilization Max Time"
|
||||||
|
unit_of_measurement: min"
|
||||||
|
top72:
|
||||||
|
name: "Z1 Cool Curve Target High Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top73:
|
||||||
|
name: "Z1 Cool Curve Target Low Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top74:
|
||||||
|
name: "Z1 Cool Curve Outside High Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top75:
|
||||||
|
name: "Z1 Cool Curve Outside Low Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top77:
|
||||||
|
name: "Heating Off Outdoor Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top78:
|
||||||
|
name: "Heater On Outdoor Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top79:
|
||||||
|
name: "Heat To Cool Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top80:
|
||||||
|
name: "Cool To Heat Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top82:
|
||||||
|
name: "Z2 Heat Curve Target High Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top83:
|
||||||
|
name: "Z2 Heat Curve Target Low Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top84:
|
||||||
|
name: "Z2 Heat Curve Outside High Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top85:
|
||||||
|
name: "Z2 Heat Curve Outside Low Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top86:
|
||||||
|
name: "Z2 Cool Curve Target High Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top87:
|
||||||
|
name: "Z2 Cool Curve Target Low Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top88:
|
||||||
|
name: "Z2 Cool Curve Outside High Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top89:
|
||||||
|
name: "Z2 Cool Curve Outside Low Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top90:
|
||||||
|
name: "Room Heater Operations Hours"
|
||||||
|
unit_of_measurement: h"
|
||||||
|
top91:
|
||||||
|
name: "DHW Heater Operations Hours"
|
||||||
|
unit_of_measurement: h"
|
||||||
|
top93:
|
||||||
|
name: "Pump Duty"
|
||||||
|
top95:
|
||||||
|
name: "Max Pump Duty"
|
||||||
|
top96:
|
||||||
|
name: "Heater Delay Time"
|
||||||
|
unit_of_measurement: min"
|
||||||
|
top97:
|
||||||
|
name: "Heater Start Delta"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top98:
|
||||||
|
name: "Heater Stop Delta"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top102:
|
||||||
|
name: "Solar On Delta"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top103:
|
||||||
|
name: "Solar Off Delta"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top104:
|
||||||
|
name: "Solar Frost Protection"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top105:
|
||||||
|
name: "Solar High Limit"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top113:
|
||||||
|
name: "Buffer Tank Delta"
|
||||||
|
unit_of_measurement: K"
|
||||||
|
top115:
|
||||||
|
name: "Water Pressure"
|
||||||
|
unit_of_measurement: bar"
|
||||||
|
top116:
|
||||||
|
name: "Second Inlet Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top117:
|
||||||
|
name: "Economizer Outlet Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top118:
|
||||||
|
name: "Second Room Thermostat Temp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top119:
|
||||||
|
name: "Bivalent Heating Start Temperature"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top120:
|
||||||
|
name: "Bivalent Heating Parallel Adv Starttemp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top121:
|
||||||
|
name: "Bivalent Heating Parallel Adv Stoptemp"
|
||||||
|
unit_of_measurement: °C"
|
||||||
|
top122:
|
||||||
|
name: "Bivalent Heating Parallel Adv Start Delay"
|
||||||
|
unit_of_measurement: min"
|
||||||
|
top123:
|
||||||
|
name: "Bivalent Heating Parallel Adv Stop Delay"
|
||||||
|
unit_of_measurement: min"
|
||||||
|
top125:
|
||||||
|
name: "2 Zone mixing valve 1 opening"
|
||||||
|
top126:
|
||||||
|
name: "2 Zone mixing valve 2 opening"
|
||||||
|
|
||||||
|
binary_sensor:
|
||||||
|
- platform: panasonic_heatpump
|
||||||
|
top0:
|
||||||
|
name: "Heatpump State"
|
||||||
|
top2:
|
||||||
|
name: "Force DHW State"
|
||||||
|
top3:
|
||||||
|
name: "Quiet Mode Schedule"
|
||||||
|
top13:
|
||||||
|
name: "Main Schedule State"
|
||||||
|
top26:
|
||||||
|
name: "Defrosting State"
|
||||||
|
top60:
|
||||||
|
name: "Internal Heater State"
|
||||||
|
top61:
|
||||||
|
name: "External Heater State"
|
||||||
|
top68:
|
||||||
|
name: "Force Heater State"
|
||||||
|
top69:
|
||||||
|
name: "Sterilization State"
|
||||||
|
top99:
|
||||||
|
name: "Buffer Installed"
|
||||||
|
top100:
|
||||||
|
name: "DHW Installed"
|
||||||
|
top108:
|
||||||
|
name: "Alt External Sensor"
|
||||||
|
top109:
|
||||||
|
name: "Anti Freeze Mode"
|
||||||
|
top110:
|
||||||
|
name: "Optional PCB"
|
||||||
|
|
||||||
|
text_sensor:
|
||||||
|
- platform: panasonic_heatpump
|
||||||
|
top4:
|
||||||
|
name: "Operating Mode State"
|
||||||
|
top17:
|
||||||
|
name: "Powerful Mode Time"
|
||||||
|
top18:
|
||||||
|
name: "Quiet Mode Level"
|
||||||
|
top19:
|
||||||
|
name: "Holiday Mode State"
|
||||||
|
top20:
|
||||||
|
name: "ThreeWay Valve State"
|
||||||
|
top44:
|
||||||
|
name: "Error"
|
||||||
|
top58:
|
||||||
|
name: "DHW Heater State"
|
||||||
|
top59:
|
||||||
|
name: "Room Heater State"
|
||||||
|
top76:
|
||||||
|
name: "Heating Mode"
|
||||||
|
top81:
|
||||||
|
name: "Cooling Mode"
|
||||||
|
top92:
|
||||||
|
name: "Heat Pump Model"
|
||||||
|
top94:
|
||||||
|
name: "Zones State"
|
||||||
|
top101:
|
||||||
|
name: "Solar Mode"
|
||||||
|
top106:
|
||||||
|
name: "Pump Flowrate Mode"
|
||||||
|
top107:
|
||||||
|
name: "Liquid Type"
|
||||||
|
top111:
|
||||||
|
name: "Z1 Sensor Settings"
|
||||||
|
top112:
|
||||||
|
name: "Z2 Sensor Settings"
|
||||||
|
top114:
|
||||||
|
name: "External Pad Heater"
|
||||||
|
top124:
|
||||||
|
name: "Bivalent Heating Setting"
|
||||||
Loading…
Reference in New Issue