Write an expression using a script on alarm

Hi everyone,

I would like to be able to create a script that changes the alarm expression, I managed to get it this far but it only accepts integers or floats if I do an expression it doesnt work:

def rebuild_alarm_with_expression(tag_path):
    configs = system.tag.getConfiguration(tag_path, True)
    if not configs:
        return

    config = configs[0]

    
    config["alarms"] = []

    alarm = {
        "name": "Critical",
        "mode": "OutsideValues",
        "priority": "Critical",
        "enabled": True,

        
        "setpointA": '{[.]temp_1_sp} - 25',
        "setpointB": '{[.]temp_1_sp} + 25'
        
    }


    config["alarms"].append(alarm)

    parent_path = tag_path.rsplit("/", 1)[0]
    config["name"] = tag_path.rsplit("/", 1)[1]

    system.tag.configure(parent_path, [config], "o")


rebuild_alarm_with_expression("[default]HMIs/test/tag_temp_1")

what is not working about the expression? Are you getting any errors?

No errors just wont change the value, if I put in a 20 for instance it’ll show 20 but if I then put this '{[.]temp_1_sp} - 25', it’ll still show the 20 so it wont accept it

Create the tag alarm with the expression you want, or an example at least, and see check the tag json. It's going to have an object value instead of a string

This would be the json of a test tag with what I would want to be written in the script:

{
"valueSource": "memory",
"alarms": [
{
"mode": "OutsideValues",
"name": "Critical",
"label": "Test Tag 1 Critical",
"priority": "High",
"displayPath": "Test Tag 1 Critical",
"setpointA": {
"bindType": "Expression",
"value": "{[.]TestSP} - 5"
},
"setpointB": {
"bindType": "Expression",
"value": "{[.]TestSP} + 5"
}
}
],
"name": "testTag",
"value": 1,
"tagType": "AtomicTag"
}

So you can see that this is the value of setpoint A, which is what you need to configure it with

I tried this but it still isnt working

def rebuild_alarm_with_expression(tag_path):
    configs = system.tag.getConfiguration(tag_path, True)
    if not configs:
        return

    config = configs[0]

    
    config["alarms"] = []

    alarm = {
      "mode": "OutsideValues",
      "name": "Critical",
      "label": "Test Tag 1 Critical",
      "priority": "High",
      "displayPath": "Test Tag 1 Critical",
      "setpointA": {
        "bindType": "Expression",
        "value": "{[.]TestSP} - 5"
      },
      "setpointB": {
        "bindType": "Expression",
        "value": "{[.]TestSP} + 5"
      }
    }


    config["alarms"].append(alarm)

    parent_path = tag_path.rsplit("/", 1)[0]
    config["name"] = tag_path.rsplit("/", 1)[1]

    system.tag.configure(parent_path, [config], "o")


rebuild_alarm_with_expression("[default]HMIs/test/tag_temp_1")

Any errors? I’d add print statements to see what it's doing

no errors but it also isnt actually writing anything the new tag

Curious so I asked the AI overlords. Seems to be an issue with configure trying to overwrite read-only values when you write it back in. It suggested to only build alarms and name in config and then use "m" to merge instead of overwrite. There is also an example #3 in the documentation you can reference as an example though that's for creating one rather than modifying one.

This code fails silently because of how system.tag.getConfiguration and system.tag.configure interact.

You are fetching the entire configuration of the tag (including read-only properties like lastModified, quality, tagPath, accessRights, etc.) and feeding it straight back into configure.

When system.tag.configure sees these read-only properties in "Overwrite" ("o") mode, it often rejects the update or behaves unpredictably because it cannot overwrite those system-managed properties.

Collision Policy "m" (Merge):

  • Using "o" (Overwrite) on a tag when you only provide the alarms property is dangerous. It might convert your tag into a generic Folder or remove its Data Type.
  • Using "m" (Merge) ensures we only update the alarms list without touching the rest of the tag configuration.

I saw this too, the problem is that it works fine if I just write an integer but if I write an expression that is when it does nothing

Expressions are only auto-interpreted in the designer. In a configure script, you have to provide the object (dictionary, typically) that represents the binding expression, and it cannot be set with system.tag.write*().