ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
ras_25j2kvsg_nd.cpp
Go to the documentation of this file.
1#include "ras_25j2kvsg_nd.h"
2
3#ifdef USE_TOSHIBA_RAS_25J2KVSG_ND
4
5#include <cmath>
6#include <iterator>
7
8#include "esphome/core/hal.h"
10#include "esphome/core/log.h"
11
13
14ESPHOME_LOG_TAG(TAG, "toshiba.climate");
15
16static constexpr const char *const CUSTOM_FANS[] PROGMEM = {"Low+", "Medium+"};
17static constexpr const char *const CUSTOM_PRESETS[] PROGMEM = {
18 "Fireplace 1", "Fireplace 2", "Frost protection", "HADA Care", "Sleep 1h", "Sleep 3h", "Sleep 5h", "Sleep 9h",
19};
20static constexpr uint8_t SLEEP_HOURS[] PROGMEM = {1, 3, 5, 9};
21// The two copies of a press can arrive in separate receiver buffers.
22static constexpr uint32_t REPEAT_MS = 200;
23static constexpr uint8_t MAX_FRAME_LENGTH = 12;
24static constexpr uint8_t MOTION_FRAME_LENGTH = 7;
25static constexpr uint8_t SHORT_MOTION_COMMAND = 0x21;
26static constexpr uint8_t FIREPLACE_1 = 0x02;
27static constexpr uint8_t FIREPLACE_2 = 0x03;
28static constexpr uint8_t FEATURE_FROST = 0x04;
29static constexpr uint8_t SILENT_1 = 0x02;
30static constexpr uint8_t SILENT_2 = 0x0A;
31static constexpr uint8_t HADA_PREFIX = 0x21;
32static constexpr uint8_t HADA_SUFFIX = 0x17;
33static constexpr uint8_t SLEEP_TIMER_MARKER = 0x7F;
34static constexpr uint8_t SLEEP_TIMER_FLAGS = 0x03;
35static constexpr float FROST_TEMP_C_DEFAULT = 8.0f;
36// Frost targets are encoded from 1 C, normal targets from the normal minimum.
37static constexpr uint8_t FROST_TEMP_CODE_BASE = 1;
38
39static float target_min(bool frost) {
40 return frost ? TOSHIBA_RAS_25J2KVSG_ND_FROST_TEMP_C_MIN : TOSHIBA_GENERIC_TEMP_C_MIN;
41}
42static float target_max(bool frost) {
43 return frost ? TOSHIBA_RAS_25J2KVSG_ND_FROST_TEMP_C_MAX : TOSHIBA_GENERIC_TEMP_C_MAX;
44}
45// NaN passes through unchanged, so it never equals a valid target.
46static float clamp_target(float target, bool frost) { return clamp(target, target_min(frost), target_max(frost)); }
47static uint8_t temperature_code_base(bool frost) {
48 return frost ? FROST_TEMP_CODE_BASE : static_cast<uint8_t>(TOSHIBA_GENERIC_TEMP_C_MIN);
49}
50static float decode_target(const uint8_t *message, bool frost) {
51 return (message[5] >> 4) + temperature_code_base(frost);
52}
53// Pulses encode_() writes for a frame sent repeat + 1 times: header, 8 bits per byte, footer mark and gap.
54static constexpr size_t frame_pulses(uint8_t nbytes, uint8_t repeat) { return (repeat + 1u) * (16u * nbytes + 4u); }
55
57 this->set_supported_custom_fan_modes_static(CUSTOM_FANS, std::size(CUSTOM_FANS));
58 this->set_supported_custom_presets_static(CUSTOM_PRESETS, std::size(CUSTOM_PRESETS));
64 this->power_selection_ = power;
66 // A fresh target follows the sensor over the range that includes frost targets.
67 this->target_temperature =
68 clamp_target(this->target_temperature, this->toshiba_preset_() == ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION);
70}
71
73 if (!this->modes_.count(restore.mode))
75 auto preset = ToshibaPreset::TOSHIBA_PRESET_NONE;
76 if (restore.uses_custom_preset && restore.custom_preset < std::size(CUSTOM_PRESETS))
78 // A restored duration is not the remaining time; never re-arm an OFF timer after reboot.
79 if ((restore.uses_custom_preset && (preset == ToshibaPreset::TOSHIBA_PRESET_NONE || is_sleep_preset(preset) ||
81 (!restore.uses_custom_preset && !this->presets_.count(restore.preset)) ||
84 restore.uses_custom_preset = false;
86 preset = ToshibaPreset::TOSHIBA_PRESET_NONE;
87 }
88 if (preset == ToshibaPreset::TOSHIBA_PRESET_HADA_CARE)
90 const bool frost = preset == ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION;
91 // The restore state is packed, so clamp a copy rather than bind a reference to the field.
92 const float target = restore.target_temperature;
93 restore.target_temperature =
94 std::isfinite(target) ? clamp_target(target, frost) : (frost ? FROST_TEMP_C_DEFAULT : 24.0f);
95}
96
97ToshibaRas25j2kvsgNdClimate::ToshibaPreset ToshibaRas25j2kvsgNdClimate::preset_from_climate(
99 switch (preset) {
101 return ToshibaPreset::TOSHIBA_PRESET_BOOST;
103 return ToshibaPreset::TOSHIBA_PRESET_ECO;
104 default:
105 return ToshibaPreset::TOSHIBA_PRESET_NONE;
106 }
107}
108
109ToshibaRas25j2kvsgNdClimate::ToshibaPreset ToshibaRas25j2kvsgNdClimate::preset_from_custom(const char *custom_preset) {
110 // Climate keeps a pointer into the supported table, so comparing pointers is enough.
111 for (size_t i = 0; i < std::size(CUSTOM_PRESETS); i++) {
112 if (custom_preset == progmem_read_ptr(&CUSTOM_PRESETS[i]))
113 return custom_preset_at(i);
114 }
115 return ToshibaPreset::TOSHIBA_PRESET_NONE;
116}
117
118ToshibaRas25j2kvsgNdClimate::ToshibaPreset ToshibaRas25j2kvsgNdClimate::toshiba_preset_() const {
119 if (this->has_custom_preset())
120 return preset_from_custom(this->get_custom_preset().c_str());
122}
123
125 switch (preset) {
126 case ToshibaPreset::TOSHIBA_PRESET_NONE:
128 break;
129 case ToshibaPreset::TOSHIBA_PRESET_BOOST:
131 break;
132 case ToshibaPreset::TOSHIBA_PRESET_ECO:
134 break;
135 default:
137 }
138}
139
140void ToshibaRas25j2kvsgNdClimate::enter_preset_(ToshibaPreset previous, ToshibaPreset preset) {
141 if (preset == ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION && previous != preset)
142 this->normal_target_temperature_ = static_cast<uint8_t>(this->target_temperature);
143 if (is_sleep_preset(preset) && !is_sleep_preset(previous))
144 this->sleep_fan_ = this->fan_code_();
145}
146
148 if (this->get_custom_fan_mode() == progmem_read_ptr(&CUSTOM_FANS[0]))
149 return TOSHIBA_FAN_SPEED_2;
150 if (this->get_custom_fan_mode() == progmem_read_ptr(&CUSTOM_FANS[1]))
151 return TOSHIBA_FAN_SPEED_4;
152 return this->encode_fan_();
153}
154
156 switch (code) {
157 case TOSHIBA_FAN_SPEED_2:
158 this->set_custom_fan_mode_(progmem_read_ptr(&CUSTOM_FANS[0]));
159 break;
160 case TOSHIBA_FAN_SPEED_4:
161 this->set_custom_fan_mode_(progmem_read_ptr(&CUSTOM_FANS[1]));
162 break;
163 default:
164 this->set_fan_mode_(decode_fan(code));
165 }
166}
167
169 const auto previous_preset = this->toshiba_preset_();
170 auto preset = previous_preset;
171 if (call.get_preset().has_value()) {
172 preset = preset_from_climate(*call.get_preset());
173 } else if (call.has_custom_preset()) {
174 preset = preset_from_custom(call.get_custom_preset().c_str());
175 }
176
177 auto mode = call.get_mode().value_or(this->mode);
178 const bool heating_preset = is_heating_preset(preset);
179 if (heating_preset && !this->modes_.count(climate::CLIMATE_MODE_HEAT)) {
180 ESP_LOGW(TAG, "This preset requires HEAT support");
181 return;
182 }
183 if (heating_preset && mode != climate::CLIMATE_MODE_HEAT) {
184 if (call.has_custom_preset() && call.get_mode().has_value()) {
185 ESP_LOGW(TAG, "This preset requires HEAT mode");
186 return;
187 }
188 if (call.has_custom_preset()) {
190 } else {
191 preset = ToshibaPreset::TOSHIBA_PRESET_NONE;
192 }
193 }
194 if (call.get_mode() == climate::CLIMATE_MODE_OFF && !call.get_preset().has_value() && !call.has_custom_preset())
195 preset = ToshibaPreset::TOSHIBA_PRESET_NONE;
196
198 return;
199 if (call.get_swing_mode().has_value() && *call.get_swing_mode() != climate::CLIMATE_SWING_OFF &&
200 preset == ToshibaPreset::TOSHIBA_PRESET_HADA_CARE) {
201 ESP_LOGW(TAG, "SWING is unavailable during HADA Care");
202 return;
203 }
204
205 const bool frost = preset == ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION;
206 float temperature = this->target_temperature;
207 if (frost && previous_preset != preset) {
208 temperature = FROST_TEMP_C_DEFAULT;
209 } else if (!frost && previous_preset == ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION) {
211 }
212 temperature = call.get_target_temperature().value_or(temperature);
213 if (clamp_target(temperature, frost) != temperature) {
214 ESP_LOGW(TAG, "Target must be %s",
215 frost ? LOG_STR_LITERAL("5-13 C for frost protection") : LOG_STR_LITERAL("17-30 C for normal operation"));
216 return;
217 }
218
219 this->enter_preset_(previous_preset, preset);
220 const bool sleep = is_sleep_preset(preset);
221 if (!sleep && is_sleep_preset(previous_preset))
222 this->apply_fan_code_(this->sleep_fan_);
223 if (call.get_fan_mode().has_value()) {
224 this->set_fan_mode_(*call.get_fan_mode());
225 } else if (call.has_custom_fan_mode()) {
227 }
228 if (sleep || mode == climate::CLIMATE_MODE_DRY)
230
231 this->mode = mode;
232 this->target_temperature = roundf(temperature);
234 if (preset == ToshibaPreset::TOSHIBA_PRESET_HADA_CARE)
236 if (call.get_swing_mode().has_value())
237 this->swing_mode = *call.get_swing_mode();
238
239 const bool state_command = call.get_mode().has_value() || call.get_target_temperature().has_value() ||
240 call.get_fan_mode().has_value() || call.has_custom_fan_mode() ||
241 call.get_preset().has_value() || call.has_custom_preset();
242 if (state_command) {
243 this->transmit_frame_(preset);
244 } else if (this->swing_mode != this->last_swing_mode_) {
245 this->transmit_motion_(TOSHIBA_MOTION_SWING, 1);
246 }
247 this->publish_state();
248}
249
251
253 uint8_t message[MAX_FRAME_LENGTH] = {0, 0, 0, 0, TOSHIBA_COMMAND_DEFAULT};
254 uint8_t length = 9;
255 const bool frost = preset == ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION;
256 const auto power = this->power_selection_;
257 message[5] = (static_cast<uint8_t>(this->target_temperature) - temperature_code_base(frost)) << 4;
258 message[6] = this->encode_mode_() | this->fan_code_();
261 message[7] = static_cast<uint8_t>(power) << 6;
262
263 if (preset == ToshibaPreset::TOSHIBA_PRESET_FIREPLACE_1) {
264 message[7] |= FIREPLACE_1;
265 } else if (preset == ToshibaPreset::TOSHIBA_PRESET_FIREPLACE_2) {
266 message[7] |= FIREPLACE_2;
267 } else if (preset == ToshibaPreset::TOSHIBA_PRESET_HADA_CARE) {
268 length = 11;
269 message[8] = HADA_PREFIX;
270 message[9] = HADA_SUFFIX;
271 } else if (is_sleep_preset(preset)) {
272 length = 12;
273 message[4] = TOSHIBA_COMMAND_DEFAULT | TOSHIBA_COMMAND_TIMER | TOSHIBA_COMMAND_POWER;
274 message[8] =
276 &SLEEP_HOURS[static_cast<uint8_t>(preset) - static_cast<uint8_t>(ToshibaPreset::TOSHIBA_PRESET_SLEEP_1H)])
277 << 2;
278 message[9] = SLEEP_TIMER_MARKER;
279 message[10] = SLEEP_TIMER_FLAGS;
280 } else if (preset != ToshibaPreset::TOSHIBA_PRESET_NONE || is_silent(power)) {
281 length = 10;
282 message[4] = TOSHIBA_COMMAND_DEFAULT | TOSHIBA_COMMAND_POWER;
283 if (preset == ToshibaPreset::TOSHIBA_PRESET_BOOST) {
284 message[8] = TOSHIBA_POWER_HIGH;
285 } else if (preset == ToshibaPreset::TOSHIBA_PRESET_ECO) {
286 message[8] = TOSHIBA_POWER_ECO;
287 } else if (frost) {
288 message[8] = FEATURE_FROST;
289 } else {
290 message[8] = power == ToshibaPowerSelection::TOSHIBA_POWER_SELECTION_SILENT_1 ? SILENT_1 : SILENT_2;
291 }
292 }
294 auto transmit = this->transmitter_->transmit();
295 auto *data = transmit.get_data();
296 const bool swing = this->swing_mode != this->last_swing_mode_;
297 data->reserve(frame_pulses(length, 1) + (swing ? frame_pulses(MOTION_FRAME_LENGTH, 1) : 0));
298 this->encode_(data, message, length, 1);
299 if (swing) {
300 this->encode_motion_(data, TOSHIBA_MOTION_SWING, 1);
301 this->last_swing_mode_ = this->swing_mode;
302 }
303 this->perform_(transmit, swing);
304}
305
306void ToshibaRas25j2kvsgNdClimate::transmit_motion_(uint8_t command, uint8_t repeat) {
307 auto transmit = this->transmitter_->transmit();
308 transmit.get_data()->reserve(frame_pulses(MOTION_FRAME_LENGTH, repeat));
309 this->encode_motion_(transmit.get_data(), command, repeat);
310 this->last_swing_mode_ = this->swing_mode;
311 this->perform_(transmit, command == TOSHIBA_MOTION_SWING);
312}
313
315 uint8_t repeat) {
316 uint8_t message[MOTION_FRAME_LENGTH] = {0, 0, 0, 0, SHORT_MOTION_COMMAND, command};
318 this->encode_(data, message, sizeof(message), repeat);
319}
320
322 uint32_t duration_us = 0;
323 if (swing) {
324 for (const int32_t pulse : transmit.get_data()->get_data())
325 duration_us += static_cast<uint32_t>(std::abs(pulse));
326 }
327 transmit.perform();
328 // perform() may wait for an earlier send before queuing this one, or block until this send finishes.
329 if (swing)
330 this->swing_ignore_until_ = millis() + (duration_us + 999) / 1000 + REPEAT_MS;
331}
332
334 if (command != TOSHIBA_MOTION_SWING)
335 return command == TOSHIBA_MOTION_VANE_STEP;
336 const uint32_t now = millis();
337 // Windows last well under 65 s, so a larger remainder is a deadline that has already passed.
338 const uint32_t remaining = this->swing_ignore_until_ - now;
339 if (remaining != 0 && remaining <= UINT16_MAX)
340 return true;
341 this->swing_mode =
343 this->last_swing_mode_ = this->swing_mode;
344 this->publish_state();
345 return true;
346}
347
348bool ToshibaRas25j2kvsgNdClimate::parse_state(const uint8_t *message, uint8_t length, ToshibaPreset &preset,
349 ToshibaPowerSelection &power) {
350 const uint8_t mode = message[6] & 0x0F;
351 const uint8_t feature = message[7] & 0x03;
352 if ((message[5] & 0x0F) != 0 || (mode > 4 && mode != 7) || (message[6] & 0xF0) > 0xC0 || (message[6] & 0x10) != 0 ||
353 (message[7] & 0x3C) != 0 || (message[7] & 0xC0) == 0xC0 || feature == 1)
354 return false;
355
356 preset = ToshibaPreset::TOSHIBA_PRESET_NONE;
357 power = static_cast<ToshibaPowerSelection>(message[7] >> 6);
358 // Only the 9 byte frame carries the Fireplace feature bits
359 if (length != 9 && feature != 0)
360 return false;
361 if (length == 9) {
362 if (message[4] != TOSHIBA_COMMAND_DEFAULT)
363 return false;
364 if (feature == FIREPLACE_1) {
365 preset = ToshibaPreset::TOSHIBA_PRESET_FIREPLACE_1;
366 } else if (feature == FIREPLACE_2) {
367 preset = ToshibaPreset::TOSHIBA_PRESET_FIREPLACE_2;
368 }
369 } else if (length == 10 && message[4] == (TOSHIBA_COMMAND_DEFAULT | TOSHIBA_COMMAND_POWER)) {
370 switch (message[8]) {
371 case TOSHIBA_POWER_HIGH:
372 preset = ToshibaPreset::TOSHIBA_PRESET_BOOST;
373 break;
374 case TOSHIBA_POWER_ECO:
375 preset = ToshibaPreset::TOSHIBA_PRESET_ECO;
376 break;
377 case FEATURE_FROST:
378 preset = ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION;
379 break;
380 case SILENT_1:
381 case SILENT_2:
383 return false;
386 break;
387 default:
388 return false;
389 }
390 } else if (length == 11 && message[4] == TOSHIBA_COMMAND_DEFAULT && message[8] == HADA_PREFIX &&
391 message[9] == HADA_SUFFIX) {
392 preset = ToshibaPreset::TOSHIBA_PRESET_HADA_CARE;
393 } else if (length == 12 && message[4] == (TOSHIBA_COMMAND_DEFAULT | TOSHIBA_COMMAND_TIMER | TOSHIBA_COMMAND_POWER) &&
394 message[9] == SLEEP_TIMER_MARKER && message[10] == SLEEP_TIMER_FLAGS && (message[6] & 0xF0) == 0) {
395 size_t i = 0;
396 while (i < std::size(SLEEP_HOURS) && message[8] != progmem_read_byte(&SLEEP_HOURS[i]) << 2)
397 i++;
398 if (i == std::size(SLEEP_HOURS))
399 return false;
400 preset = static_cast<ToshibaPreset>(static_cast<uint8_t>(ToshibaPreset::TOSHIBA_PRESET_SLEEP_1H) + i);
401 } else {
402 return false;
403 }
404 const bool frost = preset == ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION;
405 const float temperature = decode_target(message, frost);
406 if (clamp_target(temperature, frost) != temperature)
407 return false;
408 // Heating presets only exist in HEAT mode.
409 return !is_heating_preset(preset) || mode == 3;
410}
411
413 bool received = false;
414 do {
415 uint8_t message[MAX_FRAME_LENGTH]{};
416 if (!data.expect_item(TOSHIBA_HEADER_MARK, TOSHIBA_HEADER_SPACE) ||
417 !this->decode_(&data, message, TOSHIBA_HEADER_LENGTH) || !frame_header_valid(message) || message[2] < 1 ||
418 message[2] > 6 || message[2] == 2)
419 return received;
420 const uint8_t length = message[2] + 6;
421 if (!this->decode_(&data, message + TOSHIBA_HEADER_LENGTH, length - TOSHIBA_HEADER_LENGTH) ||
422 !data.expect_mark(TOSHIBA_BIT_MARK) || !frame_checksum_valid(message, length))
423 return received;
424 // The remote sends every frame twice, in one buffer or two; apply and publish each press once.
426 for (uint8_t i = 0; i < length; i++)
427 hash = fnv1a_hash_extend(hash, message[i]);
428 const uint32_t now = millis();
429 if (hash != this->last_frame_hash_ || now - this->last_frame_ms_ >= REPEAT_MS) {
430 if (!this->receive_frame_(message, length))
431 return received;
432 this->last_frame_hash_ = hash;
433 this->last_frame_ms_ = now;
434 }
435 received = true;
436 } while (data.expect_space(TOSHIBA_GAP_SPACE) && data.is_valid());
437 return received;
438}
439
441 if (length == MOTION_FRAME_LENGTH)
442 return message[4] == SHORT_MOTION_COMMAND && this->receive_motion_(message[5]);
443 ToshibaPreset preset;
445 if (!parse_state(message, length, preset, power))
446 return false;
447
448 const auto previous_preset = this->toshiba_preset_();
449 this->enter_preset_(previous_preset, preset);
450 this->decode_mode_(message);
451 this->apply_fan_code_(message[6] & 0xF0);
452 // FAN ONLY has no displayed setpoint; its temperature byte is not a new target.
454 this->target_temperature = decode_target(message, preset == ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION);
455 } else if (previous_preset == ToshibaPreset::TOSHIBA_PRESET_FROST_PROTECTION) {
457 }
458 this->apply_toshiba_preset_(preset);
459 if (preset == ToshibaPreset::TOSHIBA_PRESET_HADA_CARE)
461 if (this->store_power_selection_(power))
463 this->publish_state();
464 return true;
465}
466
468 if (this->toshiba_preset_() == ToshibaPreset::TOSHIBA_PRESET_HADA_CARE) {
469 ESP_LOGW(TAG, "Vane step is unavailable during HADA Care");
470 return;
471 }
472 this->transmit_motion_(TOSHIBA_MOTION_VANE_STEP, 0);
473}
474
476 const auto power = static_cast<ToshibaPowerSelection>(index);
477 const auto preset = this->toshiba_preset_();
478 if (!power_preset_supported(power, preset))
479 return;
480 const bool changed = this->store_power_selection_(power);
481 this->transmit_frame_(preset);
482 // Published after sending, so a preset change from the select's on_value goes out as its own frame.
483 if (changed)
485}
486
488 if (is_silent(power) && preset != ToshibaPreset::TOSHIBA_PRESET_NONE) {
489 ESP_LOGW(TAG, "Outdoor Silent with a preset is not supported");
490 return false;
491 }
492 return true;
493}
494
496 if (this->power_selection_ == power)
497 return false;
498 this->power_selection_ = power;
500 return true;
501}
502
504#ifdef USE_SELECT
505 if (this->power_selection_select_ != nullptr)
506 this->power_selection_select_->publish_state(static_cast<size_t>(this->power_selection_));
507#endif
508}
509
510} // namespace esphome::toshiba
511
512#endif // USE_TOSHIBA_RAS_25J2KVSG_ND
ESPPreferenceObject make_entity_preference(uint32_t version=0)
Create a preference object for storing this entity's state/settings.
constexpr size_t count(ValueType value) const
Check if the set contains a specific value (std::set compatibility) Returns 1 if present,...
This class is used to encode all control actions on a climate device.
Definition climate.h:31
const optional< ClimateSwingMode > & get_swing_mode() const
Definition climate.cpp:317
const optional< ClimateFanMode > & get_fan_mode() const
Definition climate.cpp:316
StringRef get_custom_fan_mode() const
Definition climate.h:124
ClimateMode mode
The active mode of the climate device.
Definition climate.h:317
float target_temperature
The target temperature of the climate device.
Definition climate.h:298
ClimateSwingMode swing_mode
The active swing mode of the climate device.
Definition climate.h:323
void set_supported_custom_presets_static(const char *const *presets, size_t count)
Points at a static table that outlives the climate (codegen); call before any runtime copy.
Definition climate.h:280
bool set_preset_(ClimatePreset preset)
Set preset. Reset custom preset. Return true if preset has been changed.
Definition climate.cpp:674
bool set_custom_preset_(const char *preset)
Set custom preset. Reset primary preset. Return true if preset has been changed.
Definition climate.h:349
bool set_fan_mode_(ClimateFanMode mode)
Set fan mode. Reset custom fan mode. Return true if fan mode has been changed.
Definition climate.cpp:663
bool has_custom_preset() const
Check if a custom preset is currently active.
Definition climate.h:288
void set_supported_custom_fan_modes_static(const char *const *modes, size_t count)
Points at a static table that outlives the climate (codegen); call before any runtime copy.
Definition climate.h:265
StringRef get_custom_preset() const
Get the active custom preset (read-only access). Returns StringRef.
Definition climate.h:329
void publish_state()
Publish the state of the climate device, to be called from integrations.
Definition climate.cpp:432
optional< ClimatePreset > preset
The active preset of the climate device.
Definition climate.h:314
bool set_custom_fan_mode_(const char *mode)
Set custom fan mode. Reset primary fan mode. Return true if fan mode has been changed.
Definition climate.h:339
StringRef get_custom_fan_mode() const
Get the active custom fan mode (read-only access). Returns StringRef.
Definition climate.h:326
climate::ClimatePresetMask presets_
Definition climate_ir.h:84
climate::ClimateModeMask modes_
Definition climate_ir.h:81
const RawTimings & get_data() const
Definition remote_base.h:66
static bool frame_header_valid(const uint8_t *message)
Definition toshiba.h:97
void encode_(remote_base::RemoteTransmitData *data, const uint8_t *message, uint8_t nbytes, uint8_t repeat)
Definition toshiba.cpp:1307
static void finalize_frame(uint8_t *message, uint8_t length)
Definition toshiba.cpp:1299
static climate::ClimateFanMode decode_fan(uint8_t code)
Definition toshiba.cpp:1382
bool decode_(remote_base::RemoteReceiveData *data, uint8_t *message, uint8_t nbytes)
Definition toshiba.cpp:1332
void decode_mode_(const uint8_t *message)
Definition toshiba.cpp:1354
climate::ClimateSwingMode last_swing_mode_
Definition toshiba.h:112
static bool frame_checksum_valid(const uint8_t *message, uint8_t length)
Definition toshiba.h:101
void transmit_motion_(uint8_t command, uint8_t repeat)
void perform_(remote_base::RemoteTransmitterBase::TransmitCall &transmit, bool swing)
static ToshibaPreset custom_preset_at(size_t index)
bool on_receive(remote_base::RemoteReceiveData data) override
bool store_power_selection_(ToshibaPowerSelection power)
static bool power_preset_supported(ToshibaPowerSelection power, ToshibaPreset preset)
static bool is_sleep_preset(ToshibaPreset preset)
static bool parse_state(const uint8_t *message, uint8_t length, ToshibaPreset &preset, ToshibaPowerSelection &power)
bool receive_frame_(const uint8_t *message, uint8_t length)
void sanitize_restore_state(climate::ClimateDeviceRestoreState &restore) override
void enter_preset_(ToshibaPreset previous, ToshibaPreset preset)
static ToshibaPreset preset_from_climate(climate::ClimatePreset preset)
static bool is_silent(ToshibaPowerSelection power)
static constexpr uint32_t POWER_SELECTION_RESTORE_VERSION
static size_t custom_preset_index(ToshibaPreset preset)
void encode_motion_(remote_base::RemoteTransmitData *data, uint8_t command, uint8_t repeat)
void control(const climate::ClimateCall &call) override
static ToshibaPreset preset_from_custom(const char *custom_preset)
static bool is_heating_preset(ToshibaPreset preset)
uint8_t custom_preset
Definition climate.h:9
ClimatePreset preset
Definition climate.h:8
const LogString * message
Definition component.cpp:35
ClimatePreset
Enum for all preset modes NOTE: If adding values, update ClimatePresetMask in climate_traits....
@ CLIMATE_PRESET_NONE
No preset is active.
@ CLIMATE_PRESET_BOOST
Device is in boost preset.
@ CLIMATE_PRESET_ECO
Device is running an energy-saving preset.
@ CLIMATE_SWING_OFF
The swing mode is set to Off.
@ CLIMATE_SWING_VERTICAL
The fan mode is set to Vertical.
@ CLIMATE_MODE_DRY
The climate device is set to dry/humidity mode.
@ CLIMATE_MODE_FAN_ONLY
The climate device only has the fan enabled, no heating or cooling is taking place.
@ CLIMATE_MODE_HEAT
The climate device is set to heat to reach the target temperature.
@ CLIMATE_MODE_OFF
The climate device is off.
@ CLIMATE_FAN_AUTO
The fan mode is set to Auto.
const float TOSHIBA_GENERIC_TEMP_C_MAX
Definition toshiba.h:46
const float TOSHIBA_GENERIC_TEMP_C_MIN
Definition toshiba.h:45
ESPHOME_LOG_TAG(TAG, "toshiba.climate")
constexpr uint32_t fnv1a_hash_extend(uint32_t hash, const char *str)
Extend a FNV-1a hash with additional string data.
Definition helpers.h:950
constexpr uint32_t FNV1_OFFSET_BASIS
FNV-1 32-bit offset basis.
Definition helpers.h:923
const char * progmem_read_ptr(const char *const *addr)
Definition hal.h:52
uint32_t IRAM_ATTR HOT millis()
Definition hal.cpp:25
uint8_t progmem_read_byte(const uint8_t *addr)
Definition hal.h:51
static void uint32_t
Struct used to save the state of the climate device in restore memory.
Definition climate.h:149
uint16_t temperature
Definition sun_gtil2.cpp:12
uint16_t length
Definition tt21100.cpp:0