Tasmota/lib/IRremoteESP8266-2.2.1.02/src/ir_Fujitsu.cpp
arendst 299bed1c05 v5.9.1f - Update libraries and a fix
5.9.1f
 * Upgrade library ArduinoJson to 5.11.2
 * Upgrade library
IRRemoteEsp8266 to 2.2.1 + 2 commits but tweaked some protocols to keep
code usage small
 * Upgrade library NeoPixelBus to 2.2.9
 * Upgrade
library OneWire to 2.3.3 + 6 commits
 * Formalize library PubSubClient
to 2.6 + 9 commits and additional delay
 * Add optional ADS1115 driver
as alternative for unsupported I2Cdevlib in esp8266-core 2.4.0-rc2
 *
Fix wrong response name for command HlwISet (#1214)
2017-11-19 18:02:03 +01:00

222 lines
5.9 KiB
C++

// Copyright 2017 Jonny Graham
#include "ir_Fujitsu.h"
#include <algorithm>
#include "IRsend.h"
// Fujitsu A/C support added by Jonny Graham
// Fujitsu A/C
// Ref:
// These values are based on averages of measurements
#define FUJITSU_AC_HDR_MARK 3224U
#define FUJITSU_AC_HDR_SPACE 1574U
#define FUJITSU_AC_BIT_MARK 448U
#define FUJITSU_AC_ONE_SPACE 1182U
#define FUJITSU_AC_ZERO_SPACE 367U
#define FUJITSU_AC_TRL_MARK 448U
#define FUJITSU_AC_TRL_SPACE 8100U
#if SEND_FUJITSU_AC
// Send a Fujitsu A/C message.
//
// Args:
// data: An array of bytes containing the IR command.
// nbytes: Nr. of bytes of data in the array. (typically either
// FUJITSU_AC_STATE_LENGTH or FUJITSU_AC_STATE_LENGTH_SHORT)
// repeat: Nr. of times the message is to be repeated.
// (Default = FUJITSU_AC_MIN_REPEAT).
//
// Status: BETA / Appears to be working.
//
void IRsend::sendFujitsuAC(unsigned char data[], uint16_t nbytes,
uint16_t repeat) {
// Set IR carrier frequency
enableIROut(38);
for (uint16_t r = 0; r <= repeat; ++r) {
// Header
mark(FUJITSU_AC_HDR_MARK);
space(FUJITSU_AC_HDR_SPACE);
// Data
for (uint16_t i = 0; i < nbytes; i++)
sendData(FUJITSU_AC_BIT_MARK, FUJITSU_AC_ONE_SPACE,
FUJITSU_AC_BIT_MARK, FUJITSU_AC_ZERO_SPACE,
data[i], 8, false);
// Footer
mark(FUJITSU_AC_TRL_MARK);
space(FUJITSU_AC_TRL_SPACE);
}
}
// Code to emulate Fujitsu A/C IR remote control unit.
// Warning: Consider this very alpha code. Seems to work, but not validated.
//
// Equipment it seems compatible with:
// * Fujitsu ASYG30LFCA with remote AR-RAH2E
// * <Add models (A/C & remotes) you've gotten it working with here>
// Initialise the object.
IRFujitsuAC::IRFujitsuAC(uint16_t pin) : _irsend(pin) {
stateReset();
}
// Reset the state of the remote to a known good state/sequence.
void IRFujitsuAC::stateReset() {
_temp = 24;
_fanSpeed = FUJITSU_AC_FAN_HIGH;
_mode = FUJITSU_AC_MODE_COOL;
_swingMode = FUJITSU_AC_SWING_BOTH;
_cmd = FUJITSU_AC_CMD_TURN_ON;
}
// Configure the pin for output.
void IRFujitsuAC::begin() {
_irsend.begin();
}
// Send the current desired state to the IR LED.
void IRFujitsuAC::send() {
getRaw();
uint8_t len = getCommandLength();
_irsend.sendFujitsuAC(remote_state, len);
}
uint8_t IRFujitsuAC::getCommandLength() {
if (remote_state[5] != 0xFE)
return FUJITSU_AC_STATE_LENGTH_SHORT;
else
return FUJITSU_AC_STATE_LENGTH;
}
// Return a pointer to the internal state date of the remote.
uint8_t* IRFujitsuAC::getRaw() {
remote_state[0] = 0x14;
remote_state[1] = 0x63;
remote_state[2] = 0x00;
remote_state[3] = 0x10;
remote_state[4] = 0x10;
bool fullCmd = false;
switch (_cmd) {
case FUJITSU_AC_CMD_TURN_OFF:
remote_state[5] = 0x02;
break;
case FUJITSU_AC_CMD_STEP_HORIZ:
remote_state[5] = 0x79;
break;
case FUJITSU_AC_CMD_STEP_VERT:
remote_state[5] = 0x6C;
break;
default:
remote_state[5] = 0xFE;
fullCmd = true;
break;
}
if (fullCmd) {
remote_state[6] = 0x09;
remote_state[7] = 0x30;
uint8_t tempByte = _temp - FUJITSU_AC_MIN_TEMP;
remote_state[8] = (_cmd == FUJITSU_AC_CMD_TURN_ON) | (tempByte << 4);
remote_state[9] = _mode | 0 << 4; // timer off
remote_state[10] = _fanSpeed | _swingMode << 4;
remote_state[11] = 0; // timerOff values
remote_state[12] = 0; // timerOff/on values
remote_state[13] = 0; // timerOn values
remote_state[14] = 0x20;
// Checksum is the sum of the 8th to 16th bytes (ie remote_state[7]
// thru remote_state[15]).
// The checksum itself is stored in the 16th byte (ie remote_state[15]).
// So we sum bytes 8th-15th...
uint8_t checksum = 0;
for (uint8_t i = 7 ; i < 15; ++i) {
checksum += remote_state[i];
}
// and then do 0 - sum and store it in 16th.
remote_state[15] = 0 - checksum;
} else {
// For the short codes, byte 7 is the inverse of byte 6
remote_state[6] = ~remote_state[5];
for (uint8_t i = 7; i < FUJITSU_AC_STATE_LENGTH; ++i) {
remote_state[i] = 0;
}
}
return remote_state;
}
// Set the requested power state of the A/C to off.
void IRFujitsuAC::off() {
_cmd = FUJITSU_AC_CMD_TURN_OFF;
}
void IRFujitsuAC::stepHoriz() {
_cmd = FUJITSU_AC_CMD_STEP_HORIZ;
}
void IRFujitsuAC::stepVert() {
_cmd = FUJITSU_AC_CMD_STEP_VERT;
}
// Set the requested command of the A/C.
void IRFujitsuAC::setCmd(uint8_t cmd) {
switch (cmd) {
case FUJITSU_AC_CMD_TURN_OFF:
case FUJITSU_AC_CMD_TURN_ON:
case FUJITSU_AC_CMD_STAY_ON:
case FUJITSU_AC_CMD_STEP_HORIZ:
case FUJITSU_AC_CMD_STEP_VERT:
break;
default:
cmd = FUJITSU_AC_CMD_STAY_ON;
break;
}
_cmd = cmd;
}
uint8_t IRFujitsuAC::getCmd() {
return _cmd;
}
// Set the temp. in deg C
void IRFujitsuAC::setTemp(uint8_t temp) {
temp = std::max((uint8_t) FUJITSU_AC_MIN_TEMP, temp);
temp = std::min((uint8_t) FUJITSU_AC_MAX_TEMP, temp);
_temp = temp;
}
uint8_t IRFujitsuAC::getTemp() {
return _temp;
}
// Set the speed of the fan
void IRFujitsuAC::setFanSpeed(uint8_t fanSpeed) {
if (fanSpeed > FUJITSU_AC_FAN_QUIET)
fanSpeed = FUJITSU_AC_FAN_HIGH; // Set the fan to maximum if out of range.
_fanSpeed = fanSpeed;
}
uint8_t IRFujitsuAC::getFanSpeed() {
return _fanSpeed;
}
// Set the requested climate operation mode of the a/c unit.
void IRFujitsuAC::setMode(uint8_t mode) {
if (mode > FUJITSU_AC_MODE_HEAT)
mode = FUJITSU_AC_MODE_HEAT; // Set the mode to maximum if out of range.
_mode = mode;
}
uint8_t IRFujitsuAC::getMode() {
return _mode;
}
// Set the requested swing operation mode of the a/c unit.
void IRFujitsuAC::setSwing(uint8_t swingMode) {
if (swingMode > FUJITSU_AC_SWING_BOTH)
swingMode = FUJITSU_AC_SWING_BOTH; // Set the mode to max if out of range
_swingMode = swingMode;
}
uint8_t IRFujitsuAC::getSwing() {
return _swingMode;
}
#endif