# Update Device Attribute based on its tag key-value

**URL:** <https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841>\
**Category:** Help\
**Tags:** workflow\
**Created:** [December 12, 2022, 9:59am UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841 "2022-12-12T09:59:22Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![ruba\_jabal](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/ruba_jabal/32/4251_2.png) [@ruba\_jabal](https://forums.losant.com/u/ruba_jabal)\
**Post date:** [December 12, 2022, 9:59am UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/1 "2022-12-12T09:59:22Z")

</div>

Hello All,

referring to below images, i have this case where i need to update device attributes value based on their defined tag (IOID).

the attributes values received as an array “Elements” as below image, however the device attributes are not ordered in specific order under “Elements” Array, and more attributes may be added to this array in future.

So I need dynamic way to loop over the “Elements” Array, read the IOID received, find which device attribute has this IOID value, then update the attribute value.

Any Idea? Suggestion?

 ![Screen Shot 2022-12-12 at 12.57.49 PM](https://us1.discourse-cdn.com/flex015/uploads/getstructure/original/2X/0/02421cf98119232d2b7d0b6078206dbdc286b728.jpeg)  
 ![Screen Shot 2022-12-12 at 12.45.26 PM](https://us1.discourse-cdn.com/flex015/uploads/getstructure/original/2X/5/5b40b9ad11108b1689a5f996d722eb89608c3909.png)

---

<div class="post-metadata">

**Author:** ![Sebastian\_Turner](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/sebastian_turner/32/4024_2.png) [@Sebastian\_Turner](https://forums.losant.com/u/Sebastian_Turner)\
**Post date:** [December 12, 2022, 3:58pm UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/2 "2022-12-12T15:58:35Z")

</div>

Good question! We are working on a potential solution and will be back shortly.

---

<div class="post-metadata">

**Author:** ![Dylan\_Schuster](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/dylan_schuster/32/2850_2.png) [@Dylan\_Schuster](https://forums.losant.com/u/Dylan_Schuster)\
**Post date:** [December 12, 2022, 4:29pm UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/3 "2022-12-12T16:29:13Z")

</div>

I figured out a way to do this without using a Loop Node.

Given an `Elements` array whose items are objects of the following shape …

```json
{
  "IOID": 71,
  "Name": "GNSS Status",
  "Value": 3
}

```

… and given a `device` object whose `attributes` property is also in array form …

```json
{
  "attributes": [
    {
      "name": "gnssStatus",
      "dataType": "number",
      "attributeTags": {
        "IOID": "71"
      }
    }
  ]
}

```

… You can build a state object for use in the [Device: State Node](https://docs.losant.com/workflows/outputs/device-state/) using a [JSON Template](https://docs.losant.com/workflows/accessing-payload-data/#json-templates) and the [`{{valueByKey}}` helper](https://docs.losant.com/workflows/accessing-payload-data/#json-templates) as follows …

```nohighlight
{
    {{#each Elements}}
      "{{valueByKey @root.device.attributes (lower IOID) 'attributeTags.IOID' 'name'}}": {{Value}}{{#unless @last}},{{/unless}}
    {{/each}}
}

```

There’s a lot to unpack here …

- `{{#each Elements}}` - Iterates over the `Elements` array. You will need to change the path of `Elements` to whatever your use case dictates. I can’t see what that value would be from your screenshot but if looks like you are looping over an outer `Data` property, so it would probably be something like `working.currentDataIteration.value.Elements`.
- `"{{valueByKey @root.device.attributes (lower IOID) 'attributeTags.IOID' 'name'}}"` - This is the meat of it, for finding the attribute name for a given device that corresponds to the `IOID` property in the current `Elements` iteration …
  - `@root.device.attributes` - The `@root` breaks out of the current `{{#each}}` iteration context and goes to find the device object’s `attributes` array on the full payload. You will need to change this path to match your use case.
  - `(lower IOID)` - The `IOID` here is the value of the `IOID` property _within the `Elements` object_. The `(lower)` portion is necessary to cast that value to a string, so that we can match it against the device, where the `IOID` is also stored as a string.
  - `'attributeTags.IOID'` - This is the path to the object property that we want to compare the IOID value to _in the device attributes array_. You should not have to change this based on your screenshots.
  - This is what to return from the device attributes array given our match. This is the name of the attribute - exactly what we’re after here.

- `{{Value}}` - This is the numerical value we want to report for that object key we just generated. This is coming from the current iteration of `Elements`.
- `{{#unless @last}},{{/unless}}` - This is necessary to properly construct our JSON object, as we must put a comma at the end of every line except the last one.

Attached is a simple application export that demonstrates this, with an Application Workflow and a device. Your use case appears to be within an Edge Workflow, but the same solution applies.

Let us know if you have any questions.

[export-6397491d6d455256a221247b-1670862469767-forums4841.zip](https://forums.losant.com/uploads/short-url/xq8hBoYC2kwboRhXbZTuP9E6iS4.zip) (2.6 KB)

---

<div class="post-metadata">

**Author:** ![ruba\_jabal](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/ruba_jabal/32/4251_2.png) [@ruba\_jabal](https://forums.losant.com/u/ruba_jabal)\
**Post date:** [December 15, 2022, 8:54am UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/4 "2022-12-15T08:54:37Z")

</div>

Dear Dylan,

Thanks for the comprehensive solution !  
I applied your suggestion and it seems pretty works.

---

<div class="post-metadata">

**Author:** ![ruba\_jabal](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/ruba_jabal/32/4251_2.png) [@ruba\_jabal](https://forums.losant.com/u/ruba_jabal)\
**Post date:** [December 17, 2022, 12:31pm UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/5 "2022-12-17T12:31:24Z")

</div>

Hello Dylan,

for the same situation, I am trying to merge below two nodes into one Device State Node, But I got an issue doing this related to Json formatting, kindly your advise

 ![Screenshot 2022-12-17 at 3.25.49 PM](https://us1.discourse-cdn.com/flex015/uploads/getstructure/original/2X/2/2cff001bcfdb052da57e342c07fd3e2dc1152b89.png)  
 ![Screenshot 2022-12-17 at 3.26.00 PM](https://us1.discourse-cdn.com/flex015/uploads/getstructure/original/2X/a/ad4d7cb79e2100021233028339ee83a3b5e5d574.png)

The Application File is Here:  
[export-fleetManagementSystemCloned.zip](https://forums.losant.com/uploads/short-url/2dbgOYQsBaZKIxL39EftvQCgWfl.zip) (9.0 KB)

---

<div class="post-metadata">

**Author:** ![Dylan\_Schuster](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/dylan_schuster/32/2850_2.png) [@Dylan\_Schuster](https://forums.losant.com/u/Dylan_Schuster)\
**Post date:** [December 17, 2022, 6:54pm UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/6 "2022-12-17T18:54:05Z")

</div>

You should be able to combine the two together like so (shortened and pseudo-code) …

```json
{
  {{#each data.count.value.Elements}}
    "{{valueByKey @root.working.DeviceID.attributes (...)": {{jsonEncode myValue}},
  {{/each}}
  "Altitude": "{{data.count.value.Altitude}}",
  ... other specifically set properties
}

```

---

<div class="post-metadata">

**Author:** ![ruba\_jabal](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/ruba_jabal/32/4251_2.png) [@ruba\_jabal](https://forums.losant.com/u/ruba_jabal)\
**Post date:** [December 18, 2022, 2:48pm UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/7 "2022-12-18T14:48:33Z")

</div>

Thanks Dylan,

i applied the same logic in “Edge Workflow” but it doesn’t recognize this part

```auto
{{#each data.count.value.Elements}}
"{{valueByKey @root.working.DeviceID.attributes (lower IOID) 'attributeTags.IOID' 'name'}}": {{Value}},{{#unless @last}}{{/unless}}
{{/each}}

```

i got below error in device log, is it related to “Edge Workflow” or “Peripheral: Get Node”? because it works perfectly in Application Workflow and “Device: Get Node”

 ![Screenshot from 2022-12-18 16-45-24](https://us1.discourse-cdn.com/flex015/uploads/getstructure/original/2X/6/6e4d37a6e4504faff2a0664aeaec4aaa42a1f203.png)  
 ![image](https://us1.discourse-cdn.com/flex015/uploads/getstructure/original/2X/8/8766ad154de8833ffcd14b7a03168b35179990f0.png)

---

<div class="post-metadata">

**Author:** ![Dylan\_Schuster](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/dylan_schuster/32/2850_2.png) [@Dylan\_Schuster](https://forums.losant.com/u/Dylan_Schuster)\
**Post date:** [December 19, 2022, 1:54pm UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/8 "2022-12-19T13:54:50Z")

</div>

You can read about the “Additional messages received” message [here](https://docs.losant.com/workflows/debugging-workflows/#throttle-limit-messages) and the “One or more reported attributes” message [here](https://docs.losant.com/devices/overview/#device-communication-log).

The second message indicates some sort of error in the`{{#each}}` helper that is building your state JSON object; probably a payload path not pointing to the right value. There is a [payload tester](https://docs.losant.com/workflows/platform-template-tester/) built into the workflow engine that allows you to provide a JSON template and a payload to render that against to view what the output will be; I recommend using that tool to get to the bottom of your issue.

Without having your actual JSON template in hand and a payload against which it is evaluating, it’s difficult for us to see where the error is occurring.

---

<div class="post-metadata">

**Author:** ![Dylan\_Schuster](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/dylan_schuster/32/2850_2.png) [@Dylan\_Schuster](https://forums.losant.com/u/Dylan_Schuster)\
**Post date:** [December 20, 2022, 7:16pm UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/9 "2022-12-20T19:16:28Z")

</div>

One important note: There is a bug in GEA versions v1.32.0 through v1.34.0 with the `{{@last}}` helper recommended in this solution. Use of the `{{@last}}` helper is fixed in Application Workflows and other cloud / browser-based uses, as well as in GEA version 1.35.0.

---

<div class="post-metadata">

**Author:** ![ruba\_jabal](https://sea1.discourse-cdn.com/flex015/user_avatar/forums.losant.com/ruba_jabal/32/4251_2.png) [@ruba\_jabal](https://forums.losant.com/u/ruba_jabal)\
**Post date:** [December 21, 2022, 7:49am UTC](https://forums.losant.com/t/update-device-attribute-based-on-its-tag-key-value/4841/10 "2022-12-21T07:49:43Z")

</div>

Thanks Dylan,

The problem has been resolved after upgrading the Losant Edge Agent.
