def generator_uniform(floors, number_people, max_in_lift=6): """generates a new lift structure with uniform distribution Arguments: floors - The number of floors that the people should be generated over. number_people - The number of people to generate. max_in_lift - The max number of people who can fit in a lift. (Default: 6) Returns: A valid lift_data structure - Follows the same structure as the BLANK_LIFT_DATA constant except it is now populated. """ if floors < 2: raise ValueError("Floors must be at least 2") lift_struct = deepcopy(BLANK_LIFT_DATA)#deep copy as the blank case contains lists #initialize the floors with lists to later put people in floor_people = [] for _ in range(floors): floor_people.append([]) #while you have people to put on a floor do: people_left = number_people while people_left >= 1: person_floor = random_randint(0, floors-1) person_want = random_randint(0, floors-1) #check the person doesn't want to go to their own floor if person_floor == person_want: continue floor_people[person_floor].append((person_want, 0)) people_left -= 1 #populate remaining fields with people and returns lift_struct["floor info"] = floor_people lift_struct["lift max people"] = max_in_lift return lift_struct
def generator_skewed(floors, number_people, max_in_lift=6, skew_type="day-end", skew_weighting=0.8): """Generates a new lift structure, skewed for either beginning or end of the day At the beginning or end of the day a much greater number of people want to either go from ground to their floor (beginning) or from their floor to ground (end). This function acts like its uniform equivalent except some percentage of the people will want to do one of the things specified above. Arguments: floors - The number of floors that the people should be generated over. number_people - The number of people to generate. max_in_lift - The max number of people who can fit in a lift. (Default: 6) skew_type - Either 'day-end' of 'day-start', Instructs the function how to skew the data. (Default: 'day-end') skew_weighting - The percentage chance of people following the skew. Returns: A valid lift_data structure - Follows the same structure as the BLANK_LIFT_DATA constant except it is now populated. """ if floors < 2: raise ValueError("Floors must be at least 2") if skew_type not in ["day-end", "day-start"]: raise ValueError("skew_type must be either 'day-end' or 'day-start'") lift_struct = deepcopy(BLANK_LIFT_DATA)#deep copy as the black case contains lists #initialize the floors with lists to later put people in floor_people = [] for _ in range(floors): floor_people.append([]) #while you have people to put on a floor do: people_left = number_people while people_left >= 1: if skew_type == "day-end" and random_random() <= skew_weighting: person_want = 0 person_floor = random_randint(0, floors-1) elif skew_type == "day-start" and random_random() <= skew_weighting: person_want = random_randint(0, floors-1) person_floor = 0 else: person_want = random_randint(0, floors-1) person_floor = random_randint(0, floors-1) #check the person doesn't want to go to their own floor if person_floor == person_want: continue floor_people[person_floor].append((person_want, 0)) people_left -= 1 #populate remaining fields with people and returns lift_struct["floor info"] = floor_people lift_struct["lift max people"] = max_in_lift return lift_struct
def create_version_code_str(test_version_indx): LEN_VERSION_CODE_STR = 20 CHAR_OFFSET_FROM_END = 6 version_char_list = [chr(random_randint(ord('!'), ord('`'))) for i in range(LEN_VERSION_CODE_STR)] # make sure there are no 'a', 'b', 'A', 'B' chars in version_char_list # if there are, replace them with a random char in the range [C, Z] for indx in range(len(version_char_list)): if version_char_list[indx] in ['a', 'b', 'A', 'B']: version_char_list[indx] = chr(random_randint(ord('C'), ord('Z'))) version_char = chr(ord('A') + test_version_indx) version_char_list[LEN_VERSION_CODE_STR - CHAR_OFFSET_FROM_END] = version_char version_code_str = ''.join(version_char_list) return version_code_str
def evaluate(self, components=None): die = [ random_randint(1, components[2]) for _ in range(int(components[1])) ] return sum( sorted(die)[(-self.level * int(components[0]) if self.level * components[0] > 0 else None):( -self.level * int(components[0]) if self.level * components[0] < 0 else None)])
def uniform_crossover(self): assert (self.ratio & 1) == 0, \ ('Invalid ratio: %d' % self.ratio) self.children = [] chromosome_length = len(self.chromosome[0]) for i in range(0, len(self.chromosome), 2): parent = self.chromosome[i], \ self.chromosome[i + 1] for j in range(self.ratio * 2 - 2): child = [] for k in range(chromosome_length): child.append(parent[random_randint(0, 1)][k]) self.children.append(child)
def act_random(self, opponent: 'Player', step: int): """ Randomizes Player's deed and manipulates with health :param step: game step#ID :param opponent: Another PlayerObj (self != opponent) """ if self.__is_comp: self.__max_random_state = 9 if self.health <= round( Player.maxHealth * 0.35) else 6 # Increasing chance of healing for computer deed_state = random_randint(1, self.__max_random_state) if deed_state in (1, 2): self.__set_last_event( self.hit_opponent(step, opponent, self.hitWeakPercents)) elif deed_state in (3, 4): self.__set_last_event( self.hit_opponent(step, opponent, self.hitStrongPercents)) else: # elif deed_state >= 3 self.__set_last_event(self.recover_yourself(step))
def rest(base=None, gain=1.0, gap=None) -> None: """ snap a little bit\n [1.3-3.6]s + base\n :param base: base time line. :param gain: The amplifier. :param gap: Iterable obj but not dict, snap + random in the gap """ snap = [random_randint(1, 3), random_randint(1, 3), random_randint(1, 3)] ndigit = [random_randint(1, 3), random_randint(1, 3), random_randint(1, 3)] random_shuffle(ndigit) choice = random_choice([0, 1, 2, 3, 4, 5]) if choice == 0: snap = (snap[0] / (ndigit[ndigit[0] - 1]) + snap[1] / (10**ndigit[ndigit[1] - 1]) + snap[2] / (10**ndigit[ndigit[2] - 1])) elif choice == 1: snap = (snap[0] / (ndigit[ndigit[0] - 1]) + snap[2] / (10**ndigit[ndigit[1] - 1]) + snap[1] / (10**ndigit[ndigit[2] - 1])) elif choice == 2: snap = (snap[1] / (ndigit[ndigit[0] - 1]) + snap[0] / (10**ndigit[ndigit[1] - 1]) + snap[2] / (10**ndigit[ndigit[2] - 1])) elif choice == 3: snap = (snap[1] / (ndigit[ndigit[0] - 1]) + snap[2] / (10**ndigit[ndigit[1] - 1]) + snap[0] / (10**ndigit[ndigit[2] - 1])) elif choice == 4: snap = (snap[2] / (ndigit[ndigit[0] - 1]) + snap[0] / (10**ndigit[ndigit[1] - 1]) + snap[1] / (10**ndigit[ndigit[2] - 1])) elif choice == 5: snap = (snap[0] / (ndigit[ndigit[0] - 1]) + snap[1] / (10**ndigit[ndigit[1] - 1]) + snap[0] / (10**ndigit[ndigit[2] - 1])) snap = round(snap, ndigit[choice % 3]) if snap < 1.5: snap += 1 if base: snap += int(base) if gain != 1: snap *= gain if gap is not None: snap += random_choice(gap) Logger.log([rest, f"Now resting for [{snap}]s... "]) time_sleep(int(snap)) Logger.log([rest, "Done. "])
def rest(self): snap = [random_randint(1, 3), random_randint(1, 3), random_randint(1, 3)] ndigit = [random_randint(1, 3), random_randint(1, 3), random_randint(1, 3)] random_shuffle(ndigit) choice = random_choice([0, 1, 2, 3, 4, 5]) if choice == 0: snap = ( snap[0] / (ndigit[ndigit[0] - 1]) + snap[1] / (10 ** ndigit[ndigit[1] - 1]) + snap[2] / (10 ** ndigit[ndigit[2] - 1]) ) elif choice == 1: snap = ( snap[0] / (ndigit[ndigit[0] - 1]) + snap[2] / (10 ** ndigit[ndigit[1] - 1]) + snap[1] / (10 ** ndigit[ndigit[2] - 1]) ) elif choice == 2: snap = ( snap[1] / (ndigit[ndigit[0] - 1]) + snap[0] / (10 ** ndigit[ndigit[1] - 1]) + snap[2] / (10 ** ndigit[ndigit[2] - 1]) ) elif choice == 3: snap = ( snap[1] / (ndigit[ndigit[0] - 1]) + snap[2] / (10 ** ndigit[ndigit[1] - 1]) + snap[0] / (10 ** ndigit[ndigit[2] - 1]) ) elif choice == 4: snap = ( snap[2] / (ndigit[ndigit[0] - 1]) + snap[0] / (10 ** ndigit[ndigit[1] - 1]) + snap[1] / (10 ** ndigit[ndigit[2] - 1]) ) elif choice == 5: snap = ( snap[0] / (ndigit[ndigit[0] - 1]) + snap[1] / (10 ** ndigit[ndigit[1] - 1]) + snap[0] / (10 ** ndigit[ndigit[2] - 1]) ) snap = round(snap, ndigit[choice % 3]) if snap < 1.5: snap += 1 time_sleep(snap * self.x) if (self.x) else time_sleep(snap)
def randint(first_number, last_number): return random_randint(first_number, last_number)
def calculate_score_value(middle_score: int, score_percentage: int): """Calculates final score that depends on 'Player. ...Percents' value and middleScores""" score_offset = random_randint(-score_percentage, +score_percentage) / 100 score = int(middle_score + (middle_score * score_offset) + 1) return score
init_printout = ["My PID is : " + str(my_pid)] #Set up Config file and read it in if present config = class_config() if fileexists(config.config_filename): init_printout.append("Config taken from file") print("will try to read Config File : ", config.config_filename) config.read_file() # overwrites from file else: # no file so my_sensorneeds to be written config.write_file() init_printout.append( "New Config File Made with default values, you probably need to edit it" ) # make a random number string between 1 and a thousand use to copy html files random_text_number = str(random_randint(1, 1001)) try: print("start copy using: ", random_text_number) config.status_html_filename = "" config.log_html_filename copyfile("cpu_log.html", "old/" + "cpu_log" + random_text_number + ".html") print("finish copy") except: print("Cannot copy old files") ############################ each below needs o be check if needed or if could be moved into config.cfg config.log_on = False config.temp_log_on = False config.log_outfile = "" config.temp_log_outfile = "" config.scan_count = 0
def main(argv): global status_buffer last_ref = -1 here = "main" my_pid = getpid() wd = class_wd("temp_control_wd") config = class_config() # initiate to default values config.prog_name = str(sys_argv[0][:-3]) print("Program Name is : ",config.prog_name) prg_version = config.prog_name[-3:] print("So Version taken as : ",prg_version) print("start ver " + prg_version + " PID (Process ID) is : " + str(my_pid)) #For debug purposed copy old html files from last run # make a random number string between 1 and a thousand random_text_number = str(random_randint(1,1001)) try: print("start copy using: ", random_text_number) copyfile("index.html", "old/" + prg_version + "index" + random_text_number + ".html") copyfile("status.html", "old/" + prg_version + "status" + random_text_number + ".html") copyfile("log.html", "old/" + prg_version + "log" + random_text_number + ".html") copyfile("debug.html", "old/" + prg_version + "debug" + random_text_number + ".html") copyfile("wd_log.html", "old/" + prg_version + "wd_log" + random_text_number + ".html") copyfile("wd.p", "old/" + prg_version + "wd" + random_text_number + ".p") print("finish copy") except: print("Cannot copy old files") schedule = class_schedule() # initiate class, is used for targets even if values not taken from schedule file init_printout = ["My PID is : " + str(my_pid)] config.use_schedule = True #***************************************************** # (1) Get the option Flags ## config.check = check(config.check) options_ok = False #try:pr(config.dbug_ftp,here,"config.local_dir_www: ", config.local_dir_www ) for x in range(1,2): opts, args = getopt_getopt(argv,"cdfhusw") options_ok = True init_printout.append("No Options Errors") # number of sensors most modes sensors_max_number = 5 for opt, arg in opts: if opt == '-w': #debug the W1 function with extra printouts config.dbug_w1 = True if opt == '-s': #Sauna control init_printout.append("Option : " + opt) config.sauna = True config.use_schedule = False #seven seg stuff being removed #config.sevenseg = False sensors_max_number = 1 if opt == '-u': #underfloor mode config.underfloor = True config.use_schedule = False if opt == '-c': # cretae a new Config file and exit init_printout.append("Option : " + opt) config.new_config_wanted = True config.exit_flag = True if opt == '-d': # extensive dconfig.prog_path = path.dirname(path.realpath(__file__))ebug printouts init_printout.append("Option : " + opt) config.dbug = True if opt == '-f': init_printout.append("Option : " + opt) config.dbug_ftp = True if opt == '-h': # print help info on options init_printout.append("Option : " + opt) init_printout.append("Help on available options") init_printout.append("With No Options Control using Schedule File and Smartplugs") init_printout.append("-h :Help ") init_printout.append("-w :Extra Debug Printouts temperature sensors interface") init_printout.append("-s :Sauna Mode Control Heater Via PWM GPIO Output ") init_printout.append("-u :Underfloor Heater Mode; Smartplug Control using default Temperature Targets from config file: ") init_printout.append("-c :Make Config file using default values") init_printout.append("-d :Debug mode extensive printouts to screen ") init_printout.append("-f :Debug ftp and file name creation ") config.exit_flag = True config.ftplog_count = 0 if config.use_schedule: schedule.read_in_schedule_data("schedule.csv") time_now_dt = datetime.now() schedule.all_to_file("schedule2_all" + prg_version + ".csv") test_file = open("test_target_temps" + prg_version + ".csv",'w') test_file.write("time,time_formated,target_temp,target_full_power") test_file.write("\n") base_time = datetime.now() + datetime_timedelta(days=-1) for more_minutes in range(1,15000,10): time_check = base_time + datetime_timedelta(minutes=more_minutes) temp = datetime(1899, 12, 30) # Note, not 31st Dec but 30th! delta = time_check - temp # Convert to Excel format time_now = float(delta.days) + (float(delta.seconds) / 86400) schedule.get_target_temp(time_check,False) test_file.write(str(round(time_now,4)) + "," + time_check.strftime('%c') + "," + str(round(schedule.target_temp,2)) \ + "," + str(round(schedule.target_full_power,2))) test_file.write("\n") #Set things up and read in # init(argv) # 6 tasks setting up variables etc #Start of part that was in int #*************.location**************************************** # (1) set up buffers and sensor data # and initialise various pr(config.dbug_ftp,here,"config.local_dir_www: ", config.local_dir_www ) # if config.sauna: # # Headings: Time,Scan#,Target,Ref Temp,On,Offset,Detect Off #smart_log_width = 0 ################# ???????????? # log_buffer_width = 4 + 3 else: # Headings: Time,Scan#,Target,Ref Temp,T1,T2,T3,T4,T5,I1,V1,P1,T1,I2,V2,P2,T2 # 1,3,5,4,4 #smart_log_width = 8 #################### ????????????? # log_buffer_width = 4 + sensors_max_number + smart_log_width ##### log_buffer_headings = ["hdg01","hdg02","hdg03","hdg04","hdg05","hdg06","hdg07","hdg08","hdg09","hdg10","hdg11","hdg14","hdg15","hdg16","hdg17","hdg18","hdg19","hdg20","hdg21"] log_buffer_flag = True log_buffer = class_text_buffer(100,log_buffer_headings,"log",config,log_buffer_flag) ####### #if not(config.sauna): # for ind in range(1,sensors_max_number+1): # log_buffer.set_buffer_heading("T" + str(ind)) #log_buffer.set_buffer_heading("Scan#") #log_buffer.set_buffer_heading("Target") #log_buffer.set_buffer_heading("Ref Temp") #if config.sauna: # log_buffer.set_buffer_heading("On") # log_buffer.set_buffer_heading("Offset") # log_buffer.set_buffer_heading("Detect Off") #else: # log_buffer.set_buffer_heading("I1") # log_buffer.set_buffer_heading("V1") # log_buffer.set_buffer_heading("P1") # log_buffer.set_buffer_heading("T1") # log_buffer.set_buffer_heading("I2") # log_buffer.set_buffer_heading("V2") # log_buffer.set_buffer_heading("P2") # log_buffer.set_buffer_heading("T2") # Pattern for setting up buffer #to set up replace "[name]" with the buffer name #enter headings #set flag True/False if want csv log file also made and sent #[name]_buffer_width = [width] #headings = ["[heading1]","[heading2]","[heading3]", ......] #[name]_cpu_log_buffer_flag = [True/False] #if also want csv log file #[name]_buffer = class_text_buffer(200,headings,"[name]",config,[name]_log_buffer_flag) #[name]_buffer_values = [""] * ([name]_buffer_width-1) #status_buffer_width = 3 #status_buffer_values = [""] * (status_buffer_width-1) ########### needed ??????? #debug_buffer_width = 4 # One More than max number in values array to allow for col with time stamp debug_buffer_values = ["not set"] * (debug_buffer_width - 1) ######################## #debug_buffer = class_text_buffer(200,debug_buffer_width,"debug",config) debug_buffer_headings = ["hdg01","hdg02","hdg03","hdg04","hdg05","hdg06","hdg07","hdg08","hdg09","hdg10","hdg11","hdg14","hdg15","hdg16","hdg17","hdg18","hdg19","hdg20","hdg21"] debug_buffer_flag = True debug_buffer = class_text_buffer(200,debug_buffer_headings,"log",config,debug_buffer_flag) #debug_buffer.set_buffer_heading("Scan#") #debug_buffer.set_buffer_heading("Line") #debug_buffer.set_buffer_heading("Third Thing") html_filename = "debug.html" html_filename_save_as = config.prog_path + "debug.html" www_filename = config.local_dir_www + "debug.html" ####################### old not needed ?? #debug_buffer.set_buffer_filenames(html_filename,html_filename_save_as,www_filename,config.ftp_creds_filename) ##################### debug_buffer.line_values[0] = "Debug Buffer Set" debug_buffer.line_values[1] = "Software version: " + prg_version debug_buffer.line_values[2] = "" #debug_buffer.pr(True,0, datetime.now()) refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) debug_buffer.pr(True,0, datetime.now()) #status_buffer = class_text_buffer(100,status_buffer_width,"status",config) status_buffer_headings = ["hdg01","hdg02","hdg03","hdg04","hdg05","hdg06","hdg07","hdg08","hdg09","hdg10","hdg11","hdg14","hdg15","hdg16","hdg17","hdg18","hdg19","hdg20","hdg21"] status_buffer_flag = True status_buffer = class_text_buffer(100,status_buffer_headings,"log",config,status_buffer_flag) # was status_buffer.set_buffer_get_heading("Reason") # now set to August 9th 2018 print("start") #status_buffer.set_buffer_heading("Reason") #status_buffer.set_buffer_heading("Message") my_sensors = class_my_sensors(sensors_max_number) # (1) (b) config.prog_path = path.dirname(path.realpath(__file__)) + "/" config.prog_name = str(sys_argv[0][:-3]) ##################################################################### config.config_filename = config.prog_path + "config_" + prg_version + ".cfg" ################################################################# print( "Just set config file to : ", config.config_filename) print("config.local_dir_www with default: ", config.local_dir_www ) print("Program and Module names", config.prog_name, config.my_module_name ) # seven seg stuff being removed # config.sevenseg = False # user local sevenseg display starttime = datetime.now() timestamp = make_time_text(starttime) pr(config.dbug_ftp,here,"This is the time stamp used for log file >>>", timestamp + "<<<<") # GPIO pin set up for Sauna Control #GPIO_setmode(GPIO_BCM) #GPIO_setup(18, GPIO_OUT) #pwm_out = GPIO_PWM(18,0.25) #pwm_out.start(0) #***************************************************** # (3) set up filenames config.set_filename(config.config_filename) init_printout.append( "Will look for this config file : " + config.config_filename) #set up configuration if fileexists(config.config_filename) and config.new_config_wanted: init_printout.append("For a default config file please first rename or delete old file") config.exit_flag = True elif config.new_config_wanted: init_printout.append("New Config File Made (" + str(config.config_filename) + ")with default values, now you can edit it") config.write_file() config.exit_flag = True else: if fileexists(config.config_filename): init_printout.append("Config taken from file") print( "will try to read Config File : " , config.config_filename ) config.read_file() # overwrites from file else : # no file so my_sensorneeds to be written config.write_file() init_printout.append("New Config File Made with default values, you probably need to edit it") #initial values set up config.ftplog_count = 0 config.last_target = config.min_target config.last_target_full_power = config.min_target pr(config.dbug_ftp,here,"config.prog_path: ", config.prog_path) pr(config.dbug_ftp,here,"config.local_dir_www: ", config.local_dir_www) config.s_filename = config.prog_path + config.sensor_config_filename pr(config.dbug_ftp,here,"config.s_filename: ", config.s_filename ) my_sensors.set_s_filename(config.s_filename) config.log_filename = timestamp + "lg.csv" pr(config.dbug_ftp,here,"config.log_filename: ", config.log_filename) my_sensors.set_log_filename(config.log_filename) config.log_filename_save_as = config.prog_path + config.log_directory + config.log_filename pr(config.dbug_ftp,here,"config.log_filename_save_as: ", config.log_filename_save_as ) my_sensors.set_log_filename_save_as(config.log_directory + config.log_filename) config.local_www_log_filename = config.local_dir_www + config.log_directory + config.log_filename pr(config.dbug_ftp,here,"config.local_www_log_filename: ",config.local_www_log_filename ) my_sensors.set_www_log_filename(config.local_www_log_filename) config.html_filename = "index.html" pr(config.dbug_ftp,here,"config.html_filename: ", config.html_filename) my_sensors.set_local_html_filename(config.html_filename) config.local_www_html_filename = config.local_dir_www + config.html_filename pr(config.dbug_ftp,here,"config.local_www_html_filename: ",config.local_www_html_filename ) my_sensors.set_www_filename(config.local_www_html_filename) config.status_html_filename = "status.html" pr(config.dbug_ftp,here,"config.status_html_filename: ", config.status_html_filename) config.status_html_filename_save_as = config.prog_path + config.status_html_filename pr(config.dbug_ftp,here,"config.status_html_filename_save_as: ", config.status_html_filename_save_as ) config.local_www_status_html_filename = config.local_dir_www + config.status_html_filename pr(config.dbug_ftp,here,"config.local_www_status_html_filename: ", config.local_www_status_html_filename ) config.log_html_filename = "log.html" pr(config.dbug_ftp,here,"config.log_html_filename : ", config.log_html_filename) config.log_html_filename_save_as = config.prog_path + config.log_html_filename pr(config.dbug_ftp,here,"config.log_html_filename_save_as : ", config.log_html_filename_save_as) config.local_www_log_html_filename = config.local_dir_www + config.log_html_filename pr(config.dbug_ftp,here,"local_www_log_html_filename : ", config.local_www_log_html_filename) ############### ???????????? # status_buffer.set_buffer_filenames(config.status_html_filename,config.status_html_filename_save_as,config.local_www_status_html_filename,config.ftp_creds_filename) ###################### ???? ############## # log_buffer.set_buffer_filenames(config.log_html_filename,config.log_html_filename_save_as,config.local_www_log_html_filename,config.ftp_creds_filename) #################### my_sensors.set_status_html_filename(config.status_html_filename) my_sensors.set_log_html_filename(config.log_html_filename) my_sensors.set_ftp_creds(config.ftp_creds_filename) #***************************************************** # (3) Load in Sensor Data # (If no file then save defaults to config.cfg file) if fileexists(config.s_filename): # if there is a file with sensor data read it in my_sensors.read_file() init_printout.append("Sensor data file data read in") new_codes_count = my_sensors.get_temps() #then if there are any new we have not seen before write to the sensor file if new_codes_count >0 : init_printout.append("New Sensors found "+ str(new_codes_count) + " new" ) my_sensors.write_file(new_codes_count,False) init_printout.append("New Sensor data written to file") elif len(W1ThermSensor.get_available_sensors()) < 1 : # Check for any sensors init_printout.append("No Temp Sensors found check connections") config.exit_flag = True else: # Wi write to a sensor file new_codes_count = my_sensors.get_temps() print("No File and new codes found - new_codes_count, my_sensors.width : ", new_codes_count, my_sensors.width) my_sensors.write_file(new_codes_count,True) my_sensors.set_sensor4readings(config.sensor4readings) #***************************************************** # (4) set up empty lists to hold smartplug info # (see "class_smartplug" for information) # NOTE: Class is set from here for 2 (two) plugs smartplug = class_smartplug(4) smartplug.timeout = 750000 # Initial Value for Timeout in Microseconds (1000000 is 1 second) config.number_heaters = 0 if smartplug.validIP(config.heaterIP0): smartplug.ip[config.number_heaters] = config.heaterIP0 smartplug.heater_power_scale[config.number_heaters] = config.heaterIP0_power_scale config.number_heaters +=1 print("Valid IP0 : ",config.heaterIP0) else: print("Invalid IP0 : ",config.heaterIP0) if smartplug.validIP(config.heaterIP1): smartplug.ip[config.number_heaters] = config.heaterIP1 smartplug.heater_power_scale[config.number_heaters] = config.heaterIP1_power_scale config.number_heaters +=1 print("Valid IP1 : ",config.heaterIP1) else: print("Invalid IP1 : ",config.heaterIP1) if smartplug.validIP(config.heaterIP2): smartplug.ip[config.number_heaters] = config.heaterIP2 smartplug.heater_power_scale[config.number_heaters] = config.heaterIP2_power_scale config.number_heaters +=1 print("Valid IP2 : ",config.heaterIP2) else: print("Invalid IP2 : ",config.heaterIP2) if smartplug.validIP(config.heaterIP3): smartplug.ip[config.number_heaters] = config.heaterIP3 smartplug.heater_power_scale[config.number_heaters] = config.heaterIP3_power_scale config.number_heaters +=1 print("Valid IP3 : ",config.heaterIP3) else: print("Invalid IP3 : ",config.heaterIP3) # Initial setup Complete so write messages for initial_ind in range(0,len(init_printout)): status_buffer.line_values[0] = "Init Report: " status_buffer.line_values[1] = init_printout[initial_ind] refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(True,0, datetime.now()) if config.exit_flag: sys_exit() #***************************************************** # (6) set up log file using parameters from config.cfg # (file based is based on current time) if len(config.log_directory) > 0: config.log_outfile = open(config.log_filename_save_as,'w') config.log_on = True else: config.log_on = False config.log_filename = None config.log_outfile = "" #***************************************************** # (6) Make su config.check = check(config.check)re the Gpio and thermometer modules are loaded # () #Commented out for test #subprocess.call(['sudo','modprobe', 'w1-gpio']) #subprocess.call(['sudo','modprobe', 'w1-therm']) #***************************************************** # (17) set up error codes # () error=["OK","1File only","2New no Data","3Timeout","4CRC er", "5Read Err","6Retry Err","7Error","8No Data","9No Dev","10Disconn"] # if there is a schedule file read it in, if not quit sch_filename = config.prog_path + "schedule.csv" if config.use_schedule: sch_filename = config.prog_path + "schedule.csv" if fileexists(sch_filename): status_buffer.line_values[0] = "Schedule Found in: " status_buffer.line_values[1] = sch_filename refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(True,1, datetime.now()) schedule = class_schedule() schedule.read_in_schedule_data(sch_filename) else: quit ( "No Schedule File Found") #Main Loop change_flag = False config.scan_count = 1 config.sensor_present = False # Scan for max_scan times or for ever if config.max_scans = 0 print("Start Main" ) while (config.scan_count <= config.max_scans) or (config.max_scans == 0): # For clarity when using debug to see start of scan pr(config.dbug,here, " ----- ", " ----- ") # now get data from all the sensor that are connected new_codes_count = my_sensors.get_temps() # then if there are any new we have not seen before write to the sensor file if new_codes_count >0 : my_sensors.write_file(new_codes_count,len(my_sensors.code) == new_codes_count) for z in range(0,len(my_sensors.code),1): if my_sensors.connected[z]: pr(config.dbug_w1,here,"sensor : " + str(my_sensors.number[z]) + " returned :", my_sensors.reading[z]) if (abs(my_sensors.last_logged[z] - my_sensors.reading[z])) > float(config.change4log): change_flag = True if config.scan_count > 1 : my_sensors.last_logged[z] = my_sensors.reading[z] if my_sensors.last_logged_error_number[z] != my_sensors.error_number[z]: change_flag = True # **************************** # Get target temperature #**************************** time_now = datetime.now() not_underfloor = False if config.sauna: # If in Sauna mode then there is only the one target temperaturetaken from the config file # In future could change this to have a scheduled time for the Sauna in a schedule file schedule.target_temp = config.default_target schedule.target_full_power = config.default_target_full_power if config.scan_count < 2 : config.target_offset = - 0.1*(schedule.target_temp - schedule.target_full_power) if schedule.target_full_power > (schedule.target_temp - 1): schedule.target_full_power = schedule.target_temp - 1 status_buffer.line_values[0] = "Target Full Power not at least 1 deg below Target" status_buffer.line_values[1] = "Using : " + schedule.target_full_power + " for target full power" refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(True,3, datetime.now()) elif config.use_schedule: # Not in sauna mode so get target temps from schedule file schedule.get_target_temp(time_now,config.dbug) if schedule.error_message != "OK" : status_buffer.line_values[0] = "Schedule Error. Will use last if they < max and > min allowed" refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.line_values[1] = schedule.error_message refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(True,1, datetime.now()) # Check that the full power is not greater than the target as then control would not work right status_buffer.line_values[0] = "" if schedule.target_full_power > config.max_target : schedule.target_full_power = config.max_target status_buffer.line_values[0] = "Target Full Power reduced to max " elif schedule.target_full_power < config.min_target : schedule.target_full_power = config.min_target status_buffer.line_values[0] = "Target Full Power increased to min " if schedule.target_temp > config.max_target : schedule.target_temp = config.max_target status_buffer.line_values[0] = status_buffer.line_values[0] + "Target Temp reduced to max " elif schedule.target_full_power < config.min_target : schedule.target_temp = config.min_target status_buffer.line_values[0] = status_buffer.line_values[0] + "Target Temp increased to min " if schedule.target_full_power > schedule.target_temp: schedule.target_full_power = schedule.target_temp status_buffer.line_values[0] = status_buffer.line_values[0] + "Target Full Power was not < Target" if status_buffer.line_values[0] != "" : status_buffer.line_values[1] = "Using : " + str(schedule.target_full_power) + " for full pwr with "+ \ str(schedule.target_temp) + " as target" refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(True,3, datetime.now()) if (config.last_target != schedule.target_temp) or \ (config.last_target_full_power != schedule.target_full_power): if abs(schedule.target_temp - config.last_target) < 0.25 : status_re_write_flag = False status_buffer.line_values[0] = "Target Change" else: status_re_write_flag = True status_buffer.line_values[0] = "Target Change" status_buffer.line_values[1] = str(config.last_target) + "/" + str(config.last_target_full_power) \ + " to " + str(schedule.target_temp) + "/" + str(schedule.target_full_power) refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(status_re_write_flag,3, datetime.now()) config.last_target = schedule.target_temp config.last_target_full_power = schedule.target_full_power #So in underfloor on heat mode so set temperatures as if in sauna mode from the config file elif config.underfloor: status_buffer.line_values[0] = "" schedule.target_temp = config.default_target schedule.target_full_power = config.default_target_full_power if schedule.target_full_power > (schedule.target_temp - 1): schedule.target_full_power = schedule.target_temp - 1 status_buffer.line_values[0] = "UF Target Full Power not at least 1 deg below Target" status_buffer.line_values[1] = "UF Using : " + schedule.target_full_power + " for target full power" refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(True,3, datetime.now()) if schedule.target_temp > config.max_target : schedule.target_temp = config.max_target status_buffer.line_values[0] = status_buffer.line_values[0] + "UF Target Temp reduced to max " elif schedule.target_full_power < config.min_target : schedule.target_temp = config.min_target status_buffer.line_values[0] = status_buffer.line_values[0] + "UF Target Temp increased to min " if schedule.target_full_power > schedule.target_temp: schedule.target_full_power = schedule.target_temp status_buffer.line_values[0] = status_buffer.line_values[0] + "UF Target Full Power was not < Target" if status_buffer.line_values[0] != "" : status_buffer.line_values[1] = "UF Using : " + str(schedule.target_full_power) + " for full pwr with "+ \ str(schedule.target_temp) + " as target" refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(True,3, datetime.now()) if (config.last_target != schedule.target_temp) or \ (config.last_target_full_power != schedule.target_full_power): # print("Change detected") if abs(schedule.target_temp - config.last_target) < 0.25 : status_re_write_flag = False status_buffer.line_values[0] = "UF Target Change" else: status_re_write_flag = True status_buffer.line_values[0] = "UF Target Change" # status_buffer.line_values[0] = "Target Change" status_buffer.line_values[1] = str(config.last_target) + "/" + str(config.last_target_full_power) \ + " to " + str(schedule.target_temp) + "/" + str(schedule.target_full_power) refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(status_re_write_flag,3, datetime.now()) config.last_target = schedule.target_temp config.last_target_full_power = schedule.target_full_power # **************************** # Start of heater Control * # **************************** # Check if reading indictates if heaters should be turned on of off config.control_error = (my_sensors.reading[config.ref_sensor_index] - \ (schedule.target_temp-config.target_offset))/config.control_hysteresis if config.sauna : if (len(my_sensors.reading) > 0) and (config.ref_sensor_index != -1 ): # seven seg modes eyc being removed #if config.sevenseg : # show_numbers(schedule.target_temp, my_sensors.reading[config.ref_sensor_index] ) if my_sensors.reading[config.ref_sensor_index] > schedule.target_full_power: config.reached_target = True if (my_sensors.reading[config.ref_sensor_index] < schedule.target_full_power) and config.reached_target: config.detect_off_count += 1 if my_sensors.reading[config.ref_sensor_index] > \ schedule.target_temp + config.target_offset + (schedule.target_temp - schedule.target_full_power) : config.sauna_on = 0 pwm_out.ChangeDutyCycle(config.percent_full_power * config.sauna_on) config.detect_off_count = 0 else: if my_sensors.reading[config.ref_sensor_index] < schedule.target_full_power + config.target_offset: config.sauna_on = 1 pwm_out.ChangeDutyCycle(config.percent_full_power * config.sauna_on) if config.reached_target: config.detect_off_count += 1 else: # calc on ratio where 100% on is 1 offset_target = schedule.target_temp + config.target_offset diff_targets = schedule.target_temp - schedule.target_full_power reading = my_sensors.reading[config.ref_sensor_index] config.sauna_on = ((offset_target + (diff_targets)) - reading) \ /(2*(diff_targets)) if config.sauna_on > 1: config.sauna_on = 1 print("reduce to 1") if config.sauna_on < 0: print("increase to 0") config.sauna_on = 0 pwm_out.ChangeDutyCycle(config.percent_full_power * config.sauna_on) # Integral Control using an offset of the target temperature # max offset is limited to difference betrween target and full power target config.target_offset = config.target_offset + (config.target_integral* \ (schedule.target_temp-my_sensors.reading[config.ref_sensor_index])) if config.target_offset > (schedule.target_temp - schedule.target_full_power): config.target_offset = (schedule.target_temp - schedule.target_full_power) if config.target_offset < - (schedule.target_temp - schedule.target_full_power): config.target_offset = - (schedule.target_temp - schedule.target_full_power) else: print("No Ref", len(my_sensors.reading), config.ref_sensor_index ) status_buffer.line_values[0] = "Error Message" status_buffer.line_values[1] = ("No ref line 469" + str(len(my_sensors.reading)) + ":" + str(config.ref_sensor_index)) refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(True,4, datetime.now()) else : if (len(my_sensors.reading) > 0) and (config.ref_sensor_index != -1 ): s_time = datetime.now() s_hour = s_time.hour # If temperature is above Target Temperature then turn all heaters off if my_sensors.reading[config.ref_sensor_index] > schedule.target_temp : #print("Turn off", my_sensors.reading[config.ref_sensor_index],schedule.target_temp + float(config.control_hysteresis)) pr(config.dbug_w1,here,"Turn off smart plugs at temp: ", my_sensors.reading[config.ref_sensor_index]) for ipind in range(0,config.number_heaters): responce = smartplug.turn_off_smartplug(ipind) if responce == "error": print("Error Plug Turn Off for index : " + str(ipind)) else: smartplug.turn_off_time_taken = smartplug.calculate_time("Turn off") pr(config.dbug,here,"Plug " + str(ipind),"off OK" + " Responce is : " + responce) # If temp below target_full_power turn all on elif my_sensors.reading[config.ref_sensor_index] < schedule.target_full_power : pr(config.dbug,here,"Turn on all" + str(my_sensors.reading[config.ref_sensor_index]) \ ,schedule.target_full_power - float(config.control_hysteresis)) for ipind in range(0,config.number_heaters): responce = smartplug.turn_on_smartplug(ipind) if responce == "error": print("Error Plug Turn On for index : " + str(ipind)) else: smartplug.turn_on_time_taken = smartplug.calculate_time("Turn on") pr(config.dbug,here,"Plug " + str(ipind),"on OK" + " Responce is : " + responce) # If between Target Temp and Full power so need to turn on just one heater elif (my_sensors.reading[config.ref_sensor_index] > schedule.target_full_power) and \ (my_sensors.reading[config.ref_sensor_index] < schedule.target_temp): for ipind in range(0,config.number_heaters): if ipind == config.one_heater_select: responce = smartplug.turn_on_smartplug(ipind) if responce == "error": print("Error Plug Turn On for index : " + str(ipind)) else: smartplug.turn_on_time_taken = smartplug.calculate_time("Turn on") pr(config.dbug,here,"Plug " + str(ipind),"on OK" + " Responce is : " + responce) else: responce = smartplug.turn_off_smartplug(ipind) if responce == "error": print("Error Plug Turn Off for index : " + str(ipind)) else: smartplug.turn_off_time_taken = smartplug.calculate_time("Turn off") # error ext line found 5 not 4 values April 3rd 2019 pr(config.dbug,here,"Plug " + str(ipind),"off OK" + " Responce is : " + responce) else: print ("No Control") status_buffer.line_values[0] = "Error Message" status_buffer.line_values[1] = "No ref line 691" refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) status_buffer.pr(True,5, datetime.now()) # **************************** # End of heater Control * # **************************** # create the index.html file and then send it to local and remote websites my_sensors.send_html_by_ftp(config,smartplug,schedule.target_temp,schedule.target_full_power) # config.ftplog_count will be 0 first time only so log at start then reset to 1 # counts up to config.ftp_log_max_count to trigger log if ther eis no change #print("change_flag, log count, max,config.scan_count", str(change_flag), config.ftplog_count, config.ftp_log_max_count,config.scan_count) if change_flag or (config.scan_count == config.max_scans) or (config.scan_count == 0) or (config.ftplog_count >= config.ftp_log_max_count): my_sensors.set_status_text(config) # figure out the status text for the temperature sensors if config.log_on: #print("Doing Log with config.ftplog_count = ",config.ftplog_count) my_sensors.log_to_file(config,smartplug,schedule.target_temp, my_sensors.reading[config.ref_sensor_index],config.dbug,smart_log_width) pr(config.dbug,here," *** config.ftplog_count : ",config.ftplog_count) my_sensors.send_log_by_ftp(config.dbug_ftp,config.log_directory,config.ftp_timeout) my_sensors.copy_log_to_www(config.dbug_ftp) config.last_ftplog = config.scan_count log_buffer_append_flag = True config.ftplog_count = 0 else: config.ftplog_count += 1 #print("Not logging so incremented count to: ",config.ftplog_count, "Then print to screen") if config.scan_count < 3 : # config.ftp_log_max_count: #print("Less Than 2 >> True",config.scan_count) log_buffer_append_flag = True else: #print("2 or More >> False",config.scan_count) log_buffer_append_flag = False if config.sauna != True: # Make sure up to date with Smartplug info for log html file responce = smartplug.get_smartplug_status(config.dbug,config) if responce == "error": print(str(smartplug.get_status_error_count) + " Error(s) Getting Smartplug Status") smartplug.get_status_error_count = 0 else: pr(config.dbug,here,"Got Status OK" + " Responce is : ",responce) log_buffer.line_values = my_sensors.make_printout_for_screen(schedule.target_temp,my_sensors.reading[config.ref_sensor_index],config,smartplug) refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) log_buffer.pr(log_buffer_append_flag,0,datetime.now()) #log_buffer.pr(log_buffer_append_flag,0, my_sensors.make_printout_for_screen(schedule.target_temp,my_sensors.reading[config.ref_sensor_index],config,smartplug)) # Following can be used to log the time taken to talk to smart plugs #debug_buffer.line_values[0] = "Scan : " + str(config.scan_count) #if config.sauna != True: # debug_buffer.line_values[0] = debug_buffer.line_values[0] + " GetStat Errs: " + str(smartplug.get_status_error_count) #debug_buffer.line_values[1] = "Maximum Smartplug Time Was " + str(round(smartplug.max_time/1000000,4)) + "secs" #debug_buffer.line_values[2] = "Timeout Is " + str(round(smartplug.timeout/1000000,4)) + "secs" #refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) #debug_buffer.pr(True,0, datetime.now()) #print("config.dbug :",config.dbug) #debug_buffer.line_values[0] = "Turn Off Time " + str(round(smartplug.turn_off_time_taken/1000000,4)) + "secs" #debug_buffer.line_values[1] = "Turn On Time " + str(round(smartplug.turn_on_time_taken/1000000,4)) + "secs" #debug_buffer.line_values[2] = "Read " + str(round(smartplug.do_read_time_taken/1000000,4)) + "secs " + \ # "Info " + str(round(smartplug.do_info_time_taken/1000000,4)) + "secs" #refresh_time = config.scan_delay + (config.scan_delay/3) #example_buffer.pr(buffer_increment_flag,0,loop_start_time,refresh_time) #debug_buffer.pr(True,0, datetime.now()) #reset change flag and operate delay before next scan change_flag = False last_ended = make_time_text(datetime.now()) # if in sauna mode and between sauna control does its own delays # write file to be used by Watch Dog Program print("sending from temp control : ",config.scan_count) wd.put_wd(config.scan_count,"ok") # Sleep for a delay print("Before Sleep for : ",config.scan_delay) time_sleep(config.scan_delay) print("After Sleep") # increment count config.scan_count += 1 # Shut down if Sauna Heater Detected as off and temperature dropping if config.sauna and (config.detect_off_count > 10) : call("sudo shutdown -h now", shell=True) return 0 if __name__ == '__main__': main(sys_argv[1:])
def randint(first_number: int, last_number: int)-> int: return random_randint(first_number, last_number)