Last active
November 2, 2018 10:49
-
-
Save TheSkorm/6ae6a5597f7ff1918fd41f67044a7d72 to your computer and use it in GitHub Desktop.
LG AirCon LSZ244VM-6 MQTT ESP8266
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* IRremoteESP8266: IRsendDemo - demonstrates sending IR codes with IRsend. | |
| Version 1.0 April, 2017 | |
| Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009, | |
| Copyright 2009 Ken Shirriff, http://arcfn.com | |
| An IR LED circuit *MUST* be connected to the ESP8266 on a pin | |
| as specified by kIrLed below. | |
| TL;DR: The IR LED needs to be driven by a transistor for a good result. | |
| Suggested circuit: | |
| https://github.com/markszabo/IRremoteESP8266/wiki#ir-sending | |
| Common mistakes & tips: | |
| * * Don't just connect the IR LED directly to the pin, it won't | |
| have enough current to drive the IR LED effectively. | |
| * * Make sure you have the IR LED polarity correct. | |
| See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity | |
| * * Typical digital camera/phones can be used to see if the IR LED is flashed. | |
| Replace the IR LED with a normal LED if you don't have a digital camera | |
| when debugging. | |
| * * Avoid using the following pins unless you really know what you are doing: | |
| * * Pin 0/D3: Can interfere with the boot/program mode & support circuits. | |
| * * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere. | |
| * * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere. | |
| * * ESP-01 modules are tricky. We suggest you use a module with more GPIOs | |
| for your first time. e.g. ESP-12 etc. | |
| */ | |
| #include <ESP8266WiFi.h> | |
| #include <PubSubClient.h> | |
| const char* ssid = ""; | |
| const char* password = ""; | |
| const char* mqtt_server = "172.16.0.31"; | |
| #ifndef UNIT_TEST | |
| #include <Arduino.h> | |
| #endif | |
| #include <IRremoteESP8266.h> | |
| #include <IRsend.h> | |
| #define HEADER1 0b1000 | |
| #define HEADER2 0b1000 | |
| #define PACKET_TEMP 0b0000 | |
| #define PACKET_POWER 0b0001 | |
| #define PACKET_PLASMA 0b1100 | |
| #define PACKET_OFF 0b1100 | |
| // these only used when packet = temp, pick one mode, one temp and one fan speed | |
| #define MODE_HEAT 0b1100 | |
| #define MODE_AUTO 0b1011 | |
| #define MODE_COOL 0b1000 | |
| #define MODE_DRY 0b1001 | |
| #define FAN_CHAOS 0b0101 | |
| #define FAN_HIGH 0b0100 | |
| #define FAN_MID 0b0010 | |
| #define FAN_LOW 0b0000 | |
| #define PLASMA1 0b0000 | |
| #define PLASMA2 0b0000 | |
| #define PLASMA3 0b0000 // use with packet plama | |
| #define POWER1 0b0000 | |
| #define POWER2 0b0000 | |
| #define POWER3 0b1000 // use with packet power | |
| #define OFF1 0b0000 | |
| #define OFF2 0b0000 | |
| #define OFF3 0b0101 // use with packet off | |
| #define MIN_TEMP 15 // this is the base temp | |
| #define ON 0b0111 //mask for on | |
| #define IR_ON_TIME 1500 | |
| #define IR_OFF_TIME 500 | |
| WiFiClient espClient; | |
| PubSubClient client(espClient); | |
| long lastMsg = 0; | |
| char msg[50]; | |
| int temp = 23; | |
| bool state = false; | |
| uint8_t fan = FAN_LOW; | |
| uint8_t mode = MODE_COOL; | |
| void reconnect() { | |
| // Loop until we're reconnected | |
| while (!client.connected()) { | |
| Serial.print("Attempting MQTT connection..."); | |
| // Attempt to connect | |
| if (client.connect("ESP8266Client", "hass", "hass")) { | |
| client.subscribe("lgac/#"); | |
| } else { | |
| Serial.print("failed, rc="); | |
| Serial.print(client.state()); | |
| Serial.println(" try again in 5 seconds"); | |
| // Wait 5 seconds before retrying | |
| delay(5000); | |
| } | |
| } | |
| } | |
| struct packet { | |
| uint8_t header1; | |
| uint8_t header2; | |
| uint8_t packet: 4; | |
| uint8_t slot1: 4; | |
| uint8_t slot2: 4; | |
| uint8_t slot3: 4; | |
| uint8_t chksum: 4; | |
| }; | |
| uint8_t checksum(struct packet packet) { | |
| return packet.header1 + packet.header2 + packet.packet + packet.slot1 + packet.slot2 + packet.slot3 & 15; // AND to 15 to get the last 4 bits for checksum | |
| }; | |
| const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). | |
| struct packet mode_temp_fan(uint8_t acmode, uint8_t temp, uint8_t fan) { | |
| struct packet pkt; | |
| pkt.header1 = HEADER1; | |
| pkt.header2 = HEADER2; | |
| pkt.packet = PACKET_TEMP; | |
| pkt.slot1 = acmode & ON; | |
| pkt.slot2 = temp - MIN_TEMP; | |
| pkt.slot3 = fan; | |
| pkt.chksum = checksum(pkt); | |
| return pkt; | |
| } | |
| struct packet power() { | |
| struct packet pkt; | |
| pkt.header1 = HEADER1; | |
| pkt.header2 = HEADER2; | |
| pkt.packet = PACKET_POWER; | |
| pkt.slot1 = POWER1; | |
| pkt.slot2 = POWER2; | |
| pkt.slot3 = POWER3; | |
| pkt.chksum = checksum(pkt); | |
| return pkt; | |
| } | |
| struct packet plasma() { | |
| struct packet pkt; | |
| pkt.header1 = HEADER1; | |
| pkt.header2 = HEADER2; | |
| pkt.packet = PACKET_POWER; | |
| pkt.slot1 = PLASMA1; | |
| pkt.slot2 = PLASMA2; | |
| pkt.slot3 = PLASMA3; | |
| pkt.chksum = checksum(pkt); | |
| return pkt; | |
| } | |
| struct packet off() { | |
| struct packet pkt; | |
| pkt.header1 = HEADER1; | |
| pkt.header2 = HEADER2; | |
| pkt.packet = PACKET_OFF; | |
| pkt.slot1 = OFF1; | |
| pkt.slot2 = OFF2; | |
| pkt.slot3 = OFF3; | |
| Serial.println(OFF1); | |
| Serial.println(OFF2); | |
| Serial.println(OFF3); | |
| pkt.chksum = checksum(pkt); | |
| return pkt; | |
| } | |
| void encode_data(uint8_t frame, uint8_t offset, uint16_t output[59]) { | |
| if (frame & 0b1000) { | |
| output[offset] = IR_ON_TIME; | |
| output[offset + 1] = IR_OFF_TIME; | |
| } else { | |
| output[offset] = IR_OFF_TIME; | |
| output[offset + 1] = IR_OFF_TIME ; | |
| } | |
| if (frame & 0b0100) { | |
| output[offset + 2] = IR_ON_TIME; | |
| output[offset + 3] = IR_OFF_TIME; | |
| } else { | |
| output[offset + 2] = IR_OFF_TIME; | |
| output[offset + 3] = IR_OFF_TIME ; | |
| } | |
| if (frame & 0b0010) { | |
| output[offset + 4] = IR_ON_TIME; | |
| output[offset + 5] = IR_OFF_TIME; | |
| } else { | |
| output[offset + 4] = IR_OFF_TIME; | |
| output[offset + 5] = IR_OFF_TIME ; | |
| } | |
| if (frame & 0b0001) { | |
| output[offset + 6] = IR_ON_TIME; | |
| output[offset + 7] = IR_OFF_TIME; | |
| } else { | |
| output[offset + 6] = IR_OFF_TIME; | |
| output[offset + 7] = IR_OFF_TIME ; | |
| } | |
| } | |
| void generate_raw(struct packet packet, uint16_t raw[59]) { | |
| raw[0] = 8500; | |
| raw[1] = 4000; | |
| raw[2] = 600; | |
| encode_data(packet.header1, (3 + (8 * 0)), raw); | |
| encode_data(packet.header2, (3 + (8 * 1)), raw); | |
| encode_data(packet.packet, (3 + (8 * 2)), raw); | |
| encode_data(packet.slot1, (3 + (8 * 3)), raw); | |
| encode_data(packet.slot2, (3 + (8 * 4)), raw); | |
| encode_data(packet.slot3, (3 + (8 * 5)), raw); | |
| encode_data(packet.chksum, (3 + (8 * 6)), raw); | |
| } | |
| IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message. | |
| // Example of data captured by IRrecvDumpV2.ino | |
| uint16_t rawData[59] ; | |
| void setup() { | |
| irsend.begin(); | |
| Serial.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY); | |
| WiFi.begin(ssid, password); | |
| while (WiFi.status() != WL_CONNECTED) { | |
| delay(500); | |
| Serial.print("."); | |
| } | |
| Serial.println(""); | |
| Serial.println("WiFi connected"); | |
| Serial.println("IP address: "); | |
| Serial.println(WiFi.localIP()); | |
| client.setServer(mqtt_server, 1883); | |
| client.setCallback(callback); | |
| } | |
| void callback(char* topic, byte* payload, unsigned int length) { | |
| Serial.print("Message arrived ["); | |
| Serial.print(topic); | |
| Serial.print("] "); | |
| for (int i = 0; i < length; i++) { | |
| Serial.print((char)payload[i]); | |
| } | |
| Serial.println(); | |
| if (strcmp(topic,"lgac/temp") == 0) { | |
| String inString = ""; | |
| inString += (char)payload[0]; | |
| inString += (char)payload[1]; // this might be backwards :S | |
| Serial.print("temp:"); | |
| temp = inString.toInt(); | |
| Serial.println(temp); | |
| } else if (strcmp(topic,"lgac/mode") == 0) { // handle on/off/power/ | |
| if ((char)payload[0] == 'o') state = false; | |
| if ((char)payload[0] == 'a') { | |
| state = true; | |
| mode = MODE_AUTO; | |
| } | |
| if ((char)payload[0] == 'c') { | |
| state = true; | |
| mode = MODE_COOL; | |
| } | |
| if ((char)payload[0] == 'h') { | |
| state = true; | |
| mode = MODE_HEAT; | |
| } | |
| if ((char)payload[0] == 'd') { | |
| state = true; | |
| mode = MODE_DRY; | |
| } | |
| } else if (strcmp(topic,"lgac/fan") == 0) { | |
| if ((char)payload[0] == 'a') fan = FAN_CHAOS; | |
| if ((char)payload[0] == 'l') fan = FAN_LOW; | |
| if ((char)payload[0] == 'm') fan = FAN_MID; | |
| if ((char)payload[0] == 'h') fan = FAN_HIGH; | |
| Serial.println("set fan"); | |
| if (fan == FAN_HIGH) { | |
| Serial.println("FAN HIGH"); | |
| } | |
| } | |
| struct packet pkt; | |
| if (state == false){ | |
| pkt = off(); | |
| } else { | |
| pkt = mode_temp_fan(mode, temp, fan); | |
| } | |
| generate_raw(pkt, rawData); | |
| for (int x = 0; x < 59; x++) { | |
| Serial.println(rawData[x]); | |
| } | |
| irsend.sendRaw(rawData, 59, 38); | |
| } | |
| void loop() { | |
| // Serial.println("a rawData capture from IRrecvDumpV2"); | |
| // struct packet test = mode_temp_fan(MODE_COOL, 23, FAN_HIGH); | |
| // generate_raw(test, rawData); | |
| // for (int x = 0; x < 59; x++) { | |
| // Serial.println(rawData[x]); | |
| // } | |
| // irsend.sendRaw(rawData, 59, 38); // Send a raw data capture at 38kHz. | |
| // delay(2000); | |
| if (!client.connected()) { | |
| reconnect(); | |
| } | |
| client.loop(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment