How to delete values in an array that break the ascending order?

I'm creating a flow that warns me in case of high mobile data usage. My phone sends the data used to Home Assistant multiple times per hour.
However when my smartphone reboots the counter is reset to 0. My wife has a OnePlus which has a problem where sometimes the data goes down.
How I want to adress this:
Every time a new value comes in, I fetch the values of the last hour in an array.
The array is sorted based on time and in normal situations the data used is also in increasing order. It Only in the case of the two above problems will data usage not be in ascending order.
What I would therefore like to achieve is that when it sees an entry in the array that is not in ascending order that this entry is deleted as well as all the entries before that.
So in the example below the two first entries should be deleted, while the remaining two entries should be kept.
Problem is that I don't know how to accomplish that. All the rest of the flow I have been able to develop but I'm missing that part. Does anybody know how to do this?
Many thanks!

{
   "_msgid":"f82704f1a1af8c25",
   "payload":[
      {
         "entity_id":"sensor.mobile_quizzical_mobile_data_consumed_since_reboot",
         "state":"0.05",
         "attributes":{
            "state_class":"total_increasing",
            "unit_of_measurement":"GB",
            "friendly_name":"Mobile quizzical mobile data consumed since reboot"
         },
         "last_changed":"2022-07-31T16:09:24.574000+00:00",
         "last_updated":"2022-07-31T16:09:24.574000+00:00"
      },
      {
         "entity_id":"sensor.mobile_quizzical_mobile_data_consumed_since_reboot",
         "state":"0.051",
         "attributes":{
            "state_class":"total_increasing",
            "unit_of_measurement":"GB",
            "friendly_name":"Mobile quizzical mobile data consumed since reboot"
         },
         "last_changed":"2022-07-31T16:27:45.603872+00:00",
         "last_updated":"2022-07-31T16:27:45.603872+00:00"
      },
      {
         "entity_id":"sensor.mobile_quizzical_mobile_data_consumed_since_reboot",
         "state":"0.0",
         "attributes":{
            "state_class":"total_increasing",
            "unit_of_measurement":"GB",
            "friendly_name":"Mobile quizzical mobile data consumed since reboot"
         },
         "last_changed":"2022-07-31T16:31:41.465519+00:00",
         "last_updated":"2022-07-31T16:31:41.465519+00:00"
      },
      {
         "entity_id":"sensor.mobile_quizzical_mobile_data_consumed_since_reboot",
         "state":"0.008",
         "attributes":{
            "state_class":"total_increasing",
            "unit_of_measurement":"GB",
            "friendly_name":"Mobile quizzical mobile data consumed since reboot"
         },
         "last_changed":"2022-07-31T17:07:51.227835+00:00",
         "last_updated":"2022-07-31T17:07:51.227835+00:00"
      }
   ],
   "topic":"",
   "startdate":"2022-07-31T16:09:24.574Z",
   "enddate":"2022-07-31T17:09:24.574Z",
   "entity_id":"sensor.mobile_quizzical_mobile_data_consumed_since_reboot"
}

You could try array.reduce().
e.g

[{"id":"7e035f31.28645","type":"inject","z":"30af2d3e.d94ea2","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"entity_id\":\"sensor.mobile_quizzical_mobile_data_consumed_since_reboot\",\"state\":\"0.05\",\"attributes\":{\"state_class\":\"total_increasing\",\"unit_of_measurement\":\"GB\",\"friendly_name\":\"Mobile quizzical mobile data consumed since reboot\"},\"last_changed\":\"2022-07-31T16:09:24.574000+00:00\",\"last_updated\":\"2022-07-31T16:09:24.574000+00:00\"},{\"entity_id\":\"sensor.mobile_quizzical_mobile_data_consumed_since_reboot\",\"state\":\"0.051\",\"attributes\":{\"state_class\":\"total_increasing\",\"unit_of_measurement\":\"GB\",\"friendly_name\":\"Mobile quizzical mobile data consumed since reboot\"},\"last_changed\":\"2022-07-31T16:27:45.603872+00:00\",\"last_updated\":\"2022-07-31T16:27:45.603872+00:00\"},{\"entity_id\":\"sensor.mobile_quizzical_mobile_data_consumed_since_reboot\",\"state\":\"0.0\",\"attributes\":{\"state_class\":\"total_increasing\",\"unit_of_measurement\":\"GB\",\"friendly_name\":\"Mobile quizzical mobile data consumed since reboot\"},\"last_changed\":\"2022-07-31T16:31:41.465519+00:00\",\"last_updated\":\"2022-07-31T16:31:41.465519+00:00\"},{\"entity_id\":\"sensor.mobile_quizzical_mobile_data_consumed_since_reboot\",\"state\":\"0.008\",\"attributes\":{\"state_class\":\"total_increasing\",\"unit_of_measurement\":\"GB\",\"friendly_name\":\"Mobile quizzical mobile data consumed since reboot\"},\"last_changed\":\"2022-07-31T17:07:51.227835+00:00\",\"last_updated\":\"2022-07-31T17:07:51.227835+00:00\"}]","payloadType":"json","x":140,"y":80,"wires":[["b74c19f4.89b1c8"]]},{"id":"b74c19f4.89b1c8","type":"function","z":"30af2d3e.d94ea2","name":"","func":"msg.payload = msg.payload.reduce((acc, obj) => {\n    let value = Number(obj.state);\n    if(value < acc.total){\n        acc = {total:0,arr:[obj]};\n    }else{\n        acc.total = value;\n        acc.arr.push(obj);\n    }\n    return acc;\n},{total:0,arr:[]}).arr\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":290,"y":80,"wires":[["80ffef4f.bd11"]]},{"id":"80ffef4f.bd11","type":"debug","z":"30af2d3e.d94ea2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":590,"y":200,"wires":[]}]
msg.payload = msg.payload.reduce((acc, obj) => { // iterates through 
          //payload array setting each element in turn to obj
          // acc will be the output
    let value = Number(obj.state); // changes obj.state to a number
    if(value < acc.total){  // check to see if new state is lower than last
        acc = {total:0,arr:[obj]}; // sets acc to object, wiping values
    }else{ // otherwise
        acc.total = value; // sets acc.total to save last value
        acc.arr.push(obj); // pushes obj to acc
    }
    return acc; // returns acc ready for next array element
},{total:0,arr:[]} // initialises acc to an object with 2 properties
).arr  // output just the array from the object returned
return msg;

Every time the state drops below the previous the previous are deleted.

I shamefully admit that I don't fully understood how this piece of code you designed works, but it delivers exactly the results I want :smile:
Thanks a lot @E1cid

Added some comments so you may understand better.

2 Likes

If you have any control over the data, you may want to try using an object rather than an array since that lets you manipulate things by a key name a lot easier and you can still work with the object as an array by using Object.values(objname).

2 Likes

Super, my level of understanding of what's going on went up from 20% to around 85%.

Thanks again!
Leaving on holiday today and after an unpleasant experience last holiday where my son accidentally went way over my mobile data plan I'm glad that I'll get a warning this time!

Thanks that is good to know for the next time I have a need to process a series of data!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.