mirror of
				https://github.com/s00500/ESPUI.git
				synced 2025-11-04 04:13:23 +00:00 
			
		
		
		
	Merge branch 'master' into lambda-with-examples
This commit is contained in:
		
							
								
								
									
										15
									
								
								src/ESPUI.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/ESPUI.h
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
// comment out to turn off debug output
 | 
			
		||||
#define DEBUG_ESPUI true
 | 
			
		||||
// #define DEBUG_ESPUI true
 | 
			
		||||
#define WS_AUTHENTICATION false
 | 
			
		||||
 | 
			
		||||
#include <Arduino.h>
 | 
			
		||||
@@ -87,16 +87,13 @@ enum Verbosity : uint8_t
 | 
			
		||||
class ESPUIClass
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
#ifdef ESP32
 | 
			
		||||
    ESPUIClass()
 | 
			
		||||
    {
 | 
			
		||||
#ifdef ESP32
 | 
			
		||||
        ControlsSemaphore = xSemaphoreCreateMutex();
 | 
			
		||||
        xSemaphoreGive(ControlsSemaphore);
 | 
			
		||||
    }
 | 
			
		||||
    SemaphoreHandle_t ControlsSemaphore = NULL;
 | 
			
		||||
#endif // def ESP32
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
    unsigned int jsonUpdateDocumentSize = 2000;
 | 
			
		||||
#ifdef ESP8266
 | 
			
		||||
    unsigned int jsonInitialDocumentSize = 2000;
 | 
			
		||||
@@ -196,7 +193,6 @@ public:
 | 
			
		||||
    void jsonDom(uint16_t startidx, AsyncWebSocketClient* client = nullptr, bool Updating = false);
 | 
			
		||||
 | 
			
		||||
    Verbosity verbosity = Verbosity::Quiet;
 | 
			
		||||
    AsyncWebServer* server;
 | 
			
		||||
 | 
			
		||||
    // emulate former extended callback API by using an intermediate lambda (no deprecation)
 | 
			
		||||
    uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, std::function<void(Control*, int, void*)> callback, void* userData)
 | 
			
		||||
@@ -240,8 +236,13 @@ protected:
 | 
			
		||||
    friend class ESPUIclient;
 | 
			
		||||
    friend class ESPUIcontrol;
 | 
			
		||||
 | 
			
		||||
#ifdef ESP32
 | 
			
		||||
    SemaphoreHandle_t ControlsSemaphore = NULL;
 | 
			
		||||
#endif // def ESP32
 | 
			
		||||
 | 
			
		||||
    void        RemoveToBeDeletedControls();
 | 
			
		||||
 | 
			
		||||
    AsyncWebServer* server;
 | 
			
		||||
    AsyncWebSocket* ws;
 | 
			
		||||
 | 
			
		||||
    const char* basicAuthUsername = nullptr;
 | 
			
		||||
 
 | 
			
		||||
@@ -229,7 +229,21 @@ void ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
 | 
			
		||||
            if (cmd.equals(F("uiok")))
 | 
			
		||||
            {
 | 
			
		||||
                // Serial.println(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:ProcessAck"));
 | 
			
		||||
                pCurrentFsmState->ProcessAck(id);
 | 
			
		||||
                pCurrentFsmState->ProcessAck(id, emptyString);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (cmd.equals(F("uifragmentok")))
 | 
			
		||||
            {
 | 
			
		||||
                if(!emptyString.equals(value))
 | 
			
		||||
                {
 | 
			
		||||
                    // Serial.println(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uifragmentok:ProcessAck:value: '")) + value + "'");
 | 
			
		||||
                    pCurrentFsmState->ProcessAck(uint16_t(-1), value);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    // Serial.println(F("ERROR:ESPUIclient::OnWsEvent:WS_EVT_DATA:uifragmentok:ProcessAck:Fragment Header is missing"));
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -269,7 +283,8 @@ client will acknowledge receipt by requesting the next chunk.
 | 
			
		||||
 */
 | 
			
		||||
uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
			
		||||
                                      DynamicJsonDocument & rootDoc,
 | 
			
		||||
                                      bool InUpdateMode)
 | 
			
		||||
                                      bool InUpdateMode,
 | 
			
		||||
                                      String FragmentRequestString)
 | 
			
		||||
{
 | 
			
		||||
#ifdef ESP32
 | 
			
		||||
    xSemaphoreTake(ESPUI.ControlsSemaphore, portMAX_DELAY);
 | 
			
		||||
@@ -283,8 +298,61 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
			
		||||
        // Follow the list until control points to the startindex'th node
 | 
			
		||||
        Control* control = ESPUI.controls;
 | 
			
		||||
        uint32_t currentIndex = 0;
 | 
			
		||||
        uint32_t DataOffset = 0;
 | 
			
		||||
        JsonArray items = rootDoc[F("controls")];
 | 
			
		||||
        bool SingleControl = false;
 | 
			
		||||
 | 
			
		||||
        if(!emptyString.equals(FragmentRequestString))
 | 
			
		||||
        {
 | 
			
		||||
            // Serial.println(F("prepareJSONChunk:Fragmentation:Got Header (1)"));
 | 
			
		||||
            // Serial.println(String("prepareJSONChunk:startindex:                  ") + String(startindex));
 | 
			
		||||
            // Serial.println(String("prepareJSONChunk:currentIndex:                ") + String(currentIndex));
 | 
			
		||||
            // Serial.println(String("prepareJSONChunk:FragmentRequestString:      '") + FragmentRequestString + "'");
 | 
			
		||||
 | 
			
		||||
            // this is actually a fragment or directed update request
 | 
			
		||||
            // parse the string we got from the UI and try to update that specific 
 | 
			
		||||
            // control.
 | 
			
		||||
            DynamicJsonDocument FragmentRequest(FragmentRequestString.length() * 3);
 | 
			
		||||
            if(0 >= FragmentRequest.capacity())
 | 
			
		||||
            {
 | 
			
		||||
                Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Could not allocate memory for a fragmentation request. Skipping Response"));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            size_t FragmentRequestStartOffset = FragmentRequestString.indexOf("{");
 | 
			
		||||
            DeserializationError error = deserializeJson(FragmentRequest, FragmentRequestString.substring(FragmentRequestStartOffset));
 | 
			
		||||
            if(DeserializationError::Ok != error)
 | 
			
		||||
            {
 | 
			
		||||
                Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Could not extract json from the fragment request"));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(!FragmentRequest.containsKey(F("id")))
 | 
			
		||||
            {
 | 
			
		||||
                Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Request does not contain a control ID"));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            uint16_t ControlId = uint16_t(FragmentRequest[F("id")]);
 | 
			
		||||
 | 
			
		||||
            if(!FragmentRequest.containsKey(F("offset")))
 | 
			
		||||
            {
 | 
			
		||||
                Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Request does not contain a starting offset"));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            DataOffset = uint16_t(FragmentRequest[F("offset")]);
 | 
			
		||||
            control = ESPUI.getControlNoLock(ControlId);
 | 
			
		||||
            if(nullptr == control)
 | 
			
		||||
            {
 | 
			
		||||
                Serial.println(String(F("ERROR:prepareJSONChunk:Fragmentation:Requested control: ")) + String(ControlId) + F(" does not exist"));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Serial.println(F("prepareJSONChunk:Fragmentation:disable the control search operation"));
 | 
			
		||||
            currentIndex = 1;
 | 
			
		||||
            startindex = 0;
 | 
			
		||||
            SingleControl = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // find a control to send
 | 
			
		||||
        while ((startindex > currentIndex) && (nullptr != control))
 | 
			
		||||
        {
 | 
			
		||||
            // only count active controls
 | 
			
		||||
@@ -320,14 +388,14 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
			
		||||
        while (nullptr != control)
 | 
			
		||||
        {
 | 
			
		||||
            // skip deleted controls or controls that have not been updated
 | 
			
		||||
            if (control->ToBeDeleted())
 | 
			
		||||
            if (control->ToBeDeleted() && !SingleControl)
 | 
			
		||||
            {
 | 
			
		||||
                // Serial.println(String("prepareJSONChunk: Ignoring Deleted control: ") + String(control->id));
 | 
			
		||||
                control = control->next;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(InUpdateMode)
 | 
			
		||||
            if(InUpdateMode && !SingleControl)
 | 
			
		||||
            {
 | 
			
		||||
                if(control->IsUpdated())
 | 
			
		||||
                {
 | 
			
		||||
@@ -343,7 +411,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
			
		||||
 | 
			
		||||
            JsonObject item = items.createNestedObject();
 | 
			
		||||
            elementcount++;
 | 
			
		||||
            control->MarshalControl(item, InUpdateMode);
 | 
			
		||||
            control->MarshalControl(item, InUpdateMode, DataOffset);
 | 
			
		||||
            
 | 
			
		||||
            if (rootDoc.overflowed() || (ESPUI.jsonChunkNumberMax > 0 && (elementcount % ESPUI.jsonChunkNumberMax) == 0))
 | 
			
		||||
            {
 | 
			
		||||
@@ -351,6 +419,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
			
		||||
                if (1 == elementcount)
 | 
			
		||||
                {
 | 
			
		||||
                    Serial.println(String(F("ERROR: prepareJSONChunk: Control ")) + String(control->id) + F(" is too large to be sent to the browser."));
 | 
			
		||||
                    // Serial.println(String(F("ERROR: prepareJSONChunk: value: ")) + control->value);
 | 
			
		||||
                    rootDoc.clear();
 | 
			
		||||
                    item = items.createNestedObject();
 | 
			
		||||
                    control->MarshalErrorMessage(item);
 | 
			
		||||
@@ -366,7 +435,11 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
			
		||||
                }
 | 
			
		||||
                // exit the loop
 | 
			
		||||
                control = nullptr;
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            else if (SingleControl)
 | 
			
		||||
            {
 | 
			
		||||
                // Serial.println("prepareJSONChunk: exit loop");
 | 
			
		||||
                control = nullptr;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
@@ -404,8 +477,7 @@ CLIENT: controls.js:handleEvent()
 | 
			
		||||
etc.
 | 
			
		||||
    Returns true if all controls have been sent (aka: Done)
 | 
			
		||||
*/
 | 
			
		||||
bool ESPUIclient::SendControlsToClient(uint16_t startidx,
 | 
			
		||||
                                       ClientUpdateType_t TransferMode)
 | 
			
		||||
bool ESPUIclient::SendControlsToClient(uint16_t startidx, ClientUpdateType_t TransferMode, String FragmentRequest)
 | 
			
		||||
{
 | 
			
		||||
    bool Response = false;
 | 
			
		||||
    // Serial.println(String("ESPUIclient:SendControlsToClient:startidx: ") + String(startidx));
 | 
			
		||||
@@ -417,9 +489,9 @@ bool ESPUIclient::SendControlsToClient(uint16_t startidx,
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (startidx >= ESPUI.controlCount)
 | 
			
		||||
        else if ((startidx >= ESPUI.controlCount) && (emptyString.equals(FragmentRequest)))
 | 
			
		||||
        {
 | 
			
		||||
            // Serial.println("ESPUIclient:SendControlsToClient: No more controls to send.");
 | 
			
		||||
            // Serial.println(F("ERROR:ESPUIclient:SendControlsToClient: No more controls to send."));
 | 
			
		||||
            Response = true;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
@@ -427,7 +499,7 @@ bool ESPUIclient::SendControlsToClient(uint16_t startidx,
 | 
			
		||||
        DynamicJsonDocument document(ESPUI.jsonInitialDocumentSize);
 | 
			
		||||
        FillInHeader(document);
 | 
			
		||||
        document[F("startindex")] = startidx;
 | 
			
		||||
        document[F("totalcontrols")] = 65534; // ESPUI.controlCount;
 | 
			
		||||
        document[F("totalcontrols")] = uint16_t(-1); // ESPUI.controlCount;
 | 
			
		||||
 | 
			
		||||
        if(0 == startidx)
 | 
			
		||||
        {
 | 
			
		||||
@@ -437,7 +509,7 @@ bool ESPUIclient::SendControlsToClient(uint16_t startidx,
 | 
			
		||||
        // Serial.println(String("ESPUIclient:SendControlsToClient:type: ") + String((uint32_t)document["type"]));
 | 
			
		||||
 | 
			
		||||
        // Serial.println("ESPUIclient:SendControlsToClient: Build Controls.");
 | 
			
		||||
        if(prepareJSONChunk(startidx, document, ClientUpdateType_t::UpdateNeeded == TransferMode))
 | 
			
		||||
        if(prepareJSONChunk(startidx, document, ClientUpdateType_t::UpdateNeeded == TransferMode, FragmentRequest))
 | 
			
		||||
        {
 | 
			
		||||
            #if defined(DEBUG_ESPUI)
 | 
			
		||||
                if (ESPUI.verbosity >= Verbosity::VerboseJSON)
 | 
			
		||||
 
 | 
			
		||||
@@ -44,8 +44,8 @@ protected:
 | 
			
		||||
 | 
			
		||||
    bool        CanSend();
 | 
			
		||||
    void        FillInHeader(ArduinoJson::DynamicJsonDocument& document);
 | 
			
		||||
    uint32_t    prepareJSONChunk(uint16_t startindex, DynamicJsonDocument& rootDoc, bool InUpdateMode);
 | 
			
		||||
    bool        SendControlsToClient(uint16_t startidx, ClientUpdateType_t TransferMode);
 | 
			
		||||
    uint32_t    prepareJSONChunk(uint16_t startindex, DynamicJsonDocument& rootDoc, bool InUpdateMode, String value);
 | 
			
		||||
    bool        SendControlsToClient(uint16_t startidx, ClientUpdateType_t TransferMode, String FragmentRequest);
 | 
			
		||||
 | 
			
		||||
    bool        SendClientNotification(ClientUpdateType_t value);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -58,12 +58,20 @@ bool fsm_EspuiClient_state_Idle::NotifyClient()
 | 
			
		||||
    return Response;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fsm_EspuiClient_state_Idle::ProcessAck(uint16_t)
 | 
			
		||||
void fsm_EspuiClient_state_Idle::ProcessAck(uint16_t ControlIndex, String FragmentRequestString)
 | 
			
		||||
{
 | 
			
		||||
    // This is an unexpected request for control data from the browser
 | 
			
		||||
    // treat it as if it was a rebuild operation
 | 
			
		||||
    // Serial.println(F("fsm_EspuiClient_state_Idle: ProcessAck"));
 | 
			
		||||
    Parent->NotifyClient(ClientUpdateType_t::RebuildNeeded);
 | 
			
		||||
    if(!emptyString.equals(FragmentRequestString))
 | 
			
		||||
    {
 | 
			
		||||
        // Serial.println(F("fsm_EspuiClient_state_Idle::ProcessAck:Fragmentation:Got fragment Header"));
 | 
			
		||||
        Parent->SendControlsToClient(ControlIndex, ClientUpdateType_t::UpdateNeeded, FragmentRequestString);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // This is an unexpected request for control data from the browser
 | 
			
		||||
        // treat it as if it was a rebuild operation
 | 
			
		||||
        // Serial.println(F("fsm_EspuiClient_state_Idle: ProcessAck"));
 | 
			
		||||
        Parent->NotifyClient(ClientUpdateType_t::RebuildNeeded);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------
 | 
			
		||||
@@ -75,10 +83,10 @@ bool fsm_EspuiClient_state_SendingUpdate::NotifyClient()
 | 
			
		||||
    return true; /* Ignore request */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fsm_EspuiClient_state_SendingUpdate::ProcessAck(uint16_t ControlIndex)
 | 
			
		||||
void fsm_EspuiClient_state_SendingUpdate::ProcessAck(uint16_t ControlIndex, String FragmentRequest)
 | 
			
		||||
{
 | 
			
		||||
    // Serial.println(F("fsm_EspuiClient_state_SendingUpdate: ProcessAck"));
 | 
			
		||||
    if(Parent->SendControlsToClient(ControlIndex, ClientUpdateType_t::UpdateNeeded))
 | 
			
		||||
    if(Parent->SendControlsToClient(ControlIndex, ClientUpdateType_t::UpdateNeeded, FragmentRequest))
 | 
			
		||||
    {
 | 
			
		||||
        // No more data to send. Go back to idle or start next request
 | 
			
		||||
        Parent->fsm_EspuiClient_state_Idle_imp.Init();
 | 
			
		||||
@@ -95,13 +103,25 @@ bool fsm_EspuiClient_state_Rebuilding::NotifyClient()
 | 
			
		||||
    return true; /* Ignore request */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fsm_EspuiClient_state_Rebuilding::ProcessAck(uint16_t ControlIndex)
 | 
			
		||||
void fsm_EspuiClient_state_Rebuilding::ProcessAck(uint16_t ControlIndex, String FragmentRequest)
 | 
			
		||||
{
 | 
			
		||||
    // Serial.println(F("fsm_EspuiClient_state_Rebuilding: ProcessAck"));
 | 
			
		||||
    if(Parent->SendControlsToClient(ControlIndex, ClientUpdateType_t::RebuildNeeded))
 | 
			
		||||
    if(Parent->SendControlsToClient(ControlIndex, ClientUpdateType_t::RebuildNeeded, FragmentRequest))
 | 
			
		||||
    {
 | 
			
		||||
        // No more data to send. Go back to idle or start next request
 | 
			
		||||
        Parent->fsm_EspuiClient_state_Idle_imp.Init();
 | 
			
		||||
        Parent->fsm_EspuiClient_state_Idle_imp.NotifyClient();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//----------------------------------------------
 | 
			
		||||
//----------------------------------------------
 | 
			
		||||
//----------------------------------------------
 | 
			
		||||
void fsm_EspuiClient_state_Reloading::ProcessAck(uint16_t ControlIndex, String FragmentRequestString)
 | 
			
		||||
{
 | 
			
		||||
    if(!emptyString.equals(FragmentRequestString))
 | 
			
		||||
    {
 | 
			
		||||
        // Serial.println(F("fsm_EspuiClient_state_Reloading::ProcessAck:Fragmentation:Got fragment Header"));
 | 
			
		||||
        Parent->SendControlsToClient(ControlIndex, ClientUpdateType_t::UpdateNeeded, FragmentRequestString);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ public:
 | 
			
		||||
 | 
			
		||||
            void Init();
 | 
			
		||||
    virtual bool NotifyClient() = 0;
 | 
			
		||||
    virtual void ProcessAck(uint16_t id) = 0;
 | 
			
		||||
    virtual void ProcessAck(uint16_t id, String FragmentRequest) = 0;
 | 
			
		||||
    virtual String GetStateName () = 0;
 | 
			
		||||
            void SetParent(ESPUIclient * value) { Parent = value; }
 | 
			
		||||
 | 
			
		||||
@@ -36,7 +36,7 @@ public:
 | 
			
		||||
    virtual     ~fsm_EspuiClient_state_Idle() {}
 | 
			
		||||
 | 
			
		||||
    virtual bool NotifyClient();
 | 
			
		||||
    virtual void ProcessAck(uint16_t id);
 | 
			
		||||
    virtual void ProcessAck(uint16_t id, String FragmentRequest);
 | 
			
		||||
            String GetStateName() { return String(F("Idle")); }
 | 
			
		||||
 | 
			
		||||
}; // fsm_EspuiClient_state_Idle
 | 
			
		||||
@@ -48,7 +48,7 @@ public:
 | 
			
		||||
    virtual     ~fsm_EspuiClient_state_SendingUpdate() {}
 | 
			
		||||
 | 
			
		||||
    virtual bool NotifyClient();
 | 
			
		||||
    virtual void ProcessAck(uint16_t id);
 | 
			
		||||
    virtual void ProcessAck(uint16_t id, String FragmentRequest);
 | 
			
		||||
            String GetStateName() { return String(F("Sending Update")); }
 | 
			
		||||
 | 
			
		||||
}; // fsm_EspuiClient_state_SendingUpdate
 | 
			
		||||
@@ -60,7 +60,7 @@ public:
 | 
			
		||||
    virtual     ~fsm_EspuiClient_state_Rebuilding() {}
 | 
			
		||||
 | 
			
		||||
    virtual bool NotifyClient();
 | 
			
		||||
    virtual void ProcessAck(uint16_t id);
 | 
			
		||||
    virtual void ProcessAck(uint16_t id, String FragmentRequest);
 | 
			
		||||
            String GetStateName() { return String(F("Sending Rebuild")); }
 | 
			
		||||
 | 
			
		||||
}; // fsm_EspuiClient_state_Rebuilding
 | 
			
		||||
@@ -72,7 +72,7 @@ public:
 | 
			
		||||
    virtual     ~fsm_EspuiClient_state_Reloading() {}
 | 
			
		||||
 | 
			
		||||
    virtual bool NotifyClient() { return false; }
 | 
			
		||||
    virtual void ProcessAck(uint16_t) {}
 | 
			
		||||
    virtual void ProcessAck(uint16_t id, String FragmentRequest);
 | 
			
		||||
            String GetStateName() { return String(F("Reloading")); }
 | 
			
		||||
 | 
			
		||||
}; // fsm_EspuiClient_state_Reloading
 | 
			
		||||
 
 | 
			
		||||
@@ -46,8 +46,43 @@ void Control::DeleteControl()
 | 
			
		||||
    callback = nullptr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Control::MarshalControl(JsonObject & item, bool refresh)
 | 
			
		||||
void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t StartingOffset)
 | 
			
		||||
{
 | 
			
		||||
    JsonObject & item = _item;
 | 
			
		||||
    uint32_t length = value.length();
 | 
			
		||||
    uint32_t maxLength = uint32_t(double(ESPUI.jsonInitialDocumentSize) * 0.75);
 | 
			
		||||
    if((length > maxLength) || StartingOffset)
 | 
			
		||||
    {
 | 
			
		||||
    	/*
 | 
			
		||||
        Serial.println(String("MarshalControl:Start Fragment Processing"));
 | 
			
		||||
        Serial.println(String("MarshalControl:id:                ") + String(id));
 | 
			
		||||
        Serial.println(String("MarshalControl:length:            ") + String(length));
 | 
			
		||||
        Serial.println(String("MarshalControl:StartingOffset:    ") + String(StartingOffset));
 | 
			
		||||
        Serial.println(String("MarshalControl:maxLength:         ") + String(maxLength));
 | 
			
		||||
 | 
			
		||||
        if(0 == StartingOffset)
 | 
			
		||||
        {
 | 
			
		||||
            Serial.println(String("MarshalControl: New control to fragement. ID: ") + String(id));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            Serial.println(String("MarshalControl: Next fragement. ID: ") + String(id));
 | 
			
		||||
        }
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
        // indicate that no additional controls should be sent
 | 
			
		||||
        _item[F("type")] = uint32_t(ControlType::Fragment);
 | 
			
		||||
        _item[F("id")]   = id;
 | 
			
		||||
 | 
			
		||||
        length = min((length - StartingOffset), maxLength);
 | 
			
		||||
        // Serial.println(String("MarshalControl:Final length:      ") + String(length));
 | 
			
		||||
 | 
			
		||||
        _item[F("offset")] = StartingOffset;
 | 
			
		||||
        _item[F("length")] = length;
 | 
			
		||||
        _item[F("total")] = value.length();
 | 
			
		||||
        item = _item.createNestedObject(F("control"));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    item[F("id")]      = id;
 | 
			
		||||
    ControlType TempType = (ControlType::Password == type) ? ControlType::Text : type;
 | 
			
		||||
    if(refresh)
 | 
			
		||||
@@ -58,8 +93,9 @@ void Control::MarshalControl(JsonObject & item, bool refresh)
 | 
			
		||||
    {
 | 
			
		||||
        item[F("type")] = uint32_t(TempType);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    item[F("label")]   = label;
 | 
			
		||||
    item[F ("value")]   = (ControlType::Password == type) ? F ("--------") : value;
 | 
			
		||||
    item[F ("value")]   = (ControlType::Password == type) ? F ("--------") : value.substring(StartingOffset, length + StartingOffset);
 | 
			
		||||
    item[F("visible")] = visible;
 | 
			
		||||
    item[F("color")]   = (int)color;
 | 
			
		||||
    item[F("enabled")] = enabled;
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@ enum ControlType : uint8_t
 | 
			
		||||
    Separator,
 | 
			
		||||
    Time,
 | 
			
		||||
 | 
			
		||||
    Fragment,
 | 
			
		||||
    Password = 99,
 | 
			
		||||
    UpdateOffset = 100,
 | 
			
		||||
};
 | 
			
		||||
@@ -81,7 +82,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    void SendCallback(int type);
 | 
			
		||||
    bool HasCallback() { return (nullptr != callback); }
 | 
			
		||||
    void MarshalControl(ArduinoJson::JsonObject& item, bool refresh);
 | 
			
		||||
    void MarshalControl(ArduinoJson::JsonObject& item, bool refresh, uint32_t DataOffset);
 | 
			
		||||
    void MarshalErrorMessage(ArduinoJson::JsonObject& item);
 | 
			
		||||
    bool ToBeDeleted() { return (ControlSyncState_t::deleted == ControlSyncState); }
 | 
			
		||||
    void DeleteControl();
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Reference in New Issue
	
	Block a user