diff --git a/PC_CONTROL_CODE/dockerInflux/mainDocker.py b/PC_CONTROL_CODE/dockerInflux/mainDocker.py index 93dddc0..fc434a5 100644 --- a/PC_CONTROL_CODE/dockerInflux/mainDocker.py +++ b/PC_CONTROL_CODE/dockerInflux/mainDocker.py @@ -7,33 +7,38 @@ from typing import Final # setting consts that can be customized # baud rate. Prob not needed as 38400 is standard -MD1200BAUD: Final[int] = int(os.getenv("MD1200BAUD", 38400)) +MD1200BAUD: Final[int] = int(os.getenv("MD1200BAUD", "38400")) # used if you want to run it on multiple JBODs SERIALADAPTER: Final[str] = os.getenv("SERIALADAPTER", "/dev/ttyUSB0") # Factor that defines how aggressive the temperature curve is -TEMP_FACTOR: Final[float] = float(os.getenv("TEMP_FACTOR", 19)) +TEMP_FACTOR: Final[float] = float(os.getenv("TEMP_FACTOR", "19")) # time between sending command to get temp and storing it. It's there to allow JBOD to answer -EPPYSLEEPY: Final[float] = float(os.getenv("EPPYSLEEPY", 1)) +EPPYSLEEPY: Final[float] = float(os.getenv("EPPYSLEEPY", "1")) -LOW_FAN_TRSHD: Final[float] = float(os.getenv("LOW_FAN_TRSHD", 21)) -HIGH_FAN_TRSHD: Final[float] = float(os.getenv("HIGH_FAN_TRSHD", 40)) +LOW_FAN_TRSHD: Final[float] = float(os.getenv("LOW_FAN_TRSHD", "21")) +HIGH_FAN_TRSHD: Final[float] = float(os.getenv("HIGH_FAN_TRSHD", "40")) GETTMPCMND: Final[str] = os.getenv("GETTMPCMND", "_temp_rd") SETFANCMND: Final[str] = os.getenv("SETFANCMND", "set_speed") -DEFOUTPRCNTG: Final[float] = float(os.getenv("DEFOUTPRCNTG", 24)) +DEFOUTPRCNTG: Final[float] = float(os.getenv("DEFOUTPRCNTG", "24")) -MDSERIALTIMEOUT: Final[float] = float(os.getenv("MDSERIALTIMEOUT", 1)) +MDSERIALTIMEOUT: Final[float] = float(os.getenv("MDSERIALTIMEOUT", "1")) -TEMPREADINTERVAL: Final[float] = float(os.getenv("TEMPREADINTERVAL", 15)) +TEMPREADINTERVAL: Final[float] = float(os.getenv("TEMPREADINTERVAL", "15")) -TEMPSETING: Final[bool] = bool(os.getenv("TEMPSETING", True)) +# If True or yes then we good +TEMPSETING = os.getenv("TEMPSETING", "1").strip().lower() in ("1", "true", "yes", "on") -PROCESSTEMPWAITTIME: Final[float] = float(os.getenv("PROCESSTEMPWAITTIME", 0.75)) +PROCESSTEMPWAITTIME: Final[float] = float(os.getenv("PROCESSTEMPWAITTIME", "0.75")) -BACKOFFTIME: Final[float] = float(os.getenv("BACKOFFTIME", 5)) +BACKOFFTIME: Final[float] = float(os.getenv("BACKOFFTIME", "5")) + +INFLUX_MAX_RETRIES: Final[int] = int(os.getenv("INFLUX_MAX_RETRIES", "3")) # INFLUXDB config +# should Influx be used? +USEINFLUX: Final[bool] = os.getenv("USEINFLUX", "True").strip().lower() in ("1", "true", "yes", "on") # token = "apg1gysUeCcxdcRTMmosJTenbEppmUNi9rXlANDB2oNadBdWAu2GVTDc_q_dyo0iyYsckKaOvPRm6ba2NK0y_A==" INFLUXTOKEN: Final[str] = str(os.getenv("INFLUX_TOKEN", "0")) # bucket = "JBOD" @@ -61,20 +66,35 @@ MDserial = serial.Serial( timeout=MDSERIALTIMEOUT) # lastTempReading: float = time.time() +setSpeedrcode = 21 MDtempDict: dict = {} MDict: dict = {} currentSerialUsage = threading.Lock() fluxSending: bool = False currentTime: float = 0 lastTempReading: float = 0 -inflxdb_LeData: list = [] # Initialize InfluxDB client and influxdb API # ---------------------UNCOMMENT----------------------- -inflxdb_client = influxdb_client.InfluxDBClient(url=INFLUXURL, token=INFLUXTOKEN, org=INFLUXORG) -write_api = inflxdb_client.write_api(write_options=SYNCHRONOUS) +if USEINFLUX: + inflxdb_client = influxdb_client.InfluxDBClient(url=INFLUXURL, token=INFLUXTOKEN, org=INFLUXORG) + write_api = inflxdb_client.write_api(write_options=SYNCHRONOUS) + inflxdb_LeData: list = [] # ---------------------UNCOMMENT----------------------- +# Just a helper function for process_temps to avoid db errors on flapping network +def process_temps_dbsend(inpdatatosend) -> bool: + if not USEINFLUX: + return True + try: + write_api.write(bucket=INFLUXBUCKET, org=INFLUXORG, record=inpdatatosend) + return True + except Exception as e: + print(f"Influx write error {e}", flush=True) + return False + + + def getTemp() -> dict: global MDict, fluxSending @@ -155,6 +175,7 @@ def setSpeed(inSpeeDict: dict) -> int: # get backplanbe average if "bp1" in inSpeeDict and "bp2" in inSpeeDict: bpavrg = (inSpeeDict["bp1"] + inSpeeDict["bp2"]) /2 + #outfanprcntg = int((bpavrg / (HIGH_FAN_TRSHD - LOW_FAN_TRSHD)) * TEMP_FACTOR) outfanprcntg = int((bpavrg / (HIGH_FAN_TRSHD - LOW_FAN_TRSHD)) * TEMP_FACTOR) # os.system(f"echo setting {outfanprcntg}%") @@ -190,26 +211,31 @@ def setSpeed(inSpeeDict: dict) -> int: # Threaded flow processor def process_temps() -> None: - global MDict, fluxSending + global MDict, fluxSending, setSpeedrcode while True: # ---LeData--- # {'bp1': 35, 'bp2': 29, 'sim0': 35, 'sim1': 34, 'exp0': 56, 'exp1': 54} # ---LeData--- + if fluxSending: # Prep InfluxDB data + + # build local copy in case MDict changes while executing + MDictLocalCopy = MDict.copy() try: inflxdb_Data_To_Send = ( influxdb_client.Point(f"{INFLUXMEASUREMENT}-script") .tag("MACHINE", MACHINE_TAG) .tag("LOCATION", LOCATION) - .field("Backplane1", MDict["bp1"]) - .field("Backplane2", MDict["bp2"]) - .field("SASIntModule0", MDict["sim0"]) - .field("SASIntModule1", MDict["sim1"]) - .field("Expander0", MDict["exp0"]) - .field("Expander1", MDict["exp1"]) - .field("Average", MDict["avg"]) + .field("Backplane1", MDictLocalCopy["bp1"]) + .field("Backplane2", MDictLocalCopy["bp2"]) + .field("SASIntModule0", MDictLocalCopy["sim0"]) + .field("SASIntModule1", MDictLocalCopy["sim1"]) + .field("Expander0", MDictLocalCopy["exp0"]) + .field("Expander1", MDictLocalCopy["exp1"]) + .field("Average", MDictLocalCopy["avg"]) + .field("FanSpeed", setSpeedrcode) ) except KeyError: time.sleep(BACKOFFTIME) @@ -217,13 +243,27 @@ def process_temps() -> None: # Prep/append data inflxdb_LeData.append(inflxdb_Data_To_Send) - # Send data to InfluxDB - write_api.write(bucket=INFLUXBUCKET, org=INFLUXORG, record=inflxdb_Data_To_Send) + # Issue YuruC3/MD1200#7 fix + if not process_temps_dbsend(inflxdb_Data_To_Send): + i = 0 + while i < INFLUX_MAX_RETRIES: + if process_temps_dbsend(inflxdb_Data_To_Send): + print("Sending data to InfluxDB", flush=True) + break + else: + time.sleep(1) + i += 1 + else: + print(f"Failed to send data to InfluxDB after {INFLUX_MAX_RETRIES} retires", flush=True) + else: + print("Sending data to InfluxDB", flush=True) + + + # Clean up before another lo#op, 0.75 inflxdb_LeData.clear() - print("Sending data to InfluxDB", flush=True) fluxSending = False @@ -238,6 +278,7 @@ MDict = getTemp() lastTempReading = time.time() def mainCodeHere() -> None: + global setSpeedrcode while True: global MDict, fluxSending, currentTime, lastTempReading # https://stackoverflow.com/questions/52578122/not-able-to-send-the-enter-command-on-pyserial @@ -287,11 +328,23 @@ def mainCodeHere() -> None: # Prepare threads and launch them -thread_main = threading.Thread(target=mainCodeHere) -thread_flux = threading.Thread(target=process_temps) -thread_main.start() -thread_flux.start() -thread_main.join() -thread_flux.join() \ No newline at end of file +# daemon to make docker exit smoother +thread_main = threading.Thread(target=mainCodeHere, daemon=True) +threads = [thread_main] + +if USEINFLUX: + thread_flux = threading.Thread(target=process_temps, daemon=True) + threads.append(thread_flux) + +for thr in threads: + thr.start() + +# Join both (this will block forever, which is fine for a daemon) +for thr in threads: + thr.join() + + + + diff --git a/PC_CONTROL_CODE/dockerInflux/md1200.env b/PC_CONTROL_CODE/dockerInflux/md1200.env index 9b58c5e..5be0577 100644 --- a/PC_CONTROL_CODE/dockerInflux/md1200.env +++ b/PC_CONTROL_CODE/dockerInflux/md1200.env @@ -1,11 +1,13 @@ # MD1200BAUD= SERIALADAPTER=/dev/ttyUSB0 -EPPYSLEEPY=1 -MDSERIALTIMEOUT=1 -TEMPREADINTERVAL=15 +# These are (for me) working values +EPPYSLEEPY=1.5 +MDSERIALTIMEOUT=2 +TEMPREADINTERVAL=30 -TEMP_FACTOR=17 + +TEMP_FACTOR=16 # LOW_FAN_TRSHD=21 # HIGH_FAN_TRSHD=40