Browse Source

Added: argparse so we can (amongst other things lel) enable debug m0de w/o changing em config, corresponding usage section in em readme, configurable max attempts per sensor sample, author/version/etc headers, "constants" for exit codes, some comments to make the c0dd more readable (thanks pythinz for your retarded required indents), explicit exit on KeyboardInterrupt (Ctrl+C), extra debug messages || Changed: "pass" to "sample", print sensor name on exceeding max attempts when not in debug mode, proper order of checking max attempts, simply pass a SystemExit exception (sys.exit() lol)

Wazakindjes 1 year ago
parent
commit
27de3000ce
3 changed files with 92 additions and 23 deletions
  1. 7 1
      README.md
  2. 3 0
      muhconf.ini.example
  3. 82 22
      temps.py

+ 7 - 1
README.md

@@ -1,10 +1,11 @@
 # The fuck is this
-This shit is a qt lil Pyth0n implementation ov reading ein `DS18B20` temperature sens0r, the values of which get stored in a MySQL database somewhere. =]]]
+This shit is a qt lil Pyth0n implementation ov reading ein `DS18B20` temperature sens0r, the values of which get stored in a MySQL/MariaDB database somewhere. =]]]
 
 It will run 5 samples (with a required 1 second delay between em) and get the average of that to store in the DB. It also supports multiple sensors but it will only store the first average. xd
 
 # Dependencies
 You prolly need to install a few Pythinz modules cuz they may not be available by default:
+* `argparse`
 * `ConfigParser`
 * `MySQLdb`
 
@@ -17,3 +18,8 @@ Then simply slam a new entry in your `crontab` to make it run periodically (the
 As you can see I have it set to run every 2 minutes, faster is not really necessary and would only clutter the DB. The `kill` part is in case a previous instance is hanging on something for some reason, and should usually fail (hence the redirections to `/dev/null` ;]). To me this only really happens when my internetz connection is being gay and takes 2+ minutes to set up a usable MySQL connection. This logic is not present in the code itself because of the "set up to read/store once, then quit" reasoning. ;];];];] It would be p hard to account for anyways, since the TCP handshake has been completed and there __are__ packets flowing, just many get dropped and have to be resent.
 
 ez pz ;]
+
+# Usage
+You can just simply run `./temps.py` obviously, but in case you need to troubleshoot something you can use `./temps.py --debug` to force debug mode without having to touch the config. [=[=[[=[==[=[=[
+
+Or just do `./temps.py -h` and check the built-in halp. ;]

+ 3 - 0
muhconf.ini.example

@@ -6,6 +6,9 @@ debug = false
 # If you have multiple sensors simply specify multiple "sensor = xxx" lines ;]
 sensor = 28-02155265b0ff
 
+# For every sample, try to read the sensor this many times until it produces some expected output (should usually take only 1 attempt but still ;])
+sample_maxattempts = 5
+
 [mysql]
 # Should be obvious lmao
 host = 127.0.0.1

+ 82 - 22
temps.py

@@ -1,16 +1,31 @@
 #!/usr/bin/python
+__author__ = "Kruz, Wazakindjes"
+__copyright__ = "Jem0eder Inc."
+__version__ = "2.0.0"
+
+import argparse
 import ConfigParser
 import MySQLdb
 import os
 import sys
 import time
 
+# Some "constants" lol
+RET_GUCCI = 0
+RET_ERR_CONF = 1
+RET_ERR_SENSOR = 2
+
+# Globals y0
 muhconf = {}
 
 def printem(txt):
+	# Because apparently we need to flush after every print to ensure it happens in real-time -.-
 	print txt
 	sys.stdout.flush()
 
+def show_version():
+	printem("temps v{0}, written by: {1}".format(__version__, __author__))
+
 def readem_conf():
 	err = False
 
@@ -18,27 +33,43 @@ def readem_conf():
 		cfg = ConfigParser.ConfigParser()
 		cfg.read("{0}/muhconf.ini".format(os.path.dirname(os.path.realpath(__file__))))
 
-		### [main] section
+		### [main] section BEGIN
+		# Booleans first
 		for main_boolopt in ["debug"]:
 			muhconf[main_boolopt] = cfg.getboolean("main", main_boolopt)
 
+		# Integers next
+		for main_intopt in ["sample_maxattempts"]:
+			optval = cfg.getint("main", main_intopt)
+
+			# Should prolly restrict it to 30 attempts, anything more seems way too excessive ;];];]
+			if main_intopt == "sample_maxattempts" and (optval <= 0 or optval > 30):
+				printem("Invalid value '{0}' for option '{1}': must be in the range of 1-30".format(optval, main_intopt))
+				err = True
+				continue
+
+			muhconf[main_intopt] = optval
 
+		# Multiple string values last
 		for main_stropt_multi in ["sensor"]:
 			optval_multi = cfg.get("main", main_stropt_multi).split("\n")
 
 			for optval in optval_multi:
+				# Even though sensor is currently the only option, let's set it up for easy expansion laturd anyways ;]
 				if main_stropt_multi == "sensor" and "/" in optval:
 					printem("Invalid value '{0}' for option '{1}': may not contain a slash".format(optval, main_stropt_multi))
 					err = True
 					continue
 
 			muhconf[main_stropt_multi] = optval_multi
+		### [main] section END
 
-
-		### [mysql] section
+		### [mysql] section BEGIN
+		# Booleans first
 		for mysql_boolopt in ["tls"]:
 			muhconf[mysql_boolopt] = cfg.getboolean("mysql", mysql_boolopt)
 
+		# Integers next
 		for mysql_intopt in ["port"]:
 			optval = cfg.getint("mysql", mysql_intopt)
 
@@ -49,28 +80,30 @@ def readem_conf():
 
 			muhconf[mysql_intopt] = optval
 
+		# String values last
 		for mysql_stropt in ["host", "user", "pass", "db", "table", "column"]:
 			muhconf[mysql_stropt] = cfg.get("mysql", mysql_stropt)
-
+		### [mysql] section END
 
 	except KeyboardInterrupt:
-		printem("CTRL + C")
+		printem("\nCTRL + C")
+		sys.exit(RET_GUCCI)
 
 	except:
 		exc_info = sys.exc_info()
-		printem("RIP config ({0}): {1}".format(exc_info[0], exc_info[1]))
-		sys.exit(1)
+		printem("\nRIP config ({0}): {1}".format(exc_info[0], exc_info[1]))
+		sys.exit(RET_ERR_CONF)
 
 	if err:
 		printem("Invalid config, not proceeding")
-		sys.exit(1)
+		sys.exit(RET_ERR_CONF)
 
 def readem_temp():
 	avgtemperatures = []
 
 	try:
 		if muhconf["debug"]:
-			printem("Connecting lol")
+			printem("Connecting to MySQL lol")
 
 		if muhconf["tls"]:
 			db = MySQLdb.connect(host=muhconf["host"], port=muhconf["port"], user=muhconf["user"], passwd=muhconf["pass"], db=muhconf["db"], ssl={'cipher': 'AES256-SHA'})
@@ -84,33 +117,40 @@ def readem_temp():
 		for sensor in muhconf["sensor"]:
 			if muhconf["debug"]:
 				printem("\tSensor: {0}".format(sensor))
+
 			temperatures = []
 			text = '';
-			for i in range(1, 6):
-				if muhconf["debug"]:
-					printem("\t\tPass: {0}".format(i))
+			for i in range(1, 6): # Goes _up to_ 6 so the last iteration is i == 5 ;]
 				text = '';
 				attempts = 0
 				while text.split("\n")[0].find("YES") == -1:
+					if attempts >= muhconf["sample_maxattempts"]:
+						plural = "s" if attempts > 1 else ""
+						if muhconf["debug"]:
+							printem("Ayyy rip readem_temp(): unable to read temperature after {0} attempt{1} (sample #{2})".format(attempts, plural, i))
+						else:
+							# Non-debug mode doesn't print the sensor name at an earlier point, so let's make it clear here ;;]];];
+							printem("Ayyy rip readem_temp(): unable to read temperature for sensor {0} after {1} attempt{2} (sample #{3})".format(sensor, attempts, plural, i))
+						sys.exit(RET_ERR_SENSOR)
+
+					if attempts > 0:
+						time.sleep(1)
+
 					# Contents of the file should be something leik dis:
 					# 79 01 80 80 7f ff 7f 80 02 : crc=02 YES
 					# 79 01 80 80 7f ff 7f 80 02 t=23562
-
 					tfile = open("/sys/bus/w1/devices/{0}/w1_slave".format(sensor))
 					text = tfile.read()
 					tfile.close()
-
 					attempts += 1
-					if attempts == 30:
-						printem("\nAyyy rip readem_temp(): unable to read temperature (pass #{0}) after {1} attempts".format(i, attempts))
-						sys.exit(2)
-
-					time.sleep(1)
 
 				secondline = text.split("\n")[1]
 				temperaturedata = secondline.split(" ")[9]
-				temperature = float(temperaturedata[2:])
-				temperatures.append(temperature / 1000)
+				temperature = float(temperaturedata[2:]) / 1000
+				temperatures.append(temperature)
+
+				if muhconf["debug"]:
+					printem("\t\tSample #{0}: {1}".format(i, temperature))
 
 			avgtemperatures.append(sum(temperatures) / float(len(temperatures)))
 
@@ -119,13 +159,33 @@ def readem_temp():
 
 	except KeyboardInterrupt:
 		printem("\nCTRL + C")
+		sys.exit(RET_GUCCI)
+
+	except SystemExit:
+		pass
 
 	except:
 		printem("\nFAT RIP: {0}".format(sys.exc_info()[0]))
-		sys.exit(2)
+		sys.exit(RET_ERR_SENSOR)
 
 if __name__ == "__main__":
+	# Read config first lol
 	readem_conf()
+
+	# Then parse args imo tbh
+	p = argparse.ArgumentParser()
+	p.add_argument('--debug', help='force debug mode (current setting from config: {0})'.format(muhconf["debug"]), action='store_true')
+	p.add_argument('--version', help='print version and exit lol', action='store_true')
+	args, noargs = p.parse_known_args() # noargs contains the 'topkek' in: ./temps.py --debug topkek
+
+	if args.version:
+		show_version()
+		sys.exit(RET_GUCCI)
+
+	if args.debug:
+		muhconf["debug"] = True
+
 	if muhconf["debug"]:
 		printem("Reading em temp")
 	readem_temp()
+	sys.exit(RET_GUCCI) # Let's do an explicit exit w/ code imo tbh famlamlaml