# Perspective Scripting to find a Custom Property on a View

**URL:** <https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466>\
**Category:** Ignition\
**Tags:** perspective, scripting\
**Created:** [September 21, 2023, 5:20pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466 "2023-09-21T17:20:58Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brian\_Shin](https://avatars.discourse-cdn.com/v4/letter/b/46a35a/32.png) [@Brian\_Shin](https://forum.inductiveautomation.com/u/Brian_Shin)\
**Post date:** [September 21, 2023, 5:20pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/1 "2023-09-21T17:20:58Z")

</div>

Hello,

I have a custom UDT tag that is on my view. Within this UDT tag are two tags:

HighAlarmEnableMode  
HighAlarmEnablePB

The PB tag needs to be a momentary bit where it's a 1 and goes back to 0. When the PB tag is a 1, a one shot energizes and latches the EnableMode bit. When the PB tag is 1 again, the one shot energizes and unlatches the EnableMode. I am trying to make it so that whenever the user presses a button, it will momentarily turn the tag to a 1 and then back to 0. I am trying to accomplish this through scripting since there is NOT a momentary button in Perspective.

The following works:

System.tag.write("[XXXX]LIT\_111.HighAlarmEnablePB",1)  
System.tag.write("[XXXX]LIT\_111.HighAlarmEnablePB",0)

It works like a champ, but then when I try to make it dynamic by having it call a tag on the view like below:

System.tag.write(self.view.custom.UDT.HighAlarmEnablePB,1)

Doing this, I get an error in my log saying that it can't find the tag. How else can I reference a custom tag on my view so that it actually finds it??

* * *

For the record, I ended up creating a new custom property on the popup. On each custom property I used the following:

`concat({view.params.TagPath}, "/HighAlarmEnablePB")`

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [September 21, 2023, 5:46pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/2 "2023-09-21T17:46:33Z")

</div>

I think `system.tag.write` has been depreciated (and it's "system", not "System"). You should be using [system.tag.writeAsync](https://docs.inductiveautomation.com/display/DOC81/system.tag.writeAsync) or [system.tag.writeBlocking](https://docs.inductiveautomation.com/display/DOC81/system.tag.writeBlocking). Note they expect the tags in list format - even when only one tag is sought (but I think it will tolerate one tag without the `[]`.

Can you right-click on `custom.UDT`, copy and paste it in here so we can check the contents?

Tip: see this before you post:

> [@Wiki - how to post code on this forum](https://forum.inductiveautomation.com/t/wiki-how-to-post-code-on-this-forum/77831):
>
> This thread is intended as a short help file for all those struggling to post formatted code on the forum. Posting formatted code on the forum (and most others) is as simple as selecting the code and pressing the \</\> button. It works the same as applying Bold or Italic styles to your document. It preserves indentation and applies syntax highlighting. [How to post code]

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [September 21, 2023, 5:51pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/3 "2023-09-21T17:51:33Z")

</div>

Putting aside the whole momentary button thing (search the forum for @pturmel's post about this),

> [@Brian\_Shin](#):
>
> Doing this, I get an error in my log saying that it can't find the tag. How else can I reference a custom tag on my view so that it actually finds it??

How is the `custom.UDT` property defined/generated ?

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [September 21, 2023, 5:58pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/4 "2023-09-21T17:58:31Z")

</div>

> [@Brian\_Shin](#):
>
> since there is NOT a momentary button in Perspective

For a reason. You are very likely to eventually regret implementing this.

---

<div class="post-metadata">

**Author:** ![Brian\_Shin](https://avatars.discourse-cdn.com/v4/letter/b/46a35a/32.png) [@Brian\_Shin](https://forum.inductiveautomation.com/u/Brian_Shin)\
**Post date:** [September 21, 2023, 6:54pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/5 "2023-09-21T18:54:31Z")

</div>

Thanks for the tip!

I have tried `system.tag.writeAsync` and that returned an error as well:

AttributeError: 'com.inductiveautomation.ignition.common.script.Imm' object has no attribute 'tags'

See UDT below:

{  
"AlarmPriority": 0,  
"DecimalPlaces": 1,  
"DeviceDescription": "Wet Well Level 1",  
"DeviceEU": "%",  
"DeviceEUAlt1": null,  
"DeviceEUAlt2": null,  
"DeviceEUPrimary": "%",  
"DeviceID": "LIT-111",  
"DisplayAlt1Mode": false,  
"DisplayAlt1PB": false,  
"DisplayAlt2Mode": false,  
"DisplayAlt2PB": false,  
"DisplayPrimaryMode": false,  
"DisplayPrimaryPB": false,  
"ForceOnMode": false,  
"ForceOnPB": false,  
"HAlmColor": "#FF9E9E",  
"HighAlarm": false,  
"HighAlarmDBValue": 90,  
"HighAlarmDelaySP": 5,  
"HighAlarmEnableMode": false,  
"HighAlarmEnablePB": false,  
"HighAlarmEnablePB\_MEM": null,  
"HighAlarmIn": 95,  
"HighAlarmProcessEnable": true,  
"HighAlarmResetPB": false,  
"HighAlarmResetRequired": false,  
"HighWarning": false,  
"HighWarningDBValue": 85,  
"HighWarningDelaySP": 5,  
"HighWarningEnableMode": false,  
"HighWarningEnablePB": false,  
"HighWarningIn": 90,  
"HighWarningProcessEnable": true,  
"HistorianPath": "histprov:SQL\_Server:/drv:ignition-mnwa3igio01:default:/tag:Wastewater/LIT\_111/",  
"InputRaw": 0,  
"LAlmColor": "#FF9E9E",  
"LowAlarm": false,  
"LowAlarmDBValue": 10,  
"LowAlarmDelaySP": 5,  
"LowAlarmEnableMode": false,  
"LowAlarmEnablePB": false,  
"LowAlarmIn": 5,  
"LowAlarmProcessEnable": true,  
"LowAlarmResetPB": false,  
"LowAlarmResetRequired": false,  
"LowWarning": false,  
"LowWarningDBValue": 15,  
"LowWarningDelaySP": 5,  
"LowWarningEnableMode": false,  
"LowWarningEnablePB": false,  
"LowWarningIn": 10,  
"LowWarningProcessEnable": true,  
"LowerAlarmDB": 5,  
"OOSMode": false,  
"OOSPB": false,  
"Output": 0,  
"OutputAlt1": 0,  
"OutputAlt2": 0,  
"OutputPrimary": 0,  
"PopupWindow": "Templates/Popups/Analogs/SymAnalogInputAlt\_Status",  
"PopupWindowSetpoints": "None",  
"PopupWindowSetpointsTagPath": "None",  
"RawInputMax": 20000,  
"RawInputMin": 0,  
"ScaledMaxAlt1": 100,  
"ScaledMaxAlt2": 100,  
"ScaledMaxPrimary": 100,  
"ScaledMinAlt1": 0,  
"ScaledMinAlt2": 0,  
"ScaledMinPrimary": 0,  
"ScalingFault": false,  
"UpperAlarmDB": 5  
}

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [September 21, 2023, 6:56pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/6 "2023-09-21T18:56:39Z")

</div>

> [@Brian\_Shin](#):
>
> 'com.inductiveautomation.ignition.common.script.Imm' object has no attribute 'tags

Are you sure you used `system.tag.writeAsync` and not `system.tags.writeAsync`?

---

<div class="post-metadata">

**Author:** ![Transistor](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/transistor/32/3380_2.png) [@Transistor](https://forum.inductiveautomation.com/u/Transistor)\
**Post date:** [September 21, 2023, 7:08pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/7 "2023-09-21T19:08:58Z")

</div>

> [@Transistor](#):
>
> Tip: see this before you post:

Did you?

---

<div class="post-metadata">

**Author:** ![Brian\_Shin](https://avatars.discourse-cdn.com/v4/letter/b/46a35a/32.png) [@Brian\_Shin](https://forum.inductiveautomation.com/u/Brian_Shin)\
**Post date:** [September 21, 2023, 7:25pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/8 "2023-09-21T19:25:18Z")

</div>

Sorry, you are correct. I still get an error even with the function written correctly:

`TypeError: 'bool' object is not iterable`

---

<div class="post-metadata">

**Author:** ![Brian\_Shin](https://avatars.discourse-cdn.com/v4/letter/b/46a35a/32.png) [@Brian\_Shin](https://forum.inductiveautomation.com/u/Brian_Shin)\
**Post date:** [September 21, 2023, 7:25pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/9 "2023-09-21T19:25:49Z")

</div>

Promise.

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [September 21, 2023, 7:30pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/10 "2023-09-21T19:30:49Z")

</div>

> [@Brian\_Shin](#):
>
> TypeError: 'bool' object is not iterable

You are likely not passing your tag value as a list. Try enclosing your tag value in `[]` like `system.tag.writeAsync([self.view.custom.UDT.HighAlarmEnablePB],[1])`

Edit: Actually, have you confirmed that `self.view.custom.UDT.HighAlarmEnablePB` is a tagpath? How are you passing the tag path to view now that you are trying to make it dynamic?

---

<div class="post-metadata">

**Author:** ![bkarabinchak.psi](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bkarabinchak.psi/32/83567_2.png) [@bkarabinchak.psi](https://forum.inductiveautomation.com/u/bkarabinchak.psi)\
**Post date:** [September 21, 2023, 7:59pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/11 "2023-09-21T19:59:35Z")

</div>

It seems like you're passing the actual value of the HighAlarmEnablePB (as hinted at by the error `bool is not iterable`) it's trying to coerce what you're feeding it into what it expects, a list of _tag paths_. You need the actual tag path to write to.

---

<div class="post-metadata">

**Author:** ![Brian\_Shin](https://avatars.discourse-cdn.com/v4/letter/b/46a35a/32.png) [@Brian\_Shin](https://forum.inductiveautomation.com/u/Brian_Shin)\
**Post date:** [September 21, 2023, 8:01pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/12 "2023-09-21T20:01:24Z")

</div>

When I try with the , it now says, `TypeError: expected a str`

There's an analog object that has the TagPath initially set by the user. When the user presses the object, that TagPath is then sent to the popup graphic. The popup graphic then has the whole UDT at it's disposal on the `view.custom.UDT`

---

<div class="post-metadata">

**Author:** ![ryan.white](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/ryan.white/32/73193_2.png) [@ryan.white](https://forum.inductiveautomation.com/u/ryan.white)\
**Post date:** [September 21, 2023, 8:02pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/13 "2023-09-21T20:02:24Z")

</div>

> [@Brian\_Shin](#):
>
> When I try with the , it now says, `TypeError: expected a str`

Means this:

> [@bkarabinchak.psi](#):
>
> It seems like you're passing the actual value of the HighAlarmEnablePB (as hinted at by the error `bool is not iterable`)

> [@Brian\_Shin](#):
>
> that TagPath is then sent to the popup graphic.

Use this parameter to build the path to the udt member, something along the line of `udtAlarmPBPath = "{}/HighAlarmEnablePB".format(event.view.params.UDTTagPath)` then use the created path in the call to `system.tag.writeAsync`

The other(possibly better) way to build the path to the alarm member would be to create a custom property on the view and bind an expression to it that is along the lines of `concat(view.params.UDTTagPath, "/HighAlarmEnablePB")`. You'd then reference this custom property to in your script to get the path to the alarm pb member of the udt.

---

<div class="post-metadata">

**Author:** ![Felipe\_CRM](https://avatars.discourse-cdn.com/v4/letter/f/dfb087/32.png) [@Felipe\_CRM](https://forum.inductiveautomation.com/u/Felipe_CRM)\
**Post date:** [September 21, 2023, 8:09pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/14 "2023-09-21T20:09:01Z")

</div>

EDIT: whoops, didn't notice ryan already beat me to the first part of this post

As for trying to pulse the value high and then low from Perspective, I would recommend you move that logic over to the PLC. If something happens between when you write `1` and when you write `0` (say there's a hiccup in the network), the tag will stay `1` which may just cause an annoying bug or could cause trouble depending on what it's controlling.

---

<div class="post-metadata">

**Author:** ![Brian\_Shin](https://avatars.discourse-cdn.com/v4/letter/b/46a35a/32.png) [@Brian\_Shin](https://forum.inductiveautomation.com/u/Brian_Shin)\
**Post date:** [September 21, 2023, 8:26pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/15 "2023-09-21T20:26:38Z")

</div>

That did it. Thanks so much!!

---

<div class="post-metadata">

**Author:** ![Brian\_Shin](https://avatars.discourse-cdn.com/v4/letter/b/46a35a/32.png) [@Brian\_Shin](https://forum.inductiveautomation.com/u/Brian_Shin)\
**Post date:** [September 21, 2023, 8:27pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/16 "2023-09-21T20:27:32Z")

</div>

I agree, it's not the best solution, but it's only a "push button" to enable/disable an alarm. Not process critical thankfully.

---

<div class="post-metadata">

**Author:** ![amy.sudibyo](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amy.sudibyo/32/38659_2.png) [@amy.sudibyo](https://forum.inductiveautomation.com/u/amy.sudibyo)\
**Post date:** [September 22, 2023, 12:52am UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/17 "2023-09-22T00:52:13Z")

</div>

If the ultimate goal is to simply toggle the EnableMode tag on or off, I don't see the need to have an additional 'momentary' tag. You've already got a custom prop on your view reading the value of your UDT, correct? So you could just check what the mode is and then use that to determine the write value.

```auto
currentMode = self.view.custom.UDT.HighAlarmEnableMode
writeVal = not(currentMode)

system.tag.writeAsync([tagPath],[writeVal])

```

---

<div class="post-metadata">

**Author:** ![Brian\_Shin](https://avatars.discourse-cdn.com/v4/letter/b/46a35a/32.png) [@Brian\_Shin](https://forum.inductiveautomation.com/u/Brian_Shin)\
**Post date:** [September 22, 2023, 1:16pm UTC](https://forum.inductiveautomation.com/t/perspective-scripting-to-find-a-custom-property-on-a-view/79466/18 "2023-09-22T13:16:32Z")

</div>

You are correct. The momentary bit is unnecessary, but the momentary bit is already in the AOI. The logic in the AOI prevents the EnableMode tag to be written to. It would be easy to change, but the ask has been to leave the AOI as is.
