kopia lustrzana https://github.com/Aircoookie/WLED
				
				
				
			
							rodzic
							
								
									2d4d7bf937
								
							
						
					
					
						commit
						3b3f8e6f43
					
				| 
						 | 
				
			
			@ -165,7 +165,7 @@ lib_deps =
 | 
			
		|||
    ESPAsyncTCP@1.2.0
 | 
			
		||||
    ESPAsyncUDP@697c75a025
 | 
			
		||||
    AsyncTCP@1.0.3
 | 
			
		||||
    Esp Async WebServer@1.2.0
 | 
			
		||||
    https://github.com/Aircoookie/ESPAsyncWebServer
 | 
			
		||||
    IRremoteESP8266@2.7.3
 | 
			
		||||
  #For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line  
 | 
			
		||||
    #TFT_eSPI
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2247,7 +2247,7 @@ uint16_t WS2812FX::mode_ripple_rainbow(void) {
 | 
			
		|||
CRGB WS2812FX::twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat)
 | 
			
		||||
{
 | 
			
		||||
  // Overall twinkle speed (changed)
 | 
			
		||||
  uint16_t ticks = ms / (32 - (SEGMENT.speed >> 3));
 | 
			
		||||
  uint16_t ticks = ms / SEGENV.aux0;
 | 
			
		||||
  uint8_t fastcycle8 = ticks;
 | 
			
		||||
  uint16_t slowcycle16 = (ticks >> 8) + salt;
 | 
			
		||||
  slowcycle16 += sin8(slowcycle16);
 | 
			
		||||
| 
						 | 
				
			
			@ -2312,10 +2312,11 @@ uint16_t WS2812FX::twinklefox_base(bool cat)
 | 
			
		|||
  // numbers that it generates is (paradoxically) stable.
 | 
			
		||||
  uint16_t PRNG16 = 11337;
 | 
			
		||||
 | 
			
		||||
  // Calculate speed
 | 
			
		||||
  if (SEGMENT.speed > 100) SEGENV.aux0 = 3 + ((255 - SEGMENT.speed) >> 3);
 | 
			
		||||
  else SEGENV.aux0 = 22 + ((100 - SEGMENT.speed) >> 1);
 | 
			
		||||
 | 
			
		||||
  // Set up the background color, "bg".
 | 
			
		||||
  // if AUTO_SELECT_BACKGROUND_COLOR == 1, and the first two colors of
 | 
			
		||||
  // the current palette are identical, then a deeply faded version of
 | 
			
		||||
  // that color is used for the background color
 | 
			
		||||
  CRGB bg;
 | 
			
		||||
  bg = col_to_crgb(SEGCOLOR(1));
 | 
			
		||||
  uint8_t bglight = bg.getAverageLight();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id);
 | 
			
		|||
void serializeState(JsonObject root);
 | 
			
		||||
void serializeInfo(JsonObject root);
 | 
			
		||||
void serveJson(AsyncWebServerRequest* request);
 | 
			
		||||
void serveLiveLeds(AsyncWebServerRequest* request);
 | 
			
		||||
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
 | 
			
		||||
 | 
			
		||||
//led.cpp
 | 
			
		||||
void setValuesFromMainSeg();
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +210,11 @@ String settingsProcessor(const String& var);
 | 
			
		|||
String dmxProcessor(const String& var);
 | 
			
		||||
void serveSettings(AsyncWebServerRequest* request);
 | 
			
		||||
 | 
			
		||||
//ws.cpp
 | 
			
		||||
void handleWs();
 | 
			
		||||
void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len);
 | 
			
		||||
void sendDataWs(AsyncWebSocketClient * client = nullptr);
 | 
			
		||||
 | 
			
		||||
//xml.cpp
 | 
			
		||||
void XML_response(AsyncWebServerRequest *request, char* dest = nullptr);
 | 
			
		||||
void URL_response(AsyncWebServerRequest *request);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -333,6 +333,12 @@ void serializeInfo(JsonObject root)
 | 
			
		|||
    root["lip"] = realtimeIP.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  #ifdef WLED_ENABLE_WEBSOCKETS
 | 
			
		||||
  root["ws"] = ws.count();
 | 
			
		||||
  #else
 | 
			
		||||
  root["ws"] = -1;
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  root["fxcount"] = strip.getModeCount();
 | 
			
		||||
  root["palcount"] = strip.getPaletteCount();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -454,21 +460,37 @@ void serveJson(AsyncWebServerRequest* request)
 | 
			
		|||
 | 
			
		||||
#define MAX_LIVE_LEDS 180
 | 
			
		||||
 | 
			
		||||
void serveLiveLeds(AsyncWebServerRequest* request)
 | 
			
		||||
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
 | 
			
		||||
{
 | 
			
		||||
  AsyncWebSocketClient * wsc;
 | 
			
		||||
  if (!request) { //not HTTP, use Websockets
 | 
			
		||||
    #ifdef WLED_ENABLE_WEBSOCKETS
 | 
			
		||||
    wsc = ws.client(wsClient);
 | 
			
		||||
    if (!wsc || wsc->queueLength() > 0) return false; //only send if queue free
 | 
			
		||||
    #endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uint16_t used = ledCount;
 | 
			
		||||
  uint16_t n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS
 | 
			
		||||
  char buffer[2000] = "{\"leds\":[";
 | 
			
		||||
  olen = 9;
 | 
			
		||||
  obuf = buffer;
 | 
			
		||||
  olen = 9;
 | 
			
		||||
 | 
			
		||||
  for (uint16_t i= 0; i < used; i += n)
 | 
			
		||||
  {
 | 
			
		||||
    olen += sprintf(buffer + olen, "\"%06X\",", strip.getPixelColor(i));
 | 
			
		||||
    olen += sprintf(obuf + olen, "\"%06X\",", strip.getPixelColor(i));
 | 
			
		||||
  }
 | 
			
		||||
  olen -= 1;
 | 
			
		||||
  oappend("],\"n\":");
 | 
			
		||||
  oappendi(n);
 | 
			
		||||
  oappend("}");
 | 
			
		||||
  request->send(200, "application/json", buffer);
 | 
			
		||||
  if (request) {
 | 
			
		||||
    request->send(200, "application/json", buffer);
 | 
			
		||||
  }
 | 
			
		||||
  #ifdef WLED_ENABLE_WEBSOCKETS
 | 
			
		||||
  else {
 | 
			
		||||
    wsc->text(obuf, olen);
 | 
			
		||||
  }
 | 
			
		||||
  #endif
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,7 +3,6 @@
 | 
			
		|||
/*
 | 
			
		||||
 * LED methods
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void setValuesFromMainSeg()
 | 
			
		||||
{
 | 
			
		||||
  WS2812FX::Segment& seg = strip.getSegment(strip.getMainSegmentId());
 | 
			
		||||
| 
						 | 
				
			
			@ -167,6 +166,7 @@ void colorUpdated(int callMode)
 | 
			
		|||
 | 
			
		||||
void updateInterfaces(uint8_t callMode)
 | 
			
		||||
{
 | 
			
		||||
  sendDataWs();
 | 
			
		||||
  #ifndef WLED_DISABLE_ALEXA
 | 
			
		||||
  if (espalexaDevice != nullptr && callMode != NOTIFIER_CALL_MODE_ALEXA) {
 | 
			
		||||
    espalexaDevice->setValue(bri);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,8 +14,11 @@ WLED::WLED()
 | 
			
		|||
void WLED::reset()
 | 
			
		||||
{
 | 
			
		||||
  briT = 0;
 | 
			
		||||
  #ifdef WLED_ENABLE_WEBSOCKETS
 | 
			
		||||
  ws.closeAll(1012);
 | 
			
		||||
  #endif
 | 
			
		||||
  long dly = millis();
 | 
			
		||||
  while (millis() - dly < 250) {
 | 
			
		||||
  while (millis() - dly < 450) {
 | 
			
		||||
    yield();        // enough time to send response to client
 | 
			
		||||
  }
 | 
			
		||||
  setAllLeds();
 | 
			
		||||
| 
						 | 
				
			
			@ -94,7 +97,8 @@ void WLED::loop()
 | 
			
		|||
    if (lastMqttReconnectAttempt > millis()) rolloverMillis++; //millis() rolls over every 50 days
 | 
			
		||||
    initMqtt();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  yield();
 | 
			
		||||
  handleWs();
 | 
			
		||||
 | 
			
		||||
// DEBUG serial logging
 | 
			
		||||
#ifdef WLED_DEBUG
 | 
			
		||||
| 
						 | 
				
			
			@ -283,6 +287,10 @@ void WLED::initAP(bool resetAP)
 | 
			
		|||
 | 
			
		||||
void WLED::initConnection()
 | 
			
		||||
{
 | 
			
		||||
  #ifdef WLED_ENABLE_WEBSOCKETS
 | 
			
		||||
  ws.onEvent(wsEvent);
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
  WiFi.disconnect(true);        // close old connections
 | 
			
		||||
#ifdef ESP8266
 | 
			
		||||
  WiFi.setPhyMode(WIFI_PHY_MODE_11N);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
// version code in format yymmddb (b = daily build)
 | 
			
		||||
#define VERSION 2006220
 | 
			
		||||
#define VERSION 2006260
 | 
			
		||||
 | 
			
		||||
// ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS).
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +30,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
#define WLED_ENABLE_ADALIGHT       // saves 500b only
 | 
			
		||||
//#define WLED_ENABLE_DMX          // uses 3.5kb (use LEDPIN other than 2)
 | 
			
		||||
#define WLED_ENABLE_WEBSOCKETS
 | 
			
		||||
 | 
			
		||||
#define WLED_DISABLE_FILESYSTEM        // SPIFFS is not used by any WLED feature yet
 | 
			
		||||
//#define WLED_ENABLE_FS_SERVING   // Enable sending html file from SPIFFS before serving progmem version
 | 
			
		||||
| 
						 | 
				
			
			@ -480,6 +481,9 @@ WLED_GLOBAL bool doPublishMqtt _INIT(false);
 | 
			
		|||
 | 
			
		||||
// server library objects
 | 
			
		||||
WLED_GLOBAL AsyncWebServer server _INIT_N(((80)));
 | 
			
		||||
#ifdef WLED_ENABLE_WEBSOCKETS
 | 
			
		||||
WLED_GLOBAL AsyncWebSocket ws _INIT_N((("/ws")));
 | 
			
		||||
#endif
 | 
			
		||||
WLED_GLOBAL AsyncClient* hueClient _INIT(NULL);
 | 
			
		||||
WLED_GLOBAL AsyncMqttClient* mqtt _INIT(NULL);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -205,10 +205,10 @@ void initServer()
 | 
			
		|||
  } else
 | 
			
		||||
  {
 | 
			
		||||
    server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){
 | 
			
		||||
      serveMessage(request, 500, "Access Denied", "Please unlock OTA in security settings!", 254);
 | 
			
		||||
      serveMessage(request, 500, "Access Denied", F("Please unlock OTA in security settings!"), 254);
 | 
			
		||||
    });
 | 
			
		||||
    server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
 | 
			
		||||
      serveMessage(request, 500, "Access Denied", "Please unlock OTA in security settings!", 254);
 | 
			
		||||
      serveMessage(request, 500, "Access Denied", F("Please unlock OTA in security settings!"), 254);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -226,6 +226,10 @@ void initServer()
 | 
			
		|||
    if (captivePortal(request)) return;
 | 
			
		||||
    serveIndexOrWelcome(request);
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  #ifdef WLED_ENABLE_WEBSOCKETS
 | 
			
		||||
  server.addHandler(&ws);
 | 
			
		||||
  #endif
 | 
			
		||||
  
 | 
			
		||||
  //called when the url is not defined here, ajax-in; get-settings
 | 
			
		||||
  server.onNotFound([](AsyncWebServerRequest *request){
 | 
			
		||||
| 
						 | 
				
			
			@ -374,7 +378,7 @@ void serveSettings(AsyncWebServerRequest* request)
 | 
			
		|||
 | 
			
		||||
  if (subPage == 1 && wifiLock && otaLock)
 | 
			
		||||
  {
 | 
			
		||||
    serveMessage(request, 500, "Access Denied", "Please unlock OTA in security settings!", 254); return;
 | 
			
		||||
    serveMessage(request, 500, "Access Denied", F("Please unlock OTA in security settings!"), 254); return;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  #ifdef WLED_DISABLE_MOBILE_UI //disable welcome page if not enough storage
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,114 @@
 | 
			
		|||
#include "wled.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * WebSockets server for bidirectional communication
 | 
			
		||||
 */
 | 
			
		||||
#ifdef WLED_ENABLE_WEBSOCKETS
 | 
			
		||||
 | 
			
		||||
uint16_t wsLiveClientId = 0;
 | 
			
		||||
unsigned long wsLastLiveTime = 0;
 | 
			
		||||
//uint8_t* wsFrameBuffer = nullptr;
 | 
			
		||||
 | 
			
		||||
#define WS_LIVE_INTERVAL 40
 | 
			
		||||
 | 
			
		||||
void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len)
 | 
			
		||||
{
 | 
			
		||||
  if(type == WS_EVT_CONNECT){
 | 
			
		||||
    //client connected
 | 
			
		||||
    sendDataWs(client);
 | 
			
		||||
    //client->ping();
 | 
			
		||||
  } else if(type == WS_EVT_DISCONNECT){
 | 
			
		||||
    //client disconnected
 | 
			
		||||
    if (client->id() == wsLiveClientId) wsLiveClientId = 0;
 | 
			
		||||
  } else if(type == WS_EVT_DATA){
 | 
			
		||||
    //data packet
 | 
			
		||||
    AwsFrameInfo * info = (AwsFrameInfo*)arg;
 | 
			
		||||
    if(info->final && info->index == 0 && info->len == len){
 | 
			
		||||
      //the whole message is in a single frame and we got all of it's data (max. 1450byte)
 | 
			
		||||
      if(info->opcode == WS_TEXT)
 | 
			
		||||
      {
 | 
			
		||||
        bool verboseResponse = false;
 | 
			
		||||
        { //scope JsonDocument so it releases its buffer
 | 
			
		||||
          DynamicJsonDocument jsonBuffer(8192);
 | 
			
		||||
          DeserializationError error = deserializeJson(jsonBuffer, data, len);
 | 
			
		||||
          JsonObject root = jsonBuffer.as<JsonObject>();
 | 
			
		||||
          if (error || root.isNull()) return;
 | 
			
		||||
 | 
			
		||||
          if (root.containsKey("lv"))
 | 
			
		||||
          {
 | 
			
		||||
            wsLiveClientId = root["lv"] ? client->id() : 0;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          verboseResponse = deserializeState(root);
 | 
			
		||||
        }
 | 
			
		||||
        if (verboseResponse || millis() - lastInterfaceUpdate < 1900) sendDataWs(client); //update if it takes longer than 100ms until next "broadcast"
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      //message is comprised of multiple frames or the frame is split into multiple packets
 | 
			
		||||
      //if(info->index == 0){
 | 
			
		||||
        //if (!wsFrameBuffer && len < 4096) wsFrameBuffer = new uint8_t[4096];
 | 
			
		||||
      //}
 | 
			
		||||
 | 
			
		||||
      //if (wsFrameBuffer && len < 4096 && info->index + info->)
 | 
			
		||||
      //{
 | 
			
		||||
 | 
			
		||||
      //}
 | 
			
		||||
 | 
			
		||||
      if((info->index + len) == info->len){
 | 
			
		||||
        if(info->final){
 | 
			
		||||
          if(info->message_opcode == WS_TEXT) {
 | 
			
		||||
            client->text("{\"error\":10}"); //we do not handle split packets right now
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else if(type == WS_EVT_ERROR){
 | 
			
		||||
    //error was received from the other end
 | 
			
		||||
 | 
			
		||||
  } else if(type == WS_EVT_PONG){
 | 
			
		||||
    //pong message was received (in response to a ping request maybe)
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sendDataWs(AsyncWebSocketClient * client)
 | 
			
		||||
{
 | 
			
		||||
  if (!ws.count()) return;
 | 
			
		||||
  AsyncWebSocketMessageBuffer * buffer;
 | 
			
		||||
 | 
			
		||||
  { //scope JsonDocument so it releases its buffer
 | 
			
		||||
    DynamicJsonDocument doc(8192);
 | 
			
		||||
    JsonObject state = doc.createNestedObject("state");
 | 
			
		||||
    serializeState(state);
 | 
			
		||||
    JsonObject info  = doc.createNestedObject("info");
 | 
			
		||||
    serializeInfo(info);
 | 
			
		||||
    size_t len = measureJson(doc);
 | 
			
		||||
    buffer = ws.makeBuffer(len);
 | 
			
		||||
    if (!buffer) return; //out of memory
 | 
			
		||||
 | 
			
		||||
    serializeJson(doc, (char *)buffer->get(), len +1);
 | 
			
		||||
  } 
 | 
			
		||||
  if (client) {
 | 
			
		||||
    client->text(buffer);
 | 
			
		||||
  } else {
 | 
			
		||||
    ws.textAll(buffer);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void handleWs()
 | 
			
		||||
{
 | 
			
		||||
  if (millis() - wsLastLiveTime > WS_LIVE_INTERVAL)
 | 
			
		||||
  {
 | 
			
		||||
    ws.cleanupClients();
 | 
			
		||||
    bool success = true;
 | 
			
		||||
    if (wsLiveClientId)
 | 
			
		||||
      success = serveLiveLeds(nullptr, wsLiveClientId);
 | 
			
		||||
    wsLastLiveTime = millis();
 | 
			
		||||
    if (!success) wsLastLiveTime -= 20; //try again in 20ms if failed due to non-empty WS queue
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
void handleWs() {}
 | 
			
		||||
void sendDataWs(AsyncWebSocketClient * client) {}
 | 
			
		||||
#endif
 | 
			
		||||
		Ładowanie…
	
		Reference in New Issue