Need help creating a counter in a Timer Gateway Event

I want to create a Gateway Event that will add 1 to the value of a memory tag every second when a certain tag is true.
The end goal is to make it so that the Memory tag (MemTag1) will reset to 0 when it goes below 0 and reset to 9 when it goes above 9.
For now I at least need it to add 1 every second when the (GoingUpTag) is true and subtract 1 every second when the (GoingDownTag) is true.

I’ve tried everything I can think to and that I’ve found online but all I’ve ended up with is this, which hasn’t been working:

newval = (system.tag.read(“MemTag1”))
if “GoingUpTag” == 1:newval + 1
system.tag.write(“MemTag1”,newval)

Thank you for any help.

First, it looks like you are missing a ‘.value’ on your system.tag.read so you are referencing a QualifiedValue object rather than the memory tag’s value.
Second, you are not actually reading the value of ‘GoingUpTag’, you are just directly comparing the string ‘GoingUpTag’ to 1, which will always return false.
Here is my example:

currVal = system.tag.read('MemTag1').value
bool = system.tag.read('GoingUpTag').value
currVal = currVal + 1 if bool else currVal - 1
if 0 <= currVal <= 9:
	system.tag.write('MemTag1', currVal)

Thank you for helping,
I understand what you mean in your first and second points and I see what I did wrong. I plugged in your code though and it did not seem to work for me. The value of “MemTag1” just stays 0. could there possibly be an issue in the third line? Because setting the values of currVal and bool makes sense to me and I have no idea why that wouldn’t work, but on line 3 will it read the value bool as true/false and execute the code before it in the line or would the code need to be after the if statement?

The syntax is fine. Show us how you ‘plugged’ the code.

Few things though: Use system.tag.readBlocking() or system.tag.readAsync instead of just read(). Which should have been readAll() in the first place, considering there are several tags to read.

val, up = [tag.value for tag in system.tag.readBlocking(["MemTag1", "GoingUpTag"])]
val = val + 1 if up else val -1

What I’m most curious about though, is what you’re trying to do.
Also, can’t a memory tag be configured to clamp to a lower and higher bound ?

You are right, it can be set to a lower and higher bound, which was an oversight on my part.
For what I’m trying to do: I’m essentially creating an animation with ten different pictures in it and I want to use the counter tag and a modulo operator to cycle the visibility of the different pictures.
I know its a strange way to do it but with no access to vision and a timer component I don’t know another way to do it.

I forgot to specify though, the animation does have to go both forwards and backwards, which is why I need to counter to both count up and count back.

So right now @pascal.fragnoud I’ve got this:

currVal = system.tag.readBlocking(“MemTag1”)
bool = system.tag.readBlocking(“GoingUpTag”)
currVal = currVal + 1 if bool else currVal - 1
if 0 <= currVal <= 9:
system.tag.write(“MemTag1”, currVal)

If its not already evident I’m fairly new to this so please pardon my ignorance, but are you saying that I should replace:

currVal = system.tag.readBlocking(“MemTag1”)
bool = system.tag.readBlocking(“GoingUpTag”)
currVal = currVal + 1 if bool else currVal - 1

with:

val, up = [tag.value for tag in system.tag.readBlocking([“MemTag1”, “GoingUpTag”])]
val = val + 1 if up else val -1

Yes. Several reasons:

  1. Try, as much as possible, to read all tags at once. It’s much more efficient. I also find it improves the readability to have all reads in one place.
  2. currVal = system.tag.readBlocking(“MemTag1”) This will return a list of qualified values. So trying to use this in operations would fail. It should, if reading just one tag, be currVal = system.tag.readBlocking(“MemTag1”)[0].value.
  3. the variable name currVal is fine, bool on the other hand is not. It doesn’t convey any meaning about what it is, except for the fact that it’s a boolean. up might be a bit too simple, but goingUp or goingForward should make things clear enough.

One last thing: That piece of code doesn’t check for tag qualities. It might be a good idea to check those, just in case something goes wrong.

paths = [“MemTag1”, “GoingUpTag”]
qvals = system.tag.readBlocking(paths)
bad_reads = [path for path, qval in zip(paths, qvals) if qval.quality.isNotGood()]
if bad_reads:
	logger.warn("bad qualities for {}".format(bad_reads))
	# you might want to return early from the script if tags are bad. It's up to you to check for what could go wrong.
	return 

currVal = currVal + 1 if goingUp else currVal -1
write_return = system.tag.writeBlocking([“MemTag1”], [currVal])
if write_return.isNotGood():
	logger.warn("tag write failed for 'MemTag1'")

That being said, I’m quite sure there’s a better way to do all this. While I’m not certain about what you want to do, at the very least incrementing or decrementing a tag based on two booleans could be done in an expression tag.
I don’t have ignition running on this machine to test things up or even verify the syntax, so I won’t try and give you an example, though.

@pascal.fragnoud
You are probably correct, although I am unsure how to proceed to do that.
The reason I am doing it this way is because I had done a similar thing on another machine.
Essentially what I’m doing is creating a floor map of machinery and I’m animating the pictures I am making by making a few separate pictures and cycling their visibility with a modulus operator.
For example:

2 = {[default]AnimationTag1}%8 && if({[MQTT Engine]rt/Infeed_Conveyer_Q}=true,true,false)

I am using another memory tag for that example (AnimationTag1) with a gateway event like so:

newval = (system.tag.read("[default]AnimationTag1")).value + 1
system.tag.write("[default]AnimationTag1", newval)

For that though the animation just cycles through so that it doesn’t have to go back ever it just resets and keeps going. For this animation its essentially a ram that slowly pushes forward and then reverses and I’m trying to get a tag that will count up when its moving forward (indicated by a tag with a Boolean value) and then count down when reversing, thereby reversing the animation (which has 10 separate pictures).

If that helps explain what I’m going for better that’s great, but if not thank you for helping!

Since this is perspective you should be using a CSS transform and @keyframes to accomplish this.

If you need it to be bound to a tag, you can place a binding on the style to add the needed class.

I don’t have the ability to really work up a good example.

Maybe @victordcq will swing by.

A search in the forum might give you enough to get started.

Does it need to have 10 different pictures or are you just doing that rn?

it shouldnt be to hard for css animation to make something move, the designer doesnt seem to like it very much tho xD
testAnimate.zip (4.4 KB)

Not sure if its ideal for what you want tho, getting this to sync up across multiple clients is not a bit messy, but can be done by setting up the animation delay with a minus value to make it start halfwaythtough or something.
pause is easy tho, i bound it to a button (since the animation seems to work even in designer mode xd