0

I have an HTML form where the user can add time data ( start and end ) to the form and can select multiple days to save it. ( this is for a circular pump daily on off time for every day ).

The form looks like this from the user point of view

This is how i process the form:

function saveCircularPumpTimes(){
    $("#circularTableForm").on("submit",function(e){
        e.preventDefault();
        var inputs = $("#circularTableForm").serializeArray();
        console.log(inputs);
        /*
        var newCircularObj = {
                "mon":[
                    { start:"", end:"" },
                    { start:"", end:"" }
                ],
                "tue":[
                    { start:"", end:"" },
                    { start:"", end:"" }
                ],

        };
        */
        var days = $("#circularPumpDays").val();
        var datas = [];
        for(var i = 0; i < inputs.length; i++){ 
        // get all the time data to an array for easier processing later.
            if( inputs[i].name.includes("circularPumpOnTimeStart") ){
                datas.push( { start:"", end:"" } );
                datas[datas.length-1].start = inputs[i].value;
            }else if( inputs[i].name.includes("circularPumpOnTimeEnd") ){
                datas[datas.length-1].end = inputs[i].value;
            }
        }
        console.log("Days: ",days);
        console.log("Datas: ",datas);
    });
}

The days array looks like this:

["mon", "tue", "wed"]

And the datas looks like this:

[
   {start: "15:36", end: "16:36"},
   {start: "15:36", end: "15:36"},
   {start: "15:36", end: "15:37"},
   {start: "15:36", end: "15:37"}
]

When the user select multiple days i would go for it like this:

       for(var i = 0; i < days.length; i++){
            if(Object.prototype.hasOwnProperty.call(newCircularObj, days[i])) {
                // User already have saved data for this day
                if( prompt("This day already exist with data inside it. Would you like to overwrite?") ){
                    newCircularObj[days[i]] = [];
                    for(var k = 0; k < datas.length; k++){
                        newCircularObj[days[i]].push( datas[i] );
                    }
                }
            }else{
                // We don't have saved data for this day, create new
                newCircularObj = new Object(days[i]);
                for(var k = 0; k < datas.length; k++){          // yeah this loop is duplicate. :( i will put it into a function
                    newCircularObj[days[i]].push( datas[i] );
                }
            }
        }

The problem with that approach is the data will be exist multiple times inside the object and i have to save it to an MCU so the space is pretty significant. For example if the user selects all seven days for the same times every time data will be included seven times inside the object.

On the MCU side i'm using ArduinoJSON library with ESP32 and i would process it like this (as you can see the whole stringified json object is inside the ram all the time so i really need the space) :

static const inline void processData(String DATA){ // in every single minute we have to do this and search for the start time.
    boolean found = false;
    SpiRamJsonDocument doc(15000);
    DeserializationError error = deserializeJson(doc, DATA); // we get the data as a JSON string.
    if (error) {
        String Error = "JSON Error Pump ~ ";
        Error += String(error.c_str());
        errorLog(Error);
        Send_Async("No Memory for circular Pump DATA", ";RoomHeating");
    }else {
        JsonObject documentRoot = doc.as<JsonObject>();
        for (JsonPair timeData : documentRoot) {
            if(Time.Get_Day() == timeData.key().c_str()){ // Time.Get_Day() is equalent with the current day String like "mon" or "tue"
                // if the day is okay we have to search for the times
                JsonArray Day = doc[Time.Get_Day()];
                for(int i = 0; i < Day.size(); i++){
                    if(Time_Has_Reached(Day[i]["start"],Day[i]["end"])){ // function for check if the start time has passed but the end is not
                        // if in between
                        found = true;
                        break;
                    }
                }
                if(found){break;}
            }
        }
    }

    if(found){
        // Turn on the pump
    }else{
        // Turn off the pump
    }
}

So the question is, how can i arrange the object so the time data exist only once if it is already saved to a day to be more efficient.

Edit: Example from the final object:

var newCircularObj = {
                "mon":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "tue":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "wed":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "thu":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "sat":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],

};
Ian Abbott
  • 15,083
  • 19
  • 33
Dr.Random
  • 430
  • 3
  • 16
  • you want to modify **saveCircularPumpTimes** to have an ouput json without duplicates by days? ans the output shown is the **console.log(inputs)** ? – Frenchy Mar 04 '21 at 15:58
  • The problem is that the final output is a big object with this approach. The MCU has limited RAM so i need a way to make it smaller but still i want to know all the details thats currently inside it – Dr.Random Mar 05 '21 at 07:17

1 Answers1

0

ok this program removes duplicates from newCircularObj:

i have taken your sample and modified some values of newCircularObj:

$(function() {

  function removeDup(ar) {
    return ar.reduce(function(item, e1) {
      var matches = item.filter(function(e2) {
        return e1.start == e2.start && e1.end == e2.end
      });
      if (matches.length == 0) {
        item.push(e1);
      }
      return item;
    }, []);

  }


  var result = {datas:{} };
  Object.keys(newCircularObj).forEach(function(it, i) { 
        result.datas[it] =  removeDup(newCircularObj[it]);
    });


  console.log(result);


});

var newCircularObj = {
                "mon":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:11", end:"15:10" },
                    { start:"14:10", end:"15:11" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "tue":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:11" },
                    { start:"14:11", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "wed":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "thu":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],
                "sat":[
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                    { start:"14:10", end:"15:10" },
                ],

};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

RESULT

{
  datas: {
    mon: [
    {  end: "15:10",  start: "14:10"},
    {  end: "15:10",  start: "14:11"},
    {  end: "15:11",  start: "14:10"}
    ],
    sat: [
    {  end: "15:10",  start: "14:10"}
    ],
    thu: [
    {  end: "15:10",  start: "14:10"}
    ],
    tue: [
    {  end: "15:10",  start: "14:10"},
    {  end: "15:11",  start: "14:10"},
    {  end: "15:10",  start: "14:11"}
    ],
    wed: [
    {  end: "15:10",  start: "14:10"}
    ]
  }
}
Frenchy
  • 16,386
  • 3
  • 16
  • 39
  • Thank you bu perhaps i formulated the question incorrectly. The user has to be able to determine its custom times for every day, even if it is exist on another day. – Dr.Random Mar 05 '21 at 07:19
  • @Dr.Random sorry i am lost..i thought you want to remove duplicate for each record of your file,,i suggest you to show the file you have (a sample, not complete if its big), and what you want as result before sending to your mcu – Frenchy Mar 05 '21 at 07:29
  • This was a sample from the file. It is a big JSON file and it has this object inside it. The problem i have is that if the user puts the data i have to save it for every day. Let's say an example. This is a circulating pump wich is circulating the water in your house. You want that pump to run at let's say Monday from 08:00 AM to 08:15AM and after on the same day it has to run from 13:00PM to 13:30PM. but you want that for Tuesday too and a couple more runtime on Tuesday. – Dr.Random Mar 05 '21 at 09:43
  • So the object would be like this: var newCircularObj = { "mon":[ { start:"08:00", end:"08:15" }, { start:"13:00", end:"13:30" } ], "tue":[ { start:"08:00", end:"08:15" }, { start:"13:00", end:"13:30" }, { start:"14:00", end:"14:30" }, { start:"15:00", end:"15:30" } }; – Dr.Random Mar 05 '21 at 09:44
  • @Dr.Random sorry i am lost, the function circular traps the submit ok? and the result id shown by the circular variable..my program removes duplicates..i dont understand where is the problem, the html code is not in microcontroller, you transfert datas after that??.. – Frenchy Mar 05 '21 at 10:16