diff --git a/src/scripts/write_variable.py b/src/scripts/write_variable.py index d77862a..f014bf1 100644 --- a/src/scripts/write_variable.py +++ b/src/scripts/write_variable.py @@ -13,50 +13,42 @@ try: online_app, target_app = ensure_online_connection(primary_project) app_name = getattr(target_app, 'get_name', lambda: "Unknown")() - # The write counterpart of read_value() has shifted across CODESYS SPs. - # Some expose 'write_value(name, value)', some 'set_value(...)', - # and some only the batch form 'write_values([(name, value), ...])'. - # Probe each available method, then fall back to dumping the available - # methods on online_app so future debug sessions know what's exposed. - candidates = [] - - # Single-write methods, (name, value) style - for method_name in ('write_value', 'set_value', 'write', 'set'): - if hasattr(online_app, method_name): - candidates.append((method_name + '(name, value)', method_name, [(VARIABLE_PATH, VARIABLE_VALUE)])) - - # Batch-write methods, [(name, value), ...] style - for method_name in ('write_values', 'set_values'): - if hasattr(online_app, method_name): - candidates.append((method_name + '([(name, value)])', method_name, [[(VARIABLE_PATH, VARIABLE_VALUE)]])) - - if not candidates: - # No known method exposed. Dump diagnostic. - attrs = sorted([a for a in dir(online_app) if not a.startswith('_')]) - raise TypeError( - "Online application exposes no known write method " - "(tried write_value/set_value/write/set/write_values/set_values).\n" - "Available attributes: %s" % attrs - ) - + # SP21+/SP22 uses a two-step prepare-then-write pattern: + # 1) set_prepared_value(name, value) -- stage the value + # 2) write_prepared_values() -- commit the staged writes + # Older SPs (and some sandboxed configurations) expose direct + # write_value(name, value) / write(name, value). Try the modern path + # first, fall back to direct. written = False last_err = None - for desc, method_name, args_list in candidates: + + if hasattr(online_app, 'set_prepared_value') and hasattr(online_app, 'write_prepared_values'): try: - getattr(online_app, method_name)(*args_list) - print("DEBUG: %s OK" % desc) + online_app.set_prepared_value(VARIABLE_PATH, VARIABLE_VALUE) + online_app.write_prepared_values() + print("DEBUG: set_prepared_value + write_prepared_values OK") written = True - break except Exception as e: last_err = e - print("DEBUG: %s failed: %s: %s" % (desc, type(e).__name__, e)) + print("DEBUG: set_prepared_value + write_prepared_values failed: %s: %s" % (type(e).__name__, e)) + + if not written: + for method_name in ('write_value', 'set_value', 'write', 'set'): + if not hasattr(online_app, method_name): + continue + try: + getattr(online_app, method_name)(VARIABLE_PATH, VARIABLE_VALUE) + print("DEBUG: %s(name, value) OK" % method_name) + written = True + break + except Exception as e: + last_err = e + print("DEBUG: %s(name, value) failed: %s: %s" % (method_name, type(e).__name__, e)) if not written: - # All known method names were exposed but every call failed. Dump - # diagnostic + last error so we can iterate. attrs = sorted([a for a in dir(online_app) if not a.startswith('_')]) raise RuntimeError( - "All known write methods were rejected. Last error: %s\n" + "Could not write variable. Last error: %s\n" "Available attributes on online_app: %s" % (last_err, attrs) )