/* Copyright 2020 Serial Rodeo Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #define BUFFER_LENGTH 64 // IR IRsend emitter; // uses pin A5 // MQTT #define MQTT_HOST "" #define MQTT_PORT 1883 #define MQTT_USERNAME "" #define MQTT_PASSWORD "" void mqttHandler(char *, byte *, unsigned int); MQTT mqtt(MQTT_HOST, MQTT_PORT, mqttHandler); // Web UI WebServer server("", 80); P(HTML) = "Projector
–|
ComputerVideoOn-Off
 
MenuVolume –SelectVolume +
D. ZoomPageKeystoneNo show
Auto PCP-Timer
ImageFreezeMute
"; uint32_t getCommand(char * button) { switch (atoi(button)) { case 0: return 0xFFFFFFFF; // (Repeat) case 1: return 0xCC0000FF; // Power case 2: return 0xCC001CE3; // Computer case 3: return 0xCC00A05F; // Video case 4: return 0xCC0038C7; // Menu case 5: return 0xCC007887; // Left case 6: return 0xCC00B847; // Right case 7: return 0xCC0031CE; // Up case 8: return 0xCC00B14E; // Down case 9: return 0xCC00F00F; // Select case 10: return 0xCC00807F; // Zoom in case 11: return 0xCC0040BF; // Zoom out case 12: return 0xCC009A65; // Page up case 13: return 0xCC005AA5; // Page down case 14: return 0xCC00DA25; // Keystone case 15: return 0xCC00D12E; // No show case 16: return 0xCC00916E; // Auto PC case 17: return 0xCC0051AE; // P-Timer case 18: return 0xCC0030CF; // Image case 19: return 0xCC00C23D; // Freeze case 20: return 0xCC00D02F; // Mute default: return 0x00000000; // (Invalid) } } void webHandler(WebServer &server, WebServer::ConnectionType type, char *, bool) { switch (type) { case WebServer::GET: { server.httpSuccess(); server.printP(HTML); break; } case WebServer::POST: { char key[16], value[16]; server.readPOSTparam(key, 16, value, 16); if (strcmp(key, "button")) { server.httpFail(); server.print("Invalid form data"); return; } uint32_t cmd = getCommand(value); if (!cmd) { server.httpFail(); server.print("Invalid button"); return; } server.httpSuccess(); Particle.publish("button", value); emitter.sendNEC(cmd, 32); break; } default: { server.httpFail(); server.print("Requests should be GET or POST"); break; } } } void mqttHandler(char * topic, byte * payload, unsigned int length) { char buffer[length + 1]; memcpy(buffer, payload, length); buffer[length] = '\0'; uint32_t cmd = getCommand(buffer); if (!cmd) { mqtt.publish("projector/status", "unknown command"); return; } emitter.sendNEC(cmd, 32); mqtt.publish("projector/status", "OK"); } void mqttConnect() { char buffer[BUFFER_LENGTH]; snprintf(buffer, BUFFER_LENGTH, "projector_%s", System.deviceID().c_str()); if (!mqtt.connect(buffer, MQTT_USERNAME, MQTT_PASSWORD)) { Particle.publish("mqtt", "failed to connect", PRIVATE); delay(1000); return; } mqtt.subscribe("projector/cmd"); Particle.publish("mqtt", "connected", PRIVATE); } void setup() { // Publish local IP address IPAddress ip = WiFi.localIP(); char buffer[BUFFER_LENGTH]; snprintf(buffer, BUFFER_LENGTH, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); Particle.publish("ip", buffer); // Connect to MQTT server mqttConnect(); // Start web server server.setDefaultCommand(&webHandler); server.begin(); // Turn off status LED RGB.control(true); RGB.brightness(0); } void loop() { // MQTT server if (mqtt.isConnected()) { mqtt.loop(); } else { mqttConnect(); } // Web server char buffer[BUFFER_LENGTH]; int length = BUFFER_LENGTH; server.processConnection(buffer, &length); }