Skip to content

Commit 201a05b

Browse files
committed
basic write support for 16bit and 8bit flags - UNTESTED
1 parent fdc8d08 commit 201a05b

1 file changed

Lines changed: 29 additions & 2 deletions

File tree

classes/transports/modbus_base.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,9 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type
392392
self._log.error(f"WRITE_ERROR: Invalid value in register '{current_value}'. Unsafe to write")
393393
#raise ValueError(err)
394394

395-
if not self.protocolSettings.validate_registry_entry(entry, value):
396-
self._log.error(f"WRITE_ERROR: Invalid new value, '{value}'. Unsafe to write")
395+
if not (entry.data_type == Data_Type._16BIT_FLAGS or entry.data_type == Data_Type._8BIT_FLAGS or entry.data_type == Data_Type._32BIT_FLAGS): #skip validation for write; validate further down
396+
if not self.protocolSettings.validate_registry_entry(entry, value):
397+
self._log.error(f"WRITE_ERROR: Invalid new value, '{value}'. Unsafe to write")
397398

398399
#handle codes
399400
if entry.variable_name+"_codes" in self.protocolSettings.codes:
@@ -438,6 +439,32 @@ def write_variable(self, entry : registry_map_entry, value : str, registry_type
438439

439440
if check_value != new_val:
440441
raise ValueError("something went wrong bitwise")
442+
elif entry.data_type == Data_Type._16BIT_FLAGS or entry.data_type == Data_Type._8BIT_FLAGS or entry.data_type == Data_Type._32BIT_FLAGS:
443+
#16 bit flags
444+
flag_size : int = Data_Type.getSize(entry.data_type)
445+
446+
if re.match(r"^[0-1]{"+flag_size+"}$", current_value): #bitflag string
447+
#is string of 01... s
448+
# Convert binary string to an integer
449+
value = int(current_value, 2)
450+
451+
# Ensure it fits within ushort range (0-65535)
452+
if value > 65535:
453+
return self._log.error(f"WRITE_ERROR: '{value}' Exceeds 65535. Unsafe to write")
454+
else:
455+
return self._log.error(f"WRITE_ERROR: Invalid new value for bitflags, '{value}'. Unsafe to write")
456+
457+
#apply bitmasks
458+
bit_index = entry.register_bit
459+
bit_mask = ((1 << bit_size) - 1) << bit_index # Create a mask for extracting X bits starting from bit_index
460+
clear_mask = ~(bit_mask) # Mask for clearing the bits to be updated
461+
462+
# Clear the bits to be updated in the current_value
463+
ushortValue = registry[entry.register] & clear_mask
464+
465+
# Set the bits according to the new_value at the specified bit position
466+
ushortValue |= (value << bit_index) & bit_mask
467+
441468
else:
442469
raise TypeError("Unsupported data type")
443470

0 commit comments

Comments
 (0)