Checking which bits changed in a word logging fake entries

So i have a word where each bit represents an alarm from a different compartment the problem is that it keeps recording non existent alarms.

Here is the script i put on tag change:

	#Exit if tag quality bad
	if not (previousValue.quality.isGood() and currentValue.quality.isGood()):
		return 0
		
	# Calculate the bits that changed using XOR
	changedBits = previousValue.value ^ currentValue.value
	
	# Initialize lists to store the changes
	true_changes = []
	false_changes = []
	
	# Loop over each bit position (0 to 15 for 16 bits)
	for i in range(16):
		# Check if the ith bit has changed by checking the corresponding bit in changedBits
		bit_changed = (changedBits >> i) & 1
		
		if bit_changed:
			# Check the state of the bit in the current value
			isTrue = (currentValue.value >> i) & 1
			
			# Append to the appropriate list based on whether the bit has changed and its current value
			if isTrue:
				true_changes.append(i)
			else:
				false_changes.append(i)
	
	for Num in true_changes:
		system.db.runNamedQuery("SMP_Caster", "EAF/BAGH Event Start", {
			"Equipment": "Compartment",
			"BH": tagPath.rsplit('/', 1)[0][-1],
			"Num": Num,
			"Event": "BLD"
		})
		
	for Num in false_changes:
		system.db.runNamedQuery("SMP_Caster", "EAF/BAGH Event End", {
			"Equipment": "Compartment",
			"BH": tagPath.rsplit('/', 1)[0][-1],
			"Num": Num,
			"Event": "BLD"
		})

It is extremely likely that your event script execution is overlapping with more tag changes. The simplest solution is to make individual tags for each bit, and react to the individual bit changes that way. If you must use a tag's valueChange event, be sure to use the "SF" version of the system calls to run your inserts. Regular database operations don't run fast enough for tag events. (Or use a gateway project tag change event, instead of a tag's valueChange event.)

1 Like

I am flexible but tag change just seemed the easiest way for me. The other way i know of is to split the tag into 16 separate boolean and make a transaction group for each one being its own trigger. One time when it changes to true the other time when it turns to false. Since it is a twin mill that is 64 events. Please let me know if there is a better way.

Split all of your integer tags into individual boolean tags.

Configure one gateway tag change event script.

Add all of the booleans to its subscription list.

Use the event information in your script to determine which tag it is so you can prepare your NQ parameters. Include the change event's new current value boolean as an NQ parameter and store it in a DB column.

Is there an SF version of named queries? I only found these

https://www.docs.inductiveautomation.com/docs/8.1/appendix/scripting-functions/system-db/system.db.runSFNamedQuery

1 Like