Sfoglia il codice sorgente

kill MyLightPacket, replace with raw byte buffer. add RGBW-CCT params (no support yet, the protocol is a mess)

Chris Mullins 8 anni fa
parent
commit
051e21e2fb

+ 29 - 49
lib/MiLight/MiLightClient.cpp

@@ -1,4 +1,5 @@
 #include <MiLightClient.h>
+#include <MiLightRadioConfig.h>
 
 MiLightRadio* MiLightClient::getRadio(const MiLightRadioType type) {
   MiLightRadio* radio = NULL;
@@ -7,7 +8,9 @@ MiLightRadio* MiLightClient::getRadio(const MiLightRadioType type) {
     return rgbwRadio->getRadio();
   } else if (type == CCT) {
     return cctRadio->getRadio();
-  } 
+  } else if (type == RGBW_CCT) {
+    return rgbwCctRadio->getRadio();
+  }
   
   if (radio != NULL) {
     radio->configure();
@@ -16,32 +19,6 @@ MiLightRadio* MiLightClient::getRadio(const MiLightRadioType type) {
   return radio;
 }
 
-void MiLightClient::deserializePacket(const uint8_t rawPacket[], MiLightPacket& packet) {
-  uint8_t ptr = 0;
-  
-  packet.deviceType = rawPacket[ptr++];
-  packet.deviceId = (rawPacket[ptr++] << 8) | rawPacket[ptr++];
-  packet.b1 = rawPacket[ptr++];
-  packet.b2 = rawPacket[ptr++];
-  packet.b3 = rawPacket[ptr++];
-  packet.sequenceNum = rawPacket[ptr++];
-}
-
-void MiLightClient::serializePacket(uint8_t rawPacket[], const MiLightPacket& packet) {
-  uint8_t ptr = 0;
-  
-  rawPacket[ptr++] = packet.deviceType;
-  
-  // big endian
-  rawPacket[ptr++] = packet.deviceId >> 8;
-  rawPacket[ptr++] = packet.deviceId & 0xFF;
-  
-  rawPacket[ptr++] = packet.b1;
-  rawPacket[ptr++] = packet.b2;
-  rawPacket[ptr++] = packet.b3;
-  rawPacket[ptr++] = packet.sequenceNum;
-}
-
 uint8_t MiLightClient::nextSequenceNum() {
   return sequenceNum++;
 }
@@ -57,25 +34,21 @@ bool MiLightClient::available(const MiLightRadioType radioType) {
   return radio->available();
 }
 
-void MiLightClient::read(const MiLightRadioType radioType, MiLightPacket& packet) {
+void MiLightClient::read(const MiLightRadioType radioType, uint8_t packet[]) {
   MiLightRadio* radio = getRadio(radioType);
   
   if (radio == NULL) {
     return;
   }
   
-  uint8_t packetBytes[MILIGHT_PACKET_LENGTH];
   size_t length;
-  radio->read(packetBytes, length);
-  deserializePacket(packetBytes, packet);
+  radio->read(packet, length);
 }
 
 void MiLightClient::write(const MiLightRadioType radioType, 
-  MiLightPacket& packet, 
+  uint8_t packet[],
   const unsigned int resendCount) {
     
-  uint8_t packetBytes[MILIGHT_PACKET_LENGTH];
-  serializePacket(packetBytes, packet);
   MiLightRadio* radio = getRadio(radioType);
   
   if (radio == NULL) {
@@ -83,7 +56,7 @@ void MiLightClient::write(const MiLightRadioType radioType,
   }
   
   for (int i = 0; i < resendCount; i++) {
-    radio->write(packetBytes, MILIGHT_PACKET_LENGTH);
+    radio->write(packet, MILIGHT_PACKET_LENGTH);
     yield();
   }
 }
@@ -95,13 +68,16 @@ void MiLightClient::writeRgbw(
   const uint8_t groupId,
   const uint8_t button) {
   
-  MiLightPacket packet;
-  packet.deviceType = RGBW;
-  packet.deviceId = deviceId;
-  packet.b1 = color;
-  packet.b2 = (brightness << 3) | (groupId & 0x07);
-  packet.b3 = button;
-  packet.sequenceNum = nextSequenceNum();
+  uint8_t packet[MilightRgbwConfig.packetLength];
+  size_t packetPtr = 0;
+  
+  packet[packetPtr++] = RGBW;
+  packet[packetPtr++] = deviceId >> 8;
+  packet[packetPtr++] = deviceId & 0xFF;
+  packet[packetPtr++] = color;
+  packet[packetPtr++] = (brightness << 3) | (groupId & 0x07);
+  packet[packetPtr++] = button;
+  packet[packetPtr++] = nextSequenceNum();
   
   write(RGBW, packet);
 }
@@ -109,14 +85,18 @@ void MiLightClient::writeRgbw(
 void MiLightClient::writeCct(const uint16_t deviceId,
   const uint8_t groupId,
   const uint8_t button) {
+    
+  uint8_t packet[MilightRgbwConfig.packetLength];
+  uint8_t sequenceNum = nextSequenceNum();
+  size_t packetPtr = 0;
   
-  MiLightPacket packet;
-  packet.deviceType = CCT;
-  packet.deviceId = deviceId;
-  packet.b1 = groupId;
-  packet.b2 = button;
-  packet.b3 = nextSequenceNum();
-  packet.sequenceNum = packet.b3;
+  packet[packetPtr++] = CCT;
+  packet[packetPtr++] = deviceId >> 8;
+  packet[packetPtr++] = deviceId & 0xFF;
+  packet[packetPtr++] = groupId;
+  packet[packetPtr++] = button;
+  packet[packetPtr++] = sequenceNum;
+  packet[packetPtr++] = sequenceNum;
   
   write(CCT, packet);
 }

+ 8 - 15
lib/MiLight/MiLightClient.h

@@ -13,19 +13,11 @@
 enum MiLightRadioType {
   UNKNOWN = 0,
   RGBW  = 0xB8,
-  CCT   = 0x5A
+  CCT   = 0x5A,
+  RGBW_CCT = 0x99
 };
 
 enum MiLightStatus { ON = 0, OFF = 1 };
-  
-struct MiLightPacket {
-  uint8_t deviceType;
-  uint16_t deviceId;
-  uint8_t b1;
-  uint8_t b2;
-  uint8_t b3;
-  uint8_t sequenceNum;
-};
 
 class MiLightRadioStack {
 public:
@@ -56,21 +48,24 @@ class MiLightClient {
     {
       rgbwRadio = new MiLightRadioStack(rf, MilightRgbwConfig);
       cctRadio = new MiLightRadioStack(rf, MilightCctConfig);
+      rgbwCctRadio = new MiLightRadioStack(rf, MilightRgbwCctConfig);
     }
     
     ~MiLightClient() {
       delete rgbwRadio;
       delete cctRadio;
+      delete rgbwCctRadio;
     }
     
     void begin() {
       rgbwRadio->getRadio()->begin();
       cctRadio->getRadio()->begin();
+      rgbwCctRadio->getRadio()->begin();
     }
     
     bool available(const MiLightRadioType radioType);
-    void read(const MiLightRadioType radioType, MiLightPacket& packet);
-    void write(const MiLightRadioType radioType, MiLightPacket& packet, const unsigned int resendCount = 50);
+    void read(const MiLightRadioType radioType, uint8_t packet[]);
+    void write(const MiLightRadioType radioType, uint8_t packet[], const unsigned int resendCount = 50);
     
     void writeRgbw(
       const uint16_t deviceId,
@@ -110,9 +105,6 @@ class MiLightClient {
     
     MiLightRadio* getRadio(const MiLightRadioType type);
     
-    static void deserializePacket(const uint8_t rawPacket[], MiLightPacket& packet);
-    static void serializePacket(uint8_t rawPacket[], const MiLightPacket& packet);
-    
     static uint8_t getCctStatusButton(uint8_t groupId, MiLightStatus status);
     static MiLightRadioType getRadioType(const String& typeName);
     
@@ -120,6 +112,7 @@ class MiLightClient {
     RF24 rf;
     MiLightRadioStack* rgbwRadio;
     MiLightRadioStack* cctRadio;
+    MiLightRadioStack* rgbwCctRadio;
     
     uint8_t sequenceNum;
     uint8_t nextSequenceNum();

+ 3 - 1
lib/MiLight/MiLightRadio.cpp

@@ -65,6 +65,9 @@ bool MiLightRadio::available()
   configure();
   
   if (_waiting) {
+#ifdef DEBUG_PRINTF
+  printf("_waiting\n");
+#endif
     return true;
   }
   
@@ -76,7 +79,6 @@ bool MiLightRadio::available()
     if (packet_length == 0 || packet_length != _packet[0] + 1U) {
       return false;
     }
-
     uint32_t packet_id = PACKET_ID(_packet);
     if (packet_id == _prev_packet_id) {
       _dupes_received++;

+ 2 - 2
lib/MiLight/MiLightRadioConfig.h

@@ -31,12 +31,12 @@ static MiLightRadioConfig MilightRgbwConfig(
 
 const uint8_t CCT_CHANNELS[] = {4, 39, 74};
 static MiLightRadioConfig MilightCctConfig(
-  0x050A, 0x55AA, 7, CCT_CHANNELS, 3 
+  0x050A, 0x55AA, 7, CCT_CHANNELS, 3
 );
 
 const uint8_t RGBWCCT_CHANNELS[] = {70, 39, 8};
 static MiLightRadioConfig MilightRgbwCctConfig(
-  0x7236, 0x1809, 9, RGBWCCT_CHANNELS, 3 
+  0x7236, 0x1809, 8, RGBWCCT_CHANNELS, 3
 );
 
 #endif

+ 7 - 0
lib/MiLight/PL1167_nRF24.cpp

@@ -349,16 +349,23 @@ int PL1167_nRF24::internal_receive()
 
   if (_crc) {
     if (outp < 2) {
+#ifdef DEBUG_PRINTF
+  printf("Failed CRC: outp < 2\n");
+#endif
       return 0;
     }
     uint16_t crc = calc_crc(tmp, outp - 2);
     if ( ((crc & 0xff) != tmp[outp - 2]) || (((crc >> 8) & 0xff) != tmp[outp - 1]) ) {
+#ifdef DEBUG_PRINTF
+  printf("Failed CRC: expected %d, got %d (%d,%d)\n", crc, tmp[outp-2], tmp[outp-1]);
+#endif
       return 0;
     }
     outp -= 2;
   }
 
   memcpy(_packet, tmp, outp);
+  
   _packet_length = outp;
   _received = true;
   return outp;

+ 13 - 8
src/main.cpp

@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <fs.h>
 #include <MiLightClient.h>
+#include <MiLightRadioConfig.h>
 #include <WebServer.h>
 #include <IntParsing.h>
 #include <Settings.h>
@@ -127,6 +128,7 @@ void handleUpdateGroup(const UrlTokenBindings* urlBindings) {
 
 void handleListenGateway() {
   uint8_t readType = 0;
+  MiLightRadioConfig *config;
   
   while (readType == 0) {
     if (!server->clientConnected()) {
@@ -135,26 +137,29 @@ void handleListenGateway() {
     
     if (milightClient->available(RGBW)) {
       readType = RGBW;
+      config = &MilightRgbwConfig;
     } else if (milightClient->available(CCT)) {
       readType = CCT;
+      config = &MilightCctConfig;
+    } else if (milightClient->available(RGBW_CCT)) {
+      readType = RGBW_CCT;
+      config = &MilightRgbwCctConfig;
     }
     
     yield();
   }
   
-  MiLightPacket packet;
+  uint8_t packet[config->packetLength];
   milightClient->read(static_cast<MiLightRadioType>(readType), packet);
   
   String response = "Packet received (";
   response += String(sizeof(packet)) + " bytes)";
   response += ":\n";
-  response += "Type         : " + String(readType) + "\n";
-  response += "Request type : " + String(packet.deviceType, HEX) + "\n";
-  response += "Device ID    : " + String(packet.deviceId, HEX) + "\n";
-  response += "B1           : " + String(packet.b1, HEX) + "\n";
-  response += "B2           : " + String(packet.b2, HEX) + "\n";
-  response += "B3           : " + String(packet.b3, HEX) + "\n";
-  response += "Sequence Num : " + String(packet.sequenceNum, HEX) + "\n";
+  
+  for (int i = 0; i < sizeof(packet); i++) {
+    response += String(packet[i], HEX) + " ";
+  }
+  
   response += "\n\n";
   
   server->send(200, "text/plain", response);