#ifndef _SANYO_Z4_H_ #define _SANYO_Z4_H_ #include enum Input { VIDEO = 0, S_VIDEO = 1, COMP1 = 2, COMP2 = 3, HDMI = 4, VGA = 5, UNKNOWN = 127, }; void setup() { Serial.begin(19200); Serial.setTimeout(1000); client.enableLastWillMessage("tele/" TOPIC "/LWT", "Offline"); } bool queryPower() { Serial.print("CR0\r"); Serial.flush(); String line = Serial.readStringUntil('\r'); if (line.length() != 2) { Serial.print("CR0\r"); Serial.flush(); line = Serial.readStringUntil('\r'); } return line == "00" || line == "40"; } Input parseInput(const String& input) { if (input == "VIDEO") return VIDEO; if (input == "S-VIDEO") return S_VIDEO; if (input == "COMP1") return COMP1; if (input == "COMP2") return COMP2; if (input == "VGA") return VGA; if (input == "HDMI") return HDMI; return UNKNOWN; } String inputToString(Input input) { if (input == VIDEO) return "VIDEO"; if (input == S_VIDEO) return "S-VIDEO"; if (input == COMP1) return "COMP1"; if (input == COMP2) return "COMP2"; if (input == VGA) return "VGA"; if (input == HDMI) return "HDMI"; return "UNKNOWN"; } void sendInputCommand(Input input) { switch(input) { case VIDEO: Serial.print("C23\r"); break; case S_VIDEO: Serial.print("C24\r"); break; case COMP1: Serial.print("C25\r"); break; case COMP2: Serial.print("C26\r"); break; case HDMI: Serial.print("C53\r"); break; case VGA: Serial.print("C50\r"); break; default: break; } Serial.flush(); Serial.readStringUntil('\r'); } Input parseInputState(const String& line) { if (line == "0") return VIDEO; if (line == "1") return S_VIDEO; if (line == "2") return COMP1; if (line == "3") return COMP2; if (line == "4") return HDMI; if (line == "5") return VGA; return UNKNOWN; } Input queryInput() { Serial.print("CR1\r"); Serial.flush(); String line = Serial.readStringUntil('\r'); if (line.length() != 1) { Serial.print("CR1\r"); Serial.flush(); line = Serial.readStringUntil('\r'); } if (line.length() != 1) { return UNKNOWN; } return parseInputState(line); } void onInput(const String& message) { Input state = queryInput(); Input desiredState = parseInput(message); if (state != desiredState && desiredState != UNKNOWN) { sendInputCommand(desiredState); state = queryInput(); } client.publish("resp/" TOPIC "/input", inputToString(state), true); } void onPower(const String& message) { bool state = queryPower(); if (message == "ON" || message == "OFF") { bool desiredState = message == "ON"; if (state != desiredState) { if (desiredState) { client.publish("cmnd/sonoff/irrc/IRSend", "{\"Protocol\":\"NEC\",\"Bits\":32,\"Data\":\"0xCC0000FF\"}"); Serial.print("C00\r"); Serial.flush(); Serial.readStringUntil('\r'); for (uint8_t i = 0; i < 5; ++i) { state = queryPower(); if (state) { break; } } } else { for (uint8_t i = 0; i < 3; ++i) { Serial.print("C02\r"); Serial.flush(); Serial.readStringUntil('\r'); delay(1000); } for (uint8_t i = 0; i < 5; ++i) { state = queryPower(); if (!state) { break; } } } } } client.publish("resp/" TOPIC "/power", state ? "ON" : "OFF", true); } void onConnectionEstablished() { client.subscribe("cmnd/" TOPIC "/power", onPower); client.subscribe("cmnd/" TOPIC "/input", onInput); client.publish("tele/" TOPIC "/LWT", "Online", true); } void loop() { client.loop(); } #endif