Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <ESP8266WiFi.h>
- #include <PubSubClient.h>
- #include <EEPROM.h>
- #include <ArduinoJson.h>
- //Device variables and constants
- const String DEVICE_NAME = "NodeMCU_test"; //!!MUST BE UNIQUE!!
- byte statusValue;
- //JSON buffer
- StaticJsonBuffer<80> jsonBuffer;
- //EEPROM variables
- int addrBoot = 0;
- int addrStatus = 1;
- byte bootValue;
- //MQTT constants
- //Update name values suitable for your setup
- const String MQTT_PAYLOAD_DEVICE_TYPE = "{\"name\":\"" + DEVICE_NAME +"\",\"type\":\"homebridge\"}";
- const String MQTT_PAYLOAD_NEW_DEVICE = "{\"name\":\"" + DEVICE_NAME +"\",\"service_name\":\"light\",\"service\":\"Lightbulb\"}";
- const String MQTT_PAYLOAD_REMOVE_DEVICE = "{\"name\":\"NodeMCU_test\"}";
- const String MQTT_PAYLOAD_INITIAL_STATE_ON = "{\"name\":\"NodeMCU_test\",\"service_name\":\"light\",\"characteristic\":\"On\",\"value\":true}";
- const String MQTT_PAYLOAD_INITIAL_STATE_OFF = "{\"name\":\"" + DEVICE_NAME +"\",\"service_name\":\"light\",\"characteristic\":\"On\",\"value\":false}";
- const String MQTT_CHANNEL_SET_DEVICE_TYPE = "mqtt/to/set/type";
- const String MQTT_CHANNEL_ADD_ACCESSORY = "homebridge/to/add";
- const String MQTT_CHANNEL_REMOVE_ACCESSORY = "homebridge/to/remove";
- const String MQTT_CHANNEL_COMMANDS = "homebridge/from/set/" + DEVICE_NAME;
- const String MQTT_CHANNEL_SET_VALUE = "homebridge/to/set";
- const String MQTT_CHANNEL_RESPONSE = "homebridge/from/response/#";
- const String MQTT_CHANNEL_RESPONSE_PERSONAL = "homebridge/from/response/" + DEVICE_NAME;
- // Update these with values suitable for your network.
- const char* ssid = "VicoEquense2.4";
- const char* password = "1112131415";
- const char* mqtt_server = "192.168.0.103";
- //WiFi and MQTT declarations
- WiFiClient espClient;
- PubSubClient client(espClient);
- void setup() {
- //declare output and input pins
- pinMode(D4, OUTPUT);
- //start the serial monitor (test purposes only)
- //Serial.begin(115200);
- //initiate the EEPROM access and check stored values
- EEPROM.begin(512);
- getSetupVariables();
- //setup the wifi connection to previous set SSID and password
- setup_wifi();
- //set the MQTT server to previous declared values and set the callback function
- client.setServer(mqtt_server, 1883);
- client.setCallback(handleMQTTCommands);
- }
- void getSetupVariables() {
- //get bootvalue variable from EEPROM value
- //0 = new device to be paired
- //1 = already paired device
- bootValue = getValueFromEEPROM(addrBoot);
- //get bootvalue variable from EEPROM value
- //0 = led off
- //1 = led on
- statusValue = getValueFromEEPROM(addrStatus);
- }
- void setup_wifi() {
- delay(10);
- // We start by connecting to a WiFi network
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- }
- }
- void handleMQTTCommands(char* topic, byte* payload, unsigned int length) {
- JsonObject& root = jsonBuffer.parseObject(payload);
- char MQTT_channel[100];
- MQTT_CHANNEL_RESPONSE_PERSONAL.toCharArray(MQTT_channel, (MQTT_CHANNEL_RESPONSE_PERSONAL.length() + 1));
- //handle remove command of the device from MQTT
- if (strcmp(topic, MQTT_channel) == 0) {
- String message = root["message"];
- if (message == "accessory '" + DEVICE_NAME +"' is removed.") {
- //set value in EEPROM to 0
- bootValue = (byte)0;
- setValueToEEPROM(addrBoot, bootValue);
- }
- }
- MQTT_CHANNEL_COMMANDS.toCharArray(MQTT_channel, (MQTT_CHANNEL_COMMANDS.length() + 1));
- //handle led commands from MQTT
- if (strcmp(topic, MQTT_channel) == 0) {
- String command = root["value"];
- if (command == "true") {
- digitalWrite(D4, HIGH);
- statusValue = (byte)1;
- } else {
- digitalWrite(D4, LOW);
- statusValue = (byte)0;
- }
- setValueToEEPROM(addrStatus, statusValue);
- }
- jsonBuffer.clear();
- delay(500);
- }
- void initialState() {
- char msg[100];
- char MQTT_channel[100];
- if((int)statusValue == 0){
- MQTT_PAYLOAD_INITIAL_STATE_OFF.toCharArray(msg, (MQTT_PAYLOAD_INITIAL_STATE_OFF.length() + 1));
- digitalWrite(D4, LOW);
- } else{
- MQTT_PAYLOAD_INITIAL_STATE_ON.toCharArray(msg, (MQTT_PAYLOAD_INITIAL_STATE_ON.length() + 1));
- digitalWrite(D4, HIGH);
- }
- MQTT_CHANNEL_SET_VALUE.toCharArray(MQTT_channel, (MQTT_CHANNEL_SET_VALUE.length() + 1));
- client.publish(MQTT_channel, msg);
- delay(500);
- }
- void reconnect() {
- // Loop until we're reconnected
- while (!client.connected()) {
- // Attempt to connect
- String clientId = DEVICE_NAME;
- if (client.connect(clientId.c_str())) {
- char MQTT_channel[100];
- char msg[100];
- //Set the type of the device to a homebridge device on the broker
- MQTT_PAYLOAD_DEVICE_TYPE.toCharArray(msg, (MQTT_PAYLOAD_DEVICE_TYPE.length() + 1));
- MQTT_CHANNEL_SET_DEVICE_TYPE.toCharArray(MQTT_channel, (MQTT_CHANNEL_SET_DEVICE_TYPE.length() + 1));
- client.publish(MQTT_channel, msg);
- delay(500);
- // Once connected, check for first boot setup requirements
- if ((int)bootValue == 0) {
- //add new accessory to homebridge MQTT
- MQTT_PAYLOAD_NEW_DEVICE.toCharArray(msg, (MQTT_PAYLOAD_NEW_DEVICE.length() + 1));
- MQTT_CHANNEL_ADD_ACCESSORY.toCharArray(MQTT_channel, (MQTT_CHANNEL_ADD_ACCESSORY.length() + 1));
- client.publish(MQTT_channel, msg);
- delay(500);
- //set value in EEPROM to 1
- bootValue = (byte)1;
- setValueToEEPROM(addrBoot, bootValue);
- }
- //subscribe to all relevant channels
- MQTT_CHANNEL_COMMANDS.toCharArray(MQTT_channel, (MQTT_CHANNEL_COMMANDS.length() + 1));
- client.subscribe(MQTT_channel);
- delay(100);
- MQTT_CHANNEL_RESPONSE.toCharArray(MQTT_channel, (MQTT_CHANNEL_RESPONSE.length() + 1));
- client.subscribe(MQTT_channel);
- //set initial state of the device
- initialState();
- } else {
- // Wait 5 seconds before retrying
- delay(5000);
- }
- }
- }
- byte getValueFromEEPROM(int address){
- return EEPROM.read(address);
- }
- void setValueToEEPROM(int address, byte value){
- EEPROM.write(address, value);
- EEPROM.commit();
- }
- void loop() {
- if (!client.connected()) {
- reconnect();
- }
- client.loop();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement