esp8266-mqtt-projector-serial/esp/include/benqx3000i.cpp

154 lines
3.2 KiB
C++
Raw Permalink Normal View History

2022-07-10 04:27:32 +02:00
#ifndef _BENQ_X3000I_H_
#define _BENQ_X3000I_H_
#include <Arduino.h>
enum Input {
HDMI1 = 1,
HDMI2 = 2,
HDMI3 = 3,
UNKNOWN = 127,
};
void setup() {
Serial.begin(9600);
Serial.setTimeout(1000);
client.enableLastWillMessage("tele/" TOPIC "/LWT", "Offline");
}
int8_t queryPower() {
Serial.print("\r*pow=?#\r");
Serial.flush();
Serial.readStringUntil('\r');
String line = Serial.readStringUntil('\r');
if (line.length() < 6) {
Serial.print("\r*pow=?#\r");
Serial.flush();
Serial.readStringUntil('\r');
line = Serial.readStringUntil('\r');
}
if (line == "*pow=on#") {
return 1;
} else if (line == "*pow==off#") {
return 0;
}
return -1;
}
Input parseInput(const String& input) {
if (input == "HDMI1") return HDMI1;
if (input == "HDMI2") return HDMI2;
if (input == "HDMI3") return HDMI3;
return UNKNOWN;
}
String inputToString(Input input) {
if (input == HDMI1) return "HDMI1";
if (input == HDMI2) return "HDMI2";
if (input == HDMI3) return "HDMI3";
return "UNKNOWN";
}
void sendInputCommand(Input input) {
switch(input) {
case HDMI1:
Serial.print("\r*sour=hdmi#\r");
break;
case HDMI2:
Serial.print("\r*sour=hdmi2#\r");
break;
case HDMI3:
Serial.print("\r*sour=smartsystem#\r");
break;
default:
break;
}
Serial.flush();
Serial.readStringUntil('\r');
}
Input parseInputState(const String& line) {
if (line == "*sour=hdmi#") return HDMI1;
if (line == "*sour=hdmi2#") return HDMI2;
if (line == "*sour=smartsystem#") return HDMI3;
return UNKNOWN;
}
Input queryInput() {
Serial.print("\r*sour=?\r");
Serial.flush();
Serial.readStringUntil('\r');
String line = Serial.readStringUntil('\r');
if (line.length() < 8) {
Serial.print("\r*sour=?\r");
Serial.flush();
Serial.readStringUntil('\r');
line = Serial.readStringUntil('\r');
}
if (line.length() <8) {
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) {
Serial.print("\r*pow=on#\r");
Serial.flush();
Serial.readStringUntil('\r');
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("\r*pow=on#\r");
Serial.flush();
Serial.readStringUntil('\r');
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