diff --git a/ESP8266-MQTT-BenQ/.gitignore b/ESP8266-MQTT-BenQ/.gitignore new file mode 100644 index 0000000..ff9e567 --- /dev/null +++ b/ESP8266-MQTT-BenQ/.gitignore @@ -0,0 +1 @@ +ESP8266-MQTT-BenQ.h diff --git a/ESP8266-MQTT-BenQ/ESP8266-MQTT-BenQ.h.template b/ESP8266-MQTT-BenQ/ESP8266-MQTT-BenQ.h.template new file mode 100644 index 0000000..41d0062 --- /dev/null +++ b/ESP8266-MQTT-BenQ/ESP8266-MQTT-BenQ.h.template @@ -0,0 +1,13 @@ +// WiFi configuration +const char* ssid = "http://kiel.freifunk.net/"; +const char* password = ""; + +// MQTT Broker +const char* mqtt_server = "broker.mqtt-dashboard.com"; + +// Device identification +const char* mqtt_device_name = "esp8266benq" + +// MQTT topics +const char* mqtt_topic_power = "benq/power"; +const char* mqtt_topic_lamptime = "benq/lamptime"; diff --git a/ESP8266-MQTT-BenQ/ESP8266-MQTT-BenQ.ino b/ESP8266-MQTT-BenQ/ESP8266-MQTT-BenQ.ino new file mode 100644 index 0000000..1fd168d --- /dev/null +++ b/ESP8266-MQTT-BenQ/ESP8266-MQTT-BenQ.ino @@ -0,0 +1,173 @@ +/********************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2015 Nis Wechselberg + * + * 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. + **********************************************************************/ + +/********************************************************************** + * ESP8266-MQTT-BenQ-BeamerControl + * + * Links the ESP8266 based serial beamer control board to an mqtt broker. + * The program uses multiple topics for incoming and outgoing messages. + * Incoming topics: + * - /power + * Outgoing topics: + * + **********************************************************************/ + +#include +#include +#include "ESP8266-MQTT-BenQ.h" + +#define DEBUGTOSERIAL 0 + +// Timestamp for last publish +long lastMsg = 0; +long publishInterval = 10000; + +// Global mqtt client object +WiFiClient espClient; +PubSubClient client(espClient); + +/* + * Initial setup for arduino + */ +void setup() { + // Configure serial port + Serial.begin(115200); + delay(10); + + // Prepare WiFi connection + setup_wifi(); + + // Connect to mqtt broker + client.setServer(mqtt_server, 1883); + client.setCallback(incoming_mqtt); +} + +/* + * Prepares the wireless connection + */ +void setup_wifi() { + // Connect to the WiFi as a client + WiFi.mode(WIFI_STA); + + // Do the connection + if (DEBUGTOSERIAL) { + Serial.println(); + Serial.print("Connecting to "); + Serial.println(ssid); + } + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + if (DEBUGTOSERIAL) { + Serial.print("."); + } + } + if (DEBUGTOSERIAL) { + Serial.println(""); + Serial.println("WiFi connected"); + + // Print IP address to serial + Serial.print("My IP address: "); + Serial.println(WiFi.localIP()); + } +} + +/* + * Callback method for incoming mqtt messages + */ +void incoming_mqtt(char* topic, byte* payload, unsigned int length) { + if (DEBUGTOSERIAL) { + 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, mqtt_topic_power) == 0) { + } +} + +/* + * Blocking reconnect to the mqtt broker + */ +void reconnect() { + // Loop until we're reconnected + while (!client.connected()) { + if (DEBUGTOSERIAL) { + Serial.print("Attempting MQTT connection..."); + } + // Attempt to connect + if (client.connect(mqtt_device_name)) { + if (DEBUGTOSERIAL) { + Serial.println("connected"); + } + // subscribe to incoming topics + client.subscribe(mqtt_topic_power); + } else { + if (DEBUGTOSERIAL) { + Serial.print("failed, rc="); + Serial.print(client.state()); + Serial.println(" try again in 5 seconds"); + } + // Wait 5 seconds before retrying + delay(5000); + } + } +} + +void updateLamptime() { + // Write request to serial + Serial.print("\r*ltim=?#\r"); + delay(250); + + // Extract lamp time from response + String message = Serial.readString(); + int startIndex = message.lastIndexOf('='); + int endIndex = message.lastIndexOf('#'); + if (startIndex != -1 && endIndex != -1) { + char publi[endIndex - startIndex]; + message.substring(startIndex + 1, endIndex).toCharArray(publi, (endIndex - startIndex)); + client.publish(mqtt_topic_lamptime, publi); + } +} + +void loop() { + // Ensure MQTT connection + if (!client.connected()) { + reconnect(); + } + + // Check the inbox + client.loop(); + + // Maybe push the current status + long now = millis(); + if (now - lastMsg > publishInterval) { + lastMsg = now; + updateLamptime(); + } +}