# Testing a array of objects of ones and zeros to see if there are state changes from 0 -1

**URL:** <https://discourse.nodered.org/t/testing-a-array-of-objects-of-ones-and-zeros-to-see-if-there-are-state-changes-from-0-1/90474>\
**Category:** General\
**Created:** [27 August 2024 09:00 UTC](https://discourse.nodered.org/t/testing-a-array-of-objects-of-ones-and-zeros-to-see-if-there-are-state-changes-from-0-1/90474 "2024-08-27T09:00:44Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![psychoLK](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/psycholk/32/93936_2.png) [@psychoLK](https://discourse.nodered.org/u/psychoLK)\
**Post date:** [27 August 2024 09:00 UTC](https://discourse.nodered.org/t/testing-a-array-of-objects-of-ones-and-zeros-to-see-if-there-are-state-changes-from-0-1/90474/1 "2024-08-27T09:00:44Z")

</div>

I am trying to make a array of Alarm status. I have IOT devices putting 1 or 0 to array indexes based on the alarm status. I want to check whether the arrray indexes changed from 0 -1 and write that data to a sql or some database. In order to do this i need to have a globle variable of previous array and current arrays. But when I compare the previous array to current they are equal all the time.

---

<div class="post-metadata">

**Author:** ![psychoLK](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/psycholk/32/93936_2.png) [@psychoLK](https://discourse.nodered.org/u/psychoLK)\
**Post date:** [27 August 2024 09:02 UTC](https://discourse.nodered.org/t/testing-a-array-of-objects-of-ones-and-zeros-to-see-if-there-are-state-changes-from-0-1/90474/2 "2024-08-27T09:02:09Z")

</div>

```auto
[
    {
        "id": "ec2fb1d34b168229",
        "type": "function",
        "z": "73d2f3c99532ca0a",
        "name": "function 73",
        "func": "// Retrieve the current state of the Alarm_Array from the global context\nvar currentState = global.get(\"Alarm_Array\") || [];\n\n// Output the currentState for debugging purposes\nmsg.payload = currentState;\n\n// Return the message to pass the current state down the flow\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 410,
        "y": 800,
        "wires": [
            [
                "58f654830be125b5"
            ]
        ]
    },
    {
        "id": "b2ac17077b912ea0",
        "type": "inject",
        "z": "73d2f3c99532ca0a",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 220,
        "y": 800,
        "wires": [
            [
                "ec2fb1d34b168229"
            ]
        ]
    },
    {
        "id": "58f654830be125b5",
        "type": "debug",
        "z": "73d2f3c99532ca0a",
        "name": "debug 82",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 560,
        "y": 800,
        "wires": []
    },
    {
        "id": "754fde939f2fea2a",
        "type": "modbus-write",
        "z": "73d2f3c99532ca0a",
        "name": "Adam Module",
        "showStatusActivities": true,
        "showErrors": true,
        "showWarnings": true,
        "unitid": "1",
        "dataType": "Coil",
        "adr": "17",
        "quantity": "1",
        "server": "c7e87354e3598a57",
        "emptyMsgOnFail": true,
        "keepMsgProperties": true,
        "delayOnStart": false,
        "startDelayTime": "",
        "x": 720,
        "y": 200,
        "wires": [
            [
                "5d26fdadcb96cb36"
            ],
            [
                "5d26fdadcb96cb36"
            ]
        ]
    },
    {
        "id": "5d26fdadcb96cb36",
        "type": "debug",
        "z": "73d2f3c99532ca0a",
        "name": "debug 78",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 940,
        "y": 200,
        "wires": []
    },
    {
        "id": "8c0638bef44ea9a6",
        "type": "inject",
        "z": "73d2f3c99532ca0a",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "true",
        "payloadType": "bool",
        "x": 390,
        "y": 60,
        "wires": [
            [
                "754fde939f2fea2a"
            ]
        ]
    },
    {
        "id": "2cde1fa0d610c4de",
        "type": "inject",
        "z": "73d2f3c99532ca0a",
        "name": "Reset Alarm",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "false",
        "payloadType": "bool",
        "x": 410,
        "y": 300,
        "wires": [
            [
                "754fde939f2fea2a"
            ]
        ]
    },
    {
        "id": "47157da9dc2fea3d",
        "type": "function",
        "z": "73d2f3c99532ca0a",
        "name": "function 70",
        "func": "// Retrieve the current Alarm_Array from the global context\nlet currentAlarmArray = global.get('Alarm_Array') || [];\nnode.warn('Current Alarm Array: ' + JSON.stringify(currentAlarmArray));\n\n// Retrieve the previous Alarm_Array from the global context\nlet previousAlarmArray = global.get('Previous') || new Array(currentAlarmArray.length).fill(0);\nnode.warn('Previous Alarm Array: ' + JSON.stringify(previousAlarmArray));\n\n// Check if the arrays are actually the same object\n// This check is only to warn if they are the same object reference, not their contents\nif (currentAlarmArray === previousAlarmArray) {\n node.warn('Warning: currentAlarmArray and previousAlarmArray are the same object!');\n}\n\n// Initialize a flag to indicate if any transition occurred\nlet transitionDetected = false;\n\n// Iterate over the arrays and check for transitions from 0 to 1\nfor (let i = 0; i < currentAlarmArray.length; i++) {\n node.warn(`Comparing index ${i}: Previous = ${previousAlarmArray[i]}, Current = ${currentAlarmArray[i]}`);\n if (previousAlarmArray[i] === 0 && currentAlarmArray[i] === 1) {\n node.warn('Transition detected at index ' + i);\n transitionDetected = true;\n }\n}\n\n// Update the previous Alarm_Array in the global context\nglobal.set('Previous', currentAlarmArray);\n\n\n// Output only if a transition was detected\nif (transitionDetected) {\n msg.payload = true;\n node.warn('Transition detected. Outputting message.');\n return msg;\n} else {\n node.warn('No transition detected.');\n return null; // No output if no transition detected\n}",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 450,
        "y": 200,
        "wires": [
            [
                "258c2fc7b2d85b6c",
                "754fde939f2fea2a"
            ]
        ]
    },
    {
        "id": "258c2fc7b2d85b6c",
        "type": "debug",
        "z": "73d2f3c99532ca0a",
        "name": "debug 84",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 680,
        "y": 320,
        "wires": []
    },
    {
        "id": "4d0bf768259ec284",
        "type": "inject",
        "z": "73d2f3c99532ca0a",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 240,
        "y": 200,
        "wires": [
            [
                "47157da9dc2fea3d",
                "258c2fc7b2d85b6c"
            ]
        ]
    },
    {
        "id": "e43ada5751d6d1e0",
        "type": "inject",
        "z": "73d2f3c99532ca0a",
        "name": "0 1",
        "props": [
            {
                "p": "index0",
                "v": "1",
                "vt": "num"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 210,
        "y": 500,
        "wires": [
            [
                "30ea31131727215a",
                "082622abc628597d"
            ]
        ]
    },
    {
        "id": "ce2244c43b72a0b3",
        "type": "inject",
        "z": "73d2f3c99532ca0a",
        "name": "0 0",
        "props": [
            {
                "p": "index0",
                "v": "0",
                "vt": "num"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 210,
        "y": 540,
        "wires": [
            [
                "30ea31131727215a"
            ]
        ]
    },
    {
        "id": "ad758fd558120133",
        "type": "inject",
        "z": "73d2f3c99532ca0a",
        "name": "1 1",
        "props": [
            {
                "p": "index1",
                "v": "1",
                "vt": "num"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "x": 210,
        "y": 600,
        "wires": [
            [
                "30ea31131727215a"
            ]
        ]
    },
    {
        "id": "b645293de534bd05",
        "type": "inject",
        "z": "73d2f3c99532ca0a",
        "name": "1 0",
        "props": [
            {
                "p": "index1",
                "v": "0",
                "vt": "num"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "x": 210,
        "y": 640,
        "wires": [
            [
                "30ea31131727215a"
            ]
        ]
    },
    {
        "id": "30ea31131727215a",
        "type": "function",
        "z": "73d2f3c99532ca0a",
        "name": "function 71",
        "func": "// Retrieve the existing Alarm_Array from the global context or initialize it if it doesn't exist\nlet Alarm_Array = global.get('Alarm_Array') || [];\n\n// Loop through the properties of the incoming message object\nfor (let key in msg) {\n // Check if the key matches the pattern \"indexX\" where X is a number\n if (key.startsWith('index')) {\n // Extract the index number from the key (e.g., \"index0\" -> 0)\n let index = parseInt(key.replace('index', ''), 10);\n\n // Ensure the Alarm_Array is large enough to accommodate the index\n Alarm_Array[index] = msg[key];\n }\n}\n\n// Store the updated Alarm_Array back into the global context\nglobal.set('Alarm_Array', Alarm_Array);\n\n// Optionally, return the updated Alarm_Array in the message payload\nmsg.payload = Alarm_Array;\n\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 450,
        "y": 500,
        "wires": [
            [
                "81853fd7963ed7f2"
            ]
        ]
    },
    {
        "id": "81853fd7963ed7f2",
        "type": "debug",
        "z": "73d2f3c99532ca0a",
        "name": "debug 79",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 640,
        "y": 500,
        "wires": []
    },
    {
        "id": "082622abc628597d",
        "type": "debug",
        "z": "73d2f3c99532ca0a",
        "name": "debug 83",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 360,
        "y": 460,
        "wires": []
    },
    {
        "id": "571fc8b0f85a5d16",
        "type": "function",
        "z": "73d2f3c99532ca0a",
        "name": "function 74",
        "func": "// Retrieve the current state of the Alarm_Array from the global context\nvar currentState = global.get(\"Previous\") || [];\n\n// Output the currentState for debugging purposes\nmsg.payload = currentState;\n\n// Return the message to pass the current state down the flow\nreturn msg;\n",
        "outputs": 1,
        "timeout": 0,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 410,
        "y": 840,
        "wires": [
            [
                "1c6b8c8538d89779"
            ]
        ]
    },
    {
        "id": "027b062e55eaba01",
        "type": "inject",
        "z": "73d2f3c99532ca0a",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 220,
        "y": 840,
        "wires": [
            [
                "571fc8b0f85a5d16"
            ]
        ]
    },
    {
        "id": "1c6b8c8538d89779",
        "type": "debug",
        "z": "73d2f3c99532ca0a",
        "name": "debug 85",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 560,
        "y": 840,
        "wires": []
    },
    {
        "id": "f429bf45cecacf6f",
        "type": "comment",
        "z": "73d2f3c99532ca0a",
        "name": "Alarm Generating devices",
        "info": "",
        "x": 150,
        "y": 460,
        "wires": []
    },
    {
        "id": "495ecc0f6306f171",
        "type": "comment",
        "z": "73d2f3c99532ca0a",
        "name": "Test previous and current arrays",
        "info": "",
        "x": 270,
        "y": 760,
        "wires": []
    },
    {
        "id": "a54d45f333aff9a1",
        "type": "comment",
        "z": "73d2f3c99532ca0a",
        "name": "Current array",
        "info": "",
        "x": 730,
        "y": 800,
        "wires": []
    },
    {
        "id": "7b3a47670759ebe8",
        "type": "comment",
        "z": "73d2f3c99532ca0a",
        "name": "Previous array",
        "info": "",
        "x": 730,
        "y": 840,
        "wires": []
    },
    {
        "id": "c7e87354e3598a57",
        "type": "modbus-client",
        "name": "Adam Module Alarm 1",
        "clienttype": "tcp",
        "bufferCommands": true,
        "stateLogEnabled": true,
        "queueLogEnabled": true,
        "failureLogEnabled": true,
        "tcpHost": "10.141.3.200",
        "tcpPort": "502",
        "tcpType": "DEFAULT",
        "serialPort": "/dev/ttyUSB",
        "serialType": "RTU-BUFFERD",
        "serialBaudrate": "9600",
        "serialDatabits": "8",
        "serialStopbits": "1",
        "serialParity": "none",
        "serialConnectionDelay": "100",
        "serialAsciiResponseStartDelimiter": "0x3A",
        "unit_id": "1",
        "commandDelay": "1",
        "clientTimeout": "1000",
        "reconnectOnTimeout": true,
        "reconnectTimeout": "2000",
        "parallelUnitIdsAllowed": false,
        "showErrors": true,
        "showWarnings": true,
        "showLogs": true
    }
]

```

---

<div class="post-metadata">

**Author:** ![psychoLK](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/psycholk/32/93936_2.png) [@psychoLK](https://discourse.nodered.org/u/psychoLK)\
**Post date:** [27 August 2024 09:17 UTC](https://discourse.nodered.org/t/testing-a-array-of-objects-of-ones-and-zeros-to-see-if-there-are-state-changes-from-0-1/90474/3 "2024-08-27T09:17:33Z")

</div>

Chat GPT came for the rescue 😃  
The issue you’re encountering where the previous state (`Previous`) seems to be updated even when the function isn’t executed is likely due to the way JavaScript handles references to objects (arrays in this case) rather than values.

### Understanding the Problem:

In JavaScript, when you assign an array (or an object) to a variable, you are assigning a reference to that array, not a copy of its values. This means that if the `currentAlarmArray` and `previousAlarmArray` point to the same array object, any changes to `currentAlarmArray` will also affect `previousAlarmArray` because they both refer to the same underlying data.

### Example:

javascript

Copy code

```auto
let arr1 = [1, 2, 3];
let arr2 = arr1; // arr2 is now a reference to arr1
arr2[0] = 100; // Modifies arr1 as well, since arr2 is just a reference
console.log(arr1); // Outputs: [100, 2, 3]

```

### In Your Case:

- When you retrieve the `currentAlarmArray` and `previousAlarmArray`, if they reference the same array, updating one will automatically update the other.
- This can happen if the `global.set` call is not made after checking for transitions, or if the global state is shared across multiple function calls where references are reused.

### Solution:

To avoid this problem, you should create a copy of the array when setting `Previous` or when retrieving the `currentAlarmArray`. This way, `Previous` and `currentAlarmArray` will refer to different arrays.

### Modify the Function:

1. **Create a copy of the array** when setting the `Previous` state:

javascript

Copy code

```auto
global.set('Previous', [...currentAlarmArray]); // Shallow copy using spread operator

```

1. Alternatively, **create a copy when retrieving** the array:

javascript

Copy code

```auto
let previousAlarmArray = global.get('Previous') || new Array(currentAlarmArray.length).fill(0);
previousAlarmArray = [...previousAlarmArray]; // Ensure it's a copy

```

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [27 August 2024 09:36 UTC](https://discourse.nodered.org/t/testing-a-array-of-objects-of-ones-and-zeros-to-see-if-there-are-state-changes-from-0-1/90474/4 "2024-08-27T09:36:28Z")

</div>

> [@psychoLK](#):
>
> ```auto
> let previousAlarmArray = global.get('Previous') || new Array(currentAlarmArray.length).fill(0);
> previousAlarmArray = [...previousAlarmArray]; // Ensure it's a copy
> 
> ```

Node red provides a method for cloning data to avoid this problem  
`let previousAlarmArray = RED.util.cloneMessage(global.get('Previous')) || new Array(currentAlarmArray.length).fill(0)`

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [10 September 2024 09:36 UTC](https://discourse.nodered.org/t/testing-a-array-of-objects-of-ones-and-zeros-to-see-if-there-are-state-changes-from-0-1/90474/5 "2024-09-10T09:36:39Z")

</div>

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