Explorar el Código

mostly functioning REST gateway

Chris Mullins hace 8 años
padre
commit
8ae6250838
Se han modificado 4 ficheros con 126 adiciones y 328 borrados
  1. 21 3
      lib/MiLight/MiLightClient.cpp
  2. 3 0
      lib/MiLight/MiLightClient.h
  3. 1 0
      platformio.ini
  4. 101 325
      src/main.cpp

+ 21 - 3
lib/MiLight/MiLightClient.cpp

@@ -17,7 +17,17 @@ void MiLightClient::read(MiLightPacket& packet) {
 void MiLightClient::write(MiLightPacket& packet, const unsigned int resendCount) {
   uint8_t *packetBytes = reinterpret_cast<uint8_t*>(&packet);
   
+  Serial.print("Packet bytes (");
+  Serial.print(sizeof(packet));
+  Serial.print(" bytes): ");
+  for (int i = 0; i < sizeof(packet); i++) {
+    Serial.print(packetBytes[i], HEX);
+    Serial.print(" ");
+  }
+  Serial.println();
+  
   for (int i = 0; i < resendCount; i++) {
+    Serial.print(".");
     radio.write(packetBytes, sizeof(packet));
   }
   Serial.println();
@@ -57,11 +67,11 @@ void MiLightClient::write(
 }
     
 void MiLightClient::updateColor(const uint16_t deviceId, const uint8_t groupId, const uint16_t hue) {
-  write(deviceId, hue, 0, groupId, MiLightButton::COLOR);
+  write(deviceId, hue, 0, groupId, COLOR);
 }
 
 void MiLightClient::updateBrightness(const uint16_t deviceId, const uint8_t groupId, const uint8_t brightness) {
-  write(deviceId, 0, brightness, groupId, MiLightButton::BRIGHTNESS);
+  write(deviceId, 0, brightness, groupId, BRIGHTNESS);
 }
 
 void MiLightClient::updateStatus(const uint16_t deviceId, const uint8_t groupId, MiLightStatus status) {
@@ -70,5 +80,13 @@ void MiLightClient::updateStatus(const uint16_t deviceId, const uint8_t groupId,
 }
 
 void MiLightClient::updateColorWhite(const uint16_t deviceId, const uint8_t groupId) {
-  write(deviceId, 0, 0, groupId, MiLightButton::COLOR_WHITE);
+  write(deviceId, 0, 0, groupId, COLOR_WHITE);
+}
+
+void MiLightClient::allOn(const uint16_t deviceId) {
+  write(deviceId, 0, 0, 0, ALL_ON);
+}
+
+void MiLightClient::allOff(const uint16_t deviceId) {
+  write(deviceId, 0, 0, 0, ALL_OFF);
 }

+ 3 - 0
lib/MiLight/MiLightClient.h

@@ -64,6 +64,9 @@ class MiLightClient {
     void updateStatus(const uint16_t deviceId, const uint8_t groupId, MiLightStatus status);
     void updateColorWhite(const uint16_t deviceId, const uint8_t groupId);
     
+    void allOn(const uint16_t deviceId);
+    void allOff(const uint16_t deviceId);
+    
   private:
     MiLightRadio& radio;
     uint8_t sequenceNum;

+ 1 - 0
platformio.ini

@@ -16,3 +16,4 @@ lib_deps =
   RF24
   SPI
   WiFiManager
+  ArduinoJson

+ 101 - 325
src/main.cpp

@@ -2,10 +2,13 @@
 #include <nRF24L01.h>
 #include <RF24.h>
 #include <WiFiManager.h>
+#include <ArduinoJson.h>
+#include <stdlib.h>
 
 #include <PL1167_nRF24.h>
 #include <MiLightRadio.h>
 #include <MiLightClient.h>
+#include <ESP8266WebServer.h>
 
 #define CE_PIN D0 
 #define CSN_PIN D8
@@ -16,341 +19,114 @@ MiLightRadio mlr(prf);
 MiLightClient milightClient(mlr);
 
 WiFiManager wifiManager;
-
-void setup() {
-  Serial.begin(9600);
-  wifiManager.autoConnect();
-  mlr.begin();
-}
-
-
-static int dupesPrinted = 0;
-static bool receiving = true;
-static bool escaped = false;
-static uint8_t outgoingPacket[7];
-static uint8_t outgoingPacketUDP[7];
-static uint8_t outgoingPacketPos = 0;
-static uint8_t nibble;
-static enum {
-  IDLE,
-  HAVE_NIBBLE,
-  COMPLETE,
-} state;
-
-static uint8_t reverse_bits(uint8_t data) {
-  uint8_t result = 0;
-  for (int i = 0; i < 8; i++) {
-    result <<= 1;
-    result |= data & 1;
-    data >>= 1;
+ESP8266WebServer server(80);
+
+template <typename T>
+const T strToHex(const String& s) {
+  T value = 0;
+  uint32_t base = 1;
+  
+  for (int i = s.length() - 1; i >= 0; i--) {
+    const char c = s.charAt(i);
+    
+    if (c >= '0' && c <= '9') {
+      value += ((c - '0') * base);
+    } else if (c >= 'a' && c <= 'f') {
+      value += ((c - 'a' + 10) * base);
+    } else if (c >= 'A' && c <= 'F') {
+      value += ((c - 'A' + 10) * base);
+    } else {
+      break;
+    }
+    
+    base <<= 4;
   }
-  return result;
+  
+  return value;
 }
 
-void udpLoop(WiFiUDP Udp, uint8_t id1, uint8_t id2) {
-  int packetSize = Udp.parsePacket();
-  if (packetSize)
-  {
-    // read the packet into packetBufffer
-    int len = Udp.read(packetBuffer, 255);
-    if (len > 0) packetBuffer[len] = 0;
-    Serial.println();
-    Serial.print("Contents: ");
-    for (int j = 0; j < len; j++) {
-      Serial.print(packetBuffer[j], HEX);
-      Serial.print(" ");
+void handleUpdateGateway() {
+  DynamicJsonBuffer buffer;
+  JsonObject& request = buffer.parse(server.arg("plain"));
+  
+  const String gatewayIdStr = request["gateway_id"];
+  const uint8_t groupId = request["group_id"];
+  uint16_t gatewayId;
+  
+  if (gatewayIdStr.startsWith("0x")) {
+    gatewayId = strToHex<uint16_t>(gatewayIdStr.substring(2));
+  } else {
+    gatewayId = request["gateway_id"];
+  }
+  
+  if (request.containsKey("status")) {
+    MiLightStatus status = (request.get<String>("status") == "on") ? ON : OFF;
+    milightClient.updateStatus(gatewayId, groupId, status);
+  }
+  
+  if (request.containsKey("hue")) {
+    milightClient.updateColor(gatewayId, groupId, request["hue"]);
+  }
+  
+  if (request.containsKey("level")) {
+    milightClient.updateBrightness(gatewayId, groupId, request["level"]);
+  }
+  
+  if (request.containsKey("command")) {
+    if (request["command"] == "set_white") {
+      milightClient.updateColorWhite(gatewayId, groupId);
     }
-    Serial.println();
-
-    outgoingPacketUDP[0] = 0xB0; // B0 - White | B8 - RGBW
-    outgoingPacketUDP[1] = id1; // Remote ID
-    outgoingPacketUDP[2] = id2; // Remote ID
-
-    if (packetBuffer[0] == 0x40) {  // Color
-      outgoingPacketUDP[3] = ((uint8_t)0xFF - packetBuffer[1]) + 0xC0;
-      outgoingPacketUDP[4] = lastOnGroup; // Use last ON group
-      outgoingPacketUDP[5] = 0x0F; // Button
-
-    } else if (packetBuffer[0] == 0x4E) { // Brightness
-
-      // 2 to 1B (2-27)
-      // (0x90-0x00 and 0xF8-0xB0) increments of 8
-      // 0x90-0x00 = 1 to 18
-      // 0xB0-F8 = 19 to 27
-      /*
-       * x - 98
-       * x - 90
-       * x - 88
-       * 2 - 80*
-       * 3 - 78
-       * 4 - 70
-       * 5 - 68
-       * 6 - 60
-       * 7 - 58
-       * 8 -50
-       * 9 - 48
-       * 10 - 40
-       * 11 - 38
-       * 12 - 30
-       * 13 - 28
-       * 14 - 20
-       * 15 - 18
-       * 16 - 10
-       * 17 - 8
-       * 18 - 0
-       * 19 - F8
-       * 20 - F0
-       * 21 - E8
-       * 22 - E0
-       * 23 - D8
-       * 24 - D0
-       * 25 - C8
-       * 26 - C0
-       * 27 - B8*
-       * xx - B0
-       * xx - A8
-       */
-
-      if (packetBuffer[1] <= 18) {
-        outgoingPacketUDP[4] = (18 - packetBuffer[1]) * 0x08;
-      } else {
-        outgoingPacketUDP[4] = 0xB8 + (27 - packetBuffer[1]) * 0x08;
-      }
-      outgoingPacketUDP[4] += lastOnGroup; // add group number
-      outgoingPacketUDP[5] = 0x0E; // Button
-
-    } else if ((packetBuffer[0] & 0xF0) == 0xC0) {
-      outgoingPacketUDP[5] = packetBuffer[0] - 0xB2; // Full White
-
-    } else if (packetBuffer[0] == 0x41) {   // Button RGBW COLOR LED ALL OFF
-      outgoingPacketUDP[5] = 0x02;
-    } else if (packetBuffer[0] == 0x42) {   // Button RGBW COLOR LED ALL ON
-      outgoingPacketUDP[5] = 0x01;
-      lastOnGroup = 0;
-    } else if (packetBuffer[0] == 0x45) {   // Group 1 ON
-      outgoingPacketUDP[5] = 0x03;
-      lastOnGroup = 1;
-    } else if (packetBuffer[0] == 0x46) {   // Group 1 OFF
-      outgoingPacketUDP[5] = 0x04;
-    } else if (packetBuffer[0] == 0x47) {   // Group 2 ON
-      outgoingPacketUDP[5] = 0x05;
-      lastOnGroup = 2;
-    } else if (packetBuffer[0] == 0x48) {   // Group 2 OFF
-      outgoingPacketUDP[5] = 0x06;
-    } else if (packetBuffer[0] == 0x49) {   // Group 3 ON
-      outgoingPacketUDP[5] = 0x07;
-      lastOnGroup = 3;
-    } else if (packetBuffer[0] == 0x4A) {   // Group 3 OFF
-      outgoingPacketUDP[5] = 0x08;
-    } else if (packetBuffer[0] == 0x4B) {   // Group 4 ON
-      outgoingPacketUDP[5] = 0x09;
-      lastOnGroup = 4;
-    } else if (packetBuffer[0] == 0x4C) {   // Group 5 OFF
-      outgoingPacketUDP[5] = 0x0A;
-
-    } else {
-      Serial.println("Wooops!");
-      outgoingPacketUDP[5] = packetBuffer[0] - 0x42; // Button
+    
+    if (request["command"] == "all_on") {
+      milightClient.allOn(gatewayId);
     }
-    outgoingPacketUDP[6]++; // Counter
-
-    Serial.print("Write : ");
-    for (int j = 0; j < sizeof(outgoingPacketUDP); j++) {
-      Serial.print(outgoingPacketUDP[j], HEX);
-      Serial.print(" ");
-    }
-    Serial.println();
-
-    mlr.write(outgoingPacketUDP, sizeof(outgoingPacketUDP));
-    resendCounter = 16;
-    lastMicros = micros();
-  }
-  delay(0);
-
-  if (resendCounter > 0) {
-    if (micros() - 350 > lastMicros) {
-      mlr.resend();
-      resendCounter--;
-      Serial.print(".");
-      lastMicros = micros();
+    
+    if (request["command"] == "all_off") {
+      milightClient.allOff(gatewayId);
     }
   }
+  
+  server.send(200, "application/json", "true");
 }
 
-unsigned int brightness = 0;
-uint16_t color = 360;
-
-void loop() {
-  if (receiving) {
-    if (mlr.available()) {
-      printf("\n");
-      Serial.print("Packet: ");
-      uint8_t packet[7];
-      size_t packet_length = sizeof(packet);
-      mlr.read(packet, packet_length);
-
-      for (int i = 0; i < packet_length; i++) {
-        //Serial.print(packet[i], HEX);
-        //Serial.print(" ");
-        printf("%02X ", packet[i]);
-      }
-      printf("\n");
-    }
-    // 
-    // int dupesReceived = mlr.dupesReceived();
-    // for (; dupesPrinted < dupesReceived; dupesPrinted++) {
-    //   printf(".");
-    //   Serial.print(".");
-    // }
-  }
-
-  while (Serial.available()) {
-    yield();
-    char inChar = (char)Serial.read();
-    uint8_t val = 0;
-    bool have_val = true;
-
-    if (inChar >= '0' && inChar <= '9') {
-      val = inChar - '0';
-    } else if (inChar >= 'a' && inChar <= 'f') {
-      val = inChar - 'a' + 10;
-    } else if (inChar >= 'A' && inChar <= 'F') {
-      val = inChar - 'A' + 10;
-    } else {
-      have_val = false;
-    }
-
-    if (!escaped) {
-      if (have_val) {
-        switch (state) {
-          case IDLE:
-            nibble = val;
-            state = HAVE_NIBBLE;
-            break;
-          case HAVE_NIBBLE:
-            if (outgoingPacketPos < sizeof(outgoingPacket)) {
-              outgoingPacket[outgoingPacketPos++] = (nibble << 4) | (val);
-            } else {
-              Serial.println("# Error: outgoing packet buffer full/packet too long");
-            }
-            if (outgoingPacketPos >= sizeof(outgoingPacket)) {
-              state = COMPLETE;
-            } else {
-              state = IDLE;
-            }
-            break;
-          case COMPLETE:
-            Serial.println("# Error: outgoing packet complete. Press enter to send.");
-            break;
+void setup() {
+  Serial.begin(9600);
+  wifiManager.autoConnect();
+  mlr.begin();
+  
+  server.on("/gateway", HTTP_PUT, handleUpdateGateway);
+  server.on("/update", HTTP_POST, 
+    [](){
+      server.sendHeader("Connection", "close");
+      server.sendHeader("Access-Control-Allow-Origin", "*");
+      server.send(200, "text/plain", (Update.hasError())?"FAIL":"OK");
+      ESP.restart();
+    },
+    [](){
+      HTTPUpload& upload = server.upload();
+      if(upload.status == UPLOAD_FILE_START){
+        WiFiUDP::stopAll();
+        uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
+        if(!Update.begin(maxSketchSpace)){//start with max available size
+          Update.printError(Serial);
         }
-      } else {
-        switch (inChar) {
-          case ' ':
-          case '\n':
-          case '\r':
-          case '.':
-            if (state == COMPLETE) {
-              Serial.print("Write : ");
-              for (int j = 0; j < sizeof(outgoingPacket); j++) {
-                Serial.print(outgoingPacket[j], HEX);
-                Serial.print(" ");
-              }
-              Serial.print(" - Size : ");
-              Serial.print(sizeof(outgoingPacket), DEC);
-              Serial.println();
-              mlr.write(outgoingPacket, sizeof(outgoingPacket));
-              Serial.println("Write End");
-            }
-            if (inChar != ' ') {
-              outgoingPacketPos = 0;
-              state = IDLE;
-            }
-            if (inChar == '.') {
-              mlr.resend();
-              delay(1);
-            }
-            break;
-          case 'x':
-            Serial.println("# Escaped to extended commands: r - Toggle receiver; Press enter to return to normal mode.");
-            escaped = true;
-            break;
+      } else if(upload.status == UPLOAD_FILE_WRITE){
+        if(Update.write(upload.buf, upload.currentSize) != upload.currentSize){
+          Update.printError(Serial);
+        }
+      } else if(upload.status == UPLOAD_FILE_END){
+        if(Update.end(true)){ //true to set the size to the current progress
+        } else {
+          Update.printError(Serial);
         }
       }
-    } else {
-      switch (inChar) {
-        case '\n':
-        case '\r':
-          outgoingPacketPos = 0;
-          state = IDLE;
-          escaped = false;
-          break;
-        case 'a':
-          Serial.println("Sending on packet");
-          // mlr.write(offPacket, sizeof(offPacket));
-          
-          milightClient.updateStatus(0x86CD, 2, ON);
-          
-          break;
-        case 'b':
-          milightClient.write(
-            0x86CD,
-            255,
-            ++brightness,
-            2,
-            MiLightButton::BRIGHTNESS
-          );
-          break;
-        case 'c':
-          milightClient.write(
-            0x86CD,
-            255,
-            --brightness,
-            2,
-            MiLightButton::BRIGHTNESS
-          );
-          break;
-          
-        case 'd':
-          milightClient.write(
-            0x86CD,
-            255,
-            brightness++,
-            2,
-            MiLightButton::BRIGHTNESS
-          );
-          break;
-        
-        case 'e':
-          milightClient.write(
-            0x86CD,
-            (++color%360),
-            0,
-            2,
-            MiLightButton::COLOR
-          );
-          break;
-        case 'f':
-          milightClient.write(
-            0x86CD,
-            (--color%360),
-            0,
-            2,
-            MiLightButton::COLOR
-          );
-          break;
-        case 'g':
-          milightClient.updateColorWhite(0x86CD, 2);
-          break;
-        
-        case 'r':
-          receiving = !receiving;
-          if (receiving) {
-            Serial.println("# Now receiving");
-          } else {
-            Serial.println("# Now not receiving");
-          }
-          break;
-      }
+      yield();
     }
-  }
-}
+  );
+  
+  server.begin();
+}
+
+void loop() {
+  server.handleClient();
+}