Explorar o código

first pass at supporting CCT

Chris Mullins %!s(int64=8) %!d(string=hai) anos
pai
achega
5f19897ca9

+ 2 - 2
lib/MiLight/MiLightClient.h

@@ -58,11 +58,11 @@ struct MiLightPacket {
 
 class MiLightClient {
   public:
-    MiLightClient(uint8_t cePin, uint8_t csnPin) :
+    MiLightClient(uint8_t cePin, uint8_t csnPin, MiLightRadioConfig& config) :
       sequenceNum(0) {
       rf = new RF24(cePin, csnPin);
       prf = new PL1167_nRF24(*rf);
-      radio = new MiLightRadio(*prf);
+      radio = new MiLightRadio(*prf, config);
     }
     
     ~MiLightClient() {

+ 12 - 10
lib/MiLight/MiLightRadio.cpp

@@ -9,11 +9,8 @@
 
 #define PACKET_ID(packet) ( ((packet[1] & 0xF0)<<24) | (packet[2]<<16) | (packet[3]<<8) | (packet[7]) )
 
-static const uint8_t CHANNELS[] = {9, 40, 71};
-#define NUM_CHANNELS (sizeof(CHANNELS)/sizeof(CHANNELS[0]))
-
-MiLightRadio::MiLightRadio(AbstractPL1167 &pl1167)
-  : _pl1167(pl1167) {
+MiLightRadio::MiLightRadio(AbstractPL1167 &pl1167, MiLightRadioConfig& config)
+  : _pl1167(pl1167), config(config) {
   _waiting = false;
 }
 
@@ -39,7 +36,9 @@ int MiLightRadio::begin()
     return retval;
   }
 
-  retval = _pl1167.setSyncword(0x147A, 0x258B);
+  // retval = _pl1167.setSyncword(0x147A, 0x258B);
+  // retval = _pl1167.setSyncword(0x050A, 0x55AA);
+  retval = _pl1167.setSyncword(config.syncword0, config.syncword3);
   if (retval < 0) {
     return retval;
   }
@@ -59,15 +58,18 @@ bool MiLightRadio::available()
   if (_waiting) {
     return true;
   }
-
-  if (_pl1167.receive(CHANNELS[0]) > 0) {
+  
+  if (_pl1167.receive(config.channels[0]) > 0) {
+  Serial.println(1);
     size_t packet_length = sizeof(_packet);
     if (_pl1167.readFIFO(_packet, packet_length) < 0) {
       return false;
     }
+  Serial.println(2);
     if (packet_length == 0 || packet_length != _packet[0] + 1U) {
       return false;
     }
+  Serial.println(3);
 
     uint32_t packet_id = PACKET_ID(_packet);
     if (packet_id == _prev_packet_id) {
@@ -126,9 +128,9 @@ int MiLightRadio::write(uint8_t frame[], size_t frame_length)
 
 int MiLightRadio::resend()
 {
-  for (size_t i = 0; i < NUM_CHANNELS; i++) {
+  for (size_t i = 0; i < config.numChannels; i++) {
     _pl1167.writeFIFO(_out_packet, _out_packet[0] + 1);
-    _pl1167.transmit(CHANNELS[i]);
+    _pl1167.transmit(config.channels[i]);
   }
   return 0;
 }

+ 4 - 1
lib/MiLight/MiLightRadio.h

@@ -14,13 +14,15 @@
 #endif
 
 #include "AbstractPL1167.h"
+#include <MiLightRadioConfig.h>
 
 #ifndef MILIGHTRADIO_H_
 #define MILIGHTRADIO_H_
 
 class MiLightRadio {
   public:
-    MiLightRadio(AbstractPL1167 &pl1167);
+    MiLightRadio(AbstractPL1167 &pl1167, MiLightRadioConfig& config);
+    
     int begin();
     bool available();
     int read(uint8_t frame[], size_t &frame_length);
@@ -29,6 +31,7 @@ class MiLightRadio {
     int resend();
   private:
     AbstractPL1167 &_pl1167;
+    const MiLightRadioConfig& config;
     uint32_t _prev_packet_id;
 
     uint8_t _packet[8], _out_packet[8];

+ 34 - 0
lib/MiLight/MiLightRadioConfig.h

@@ -0,0 +1,34 @@
+#include <Arduino.h>
+
+#ifndef _MILIGHT_RADIO_CONFIG
+#define _MILIGHT_RADIO_CONFIG 
+
+class MiLightRadioConfig {
+public:
+  MiLightRadioConfig(const uint16_t syncword0,
+  const uint16_t syncword3,
+  const uint8_t* channels,
+  const size_t numChannels) 
+    : syncword0(syncword0),
+      syncword3(syncword3),
+      channels(channels),
+      numChannels(numChannels)
+  {}
+    
+  const uint16_t syncword0;
+  const uint16_t syncword3;
+  const uint8_t* channels;
+  const size_t numChannels;
+};
+
+const uint8_t RGBW_CHANNELS[] = {9, 40, 71};
+static MiLightRadioConfig MilightRgbwConfig(
+  0x147A, 0x258B, RGBW_CHANNELS, 3
+);
+
+const uint8_t CCT_CHANNELS[] = {4, 39, 74};
+static MiLightRadioConfig MilightCctConfig(
+  0x050A, 0x55AA, CCT_CHANNELS, 3 
+);
+
+#endif

+ 3 - 0
lib/MiLight/PL1167_nRF24.cpp

@@ -145,6 +145,9 @@ int PL1167_nRF24::receive(uint8_t channel)
 
   _radio.startListening();
   if (_radio.available()) {
+#ifdef DEBUG_PRINTF
+  printf("Radio is available");
+#endif
     internal_receive();
   }
 

+ 2 - 0
lib/MiLight/PL1167_nRF24.h

@@ -15,6 +15,8 @@
 #ifndef PL1167_NRF24_H_
 #define PL1167_NRF24_H_
 
+#define DEBUG_PRINTF
+
 class PL1167_nRF24 : public AbstractPL1167 {
   public:
     PL1167_nRF24(RF24 &radio);

+ 3 - 3
src/main.cpp

@@ -186,7 +186,7 @@ void initMilightUdpServers() {
   }
 }
 
-void initMilightClient() {
+void initMilightClients() {
   if (milightClient) {
     delete milightClient;
   }
@@ -203,7 +203,7 @@ void handleUpdateSettings() {
   if (parsedSettings.success()) {
     settings.patch(parsedSettings);
     settings.save();
-    initMilightClient();
+    initMilightClients();
     initMilightUdpServers();
     
     if (server->authenticationRequired() && !settings.hasAuthSettings()) {
@@ -223,7 +223,7 @@ void setup() {
   wifiManager.autoConnect();
   SPIFFS.begin();
   Settings::load(settings);
-  initMilightClient();
+  initMilightClients();
   initMilightUdpServers();
   
   server->on("/", HTTP_GET, handleServeFile(WEB_INDEX_FILENAME, "text/html"));

+ 74 - 16
web/index.html

@@ -34,6 +34,7 @@
       background-color: #fff; 
       border: 1px solid #ccc;
     }
+    .inline { display: inline-block; }
     .hue-picker {
       height: 2em;
       width: 100%;
@@ -87,14 +88,20 @@
         
       if (deviceId == "") {
         alert("Please enter a device ID.");
-        throw "abc";
+        throw "Must enter device ID";
       }
         
       return "/gateways/" + deviceId + "/" + groupId;
     }
     
+    var getCurrentMode = function() {
+      return $('input[name="mode"]:checked').data('value');
+    };
+    
     var updateGroup = _.throttle(
       function(params) {
+        params.mode = currentMode();
+        
         $.ajax(
           activeUrl(),
           {
@@ -215,6 +222,18 @@
       }
     };
     
+    var updateModeOptions = function() {
+      var currentMode = getCurrentMode();
+      
+      $('.mode-option').map(function() {
+        if ($(this).data('for') != currentMode) {
+          $(this).hide();
+        } else {
+          $(this).show();
+        }
+      });
+    };
+    
     $(function() {
       $('.radio-option').click(function() {
         $(this).prev().prop('checked', true);
@@ -282,6 +301,8 @@
         $('#gateway-server-configs').append(gatewayServerRow('', ''));
       });
       
+      $('#mode').change(updateModeOptions);
+      
       $('body').on('click', '.remove-gateway-server', function() {
         $(this).closest('tr').remove();
       });
@@ -358,6 +379,7 @@
       });
       
       loadSettings();
+      updateModeOptions();
     });
   </script>
   
@@ -382,7 +404,7 @@
 				</select>
       </div>
       
-      <div class="col-sm-8">
+      <div class="col-sm-3">
         <label for="groupId">Group</label>
         
         <div class="btn-group" id="groupId" data-toggle="buttons">
@@ -403,25 +425,59 @@
           </label>
         </div>
       </div>
+      
+      <div class="col-sm-4">
+        <label for="groupId">Mode</label>
+        
+        <div class="btn-group" id="mode" data-toggle="buttons">
+          <label class="btn btn-secondary active">
+            <input type="radio" name="mode" autocomplete="off" data-value="rgbw" checked> RGBW
+          </label>
+          <label class="btn btn-secondary">
+            <input type="radio" name="mode" autocomplete="off" data-value="cct"> CCT
+          </label>
+        </div>
+      </div>
     </div>
     
-    <div class="row">
-      <div class="col-sm-12">
-        <h5>Hue</h5>
+    <div class="row"><div class="col-sm-12">
+    <div class="mode-option" data-for="rgbw">
+      <div class="row">
+        <div class="col-sm-12">
+          <h5>Hue</h5>
+        </div>
+      </div>
+      
+      <div class="row">
+        <div class="col-sm-6">
+          <span class="hue-picker">
+            <span class="hue-picker-inner"></span>
+            <span class="hue-value-display"></span>
+          </span>
+        </div>
       </div>
     </div>
-    
-    <div class="row">
-      <div class="col-sm-6">
-        <span class="hue-picker">
-          <span class="hue-picker-inner"></span>
-          <span class="hue-value-display"></span>
-        </span>
+    </div></div>
+          
+    <div class="mode-option" data-for="cct">
+      <div class="row">
+        <div class="col-sm-12">
+          <h5>Color Temperature</h5>
+        </div>
+      </div>
+      <div class="row">
+        <div class="col-sm-6">
+          <input class="slider raw-update" name="color-temperature"
+              data-slider-min="0"
+              data-slider-max="100"
+              data-slider-value="100"
+          />
+        </div>
       </div>
     </div>
     
     <div class="row">
-      <div class="col-sm-6">
+      <div class="col-sm-12">
         <h5>Brightness</h5>
       </div>
     </div>
@@ -448,9 +504,11 @@
           <li>
             <input type="checkbox" name="status" class="raw-update" data-toggle="toggle" checked/>
           </li>
-          <li>
-            <button type="button" class="btn btn-secondary command-btn" data-command="set_white">White</button>
-          </li>
+          <div class="mode-option inline" data-for="rgbw">
+            <li>
+              <button type="button" class="btn btn-secondary command-btn" data-command="set_white">White</button>
+            </li>
+          </div>
           <li>
             <button type="button" class="btn btn-success command-btn" data-command="pair">
               <i class="glyphicon glyphicon-plus"></i>