#include "wled.h" /* * Sending XML status files to client */ //build XML response to HTTP /win API request void XML_response(AsyncWebServerRequest *request, char* dest) { char sbuf[(dest == nullptr)?1024:1]; //allocate local buffer if none passed obuf = (dest == nullptr)? sbuf:dest; olen = 0; oappend((const char*)F("")); oappendi((nightlightActive && nightlightMode > NL_MODE_SET) ? briT : bri); oappend(""); for (int i = 0; i < 3; i++) { oappend(""); oappendi(col[i]); oappend(""); } for (int i = 0; i < 3; i++) { oappend(""); oappendi(colSec[i]); oappend(""); } oappend(""); oappendi(notifyDirect); oappend(""); oappendi(receiveNotifications); oappend(""); oappendi(nightlightActive); oappend(""); oappendi(nightlightMode > NL_MODE_SET); oappend(""); oappendi(nightlightDelayMins); oappend(""); oappendi(nightlightTargetBri); oappend(""); oappendi(effectCurrent); oappend(""); oappendi(effectSpeed); oappend(""); oappendi(effectIntensity); oappend(""); oappendi(effectPalette); oappend(""); if (strip.rgbwMode) { oappendi(col[3]); } else { oappend("-1"); } oappend(""); oappendi(colSec[3]); oappend(""); oappendi((currentPreset < 1) ? 0:currentPreset); oappend(""); oappendi(presetCyclingEnabled); oappend(""); if (realtimeMode) { String mesg = "Live "; if (realtimeMode == REALTIME_MODE_E131 || realtimeMode == REALTIME_MODE_ARTNET) { mesg += (realtimeMode == REALTIME_MODE_E131) ? "E1.31" : "Art-Net"; mesg += " mode "; mesg += DMXMode; mesg += F(" at DMX Address "); mesg += DMXAddress; mesg += " from "; mesg += realtimeIP[0]; for (int i = 1; i < 4; i++) { mesg += "."; mesg += realtimeIP[i]; } } else if (realtimeMode == REALTIME_MODE_UDP || realtimeMode == REALTIME_MODE_HYPERION || realtimeMode == REALTIME_MODE_TPM2NET) { mesg += "UDP from "; mesg += realtimeIP[0]; for (int i = 1; i < 4; i++) { mesg += "."; mesg += realtimeIP[i]; } } else if (realtimeMode == REALTIME_MODE_ADALIGHT) { mesg += F("USB Adalight"); } else { //generic mesg += "data"; } oappend((char*)mesg.c_str()); } else { oappend(serverDescription); } oappend(""); oappendi(strip.getMainSegmentId()); oappend(""); if (request != nullptr) request->send(200, "text/xml", obuf); } void URL_response(AsyncWebServerRequest *request) { char sbuf[256]; char s2buf[100]; obuf = s2buf; olen = 0; char s[16]; oappend("http://"); IPAddress localIP = WiFi.localIP(); sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]); oappend(s); oappend("/win&A="); oappendi(bri); oappend("&CL=h"); for (int i = 0; i < 3; i++) { sprintf(s,"%02X", col[i]); oappend(s); } oappend("&C2=h"); for (int i = 0; i < 3; i++) { sprintf(s,"%02X", colSec[i]); oappend(s); } oappend("&FX="); oappendi(effectCurrent); oappend("&SX="); oappendi(effectSpeed); oappend("&IX="); oappendi(effectIntensity); oappend("&FP="); oappendi(effectPalette); obuf = sbuf; olen = 0; oappend((const char*)F("")); oappend(s2buf); oappend((const char*)F("")); if (request != nullptr) request->send(200, "text/html", obuf); } //append a numeric setting to string buffer void sappend(char stype, const char* key, int val) { char ds[] = "d.Sf."; switch(stype) { case 'c': //checkbox oappend(ds); oappend(key); oappend(".checked="); oappendi(val); oappend(";"); break; case 'v': //numeric oappend(ds); oappend(key); oappend(".value="); oappendi(val); oappend(";"); break; case 'i': //selectedIndex oappend(ds); oappend(key); oappend(".selectedIndex="); oappendi(val); oappend(";"); break; } } //append a string setting to buffer void sappends(char stype, const char* key, char* val) { switch(stype) { case 's': //string (we can interpret val as char*) oappend("d.Sf."); oappend(key); oappend(".value=\""); oappend(val); oappend("\";"); break; case 'm': //message oappend("d.getElementsByClassName"); oappend(key); oappend(".innerHTML=\""); oappend(val); oappend("\";"); break; } } //get values for settings form in javascript void getSettingsJS(byte subPage, char* dest) { //0: menu 1: wifi 2: leds 3: ui 4: sync 5: time 6: sec DEBUG_PRINT("settings resp"); DEBUG_PRINTLN(subPage); obuf = dest; olen = 0; if (subPage <1 || subPage >7) return; if (subPage == 1) { sappends('s',"CS",clientSSID); byte l = strlen(clientPass); char fpass[l+1]; //fill password field with *** fpass[l] = 0; memset(fpass,'*',l); sappends('s',"CP",fpass); char k[3]; k[2] = 0; //IP addresses for (int i = 0; i<4; i++) { k[1] = 48+i; //ascii 0,1,2,3 k[0] = 'I'; sappend('v',k,staticIP[i]); k[0] = 'G'; sappend('v',k,staticGateway[i]); k[0] = 'S'; sappend('v',k,staticSubnet[i]); } sappends('s',"CM",cmDNS); sappend('i',"AB",apBehavior); sappends('s',"AS",apSSID); sappend('c',"AH",apHide); l = strlen(apPass); char fapass[l+1]; //fill password field with *** fapass[l] = 0; memset(fapass,'*',l); sappends('s',"AP",fapass); sappend('v',"AC",apChannel); sappend('c',"WS",noWifiSleep); if (WiFi.localIP()[0] != 0) //is connected { char s[16]; IPAddress localIP = WiFi.localIP(); sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]); sappends('m',"(\"sip\")[0]",s); } else { sappends('m',"(\"sip\")[0]","Not connected"); } if (WiFi.softAPIP()[0] != 0) //is active { char s[16]; IPAddress apIP = WiFi.softAPIP(); sprintf(s, "%d.%d.%d.%d", apIP[0], apIP[1], apIP[2], apIP[3]); sappends('m',"(\"sip\")[1]",s); } else { sappends('m',"(\"sip\")[1]","Not active"); } } if (subPage == 2) { #ifdef ESP8266 #if LEDPIN == 3 oappend("d.Sf.LC.max=500;"); #endif #endif sappend('v',"LC",ledCount); sappend('v',"MA",strip.ablMilliampsMax); sappend('v',"LA",strip.milliampsPerLed); if (strip.currentMilliamps) { sappends('m',"(\"pow\")[0]",""); olen -= 2; //delete "; oappendi(strip.currentMilliamps); oappend("mA\";"); } sappend('v',"CA",briS); sappend('c',"EW",useRGBW); sappend('i',"CO",strip.colorOrder); sappend('v',"AW",strip.rgbwMode); sappend('c',"BO",turnOnAtBoot); sappend('v',"BP",bootPreset); sappend('c',"GB",strip.gammaCorrectBri); sappend('c',"GC",strip.gammaCorrectCol); sappend('c',"TF",fadeTransition); sappend('v',"TD",transitionDelayDefault); sappend('c',"PF",strip.paletteFade); sappend('v',"BF",briMultiplier); sappend('v',"TB",nightlightTargetBri); sappend('v',"TL",nightlightDelayMinsDefault); sappend('v',"TW",nightlightMode); sappend('i',"PB",strip.paletteBlend); sappend('c',"RV",strip.reverseMode); sappend('c',"SL",skipFirstLed); } if (subPage == 3) { sappends('s',"DS",serverDescription); sappend('c',"ST",syncToggleReceive); } if (subPage == 4) { sappend('c',"BT",buttonEnabled); sappend('v',"IR",irEnabled); sappend('v',"UP",udpPort); sappend('c',"RB",receiveNotificationBrightness); sappend('c',"RC",receiveNotificationColor); sappend('c',"RX",receiveNotificationEffects); sappend('c',"SD",notifyDirectDefault); sappend('c',"SB",notifyButton); sappend('c',"SH",notifyHue); sappend('c',"SM",notifyMacro); sappend('c',"S2",notifyTwice); sappend('c',"RD",receiveDirect); sappend('v',"EP",e131Port); sappend('c',"ES",e131SkipOutOfSequence); sappend('c',"EM",e131Multicast); sappend('v',"EU",e131Universe); sappend('v',"DA",DMXAddress); sappend('v',"DM",DMXMode); sappend('v',"ET",realtimeTimeoutMs); sappend('c',"FB",arlsForceMaxBri); sappend('c',"RG",arlsDisableGammaCorrection); sappend('v',"WO",arlsOffset); sappend('c',"AL",alexaEnabled); sappends('s',"AI",alexaInvocationName); sappend('c',"SA",notifyAlexa); sappends('s',"BK",(char*)((blynkEnabled)?"Hidden":"")); #ifdef WLED_ENABLE_MQTT sappend('c',"MQ",mqttEnabled); sappends('s',"MS",mqttServer); sappend('v',"MQPORT",mqttPort); sappends('s',"MQUSER",mqttUser); sappends('s',"MQPASS",mqttPass); byte l = strlen(mqttPass); char fpass[l+1]; //fill password field with *** fpass[l] = 0; memset(fpass,'*',l); sappends('s',"MQPASS",fpass); sappends('s',"MQCID",mqttClientID); sappends('s',"MD",mqttDeviceTopic); sappends('s',"MG",mqttGroupTopic); #endif #ifndef WLED_DISABLE_HUESYNC sappend('v',"H0",hueIP[0]); sappend('v',"H1",hueIP[1]); sappend('v',"H2",hueIP[2]); sappend('v',"H3",hueIP[3]); sappend('v',"HL",huePollLightId); sappend('v',"HI",huePollIntervalMs); sappend('c',"HP",huePollingEnabled); sappend('c',"HO",hueApplyOnOff); sappend('c',"HB",hueApplyBri); sappend('c',"HC",hueApplyColor); char hueErrorString[25]; switch (hueError) { case HUE_ERROR_INACTIVE : strcpy(hueErrorString,(char*)F("Inactive")); break; case HUE_ERROR_ACTIVE : strcpy(hueErrorString,(char*)F("Active")); break; case HUE_ERROR_UNAUTHORIZED : strcpy(hueErrorString,(char*)F("Unauthorized")); break; case HUE_ERROR_LIGHTID : strcpy(hueErrorString,(char*)F("Invalid light ID")); break; case HUE_ERROR_PUSHLINK : strcpy(hueErrorString,(char*)F("Link button not pressed")); break; case HUE_ERROR_JSON_PARSING : strcpy(hueErrorString,(char*)F("JSON parsing error")); break; case HUE_ERROR_TIMEOUT : strcpy(hueErrorString,(char*)F("Timeout")); break; default: sprintf(hueErrorString,"Bridge Error %i",hueError); } sappends('m',"(\"sip\")[0]",hueErrorString); #endif } if (subPage == 5) { sappend('c',"NT",ntpEnabled); sappends('s',"NS",ntpServerName); sappend('c',"CF",!useAMPM); sappend('i',"TZ",currentTimezone); sappend('v',"UO",utcOffsetSecs); char tm[32]; getTimeString(tm); sappends('m',"(\"times\")[0]",tm); sappend('i',"OL",overlayCurrent); sappend('v',"O1",overlayMin); sappend('v',"O2",overlayMax); sappend('v',"OM",analogClock12pixel); sappend('c',"OS",analogClockSecondsTrail); sappend('c',"O5",analogClock5MinuteMarks); sappends('s',"CX",cronixieDisplay); sappend('c',"CB",cronixieBacklight); sappend('c',"CE",countdownMode); sappend('v',"CY",countdownYear); sappend('v',"CI",countdownMonth); sappend('v',"CD",countdownDay); sappend('v',"CH",countdownHour); sappend('v',"CM",countdownMin); sappend('v',"CS",countdownSec); char k[4]; k[0]= 'M'; for (int i=1;i<17;i++) { char m[65]; loadMacro(i, m); sprintf(k+1,"%i",i); sappends('s',k,m); } sappend('v',"MB",macroBoot); sappend('v',"A0",macroAlexaOn); sappend('v',"A1",macroAlexaOff); sappend('v',"MP",macroButton); sappend('v',"ML",macroLongPress); sappend('v',"MC",macroCountdown); sappend('v',"MN",macroNl); sappend('v',"MD",macroDoublePress); k[2] = 0; //Time macros for (int i = 0; i<8; i++) { k[1] = 48+i; //ascii 0,1,2,3 k[0] = 'H'; sappend('v',k,timerHours[i]); k[0] = 'N'; sappend('v',k,timerMinutes[i]); k[0] = 'T'; sappend('v',k,timerMacro[i]); k[0] = 'W'; sappend('v',k,timerWeekday[i]); } } if (subPage == 6) { sappend('c',"NO",otaLock); sappend('c',"OW",wifiLock); sappend('c',"AO",aOtaEnabled); sappends('m',"(\"sip\")[0]","WLED "); olen -= 2; //delete "; oappend(versionString); oappend(" (build "); oappendi(VERSION); oappend(")\";"); } #ifdef WLED_ENABLE_DMX // include only if DMX is enabled if (subPage == 7) { sappend('v',"PU",e131ProxyUniverse); sappend('v',"CN",DMXChannels); sappend('v',"CG",DMXGap); sappend('v',"CS",DMXStart); sappend('v',"SL",DMXStartLED); sappend('i',"CH1",DMXFixtureMap[0]); sappend('i',"CH2",DMXFixtureMap[1]); sappend('i',"CH3",DMXFixtureMap[2]); sappend('i',"CH4",DMXFixtureMap[3]); sappend('i',"CH5",DMXFixtureMap[4]); sappend('i',"CH6",DMXFixtureMap[5]); sappend('i',"CH7",DMXFixtureMap[6]); sappend('i',"CH8",DMXFixtureMap[7]); sappend('i',"CH9",DMXFixtureMap[8]); sappend('i',"CH10",DMXFixtureMap[9]); sappend('i',"CH11",DMXFixtureMap[10]); sappend('i',"CH12",DMXFixtureMap[11]); sappend('i',"CH13",DMXFixtureMap[12]); sappend('i',"CH14",DMXFixtureMap[13]); sappend('i',"CH15",DMXFixtureMap[14]); } #endif oappend("}"); }