Derived Tag Write Expression throwing Bad_ReadOnly when the source tag is not being referenced at all

I am still trying to build dynamic UDTs, and I am so close! The only problem I have yet to overcome is how to use inferred values for referencing other tags, for writing. I can do it for reading with a small expression, but standard Expression Tags can't write. Derived tags at least seem like they are designed to allow the expression language to write.

After multiple iterations, I have something that looks like this (with the associated error if I manually change the setpoint value in the Tag Browser, which is how I test it):

I understand that {source} is the text representing the path I want to reference, but there doesn't seem to be a dereferencing operator that does precisely what I want (like float theVal = *_refTarget).
The tag({source}) term effectively de-references the tag path stored in _refTarget (I know this because it works for reading out variables in other places), and the script "writeToByRef" is simply

def writeToByRef(tag_path, value):
	system.tag.writeBlocking([tag_path], value)

I have confirmed this works in the script editor, using the text contained in my [.]_refTarget variable.

Given the error that it can't write to the source, I am a bit confused as I thought I had hijacked the write expression to not even bother writing to the source tag. Is this a protective mechanism that maybe I can disable? Or maybe there is an actual way to do this directly in the expression language?

Don't write within the write expression. Return the value to be written. That's what expressions do--return values. The {source} given to the write expression is the value written to your derived tag, that you are responsible for converting as appropriate into a value suitable for the linked tag.

Sigh. You are so hung up on object orientation that you refuse to use the platform as designed.

I'd rather do this! It's what I tried first, but I couldn't get past the "source tag is read only" error (it isn't) (the tag referred to by the path stored in [.]_refTarget isn't), but [.]_refTarget is an expression (I want it to be a reference, but it doesn't seem to work, see below).

It may also be because the _refTarget is a path itself, not the actual tag, and I can't seem to dereference it.

With a 'Source Tag Path' of [.]_refTarget, which returns a string tag path, your read expression should just be {source} and your write expression should just be {value}. That's it. A derived tag is already indirect. You don't need to use one for this purpose at all (a reference tag would suffice) - a derived tag is meant for intercepting an outgoing value from the source tag and rewriting it in a more complex way than simple tag scaling can perform.
The canonical example would be an OPC tag returning temp in celsius.
A derived tag could be used for a bidirectional temp-in-fahrenheit tag, by performing the appropriate conversion on read and write. No scripting necessary, and in fact scripting in derived tags is pretty much always a bad pattern, in my opinion.

1 Like

So for clarity (because I did try this, and it doesn't seem to work as I hoped): _refTarget is an Expression Tag that builds a path based on the UDT parameters:

image

I want to use the resulting value as the target for my true IO, but I can't do it back through that because it is an Expression (read-only). If I try to change that to a Reference Tag (what I did initally), I get this:

image

this yields no resulting value, with a Quality of Uncertain_InitialValue (irrespective of if I try to use a float or a string or an int -- the actual value at the example tag is a float). This does yield a value in Expression mode, just not in Reference mode.

Putting just {source} and {value} in my setpoint variable does not work -- if I do it in String type (the value should be a float), I get the tag path stored in [.]_refTarget, if I do it in Float, I get a type error (which makes sense if it is just getting the path.

What I really want is to somehow do what feels like it should be {[.]_refTarget} in the Source Tag Path, but if I do that I get a Error_Configuration. I want the path stored at the address given! Same with the previous attempt -- if I try to do the following for my setpoint variable, I get an Uncertain_InitialValue (not an error in config):

Here's a really simple instance of my problem -- just a toggle switch. I have a base type that holds some standardized metadata, I used that as the base UDT and then added a single variable state that should link to the tag whose path is stored in _refTarget:

I had this working somehow yesterday but I can't remember exactly how I did it (this one might have been on a previous less-generalized schema), but the Tag Browser deleted multiple of my UDT types somehow when I erroneously clicked and slightly dragged, so I am starting over anyway.

This is an example of how I was successfully reading values, although it does not work for writing:

Kind of off topic but related. I have an UDT OPC tag where the value of the tag needs to be multiplied by 0.1. A derived tag works but then two UDTs need to be defined, one as OPC and the second as Derived do multiplication can be done. Is there a better way?