Advertisement
Guest User

Untitled

a guest
Jan 18th, 2018
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.23 KB | None | 0 0
  1. #include <ESP8266WiFi.h>
  2. #include <PubSubClient.h>
  3. #include <EEPROM.h>
  4. #include <ArduinoJson.h>
  5.  
  6. //Device variables and constants
  7. const String DEVICE_NAME = "NodeMCU_test"; //!!MUST BE UNIQUE!!
  8. byte statusValue;
  9.  
  10. //JSON buffer
  11. StaticJsonBuffer<80> jsonBuffer;
  12.  
  13. //EEPROM variables
  14. int addrBoot = 0;
  15. int addrStatus = 1;
  16. byte bootValue;
  17.  
  18. //MQTT constants
  19. //Update name values suitable for your setup
  20. const String MQTT_PAYLOAD_DEVICE_TYPE         = "{\"name\":\"" + DEVICE_NAME +"\",\"type\":\"homebridge\"}";
  21. const String MQTT_PAYLOAD_NEW_DEVICE          = "{\"name\":\"" + DEVICE_NAME +"\",\"service_name\":\"light\",\"service\":\"Lightbulb\"}";
  22. const String MQTT_PAYLOAD_REMOVE_DEVICE       = "{\"name\":\"NodeMCU_test\"}";
  23. const String MQTT_PAYLOAD_INITIAL_STATE_ON    = "{\"name\":\"NodeMCU_test\",\"service_name\":\"light\",\"characteristic\":\"On\",\"value\":true}";
  24. const String MQTT_PAYLOAD_INITIAL_STATE_OFF   = "{\"name\":\"" + DEVICE_NAME +"\",\"service_name\":\"light\",\"characteristic\":\"On\",\"value\":false}";
  25.  
  26. const String MQTT_CHANNEL_SET_DEVICE_TYPE      = "mqtt/to/set/type";
  27. const String MQTT_CHANNEL_ADD_ACCESSORY        = "homebridge/to/add";
  28. const String MQTT_CHANNEL_REMOVE_ACCESSORY     = "homebridge/to/remove";
  29. const String MQTT_CHANNEL_COMMANDS             = "homebridge/from/set/" + DEVICE_NAME;
  30. const String MQTT_CHANNEL_SET_VALUE            = "homebridge/to/set";
  31. const String MQTT_CHANNEL_RESPONSE             = "homebridge/from/response/#";
  32. const String MQTT_CHANNEL_RESPONSE_PERSONAL    = "homebridge/from/response/" + DEVICE_NAME;
  33.  
  34. // Update these with values suitable for your network.
  35. const char* ssid          = "VicoEquense2.4";
  36. const char* password      = "1112131415";
  37. const char* mqtt_server   = "192.168.0.103";
  38.  
  39. //WiFi and MQTT declarations
  40. WiFiClient espClient;
  41. PubSubClient client(espClient);
  42.  
  43. void setup() {
  44.   //declare output and input pins
  45.   pinMode(D4, OUTPUT);
  46.   //start the serial monitor (test purposes only)
  47.   //Serial.begin(115200);
  48.   //initiate the EEPROM access and check stored values
  49.   EEPROM.begin(512);
  50.   getSetupVariables();
  51.   //setup the wifi connection to previous set SSID and password
  52.   setup_wifi();
  53.   //set the MQTT server to previous declared values and set the callback function
  54.   client.setServer(mqtt_server, 1883);
  55.   client.setCallback(handleMQTTCommands);
  56. }
  57.  
  58. void getSetupVariables() {
  59.   //get bootvalue variable from EEPROM value
  60.   //0 = new device to be paired
  61.   //1 = already paired device
  62.   bootValue = getValueFromEEPROM(addrBoot);
  63.   //get bootvalue variable from EEPROM value
  64.   //0 = led off
  65.   //1 = led on
  66.   statusValue = getValueFromEEPROM(addrStatus);
  67. }
  68.  
  69. void setup_wifi() {
  70.   delay(10);
  71.   // We start by connecting to a WiFi network
  72.   WiFi.begin(ssid, password);
  73.  
  74.   while (WiFi.status() != WL_CONNECTED) {
  75.     delay(500);
  76.   }
  77. }
  78.  
  79. void handleMQTTCommands(char* topic, byte* payload, unsigned int length) {
  80.   JsonObject& root = jsonBuffer.parseObject(payload);
  81.   char MQTT_channel[100];
  82.  
  83.   MQTT_CHANNEL_RESPONSE_PERSONAL.toCharArray(MQTT_channel, (MQTT_CHANNEL_RESPONSE_PERSONAL.length() + 1));
  84.   //handle remove command of the device from MQTT
  85.   if (strcmp(topic, MQTT_channel) == 0) {
  86.     String message = root["message"];
  87.  
  88.     if (message == "accessory '" + DEVICE_NAME +"' is removed.") {
  89.       //set value in EEPROM to 0
  90.       bootValue = (byte)0;
  91.       setValueToEEPROM(addrBoot, bootValue);
  92.     }
  93.   }
  94.  
  95.   MQTT_CHANNEL_COMMANDS.toCharArray(MQTT_channel, (MQTT_CHANNEL_COMMANDS.length() + 1));
  96.   //handle led commands from MQTT
  97.   if (strcmp(topic, MQTT_channel) == 0) {
  98.     String command = root["value"];
  99.  
  100.     if (command == "true") {
  101.       digitalWrite(D4, HIGH);
  102.       statusValue = (byte)1;
  103.     } else {
  104.       digitalWrite(D4, LOW);
  105.       statusValue = (byte)0;
  106.     }
  107.     setValueToEEPROM(addrStatus, statusValue);
  108.   }
  109.   jsonBuffer.clear();
  110.   delay(500);
  111. }
  112.  
  113. void initialState() {
  114.   char msg[100];
  115.   char MQTT_channel[100];
  116.   if((int)statusValue == 0){
  117.     MQTT_PAYLOAD_INITIAL_STATE_OFF.toCharArray(msg, (MQTT_PAYLOAD_INITIAL_STATE_OFF.length() + 1));
  118.     digitalWrite(D4, LOW);
  119.   } else{
  120.     MQTT_PAYLOAD_INITIAL_STATE_ON.toCharArray(msg, (MQTT_PAYLOAD_INITIAL_STATE_ON.length() + 1));
  121.     digitalWrite(D4, HIGH);
  122.   }
  123.   MQTT_CHANNEL_SET_VALUE.toCharArray(MQTT_channel, (MQTT_CHANNEL_SET_VALUE.length() + 1));
  124.   client.publish(MQTT_channel, msg);
  125.   delay(500);
  126. }
  127.  
  128. void reconnect() {
  129.   // Loop until we're reconnected
  130.   while (!client.connected()) {
  131.     // Attempt to connect
  132.     String clientId = DEVICE_NAME;
  133.     if (client.connect(clientId.c_str())) {
  134.      
  135.       char MQTT_channel[100];
  136.       char msg[100];
  137.      
  138.       //Set the type of the device to a homebridge device on the broker
  139.       MQTT_PAYLOAD_DEVICE_TYPE.toCharArray(msg, (MQTT_PAYLOAD_DEVICE_TYPE.length() + 1));
  140.       MQTT_CHANNEL_SET_DEVICE_TYPE.toCharArray(MQTT_channel, (MQTT_CHANNEL_SET_DEVICE_TYPE.length() + 1));
  141.       client.publish(MQTT_channel, msg);
  142.       delay(500);
  143.      
  144.       // Once connected, check for first boot setup requirements
  145.       if ((int)bootValue == 0) {
  146.         //add new accessory to homebridge MQTT
  147.         MQTT_PAYLOAD_NEW_DEVICE.toCharArray(msg, (MQTT_PAYLOAD_NEW_DEVICE.length() + 1));
  148.         MQTT_CHANNEL_ADD_ACCESSORY.toCharArray(MQTT_channel, (MQTT_CHANNEL_ADD_ACCESSORY.length() + 1));
  149.         client.publish(MQTT_channel, msg);
  150.         delay(500);
  151.         //set value in EEPROM to 1
  152.         bootValue = (byte)1;
  153.         setValueToEEPROM(addrBoot, bootValue);
  154.       }
  155.  
  156.       //subscribe to all relevant channels
  157.       MQTT_CHANNEL_COMMANDS.toCharArray(MQTT_channel, (MQTT_CHANNEL_COMMANDS.length() + 1));
  158.       client.subscribe(MQTT_channel);
  159.       delay(100);
  160.       MQTT_CHANNEL_RESPONSE.toCharArray(MQTT_channel, (MQTT_CHANNEL_RESPONSE.length() + 1));
  161.       client.subscribe(MQTT_channel);
  162.       //set initial state of the device
  163.       initialState();
  164.     } else {
  165.       // Wait 5 seconds before retrying
  166.       delay(5000);
  167.     }
  168.   }
  169. }
  170.  
  171. byte getValueFromEEPROM(int address){
  172.   return EEPROM.read(address);
  173. }
  174.  
  175. void setValueToEEPROM(int address, byte value){
  176.   EEPROM.write(address, value);
  177.   EEPROM.commit();
  178. }
  179.  
  180. void loop() {
  181.   if (!client.connected()) {
  182.     reconnect();
  183.   }
  184.   client.loop();
  185. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement