From 877915ae38951a8aa8c2a6333f72e896ed9b0acf Mon Sep 17 00:00:00 2001 From: Gertjan Koolen Date: Tue, 17 Mar 2026 09:48:12 +0100 Subject: [PATCH 01/14] frequency avoidance - work in progress --- scanner.py | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/scanner.py b/scanner.py index 2fecf56..153c6ae 100644 --- a/scanner.py +++ b/scanner.py @@ -27,6 +27,8 @@ PATTERN = re.compile( r"(?P[0-9a-fA-F]+)\s+" # Second hex r"(?P[0-9a-fA-F]+)-" # Third hex r"(?P[0-9a-fA-F]+)" # Fourth hex + r"nv=(?P-?\d+\.?\d*)\s+" # voltage noise/interference + r"ni=(?P-?\d+\.?\d*)\s+" # current noise/interference ) config_path = '/home/bart/python-scanner/config.yaml' @@ -63,12 +65,12 @@ def dump_into_database(): if state["noise_scan"]==False: # regular scan data formatted_rows = [ - [sweep_insert_time, r[0], r[5], r[6], r[1], r[2], r[3], r[4]] + [sweep_insert_time, r[0], r[5], r[6], r[1], r[2], r[3], r[4], r[11], r[12]] for r in data_rows ] sql = """ - INSERT INTO SequenceValues (StartTimeOfSweep, Freq, ZR, ZX, Vampl, Vphase, Iampl, Iphase) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) \ + INSERT INTO SequenceValues (StartTimeOfSweep, Freq, ZR, ZX, Vampl, Vphase, Iampl, Iphase, Vnoise, Inoise) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) \ """ else: # noise scan data @@ -97,7 +99,7 @@ def dump_into_database(): def dump_csv(filename="data.csv"): df = pd.DataFrame( data_rows, - columns=["Freq", "Va", "Vp", "Ia", "Ip", "ZR", "ZX", "adc_vmin", "adc_vmax", "adc_imin", "adc_imax"] + columns=["Freq", "Va", "Vp", "Ia", "Ip", "ZR", "ZX", "adc_vmin", "adc_vmax", "adc_imin", "adc_imax", "nv", "ni"] ) df.to_csv(filename, index=False) @@ -134,17 +136,19 @@ def extract_to_dataframe(line): if not match: return # silently ignore malformed lines row = [ - float(state["freq"]), - float(match.group("Va")), - float(match.group("Vp")), - float(match.group("Ia")), - float(match.group("Ip")), - float(match.group("ZR")), - float(match.group("ZX")), - int(match.group("adc_vmin"), 16), - int(match.group("adc_vmax"), 16), - int(match.group("adc_imin"), 16), - int(match.group("adc_imax"), 16), + float(state["freq"]), # row 0 + float(match.group("Va")), # row 1 + float(match.group("Vp")), # row 2 + float(match.group("Ia")), # row 3 + float(match.group("Ip")), # row 4 + float(match.group("ZR")), # row 5 + float(match.group("ZX")), # row 6 + int(match.group("adc_vmin"), 16), # row 7 + int(match.group("adc_vmax"), 16), # row 8 + int(match.group("adc_imin"), 16), # row 9 + int(match.group("adc_imax"), 16), # row 10 + float(match.group("nv")), # row 11 + float(match.group("ni")), # row 12 ] row[1] = row[1]/(2*3.14159*row[0]*0.00005 + 1) # compensate Va for pole at 20kHz row[5] = row[1]/row[3] * math.cos(0.01745*(row[2]-row[4])) @@ -160,7 +164,7 @@ def process_line(line): def get_dataframe(): return pd.DataFrame( data_rows, - columns=["Va", "Vp", "Ia", "Ip", "ZR", "ZX", "adc_vmin", "adc_vmax", "adc_imin", "adc_imax"] + columns=["Va", "Vp", "Ia", "Ip", "ZR", "ZX", "adc_vmin", "adc_vmax", "adc_imin", "adc_imax", "nv", "ni"] ) class TelnetReader: From 5d20d50822527414d8da114dc98dbb8bf972788d Mon Sep 17 00:00:00 2001 From: Gertjan Date: Tue, 17 Mar 2026 12:33:19 +0100 Subject: [PATCH 02/14] Interference avoidance is tested and working (on-desk) --- .gitignore | 1 + scanner.py | 88 +++++++++++++++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 38 deletions(-) diff --git a/.gitignore b/.gitignore index 21d0b89..fa1a06e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .venv/ +config.yaml \ No newline at end of file diff --git a/scanner.py b/scanner.py index 153c6ae..4b2e645 100644 --- a/scanner.py +++ b/scanner.py @@ -6,7 +6,7 @@ import re import telnetlib3 import csv import time -import pyodbc +import pyodbc # XXXDB import math from datetime import datetime import yaml @@ -14,24 +14,21 @@ import os data_rows = [] # global 2-D list state = {} +blacklist = [] +ALLOWED_NOISE_LEVEL = 100.0 PATTERN = re.compile( - r"Va=(?P-?\d+\.?\d*)\s+" - r"Vp=(?P-?\d+\.?\d*)\s+\|\s+" - r"Ia=(?P-?\d+\.?\d*)\s+" - r"Ip=(?P-?\d+\.?\d*)\s+\|\s+" - r"ZR=(?P-?\d+\.?\d*)\s+" - r"ZX=(?P-?\d+\.?\d*)" - r".*?irq=\d+\s+" # Skip to 'irq=', match the first digits and space - r"(?P[0-9a-fA-F]+)-" # First hex - r"(?P[0-9a-fA-F]+)\s+" # Second hex - r"(?P[0-9a-fA-F]+)-" # Third hex - r"(?P[0-9a-fA-F]+)" # Fourth hex - r"nv=(?P-?\d+\.?\d*)\s+" # voltage noise/interference - r"ni=(?P-?\d+\.?\d*)\s+" # current noise/interference + r"Va=(?P[\d.-]+)\s+Vp=(?P[\d.-]+)\s+\|\s+" + r"Ia=(?P[\d.-]+)\s+Ip=(?P[\d.-]+)\s+\|\s+" + r"ZR=(?P[\d.-]+)\s+ZX=(?P[\d.-]+).*?\|\s+" # Skips R=... + r".*?irq=\w+\s+" # Skips the first irq value (59) + r"(?P[0-9a-fA-F]+)-(?P[0-9a-fA-F]+)\s+" + r"(?P[0-9a-fA-F]+)-(?P[0-9a-fA-F]+).*?\|\s+" + r"nv=(?P[\d.-]+)\s+ni=(?P[\d.-]+)" ) -config_path = '/home/bart/python-scanner/config.yaml' +config_path = '/home/bart/python-scanner/config.yaml' # XXXDB +#config_path = 'config.yaml' def load_yaml_config(state_dict): if os.path.exists(config_path): @@ -200,18 +197,20 @@ class TelnetReader: except KeyboardInterrupt: print("Interrupted by user.") print(data_rows) - if state["freq"]>0.00001: # check if scan endeed normally (e.g. no abort due to clipping) - #dump_csv("measurements.csv") - dump_into_database() - #append_line_to_file(0, "scan_freq.csv") - #append_line_to_file(1, "scan_Va.csv") - #append_line_to_file(2, "scan_Vp.csv") - #append_line_to_file(3, "scan_Ia.csv") - #append_line_to_file(4, "scan_Ip.csv") - #append_line_to_file(5, "scan_ZR.csv") - #append_line_to_file(6, "scan_ZX.csv") - #append_Nyquist_run("scan_Nyquist.csv") - #state["noise_scan"] = not state["noise_scan"] + if state["freq"]>0.00001: # check if scan ended normally (e.g. no abort due to clipping) + if False: + dump_into_database() + else: + dump_csv("measurements.csv") + #append_line_to_file(0, "scan_freq.csv") + #append_line_to_file(1, "scan_Va.csv") + #append_line_to_file(2, "scan_Vp.csv") + #append_line_to_file(3, "scan_Ia.csv") + #append_line_to_file(4, "scan_Ip.csv") + #append_line_to_file(5, "scan_ZR.csv") + #append_line_to_file(6, "scan_ZX.csv") + #append_Nyquist_run("scan_Nyquist.csv") + #state["noise_scan"] = not state["noise_scan"] else: print("scan aborted\r") gc.collect() # clean up internal memory (garbage collect) @@ -240,11 +239,14 @@ class TelnetReader: # there will be a lot of lines, but they will be skipped as they do not match the pattern else: # regular loop (not initializing) extract_to_dataframe(line) # capture the measurement + if data_rows and (data_rows[-1][11]>ALLOWED_NOISE_LEVEL or data_rows[-1][12]>ALLOWED_NOISE_LEVEL): + # Too much noise: add to blacklist + print("Too much noise - adding to blacklist") + blacklist.append({"Freq": state["freq"], "NrToSkip": 10}) + print(f"Blacklist: {blacklist}\r") + del data_rows[-1] # remove this last entry from the list (for DB it is okay, but for CSV things will shift) # print(f"minmax: {data_rows[7]},{data_rows[8]},{data_rows[9]},{data_rows[10] }\n") - if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): - #response = f"a{state["ampl"]:.1f}\r" # send ampl to trigger sweep - #self.tn.write(response.encode("utf-8")) - # there will be a lot of lines, but they will be skipped as they do not match the pattern + if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): # XXXDB state["freq"] = 0 # force ending of the scan, and write no data in the database # calculate next freq if state["freq"] > 1.0: @@ -255,13 +257,17 @@ class TelnetReader: else: freq_multiplier = state["freq_step_multiply"] ** 4 # skip 3/4 steps to speed up state["freq"] *= freq_multiplier - if (state["freq"]>40) and (state["freq"]<660) and ((state["freq"]%50<2.5) or (-state["freq"]%50<2.5)): - state["freq"] *= freq_multiplier # if near a 50Hz harmonic, skip to the next frequency - while (state["freq"]<0.6) and ((state["freq"]%state["interference_freq"]40) and (state["freq"]<660) and ((state["freq"]%50<2.5) or (-state["freq"]%50<2.5)): +# state["freq"] *= freq_multiplier # if near a 50Hz harmonic, skip to the next frequency +# while (state["freq"]<0.6) and ((state["freq"]%state["interference_freq"] 0.01: response = f"\rf{state["freq"]:.1f}\r" # new freq else: @@ -272,9 +278,9 @@ class TelnetReader: bandwidth = 0.5 response = f"b{bandwidth:.3f}\r" # new freq self.tn.write(response.encode("utf-8")) - state["remaining_receive_lines"] = 1 + 4/bandwidth + state["remaining_receive_lines"] = 2 + 4/bandwidth print(line) - print(state) +# print(state) state["initializing"] = 0 # Example: @@ -292,7 +298,7 @@ class TelnetReader: if __name__ == "__main__": reader = TelnetReader(host="localhost", port=2002) # reader = TelnetReader(host="10.1.122.152", port=2002) -# reader = TelnetReader(host="192.168.1.196", port=2002) +# reader = TelnetReader(host="192.168.1.235", port=2002) try: reader.connect() @@ -306,6 +312,12 @@ if __name__ == "__main__": state["initializing"] = 1; reader.read_loop() + # decrement all freq's in blacklist: + print(f"Before decrementing: {blacklist}") + for item in blacklist: + item["NrToSkip"] -= 1 + blacklist = [item for item in blacklist if item["NrToSkip"] != 0] # remove all zero items + print(f"After removing zeros: {blacklist}") finally: reader.disconnect() From 06f35acc4e8d5904306ea6540221b3f2a4005117 Mon Sep 17 00:00:00 2001 From: gertjan Date: Tue, 17 Mar 2026 23:20:26 +0100 Subject: [PATCH 03/14] tested and tuned on Veghel Lab system --- config.yaml | 8 ++++---- scanner.py | 20 +++++++++++--------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/config.yaml b/config.yaml index 6e3e2c2..5a2cb4e 100644 --- a/config.yaml +++ b/config.yaml @@ -1,9 +1,9 @@ # Configuration file for scanner service # it is automatically re-loaded between scans -start_freq: 10000.0 -stop_freq: 0.1 +start_freq: 1000 +stop_freq: 0.2 freq_step_multiply: 0.95 +allowed_noise_level: 9 +skip_scans_for_noisy_freqs: 5 ampl: 1600 -interference_freq: 0.052 -interference_bandwidth: 0.008 noise_scan: False diff --git a/scanner.py b/scanner.py index 4b2e645..f36a1a9 100644 --- a/scanner.py +++ b/scanner.py @@ -15,7 +15,7 @@ import os data_rows = [] # global 2-D list state = {} blacklist = [] -ALLOWED_NOISE_LEVEL = 100.0 +Inoise_baseline = 0.1 PATTERN = re.compile( r"Va=(?P[\d.-]+)\s+Vp=(?P[\d.-]+)\s+\|\s+" @@ -198,7 +198,7 @@ class TelnetReader: print("Interrupted by user.") print(data_rows) if state["freq"]>0.00001: # check if scan ended normally (e.g. no abort due to clipping) - if False: + if True: # XXXDB dump_into_database() else: dump_csv("measurements.csv") @@ -217,6 +217,7 @@ class TelnetReader: def process_line(self, line): global state + global Inoise_baseline # print(f"RAW: {line}") if not line.startswith("Va="): # skip lines that are not to be analyzed return @@ -239,15 +240,17 @@ class TelnetReader: # there will be a lot of lines, but they will be skipped as they do not match the pattern else: # regular loop (not initializing) extract_to_dataframe(line) # capture the measurement - if data_rows and (data_rows[-1][11]>ALLOWED_NOISE_LEVEL or data_rows[-1][12]>ALLOWED_NOISE_LEVEL): + if state["freq"]>3.0: + Inoise_baseline = 0.8*Inoise_baseline + 0.2*data_rows[-1][12] # remember last baseline around 3Hz (assuming top-down scanning) + if data_rows and (data_rows[-1][11]>state["allowed_noise_level"] or data_rows[-1][12]>state["allowed_noise_level"] or (state["freq"]<3.0 and data_rows[-1][12]>1.25*Inoise_baseline)): # Too much noise: add to blacklist print("Too much noise - adding to blacklist") - blacklist.append({"Freq": state["freq"], "NrToSkip": 10}) + blacklist.append({"Freq": state["freq"], "NrToSkip": state["skip_scans_for_noisy_freqs"]}) print(f"Blacklist: {blacklist}\r") del data_rows[-1] # remove this last entry from the list (for DB it is okay, but for CSV things will shift) -# print(f"minmax: {data_rows[7]},{data_rows[8]},{data_rows[9]},{data_rows[10] }\n") - if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): # XXXDB - state["freq"] = 0 # force ending of the scan, and write no data in the database + else: + if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): # XXXDB + state["freq"] = 0 # force ending of the scan, and write no data in the database # calculate next freq if state["freq"] > 1.0: freq_multiplier = state["freq_step_multiply"] # calc next freq @@ -313,11 +316,10 @@ if __name__ == "__main__": reader.read_loop() # decrement all freq's in blacklist: - print(f"Before decrementing: {blacklist}") for item in blacklist: item["NrToSkip"] -= 1 blacklist = [item for item in blacklist if item["NrToSkip"] != 0] # remove all zero items - print(f"After removing zeros: {blacklist}") + print(f"Blacklist: {blacklist}") finally: reader.disconnect() From f73dcd0a22055c92cfdd4fd18ed1f3436af8f955 Mon Sep 17 00:00:00 2001 From: Gertjan Koolen Date: Sat, 21 Mar 2026 23:57:29 +0100 Subject: [PATCH 04/14] Modified for new integrated readouts (Q command) - untested --- scanner.py | 117 +++++++++++++++++++++++------------------------------ 1 file changed, 50 insertions(+), 67 deletions(-) diff --git a/scanner.py b/scanner.py index f36a1a9..dea21da 100644 --- a/scanner.py +++ b/scanner.py @@ -25,7 +25,9 @@ PATTERN = re.compile( r"(?P[0-9a-fA-F]+)-(?P[0-9a-fA-F]+)\s+" r"(?P[0-9a-fA-F]+)-(?P[0-9a-fA-F]+).*?\|\s+" r"nv=(?P[\d.-]+)\s+ni=(?P[\d.-]+)" + r"QZR=(?P[\d.-]+)\s+QZX=(?P[\d.-]+)" ) +Va=16.376152 Vp=5.82 | Ia=30.656820 Ip=5.84 | ZR=0.534176 ZX=-0.000190 R=516.000 | freq=1000.0 ampl=100.0 | BW=0.500| irq=59 0c-7b 18-83 | nv=4.494 ni=8.487 | QZR=0.654321 QZX=12.123456 config_path = '/home/bart/python-scanner/config.yaml' # XXXDB #config_path = 'config.yaml' @@ -146,10 +148,9 @@ def extract_to_dataframe(line): int(match.group("adc_imax"), 16), # row 10 float(match.group("nv")), # row 11 float(match.group("ni")), # row 12 + float(match.group("QZR")), # row 13 + float(match.group("QZX")), # row 14 ] - row[1] = row[1]/(2*3.14159*row[0]*0.00005 + 1) # compensate Va for pole at 20kHz - row[5] = row[1]/row[3] * math.cos(0.01745*(row[2]-row[4])) - row[6] = row[1]/row[3] * math.sin(0.01745*(row[2]-row[4])) data_rows.append(row) def process_line(line): @@ -161,7 +162,7 @@ def process_line(line): def get_dataframe(): return pd.DataFrame( data_rows, - columns=["Va", "Vp", "Ia", "Ip", "ZR", "ZX", "adc_vmin", "adc_vmax", "adc_imin", "adc_imax", "nv", "ni"] + columns=["Va", "Vp", "Ia", "Ip", "QZR", "QZX", "adc_vmin", "adc_vmax", "adc_imin", "adc_imax", "nv", "ni"] ) class TelnetReader: @@ -218,73 +219,56 @@ class TelnetReader: def process_line(self, line): global state global Inoise_baseline -# print(f"RAW: {line}") + print(line) if not line.startswith("Va="): # skip lines that are not to be analyzed return - if state["remaining_receive_lines"] > 0 : - state["remaining_receive_lines"] -= 1 # we are waiting for settling - just skip the line - else: - # prepare new frequency measurement - if state["initializing"] == 1: - # since we just start a frequency scan, let's set the R, Max and Amplitude - response = f"\rr516\r" # set Resistance value for scaling HAL sensor - self.tn.write(response.encode("utf-8")) - response = f"m1600\r" # set max amplitude value - self.tn.write(response.encode("utf-8")) - # for noise scans the amplitude is zero, else the state["ampl"] - if state["noise_scan"]==True: - response = f"a0\r" # zero amplitude for noise measurement - else: - response = f"a{state["ampl"]:.1f}\r" # set amplitude - self.tn.write(response.encode("utf-8")) - # there will be a lot of lines, but they will be skipped as they do not match the pattern - else: # regular loop (not initializing) - extract_to_dataframe(line) # capture the measurement - if state["freq"]>3.0: - Inoise_baseline = 0.8*Inoise_baseline + 0.2*data_rows[-1][12] # remember last baseline around 3Hz (assuming top-down scanning) - if data_rows and (data_rows[-1][11]>state["allowed_noise_level"] or data_rows[-1][12]>state["allowed_noise_level"] or (state["freq"]<3.0 and data_rows[-1][12]>1.25*Inoise_baseline)): - # Too much noise: add to blacklist - print("Too much noise - adding to blacklist") - blacklist.append({"Freq": state["freq"], "NrToSkip": state["skip_scans_for_noisy_freqs"]}) - print(f"Blacklist: {blacklist}\r") - del data_rows[-1] # remove this last entry from the list (for DB it is okay, but for CSV things will shift) - else: - if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): # XXXDB - state["freq"] = 0 # force ending of the scan, and write no data in the database - # calculate next freq - if state["freq"] > 1.0: - freq_multiplier = state["freq_step_multiply"] # calc next freq - else: - if state["freq"] > 0.01: - freq_multiplier = state["freq_step_multiply"] ** 2 # skip 1/2 steps to speed up - else: - freq_multiplier = state["freq_step_multiply"] ** 4 # skip 3/4 steps to speed up - state["freq"] *= freq_multiplier -# if (state["freq"]>40) and (state["freq"]<660) and ((state["freq"]%50<2.5) or (-state["freq"]%50<2.5)): -# state["freq"] *= freq_multiplier # if near a 50Hz harmonic, skip to the next frequency -# while (state["freq"]<0.6) and ((state["freq"]%state["interference_freq"]3.0: + Inoise_baseline = 0.8*Inoise_baseline + 0.2*data_rows[-1][12] # remember last baseline around 3Hz (assuming top-down scanning) + if data_rows and (data_rows[-1][11]>state["allowed_noise_level"] or data_rows[-1][12]>state["allowed_noise_level"] or (state["freq"]<3.0 and data_rows[-1][12]>1.25*Inoise_baseline)): + # Too much noise: add to blacklist + print("Too much noise - adding to blacklist") + blacklist.append({"Freq": state["freq"], "NrToSkip": state["skip_scans_for_noisy_freqs"]}) + print(f"Blacklist: {blacklist}\r") + del data_rows[-1] # remove this last entry from the list (for DB it is okay, but for CSV things will shift) + else: + if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): # XXXDB + state["freq"] = 0 # force ending of the scan, and write no data in the database + # calculate next freq + if state["freq"] > 1.0: + freq_multiplier = state["freq_step_multiply"] # calc next freq else: - # program the health monitor to go to the next frequency: if state["freq"] > 0.01: - response = f"\rf{state["freq"]:.1f}\r" # new freq + freq_multiplier = state["freq_step_multiply"] ** 2 # skip 1/2 steps to speed up else: - response = f"\rf{state["freq"]:.3f}\r" # new freq - self.tn.write(response.encode("utf-8")) - bandwidth = state["freq"]/20 - if bandwidth > 0.5 : - bandwidth = 0.5 - response = f"b{bandwidth:.3f}\r" # new freq - self.tn.write(response.encode("utf-8")) - state["remaining_receive_lines"] = 2 + 4/bandwidth - print(line) -# print(state) - state["initializing"] = 0 + freq_multiplier = state["freq_step_multiply"] ** 4 # skip 3/4 steps to speed up + state["freq"] *= freq_multiplier + while (any(item["Freq"] == state["freq"] for item in blacklist)): + print("skipping freq") + state["freq"] *= freq_multiplier # skip all frequencies that are blacklisted + if state["freq"] <= state["stop_freq"]: + print("Reached stop frequency") + else: + # program the health monitor to go to the next frequency: + response = f"\rQ{state["freq"]:.3f}\r" # new freq + self.tn.write(response.encode("utf-8")) +# print(state) + state["initializing"] = 0 # Example: # value = self.extract_value(line) @@ -311,7 +295,6 @@ if __name__ == "__main__": load_yaml_config(state) # Load configuration settings state["freq"] = state["start_freq"]; - state["remaining_receive_lines"] = 0; state["initializing"] = 1; reader.read_loop() From a64bfe98c578e1e5c55a181602131f270d374c6d Mon Sep 17 00:00:00 2001 From: gertjan Date: Tue, 24 Mar 2026 01:28:34 +0100 Subject: [PATCH 05/14] debugged for Q mode integration --- scanner.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/scanner.py b/scanner.py index dea21da..1ae1ded 100644 --- a/scanner.py +++ b/scanner.py @@ -18,16 +18,15 @@ blacklist = [] Inoise_baseline = 0.1 PATTERN = re.compile( - r"Va=(?P[\d.-]+)\s+Vp=(?P[\d.-]+)\s+\|\s+" - r"Ia=(?P[\d.-]+)\s+Ip=(?P[\d.-]+)\s+\|\s+" - r"ZR=(?P[\d.-]+)\s+ZX=(?P[\d.-]+).*?\|\s+" # Skips R=... - r".*?irq=\w+\s+" # Skips the first irq value (59) + r"Va=(?P[\d.-]+)\s+Vp=(?P[\d.-]+)\s*\|\s*" + r"Ia=(?P[\d.-]+)\s+Ip=(?P[\d.-]+)\s*\|\s*" + r"ZR=(?P[\d.-]+)\s+ZX=(?P[\d.-]+).*?\|\s*" + r".*?irq=\w+\s+" r"(?P[0-9a-fA-F]+)-(?P[0-9a-fA-F]+)\s+" - r"(?P[0-9a-fA-F]+)-(?P[0-9a-fA-F]+).*?\|\s+" - r"nv=(?P[\d.-]+)\s+ni=(?P[\d.-]+)" + r"(?P[0-9a-fA-F]+)-(?P[0-9a-fA-F]+).*?\|\s*" + r"nv=(?P[\d.-]+)\s+ni=(?P[\d.-]+)\s*\|\s*" r"QZR=(?P[\d.-]+)\s+QZX=(?P[\d.-]+)" ) -Va=16.376152 Vp=5.82 | Ia=30.656820 Ip=5.84 | ZR=0.534176 ZX=-0.000190 R=516.000 | freq=1000.0 ampl=100.0 | BW=0.500| irq=59 0c-7b 18-83 | nv=4.494 ni=8.487 | QZR=0.654321 QZX=12.123456 config_path = '/home/bart/python-scanner/config.yaml' # XXXDB #config_path = 'config.yaml' @@ -64,7 +63,7 @@ def dump_into_database(): if state["noise_scan"]==False: # regular scan data formatted_rows = [ - [sweep_insert_time, r[0], r[5], r[6], r[1], r[2], r[3], r[4], r[11], r[12]] + [sweep_insert_time, r[0], r[13], r[14], r[1], r[2], r[3], r[4], r[11], r[12]] for r in data_rows ] sql = """ @@ -98,7 +97,7 @@ def dump_into_database(): def dump_csv(filename="data.csv"): df = pd.DataFrame( data_rows, - columns=["Freq", "Va", "Vp", "Ia", "Ip", "ZR", "ZX", "adc_vmin", "adc_vmax", "adc_imin", "adc_imax", "nv", "ni"] + columns=["Freq", "Va", "Vp", "Ia", "Ip", "QZR", "QZX", "adc_vmin", "adc_vmax", "adc_imin", "adc_imax", "nv", "ni"] ) df.to_csv(filename, index=False) @@ -151,6 +150,7 @@ def extract_to_dataframe(line): float(match.group("QZR")), # row 13 float(match.group("QZX")), # row 14 ] +# print(row) #### XX data_rows.append(row) def process_line(line): @@ -188,12 +188,14 @@ class TelnetReader: # Main loop: reads incoming lines forever try: while state["freq"] > state["stop_freq"]: - line = self.tn.read_until(b"\n") # read line - if not line: - break - - decoded = line.decode("utf-8", errors="ignore").strip() - self.process_line(decoded) # extract all info from line + if state["initializing"] == 1: + self.process_line("Va=") + else: + line = self.tn.read_until(b"\n") # read line + if not line: + break + decoded = line.decode("utf-8", errors="ignore").strip() + self.process_line(decoded) # extract all info from line except KeyboardInterrupt: print("Interrupted by user.") @@ -227,7 +229,7 @@ class TelnetReader: # since we just start a frequency scan, let's set the R, Max and Amplitude response = f"\rr516\r" # set Resistance value for scaling HAL sensor self.tn.write(response.encode("utf-8")) - response = f"m1600\r" # set max amplitude value + response = f"m1600\r" # set max amplitude value self.tn.write(response.encode("utf-8")) # for noise scans the amplitude is zero, else the state["ampl"] if state["noise_scan"]==True: From b07edd3839a7c36007d73b543fabc79a13e00e7a Mon Sep 17 00:00:00 2001 From: gertjan Date: Wed, 25 Mar 2026 11:17:22 +0100 Subject: [PATCH 06/14] Tested and working with new Q method --- scanner.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scanner.py b/scanner.py index 1ae1ded..3044700 100644 --- a/scanner.py +++ b/scanner.py @@ -16,6 +16,7 @@ data_rows = [] # global 2-D list state = {} blacklist = [] Inoise_baseline = 0.1 +n_clip_events = 0 PATTERN = re.compile( r"Va=(?P[\d.-]+)\s+Vp=(?P[\d.-]+)\s*\|\s*" @@ -221,6 +222,7 @@ class TelnetReader: def process_line(self, line): global state global Inoise_baseline + global n_clip_events print(line) if not line.startswith("Va="): # skip lines that are not to be analyzed return @@ -242,7 +244,7 @@ class TelnetReader: extract_to_dataframe(line) # capture the measurement if state["freq"]>3.0: Inoise_baseline = 0.8*Inoise_baseline + 0.2*data_rows[-1][12] # remember last baseline around 3Hz (assuming top-down scanning) - if data_rows and (data_rows[-1][11]>state["allowed_noise_level"] or data_rows[-1][12]>state["allowed_noise_level"] or (state["freq"]<3.0 and data_rows[-1][12]>1.25*Inoise_baseline)): + if data_rows and (state["freq"]>10) and (data_rows[-1][11]>state["allowed_noise_level"] or data_rows[-1][12]>state["allowed_noise_level"]): # or (state["freq"]<3.0 and data_rows[-1][12]>1.25*Inoise_baseline)): # Too much noise: add to blacklist print("Too much noise - adding to blacklist") blacklist.append({"Freq": state["freq"], "NrToSkip": state["skip_scans_for_noisy_freqs"]}) @@ -250,7 +252,11 @@ class TelnetReader: del data_rows[-1] # remove this last entry from the list (for DB it is okay, but for CSV things will shift) else: if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): # XXXDB - state["freq"] = 0 # force ending of the scan, and write no data in the database + if (++n_clip_events > 2): # react only after multiple clip events (solves startup issue) + if data_rows[-1][9]>0: # make exception (for our broken hardware?) + state["freq"] = 0 # force ending of the scan, and write no data in the database + else: + n_clip_events=0 # calculate next freq if state["freq"] > 1.0: freq_multiplier = state["freq_step_multiply"] # calc next freq From 390dccedfebbd966f64bd6c5c54a09573d24a96d Mon Sep 17 00:00:00 2001 From: gertjan Date: Fri, 27 Mar 2026 13:21:15 +0100 Subject: [PATCH 07/14] Fixed bug of first scanned frequency --- scanner.py | 75 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/scanner.py b/scanner.py index 3044700..0e67a39 100644 --- a/scanner.py +++ b/scanner.py @@ -189,7 +189,7 @@ class TelnetReader: # Main loop: reads incoming lines forever try: while state["freq"] > state["stop_freq"]: - if state["initializing"] == 1: + if state["initializing"]>0: self.process_line("Va=") else: line = self.tn.read_until(b"\n") # read line @@ -240,43 +240,46 @@ class TelnetReader: response = f"a{state["ampl"]:.1f}\r" # set amplitude self.tn.write(response.encode("utf-8")) # there will be a lot of lines, but they will be skipped as they do not match the pattern - else: # regular loop (not initializing) - extract_to_dataframe(line) # capture the measurement - if state["freq"]>3.0: - Inoise_baseline = 0.8*Inoise_baseline + 0.2*data_rows[-1][12] # remember last baseline around 3Hz (assuming top-down scanning) - if data_rows and (state["freq"]>10) and (data_rows[-1][11]>state["allowed_noise_level"] or data_rows[-1][12]>state["allowed_noise_level"]): # or (state["freq"]<3.0 and data_rows[-1][12]>1.25*Inoise_baseline)): - # Too much noise: add to blacklist - print("Too much noise - adding to blacklist") - blacklist.append({"Freq": state["freq"], "NrToSkip": state["skip_scans_for_noisy_freqs"]}) - print(f"Blacklist: {blacklist}\r") - del data_rows[-1] # remove this last entry from the list (for DB it is okay, but for CSV things will shift) - else: - if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): # XXXDB - if (++n_clip_events > 2): # react only after multiple clip events (solves startup issue) - if data_rows[-1][9]>0: # make exception (for our broken hardware?) - state["freq"] = 0 # force ending of the scan, and write no data in the database + state["initializing"] = 2 + else: # regular loop (initializing is 0 (normal) or 2 (first sample)) + if state["initializing"] == 0: + extract_to_dataframe(line) # capture the measurement + if state["freq"]>3.0: + Inoise_baseline = 0.8*Inoise_baseline + 0.2*data_rows[-1][12] # remember last baseline around 3Hz (assuming top-down scanning) + if data_rows and (state["freq"]>10) and (data_rows[-1][11]>state["allowed_noise_level"] or data_rows[-1][12]>state["allowed_noise_level"]): # or (state["freq"]<3.0 and data_rows[-1][12]>1.25*Inoise_baseline)): + # Too much noise: add to blacklist + print("Too much noise - adding to blacklist") + blacklist.append({"Freq": state["freq"], "NrToSkip": state["skip_scans_for_noisy_freqs"]}) + print(f"Blacklist: {blacklist}\r") + del data_rows[-1] # remove this last entry from the list (for DB it is okay, but for CSV things will shift) else: - n_clip_events=0 - # calculate next freq - if state["freq"] > 1.0: - freq_multiplier = state["freq_step_multiply"] # calc next freq - else: - if state["freq"] > 0.01: - freq_multiplier = state["freq_step_multiply"] ** 2 # skip 1/2 steps to speed up + if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): # XXXDB + if (++n_clip_events > 2): # react only after multiple clip events (solves startup issue) + if data_rows[-1][9]>0: # make exception (for our broken hardware?) + state["freq"] = 0 # force ending of the scan, and write no data in the database + else: + n_clip_events=0 + # calculate next freq + if state["freq"] > 1.0: + freq_multiplier = state["freq_step_multiply"] # calc next freq else: - freq_multiplier = state["freq_step_multiply"] ** 4 # skip 3/4 steps to speed up - state["freq"] *= freq_multiplier - while (any(item["Freq"] == state["freq"] for item in blacklist)): - print("skipping freq") - state["freq"] *= freq_multiplier # skip all frequencies that are blacklisted - if state["freq"] <= state["stop_freq"]: - print("Reached stop frequency") - else: - # program the health monitor to go to the next frequency: - response = f"\rQ{state["freq"]:.3f}\r" # new freq - self.tn.write(response.encode("utf-8")) -# print(state) - state["initializing"] = 0 + if state["freq"] > 0.01: + freq_multiplier = state["freq_step_multiply"] ** 2 # skip 1/2 steps to speed up + else: + freq_multiplier = state["freq_step_multiply"] ** 4 # skip 3/4 steps to speed up + state["freq"] *= freq_multiplier + while (any(item["Freq"] == state["freq"] for item in blacklist)): + print("skipping freq") + state["freq"] *= freq_multiplier # skip all frequencies that are blacklisted + + if state["freq"] <= state["stop_freq"]: + print("Reached stop frequency") + else: + # program the health monitor to go to the next frequency: + response = f"\rQ{state["freq"]:.3f}\r" # new freq + self.tn.write(response.encode("utf-8")) +# print(state) + state["initializing"] = 0 # Example: # value = self.extract_value(line) From f0cc0a2b935b1199425b38d9b27c02c715eeea44 Mon Sep 17 00:00:00 2001 From: gertjan Date: Tue, 17 Mar 2026 23:20:26 +0100 Subject: [PATCH 08/14] tested and tuned on Veghel Lab system --- config.yaml | 8 ++++---- scanner.py | 51 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/config.yaml b/config.yaml index 6e3e2c2..5a2cb4e 100644 --- a/config.yaml +++ b/config.yaml @@ -1,9 +1,9 @@ # Configuration file for scanner service # it is automatically re-loaded between scans -start_freq: 10000.0 -stop_freq: 0.1 +start_freq: 1000 +stop_freq: 0.2 freq_step_multiply: 0.95 +allowed_noise_level: 9 +skip_scans_for_noisy_freqs: 5 ampl: 1600 -interference_freq: 0.052 -interference_bandwidth: 0.008 noise_scan: False diff --git a/scanner.py b/scanner.py index 2fecf56..0e952c9 100644 --- a/scanner.py +++ b/scanner.py @@ -14,6 +14,8 @@ import os data_rows = [] # global 2-D list state = {} +blacklist = [] +Inoise_baseline = 0.1 PATTERN = re.compile( r"Va=(?P-?\d+\.?\d*)\s+" @@ -196,24 +198,27 @@ class TelnetReader: except KeyboardInterrupt: print("Interrupted by user.") print(data_rows) - if state["freq"]>0.00001: # check if scan endeed normally (e.g. no abort due to clipping) - #dump_csv("measurements.csv") - dump_into_database() - #append_line_to_file(0, "scan_freq.csv") - #append_line_to_file(1, "scan_Va.csv") - #append_line_to_file(2, "scan_Vp.csv") - #append_line_to_file(3, "scan_Ia.csv") - #append_line_to_file(4, "scan_Ip.csv") - #append_line_to_file(5, "scan_ZR.csv") - #append_line_to_file(6, "scan_ZX.csv") - #append_Nyquist_run("scan_Nyquist.csv") - #state["noise_scan"] = not state["noise_scan"] + if state["freq"]>0.00001: # check if scan ended normally (e.g. no abort due to clipping) + if True: # XXXDB + dump_into_database() + else: + dump_csv("measurements.csv") + #append_line_to_file(0, "scan_freq.csv") + #append_line_to_file(1, "scan_Va.csv") + #append_line_to_file(2, "scan_Vp.csv") + #append_line_to_file(3, "scan_Ia.csv") + #append_line_to_file(4, "scan_Ip.csv") + #append_line_to_file(5, "scan_ZR.csv") + #append_line_to_file(6, "scan_ZX.csv") + #append_Nyquist_run("scan_Nyquist.csv") + #state["noise_scan"] = not state["noise_scan"] else: print("scan aborted\r") gc.collect() # clean up internal memory (garbage collect) def process_line(self, line): global state + global Inoise_baseline # print(f"RAW: {line}") if not line.startswith("Va="): # skip lines that are not to be analyzed return @@ -236,12 +241,17 @@ class TelnetReader: # there will be a lot of lines, but they will be skipped as they do not match the pattern else: # regular loop (not initializing) extract_to_dataframe(line) # capture the measurement -# print(f"minmax: {data_rows[7]},{data_rows[8]},{data_rows[9]},{data_rows[10] }\n") - if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): - #response = f"a{state["ampl"]:.1f}\r" # send ampl to trigger sweep - #self.tn.write(response.encode("utf-8")) - # there will be a lot of lines, but they will be skipped as they do not match the pattern - state["freq"] = 0 # force ending of the scan, and write no data in the database + if state["freq"]>3.0: + Inoise_baseline = 0.8*Inoise_baseline + 0.2*data_rows[-1][12] # remember last baseline around 3Hz (assuming top-down scanning) + if data_rows and (data_rows[-1][11]>state["allowed_noise_level"] or data_rows[-1][12]>state["allowed_noise_level"] or (state["freq"]<3.0 and data_rows[-1][12]>1.25*Inoise_baseline)): + # Too much noise: add to blacklist + print("Too much noise - adding to blacklist") + blacklist.append({"Freq": state["freq"], "NrToSkip": state["skip_scans_for_noisy_freqs"]}) + print(f"Blacklist: {blacklist}\r") + del data_rows[-1] # remove this last entry from the list (for DB it is okay, but for CSV things will shift) + else: + if data_rows and (data_rows[-1][7]<5 or data_rows[-1][8]>250 or data_rows[-1][9]<5 or data_rows[-1][10]>250): # XXXDB + state["freq"] = 0 # force ending of the scan, and write no data in the database # calculate next freq if state["freq"] > 1.0: freq_multiplier = state["freq_step_multiply"] # calc next freq @@ -302,6 +312,11 @@ if __name__ == "__main__": state["initializing"] = 1; reader.read_loop() + # decrement all freq's in blacklist: + for item in blacklist: + item["NrToSkip"] -= 1 + blacklist = [item for item in blacklist if item["NrToSkip"] != 0] # remove all zero items + print(f"Blacklist: {blacklist}") finally: reader.disconnect() From 73e85828354c9c4a682bc3fc45c887a6e4e358cf Mon Sep 17 00:00:00 2001 From: gertjan Date: Fri, 3 Apr 2026 16:19:30 +0200 Subject: [PATCH 09/14] oud algoritme van 17-mrt-2026 maar dan met versienummer support --- config.yaml | 11 +++++--- scanner.py | 79 +++++++++++++++++++++++++++++++++-------------------- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/config.yaml b/config.yaml index 5a2cb4e..ce73f01 100644 --- a/config.yaml +++ b/config.yaml @@ -1,9 +1,12 @@ # Configuration file for scanner service # it is automatically re-loaded between scans -start_freq: 1000 -stop_freq: 0.2 +start_freq: 4000 +stop_freq: 0.4 freq_step_multiply: 0.95 -allowed_noise_level: 9 -skip_scans_for_noisy_freqs: 5 +allowed_noise_level: 15 +skip_scans_for_noisy_freqs: 3 ampl: 1600 noise_scan: False +hw_version: "2026-04-02" # dit was met 3.33 Ohm weerstand voor stromen boven 1000A +scan_comment: "Paasweekend scan met varierende stoom levels" + diff --git a/scanner.py b/scanner.py index 0e952c9..2cff08c 100644 --- a/scanner.py +++ b/scanner.py @@ -12,23 +12,22 @@ from datetime import datetime import yaml import os +VersionScripSoftware = "2026-03-17" +VersionDspSoftware = "Unknown" + data_rows = [] # global 2-D list state = {} blacklist = [] Inoise_baseline = 0.1 PATTERN = re.compile( - r"Va=(?P-?\d+\.?\d*)\s+" - r"Vp=(?P-?\d+\.?\d*)\s+\|\s+" - r"Ia=(?P-?\d+\.?\d*)\s+" - r"Ip=(?P-?\d+\.?\d*)\s+\|\s+" - r"ZR=(?P-?\d+\.?\d*)\s+" - r"ZX=(?P-?\d+\.?\d*)" - r".*?irq=\d+\s+" # Skip to 'irq=', match the first digits and space - r"(?P[0-9a-fA-F]+)-" # First hex - r"(?P[0-9a-fA-F]+)\s+" # Second hex - r"(?P[0-9a-fA-F]+)-" # Third hex - r"(?P[0-9a-fA-F]+)" # Fourth hex + r"Va=(?P[\d.-]+)\s+Vp=(?P[\d.-]+)\s*\|\s*" + r"Ia=(?P[\d.-]+)\s+Ip=(?P[\d.-]+)\s*\|\s*" + r"ZR=(?P[\d.-]+)\s+ZX=(?P[\d.-]+).*?\|\s*" + r".*?irq=\w+\s+" + r"(?P[0-9a-fA-F]+)-(?P[0-9a-fA-F]+)\s+" + r"(?P[0-9a-fA-F]+)-(?P[0-9a-fA-F]+).*?\|\s*" + r"nv=(?P[\d.-]+)\s+ni=(?P[\d.-]+)\s*\|\s*" ) config_path = '/home/bart/python-scanner/config.yaml' @@ -56,11 +55,26 @@ conn_str = ( ) def dump_into_database(): + print("dump into database\n") try: with pyodbc.connect(conn_str) as conn: cursor = conn.cursor() sweep_insert_time = datetime.now() - print("dump into database\n") + # Add scan details + cursor.execute(""" + IF NOT EXISTS ( + SELECT 1 FROM ScanDetails WHERE StartTimeOfSweep = ? + ) + INSERT INTO ScanDetails + (StartTimeOfSweep, VersionScanScript, VersionDspSoftware, VersionHardware, Comment) + VALUES (?, ?, ?, ?, ?) + """, sweep_insert_time, + sweep_insert_time, VersionScripSoftware, VersionDspSoftware, state["hw_version"], state["scan_comment"]) + print("commit1\n") + conn.commit() + + with pyodbc.connect(conn_str) as conn: + cursor = conn.cursor() # Prepare the data: SQL Server expects the columns in order. if state["noise_scan"]==False: # regular scan data @@ -89,7 +103,7 @@ def dump_into_database(): cursor.fast_executemany = False # needs less RAM cursor.executemany(sql, formatted_rows) - print("commit\n") + print("commit2\n") conn.commit() print(f"Successfully inserted {len(formatted_rows)} rows.") @@ -136,17 +150,19 @@ def extract_to_dataframe(line): if not match: return # silently ignore malformed lines row = [ - float(state["freq"]), - float(match.group("Va")), - float(match.group("Vp")), - float(match.group("Ia")), - float(match.group("Ip")), - float(match.group("ZR")), - float(match.group("ZX")), - int(match.group("adc_vmin"), 16), - int(match.group("adc_vmax"), 16), - int(match.group("adc_imin"), 16), - int(match.group("adc_imax"), 16), + float(state["freq"]), # row 0 + float(match.group("Va")), # row 1 + float(match.group("Vp")), # row 2 + float(match.group("Ia")), # row 3 + float(match.group("Ip")), # row 4 + float(match.group("ZR")), # row 5 + float(match.group("ZX")), # row 6 + int(match.group("adc_vmin"), 16), # row 7 + int(match.group("adc_vmax"), 16), # row 8 + int(match.group("adc_imin"), 16), # row 9 + int(match.group("adc_imax"), 16), # row 10 + float(match.group("nv")), # row 11 + float(match.group("ni")), # row 12 ] row[1] = row[1]/(2*3.14159*row[0]*0.00005 + 1) # compensate Va for pole at 20kHz row[5] = row[1]/row[3] * math.cos(0.01745*(row[2]-row[4])) @@ -219,7 +235,10 @@ class TelnetReader: def process_line(self, line): global state global Inoise_baseline -# print(f"RAW: {line}") + global VersionDspSoftware + if line.startswith("SW-Version"): + VersionDspSoftware = line.split(":", 1)[1].strip() # remember the DSP software version from its reporting + print(f"DSP SW Version={VersionDspSoftware}\r\n") if not line.startswith("Va="): # skip lines that are not to be analyzed return if state["remaining_receive_lines"] > 0 : @@ -228,7 +247,7 @@ class TelnetReader: # prepare new frequency measurement if state["initializing"] == 1: # since we just start a frequency scan, let's set the R, Max and Amplitude - response = f"\rr516\r" # set Resistance value for scaling HAL sensor + response = f"\rr344\r" # set Resistance value for scaling HAL sensor self.tn.write(response.encode("utf-8")) response = f"m1600\r" # set max amplitude value self.tn.write(response.encode("utf-8")) @@ -263,8 +282,8 @@ class TelnetReader: state["freq"] *= freq_multiplier if (state["freq"]>40) and (state["freq"]<660) and ((state["freq"]%50<2.5) or (-state["freq"]%50<2.5)): state["freq"] *= freq_multiplier # if near a 50Hz harmonic, skip to the next frequency - while (state["freq"]<0.6) and ((state["freq"]%state["interference_freq"] Date: Fri, 3 Apr 2026 16:22:58 +0200 Subject: [PATCH 10/14] fixed the indentation typo --- scanner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scanner.py b/scanner.py index 2cff08c..6ca9d82 100644 --- a/scanner.py +++ b/scanner.py @@ -298,8 +298,8 @@ class TelnetReader: response = f"b{bandwidth:.3f}\r" # new freq self.tn.write(response.encode("utf-8")) state["remaining_receive_lines"] = 1 + 4/bandwidth - print(line) - print(state) + print(line) + print(state) state["initializing"] = 0 # Example: From a1798d1a29c7a3c41751e805c224796bc3022892 Mon Sep 17 00:00:00 2001 From: Gertjan Koolen Date: Wed, 15 Apr 2026 21:10:12 +0200 Subject: [PATCH 11/14] Added backup workflow --- .forgejo/workflows/backup-repo.yaml | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .forgejo/workflows/backup-repo.yaml diff --git a/.forgejo/workflows/backup-repo.yaml b/.forgejo/workflows/backup-repo.yaml new file mode 100644 index 0000000..d49c28d --- /dev/null +++ b/.forgejo/workflows/backup-repo.yaml @@ -0,0 +1,39 @@ +name: Git Backup to WebDAV +on: + push: + # This ensures it runs on every branch push + branches: + - '**' +jobs: + print-content: + runs-on: debian-latest + steps: + - name: checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: archive repository + run: | + PROJECT_NAME=$(echo "${{ github.repository }}" | cut -d'/' -f2) + BRANCH_NAME=$(echo "${{ github.ref_name }}" | sed 's/\//-/g') + TIMESTAMP=$(date +'%Y-%m-%d_%H-%M') + + # Create the local variable + FINAL_NAME="${PROJECT_NAME}_${BRANCH_NAME}_${TIMESTAMP}.tar.gz" + + # CRITICAL: Save it for the next step + echo "PROJECTNAME=$PROJECT_NAME" >> $GITHUB_ENV + echo "FILENAME=$FINAL_NAME" >> $GITHUB_ENV + + # Create the archive + git archive --format=tar.gz -v -o "$FINAL_NAME" HEAD + echo "Archive created: $FINAL_NAME" + + - name: Upload via Curl + run: | + ls -lh "$FILENAME" + + curl -T "$FILENAME" \ + -u "${{ secrets.WEBDAV_USER }}:${{ secrets.WEBDAV_PASSWORD }}" \ + "${{ secrets.WEBDAV_URL }}/$PROJECTNAME/$FILENAME" From bc7cb4d360e7e7815a72a67fbc9e047481e43fa6 Mon Sep 17 00:00:00 2001 From: gertjan Date: Mon, 18 May 2026 08:41:35 +0200 Subject: [PATCH 12/14] added noise measurements --- scanner.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scanner.py b/scanner.py index 6ca9d82..0e85db8 100644 --- a/scanner.py +++ b/scanner.py @@ -12,7 +12,7 @@ from datetime import datetime import yaml import os -VersionScripSoftware = "2026-03-17" +VersionScripSoftware = "2026-05-18" VersionDspSoftware = "Unknown" data_rows = [] # global 2-D list @@ -79,12 +79,12 @@ def dump_into_database(): if state["noise_scan"]==False: # regular scan data formatted_rows = [ - [sweep_insert_time, r[0], r[5], r[6], r[1], r[2], r[3], r[4]] + [sweep_insert_time, r[0], r[5], r[6], r[1], r[2], r[3], r[4], r[11], r[12]] for r in data_rows ] sql = """ - INSERT INTO SequenceValues (StartTimeOfSweep, Freq, ZR, ZX, Vampl, Vphase, Iampl, Iphase) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) \ + INSERT INTO SequenceValues (StartTimeOfSweep, Freq, ZR, ZX, Vampl, Vphase, Iampl, Iphase, Vnoise, Inoise) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) \ """ else: # noise scan data From 22eb53c06887e0e35f014bb122da4bbbc8ffbb51 Mon Sep 17 00:00:00 2001 From: gertjan Date: Thu, 28 May 2026 22:13:38 +0200 Subject: [PATCH 13/14] Na R27 en R28 aanpassing: gebruikt R=331 --- scanner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scanner.py b/scanner.py index 0e85db8..039d362 100644 --- a/scanner.py +++ b/scanner.py @@ -12,7 +12,7 @@ from datetime import datetime import yaml import os -VersionScripSoftware = "2026-05-18" +VersionScripSoftware = "2026-05-28" VersionDspSoftware = "Unknown" data_rows = [] # global 2-D list @@ -247,7 +247,7 @@ class TelnetReader: # prepare new frequency measurement if state["initializing"] == 1: # since we just start a frequency scan, let's set the R, Max and Amplitude - response = f"\rr344\r" # set Resistance value for scaling HAL sensor + response = f"\rr331\r" # set Resistance value for scaling HAL sensor self.tn.write(response.encode("utf-8")) response = f"m1600\r" # set max amplitude value self.tn.write(response.encode("utf-8")) From da651c7966442a3f8b79aa3fcae26b2fce564d6b Mon Sep 17 00:00:00 2001 From: gertjan Date: Sat, 30 May 2026 11:18:08 +0200 Subject: [PATCH 14/14] aangepaste start en config --- config.yaml | 4 ++-- start | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/config.yaml b/config.yaml index ce73f01..c4b0e10 100644 --- a/config.yaml +++ b/config.yaml @@ -7,6 +7,6 @@ allowed_noise_level: 15 skip_scans_for_noisy_freqs: 3 ampl: 1600 noise_scan: False -hw_version: "2026-04-02" # dit was met 3.33 Ohm weerstand voor stromen boven 1000A -scan_comment: "Paasweekend scan met varierende stoom levels" +hw_version: "2026-05-28" # aangepaste R27 en R28 voor boven 700A +scan_comment: "normale full scan met verbeterde PCB (nu goed boven 700A)" diff --git a/start b/start index 9f5833a..e464161 100755 --- a/start +++ b/start @@ -1 +1,3 @@ +sudo systemctl restart ser2net.service +sleep 2 systemctl --user start python-scanner