def _check_schedule(): current_time = datetime.datetime.now() check_start = current_time - datetime.timedelta(days=1) check_end = current_time + datetime.timedelta(days=1) rain = not options.manual_mode and (rain_blocks.block_end() > datetime.datetime.now() or inputs.rain_sensed()) active = log.active_runs() for entry in active: ignore_rain = stations.get(entry['station']).ignore_rain if entry['end'] <= current_time or (rain and not ignore_rain and not entry['blocked'] and not entry['manual']): log.finish_run(entry) if not entry['blocked']: stations.deactivate(entry['station']) if not options.manual_mode: schedule = predicted_schedule(check_start, check_end) #import pprint #logging.debug("Schedule: %s", pprint.pformat(schedule)) for entry in schedule: if entry['start'] <= current_time < entry['end']: log.start_run(entry) if not entry['blocked']: stations.activate(entry['station']) if stations.master is not None or options.master_relay: master_on = False # It's easy if we don't have to use delays: if options.master_on_delay == options.master_off_delay == 0: for entry in active: if not entry['blocked'] and stations.get(entry['station']).activate_master: master_on = True break else: # In manual mode we cannot predict, we only know what is currently running and the history if options.manual_mode: active = log.finished_runs() + active else: active = combined_schedule(check_start, check_end) for entry in active: if not entry['blocked'] and stations.get(entry['station']).activate_master: if entry['start'] + datetime.timedelta(seconds=options.master_on_delay) \ <= current_time < \ entry['end'] + datetime.timedelta(seconds=options.master_off_delay): master_on = True break if stations.master is not None: master_station = stations.get(stations.master) if master_on != master_station.active: master_station.active = master_on if options.master_relay: if master_on != outputs.relay_output: outputs.relay_output = master_on
def set_stations_in_scheduler_off(): """Stoping selected station in scheduler.""" current_time = datetime.datetime.now() check_start = current_time - datetime.timedelta(days=1) check_end = current_time + datetime.timedelta(days=1) # In manual mode we cannot predict, we only know what is currently running and the history if options.manual_mode: active = log.finished_runs() + log.active_runs() else: active = combined_schedule(check_start, check_end) ending = False # active stations for entry in active: for used_stations in tank_options[ 'used_stations']: # selected stations for stoping if entry[ 'station'] == used_stations: # is this station in selected stations? log.finish_run(entry) # save end in log stations.deactivate(entry['station']) # stations to OFF ending = True if ending: log.info(NAME, _(u'Stoping stations in scheduler'))
def __init__(self): super(_Scheduler, self).__init__() self.daemon = True #options.add_callback('scheduler_enabled', self._option_cb) options.add_callback('manual_mode', self._option_cb) options.add_callback('master_relay', self._option_cb) # If manual mode is active, finish all stale runs: if options.manual_mode: log.finish_run(None)
def _option_cb(self, key, old, new): # Clear if manual mode changed: if key == 'manual_mode': programs.run_now_program = None run_once.clear() log.finish_run(None) stations.clear() # Stop relay if not used anymore: if key == 'master_relay' and not new and outputs.relay_output: outputs.relay_output = False
def _botCmd_stop(self, bot, update): # msg for stop all station and disable scheduler chat_id = update.message.chat.id if chat_id in list(self._currentChats): txt = _(u'{} System - scheduler OFF. All stations OFF.').format(options.name) programs.run_now_program = None run_once.clear() log.finish_run(None) stations.clear() else: txt = _(u'Sorry I can not do that.') if is_python2(): bot.sendMessage(chat_id, text=txt.encode('utf-8')) else: bot.sendMessage(chat_id, text=txt)
def _botCmd_runOnce(self, bot, update, args): # run-now program xx chat_id = update.message.chat.id if chat_id in list(self._currentChats): txt = _(u'{} RunOnce: program {}.').format(options.name, args) for program in programs.get(): if (program.index == int(args-1)): options.manual_mode = False log.finish_run(None) stations.clear() programs.run_now(program.index) break program.index+1 else: txt = _(u'Sorry I can not do that.') if is_python2(): bot.sendMessage(chat_id, text=txt.encode('utf-8')) else: bot.sendMessage(chat_id, text=txt)
def run(self): log.clear(NAME) while not self._stop.is_set(): try: if plugin_options['use_button']: # if button plugin is enabled actual_buttons = read_buttons() #led_outputs(actual_buttons) for i in range(8): tb = "button" + str(i) if actual_buttons == i and plugin_options[tb]== "reboot": log.info(NAME, datetime_string() + ': ' + _('System reboot')) stations.clear() reboot() self._sleep(2) if actual_buttons == i and plugin_options[tb]== "pwrOff": log.info(NAME, datetime_string() + ': ' + _('System shutdown')) stations.clear() poweroff() self._sleep(2) if actual_buttons == i and plugin_options[tb]== "stopAll": log.info(NAME, datetime_string() + ': ' + _('All stations now stopped')) log.finish_run(None) # save log stations.clear() # set all station to off self._sleep(2) if actual_buttons == i and plugin_options[tb]== "schedEn": log.info(NAME, datetime_string() + ': ' + _('Scheduler is now enabled')) options.scheduler_enabled = True self._sleep(2) if actual_buttons == i and plugin_options[tb]== "schedDis": log.info(NAME, datetime_string() + ': ' + _('Scheduler is now disabled')) options.scheduler_enabled = False self._sleep(2) if actual_buttons == i and plugin_options[tb]== "RunP1": log.info(NAME, datetime_string() + ': ' + _('Run now program 1')) for program in programs.get(): if (program.index == 0): # Run-now program 1 options.manual_mode = False log.finish_run(None) stations.clear() programs.run_now(program.index) program.index+1 self._sleep(2) if actual_buttons == i and plugin_options[tb]== "RunP2": log.info(NAME, datetime_string() + ': ' + _('Run now program 2')) for program in programs.get(): if (program.index == 1): # Run-now program 2 options.manual_mode = False log.finish_run(None) stations.clear() programs.run_now(program.index) program.index+1 self._sleep(2) if actual_buttons == i and plugin_options[tb]== "RunP3": log.info(NAME, datetime_string() + ': ' + _('Run now program 3')) for program in programs.get(): if (program.index == 2): # Run-now program 3 options.manual_mode = False log.finish_run(None) stations.clear() programs.run_now(program.index) program.index+1 self._sleep(2) if actual_buttons == i and plugin_options[tb]== "RunP4": log.info(NAME, datetime_string() + ': ' + _('Run now program 4')) for program in programs.get(): if (program.index == 3): # Run-now program 4 options.manual_mode = False log.finish_run(None) stations.clear() programs.run_now(program.index) program.index+1 self._sleep(2) if actual_buttons == i and plugin_options[tb]== "RunP5": log.info(NAME, datetime_string() + ': ' + _('Run now program 5')) for program in programs.get(): if (program.index == 4): # Run-now program 5 options.manual_mode = False log.finish_run(None) stations.clear() programs.run_now(program.index) program.index+1 self._sleep(2) if actual_buttons == i and plugin_options[tb]== "RunP6": log.info(NAME, datetime_string() + ': ' + _('Run now program 6')) for program in programs.get(): if (program.index == 5): # Run-now program 6 options.manual_mode = False log.finish_run(None) stations.clear() programs.run_now(program.index) program.index+1 self._sleep(2) if actual_buttons == i and plugin_options[tb]== "RunP7": log.info(NAME, datetime_string() + ': ' + _('Run now program 7')) for program in programs.get(): if (program.index == 6): # Run-now program 7 options.manual_mode = False log.finish_run(None) stations.clear() programs.run_now(program.index) program.index+1 self._sleep(2) if actual_buttons == i and plugin_options[tb]== "RunP8": log.info(NAME, datetime_string() + ': ' + _('Run now program 8')) for program in programs.get(): if (program.index == 7): # Run-now program 8 options.manual_mode = False log.finish_run(None) stations.clear() programs.run_now(program.index) program.index+1 self._sleep(2) self._sleep(1) except Exception: log.clear(NAME) log.error(NAME, _('Button plug-in') + ':\n' + traceback.format_exc()) self._sleep(60) pass
def run(self): last_millis = 0 # timer for save log once_text = True # once_text to mini is auxiliary for blocking two_text = True three_text = True five_text = True six_text = True send = False mini = True sonic_cm = -1 level_in_tank = 0 regulation_text = _(u'Regulation NONE.') if NAME in rain_blocks: del rain_blocks[NAME] self._sleep(2) tank_mon = None if tank_options['use_footer']: tank_mon = showInFooter( ) # instantiate class to enable data in footer tank_mon.button = "tank_monitor/settings" # button redirect on footer tank_mon.label = _(u'Tank') # label on footer end = datetime.datetime.now() avg_lst = [0] * tank_options['avg_samples'] avg_cnt = 0 avg_rdy = False while not self._stop_event.is_set(): try: if tank_options['use_sonic']: if two_text: log.clear(NAME) log.info(NAME, _(u'Water tank monitor is enabled.')) once_text = True two_text = False ping_read = get_sonic_cm() if tank_options[ 'use_avg'] and ping_read > 0: # use averaging try: avg_lst[avg_cnt] = ping_read except: avg_lst.append(ping_read) avg_cnt += 1 if avg_cnt > tank_options['avg_samples']: avg_cnt = 0 avg_rdy = True if avg_rdy: sonic_cm = average_list(avg_lst) level_in_tank = get_sonic_tank_cm(sonic_cm) else: sonic_cm = 0 log.clear(NAME) log.info( NAME, _(u'Waiting for {} samples to be read from the sensor (when using averaging).' ).format(tank_options['avg_samples'])) else: # without averaging if ping_read > 0: # if sonic value is bad (-1) not use these sonic_cm = ping_read level_in_tank = get_sonic_tank_cm(sonic_cm) else: sonic_cm = 0 level_in_tank = 0 tempText = "" if level_in_tank > 0 and sonic_cm != 0: # if level is ok and sonic is ok three_text = True status['level'] = level_in_tank status['ping'] = sonic_cm status['volume'] = get_volume(level_in_tank) status['percent'] = get_tank(level_in_tank) log.clear(NAME) log.info( NAME, datetime_string() + ' ' + _(u'Water level') + ': ' + str(status['level']) + ' ' + _(u'cm') + ' (' + str(status['percent']) + ' ' + (u'%).')) if tank_options['check_liters']: # display in liters tempText = str( status['volume'] ) + ' ' + _(u'liters') + ', ' + str( status['level']) + ' ' + _(u'cm') + ' (' + str( status['percent']) + ' ' + (u'%)') log.info( NAME, _(u'Ping') + ': ' + str(status['ping']) + ' ' + _(u'cm') + ', ' + _(u'Volume') + ': ' + str(status['volume']) + ' ' + _(u'liters') + '.') else: tempText = str( status['volume'] ) + ' ' + _(u'm3') + ', ' + str( status['level']) + ' ' + _(u'cm') + ' (' + str( status['percent']) + ' ' + (u'%)') log.info( NAME, _(u'Ping') + ': ' + str(status['ping']) + ' ' + _(u'cm') + ', ' + _(u'Volume') + ': ' + str(status['volume']) + ' ' + _(u'm3') + '.') log.info( NAME, str(status['maxlevel_datetime']) + ' ' + _(u'Maximum Water level') + ': ' + str(status['maxlevel']) + ' ' + _(u'cm') + '.') log.info( NAME, str(status['minlevel_datetime']) + ' ' + _(u'Minimum Water level') + ': ' + str(status['minlevel']) + ' ' + _(u'cm') + '.') log.info(NAME, regulation_text) if tank_options[ 'enable_reg']: # if enable regulation "maximum water level" reg_station = stations.get( tank_options['reg_output']) if level_in_tank > tank_options[ 'reg_max']: # if actual level in tank > set maximum water level if five_text: five_text = False six_text = True regulation_text = datetime_string( ) + ' ' + _( u'Regulation set ON.' ) + ' ' + ' (' + _(u'Output') + ' ' + str( reg_station.index + 1) + ').' start = datetime.datetime.now() sid = reg_station.index end = datetime.datetime.now( ) + datetime.timedelta( seconds=tank_options['reg_ss'], minutes=tank_options['reg_mm']) new_schedule = { 'active': True, 'program': -1, 'station': sid, 'program_name': _('Tank Monitor'), 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': start, 'original_start': start, 'end': end, 'uid': '%s-%s-%d' % (str(start), "Manual", sid), 'usage': stations.get(sid).usage } log.start_run(new_schedule) stations.activate(new_schedule['station']) if level_in_tank < tank_options[ 'reg_min']: # if actual level in tank < set minimum water level if six_text: # blocking for once five_text = True six_text = False regulation_text = datetime_string( ) + ' ' + _( u'Regulation set OFF.' ) + ' ' + ' (' + _(u'Output') + ' ' + str( reg_station.index + 1) + ').' sid = reg_station.index stations.deactivate(sid) active = log.active_runs() for interval in active: if interval['station'] == sid: log.finish_run(interval) now = datetime.datetime.now() if now > end: # if program end in schedule release five_text to true in regulation for next scheduling # five_text = True six_text = False regulation_text = datetime_string() + ' ' + _( u'Waiting.') if status['level'] > status[ 'maxlevel']: # maximum level check status['maxlevel'] = status['level'] tank_options.__setitem__('saved_max', status['level']) status['maxlevel_datetime'] = datetime_string() log.info( NAME, datetime_string() + ': ' + _(u'Maximum has updated.')) update_log() if status['level'] < status['minlevel'] and status[ 'level'] > 2: # minimum level check status['minlevel'] = status['level'] tank_options.__setitem__('saved_min', status['level']) status['minlevel_datetime'] = datetime_string() log.info( NAME, datetime_string() + ': ' + _(u'Minimum has updated.')) update_log() if status['level'] <= int( tank_options['water_minimum'] ) and mini and not options.manual_mode and status[ 'level'] > 2: # level value is lower if tank_options[ 'use_send_email']: # if email is enabled send = True # send mini = False if tank_options['use_stop']: # if stop scheduler set_stations_in_scheduler_off() log.info( NAME, datetime_string() + ' ' + _(u'ERROR: Water in Tank') + ' < ' + str(tank_options['water_minimum']) + ' ' + _(u'cm') + _(u'!')) delaytime = int(tank_options['delay_duration']) if delaytime > 0: # if there is no water in the tank and the stations stop, then we set the rain delay for this time for blocking rain_blocks[NAME] = datetime.datetime.now( ) + datetime.timedelta( hours=float(delaytime)) if level_in_tank > int( tank_options['water_minimum'] ) + 5 and not mini: # refresh send email if actual level > options minimum +5 mini = True if NAME in rain_blocks and level_in_tank > int( tank_options['water_minimum']): del rain_blocks[NAME] if tank_options['enable_log']: millis = int(round(time.time() * 1000)) interval = (tank_options['log_interval'] * 60000) if (millis - last_millis) > interval: last_millis = millis update_log() elif level_in_tank == -1 and sonic_cm == 0: # waiting for samples tempText = _('Waiting for samples') else: # error probe tempText = _('FAULT') log.clear(NAME) log.info( NAME, datetime_string() + ' ' + _(u'Water level: Error.')) if tank_options[ 'use_water_err'] and three_text: # if probe has error send email three_text = False log.info( NAME, datetime_string() + ' ' + _(u'ERROR: Water probe has fault?')) msg = '<b>' + _( u'Water Tank Monitor plug-in' ) + '</b> ' + '<br><p style="color:red;">' + _( u'System detected error: Water probe has fault?' ) + '</p>' msglog = _( u'Water Tank Monitor plug-in' ) + ': ' + _( u'System detected error: Water probe has fault?' ) try: from plugins.email_notifications import try_mail try_mail( msg, msglog, attachment=None, subject=tank_options['emlsubject'] ) # try_mail(text, logtext, attachment=None, subject=None) except Exception: log.error( NAME, _(u'Water Tank Monitor plug-in') + ':\n' + traceback.format_exc()) if tank_options['use_water_stop']: if NAME not in rain_blocks: set_stations_in_scheduler_off() delaytime = int(tank_options['delay_duration']) if delaytime > 0: # if probe has fault, then we set the rain delay for this time for blocking rain_blocks[NAME] = datetime.datetime.now( ) + datetime.timedelta( hours=float(delaytime)) if tank_options['enable_reg']: tempText += ', ' + regulation_text if tank_options['use_footer']: if tank_mon is not None: tank_mon.val = tempText.encode('utf8').decode( 'utf8') # value on footer self._sleep(3) else: if once_text: log.clear(NAME) log.info(NAME, _(u'Water tank monitor is disabled.')) once_text = False two_text = True last_level = 0 self._sleep(1) if send: msg = '<b>' + _( u'Water Tank Monitor plug-in' ) + '</b> ' + '<br><p style="color:red;">' + _( u'System detected error: Water Tank has minimum Water Level' ) + ': ' + str(tank_options['water_minimum']) + _( u'cm') + '.\n' + '</p>' msglog = _(u'Water Tank Monitor plug-in') + ': ' + _( u'System detected error: Water Tank has minimum Water Level' ) + ': ' + str( tank_options['water_minimum']) + _(u'cm') + '. ' send = False try: try_mail = None if tank_options['eplug'] == 0: # email_notifications from plugins.email_notifications import try_mail if tank_options[ 'eplug'] == 1: # email_notifications SSL from plugins.email_notifications_ssl import try_mail if try_mail is not None: try_mail( msg, msglog, attachment=None, subject=tank_options['emlsubject'] ) # try_mail(text, logtext, attachment=None, subject=None) except Exception: log.info( NAME, _(u'E-mail not send! The Email Notifications plug-in is not found in OSPy or not correctly setuped.' )) log.error( NAME, _(u'Water Tank Monitor plug-in') + ':\n' + traceback.format_exc()) except Exception: log.clear(NAME) log.error( NAME, _(u'Water Tank Monitor plug-in') + ':\n' + traceback.format_exc()) self._sleep(60)
def FTP_download(self): try: # read command file and save to ramdisk self.ftp.retrbinary("RETR " + plugin_options['loc'] + "data.txt", open("/home/pi/ramdisk/data.txt", 'wb').write) fs = file("/home/pi/ramdisk/data.txt", 'r') obsahaut = fs.readline() fs.close() log.debug( NAME, _(u'FTP received data from file data.txt') + ': ' + str(obsahaut)) change = False if (obsahaut == "AU"): # scheduller options.manual_mode = False log.info(NAME, _(u'Scheduler mode is activated.')) change = True if (obsahaut == "MA"): # manual options.manual_mode = True log.info(NAME, _(u'Manual mode is activated.')) change = True for num_output in range(0, options.output_count): s = 'Z' + str(num_output) if (obsahaut == s): # stations xx ON options.manual_mode = True log.info(NAME, _(u'Manual mode is activated.')) stations.activate(num_output) log.info(NAME, _(u'Activated stations') + ': ' + str(num_output + 1)) change = True s = 'V' + str(num_output) if (obsahaut == s): # stations xx OFF options.manual_mode = True log.info(NAME, _(u'Manual mode is activated.')) stations.deactivate(num_output) log.info( NAME, _(u'Deactivated stations') + ': ' + str(num_output + 1)) change = True for program in programs.get(): s = 'P' + str(program.index + 1) if (obsahaut == s): # Run-now program xx options.manual_mode = False log.info(NAME, _(u'Scheduler mode is activated.')) programs.run_now(program.index) log.info(NAME, _(u'Activated program') + ': ' + str(program.name)) self._sleep(2) change = True program.index + 1 if (obsahaut == "STOP"): # stop all stations and disable scheduler options.scheduler_enabled = False programs.run_now_program = None run_once.clear() log.finish_run(None) stations.clear() log.info(NAME, _(u'Stop all stations and disable system.')) change = True if (obsahaut == "START"): # enable scheduler options.scheduler_enabled = True log.info(NAME, _(u'Enable system.')) change = True if (change): # delete data.txt command now is OK fs = open('/home/pi/ramdisk/data.txt', 'w') fs.write('OK') fs.close() FTP_upload(self) # send to server actual data # TODO save_to_options except Exception: log.clear(NAME) log.info( NAME, _(u'Remote FTP control settings') + ':\n' + traceback.format_exc()) pass
def GET(self): from ospy import server qdict = web.input() stop_all = get_input(qdict, 'stop_all', False, lambda x: True) scheduler_enabled = get_input(qdict, 'scheduler_enabled', None, lambda x: x == '1') manual_mode = get_input(qdict, 'manual_mode', None, lambda x: x == '1') rain_block = get_input(qdict, 'rain_block', None, float) level_adjustment = get_input(qdict, 'level_adjustment', None, float) toggle_temp = get_input(qdict, 'toggle_temp', False, lambda x: True) if stop_all: if not options.manual_mode: options.scheduler_enabled = False programs.run_now_program = None run_once.clear() log.finish_run(None) stations.clear() if scheduler_enabled is not None: options.scheduler_enabled = scheduler_enabled if manual_mode is not None: options.manual_mode = manual_mode if rain_block is not None: options.rain_block = datetime.datetime.now() + datetime.timedelta(hours=rain_block) if level_adjustment is not None: options.level_adjustment = level_adjustment / 100 if toggle_temp: options.temp_unit = "F" if options.temp_unit == "C" else "C" set_to = get_input(qdict, 'set_to', None, int) sid = get_input(qdict, 'sid', 0, int) - 1 set_time = get_input(qdict, 'set_time', 0, int) if set_to is not None and 0 <= sid < stations.count() and options.manual_mode: if set_to: # if status is on start = datetime.datetime.now() new_schedule = { 'active': True, 'program': -1, 'station': sid, 'program_name': "Manual", 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': start, 'original_start': start, 'end': start + datetime.timedelta(days=3650), 'uid': '%s-%s-%d' % (str(start), "Manual", sid), 'usage': stations.get(sid).usage } if set_time > 0: # if an optional duration time is given new_schedule['end'] = datetime.datetime.now() + datetime.timedelta(seconds=set_time) log.start_run(new_schedule) stations.activate(new_schedule['station']) else: # If status is off stations.deactivate(sid) active = log.active_runs() for interval in active: if interval['station'] == sid: log.finish_run(interval) self._redirect_back()
def _check_schedule(): current_time = datetime.datetime.now() check_start = current_time - datetime.timedelta(days=1) check_end = current_time + datetime.timedelta(days=1) rain = not options.manual_mode and ( rain_blocks.block_end() > datetime.datetime.now() or inputs.rain_sensed()) active = log.active_runs() for entry in active: ignore_rain = stations.get(entry['station']).ignore_rain if entry['end'] <= current_time or (rain and not ignore_rain and not entry['blocked'] and not entry['manual']): log.finish_run(entry) if not entry['blocked']: stations.deactivate(entry['station']) if not options.manual_mode: schedule = predicted_schedule(check_start, check_end) #import pprint #logging.debug("Schedule: %s", pprint.pformat(schedule)) for entry in schedule: if entry['start'] <= current_time < entry['end']: log.start_run(entry) if not entry['blocked']: stations.activate(entry['station']) if stations.master is not None: master_on = False # It's easy if we don't have to use delays: if options.master_on_delay == options.master_off_delay == 0: for entry in active: if not entry['blocked'] and stations.get( entry['station']).activate_master: master_on = True break else: # In manual mode we cannot predict, we only know what is currently running and the history if options.manual_mode: active = log.finished_runs() + active else: active = combined_schedule(check_start, check_end) for entry in active: if not entry['blocked'] and stations.get( entry['station']).activate_master: if entry['start'] + datetime.timedelta(seconds=options.master_on_delay) \ <= current_time < \ entry['end'] + datetime.timedelta(seconds=options.master_off_delay): master_on = True break if stations.master is not None: master_station = stations.get(stations.master) if master_on != master_station.active: master_station.active = master_on if options.master_relay: outputs.relay_output = master_on if stations.master_two is not None: master_two_on = False # It's easy if we don't have to use delays: if options.master_on_delay_two == options.master_off_delay_two == 0: for entry in active: if not entry['blocked'] and stations.get( entry['station']).activate_master_two: master_two_on = True break else: # In manual mode we cannot predict, we only know what is currently running and the history if options.manual_mode: active = log.finished_runs() + active else: active = combined_schedule(check_start, check_end) for entry in active: if not entry['blocked'] and stations.get( entry['station']).activate_master_two: if entry['start'] + datetime.timedelta(seconds=options.master_on_delay) \ <= current_time < \ entry['end'] + datetime.timedelta(seconds=options.master_off_delay): master_two_on = True break if stations.master_two is not None: master_station_two = stations.get(stations.master_two) if master_two_on != master_station_two.active: master_station_two.active = master_two_on
def run(self): Temperature = 0 Humidity = 0 last_millis = 0 # timer for save log var1 = True # Auxiliary variable for once on var2 = True # Auxiliary variable for once off air_temp = None if plugin_options['use_footer']: air_temp = showInFooter( ) # instantiate class to enable data in footer air_temp.button = "air_temp_humi/settings" # button redirect on footer air_temp.label = _(u'Temperature') # label on footer regulation_text = '' #flow = showOnTimeline() # instantiate class to enable data display #flow.unit = _(u'Liters') #flow.val = 10 #flow.clear while not self._stop_event.is_set(): try: if plugin_options['enabled']: # if plugin is enabled log.clear(NAME) log.info(NAME, datetime_string()) tempText = "" if plugin_options[ 'enable_dht']: # if DHTxx probe is enabled try: result = 1 # 1=ERR_MISSING_DATA if plugin_options['dht_type'] == 0: # DHT11 result = instance.read() if plugin_options['dht_type'] == 1: # DHT22 result = instance22.read() if result.is_valid( ): # 0=ERR_NO_ERROR, 1=ERR_MISSING_DATA, 2=ERR_CRC Temperature = result.temperature Humidity = result.humidity global tempDHT, humiDHT tempDHT = Temperature humiDHT = Humidity except: log.clear(NAME) log.info(NAME, datetime_string()) if plugin_options['dht_type'] == 0: # DHT11 log.info(NAME, _(u'DHT11 data is not valid')) tempText += ' ' + _(u'DHT11 data is not valid') if plugin_options['dht_type'] == 1: # DHT22 log.info(NAME, _(u'DHT22 data is not valid')) tempText += ' ' + _(u'DHT22 data is not valid') if Humidity and Temperature != 0: self.status['temp'] = Temperature self.status['humi'] = Humidity log.info( NAME, _(u'Temperature') + ' ' + _(u'DHT') + ': ' + u'%.1f \u2103' % Temperature) log.info( NAME, _(u'Humidity') + ' ' + _(u'DHT') + ': ' + u'%.1f' % Humidity + ' %RH') tempText += ' ' + _( u'DHT' ) + ': ' + u'%.1f \u2103' % Temperature + ' ' + u'%.1f' % Humidity + ' %RH' + ' ' if plugin_options['enabled_reg']: log.info(NAME, regulation_text) station = stations.get( plugin_options['control_output']) if plugin_options[ 'enabled_reg']: # if regulation is enabled if Humidity > (plugin_options['humidity_on'] + plugin_options['hysteresis'] / 2) and var1 is True: start = datetime.datetime.now() sid = station.index end = datetime.datetime.now( ) + datetime.timedelta( seconds=plugin_options['reg_ss'], minutes=plugin_options['reg_mm']) new_schedule = { 'active': True, 'program': -1, 'station': sid, 'program_name': _('Air Temperature'), 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': start, 'original_start': start, 'end': end, 'uid': '%s-%s-%d' % (str(start), "Manual", sid), 'usage': stations.get(sid).usage } log.start_run(new_schedule) stations.activate(new_schedule['station']) var1 = False var2 = True self.status['outp'] = 1 regulation_text = datetime_string( ) + ' ' + _( u'Regulation set ON.' ) + ' ' + ' (' + _('Output') + ' ' + str( station.index + 1) + ').' update_log(self.status) if Humidity < (plugin_options['humidity_off'] - plugin_options['hysteresis'] / 2) and var2 is True: sid = station.index stations.deactivate(sid) active = log.active_runs() for interval in active: if interval['station'] == sid: log.finish_run(interval) var1 = True var2 = False self.status['outp'] = 0 regulation_text = datetime_string( ) + ' ' + _( u'Regulation set OFF.' ) + ' ' + ' (' + _('Output') + ' ' + str( station.index + 1) + ').' update_log(self.status) if plugin_options[ 'ds_enabled']: # if in plugin is enabled DS18B20 DS18B20_read_data( ) # get read DS18B20 temperature data to global tempDS[xx] tempText += _(u'DS') + ': ' for i in range(0, plugin_options['ds_used']): self.status['DS%d' % i] = tempDS[i] log.info( NAME, _(u'Temperature') + ' ' + _(u'DS') + str(i + 1) + ' (' + u'%s' % plugin_options['label_ds%d' % i] + '): ' + u'%.1f \u2103' % self.status['DS%d' % i]) tempText += u' %s' % plugin_options[ 'label_ds%d' % i] + u' %.1f \u2103' % self.status['DS%d' % i] if plugin_options['enabled_reg']: tempText += ' ' + regulation_text if plugin_options['use_footer']: if air_temp is not None: if is_python2(): air_temp.val = tempText # value on footer else: air_temp.val = tempText.encode('utf8').decode( 'utf8') # value on footer if plugin_options['enable_log']: # enabled logging millis = int(round(time.time() * 1000)) interval = (plugin_options['log_interval'] * 60000) if (millis - last_millis) > interval: last_millis = millis update_log(self.status) self._sleep(5) except Exception: log.error( NAME, _(u'Air Temperature and Humidity Monitor plug-in') + ':\n' + traceback.format_exc()) self._sleep(60)
def on_message(client, userdata, message): log.clear(NAME) log.info( NAME, datetime_string() + ' ' + _('Message received') + ': ' + str(message.payload.decode("utf-8"))) #print("Message topic=",message.topic) #print("Message qos=",message.qos) #print("Message retain flag=",message.retain) if plugin_options["use_mqtt_secondary"]: if not options.manual_mode: # check operation status log.info( NAME, datetime_string() + ' ' + _('You must this OSPy switch to manual mode!')) return if inputs.rain_sensed(): # check rain sensor log.info( NAME, datetime_string() + ' ' + _('Skipping command, rain sense is detected!')) return if rain_blocks.seconds_left(): # check rain delay log.info( NAME, datetime_string() + ' ' + _('Skipping command, rain delay is activated!')) return try: rec_data = str(message.payload) cmd = json.loads(rec_data) except ValueError as e: log.info(NAME, _('Could not decode command:') + ':\n' + message.payload, e) return first = int( plugin_options["first_station"]) - 1 # first secondary station count = int(plugin_options["station_count"]) # count secondary station try: for i in range( first, first + count): # count of station (example on main OSPy: 5 to 10) zone = cmd[i]["status"] # "off" or "on" state #station = cmd[i]["station"] #name = cmd[i]["name"] #print station, name, zone sid = i - first if sid <= stations.count(): # local station size check if zone == "on": start = datetime.datetime.now() mqn = _('MQTT Manual') new_schedule = { 'active': True, 'program': -1, 'station': sid, 'program_name': mqn, 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': start, 'original_start': start, 'end': start + datetime.timedelta(days=3650), 'uid': '%s-%s-%d' % (str(start), mqn, sid), 'usage': stations.get(sid).usage } # if an optional duration time is given #set_time = xxx second #new_schedule['end'] = datetime.datetime.now() + datetime.timedelta(seconds=set_time) log.start_run(new_schedule) stations.activate(new_schedule['station']) if zone == "off": stations.deactivate(sid) active = log.active_runs() for interval in active: if interval['station'] == i: log.finish_run(interval) else: log.error( NAME, _('MQTT plug-in') + ':\n' + _('Setup stations count is smaler! Set correct first station and station count.' )) except Exception: log.error(NAME, _('MQTT plug-in') + ':\n' + traceback.format_exc()) time.sleep(1)
def sms_check(self): """Control and processing SMS""" try: import gammu except Exception: log.error(NAME, _('SMS Modem plug-in') + ':\n' + traceback.format_exc()) tel1 = sms_options['tel1'] tel2 = sms_options['tel2'] comm1 = sms_options['txt1'] comm2 = sms_options['txt2'] comm3 = sms_options['txt3'] comm4 = sms_options['txt4'] comm5 = sms_options['txt5'] comm6 = sms_options['txt6'] comm7 = sms_options['txt7'] comm8 = sms_options['txt8'] comm9 = sms_options['txt9'] sm = gammu.StateMachine() sm.ReadConfig() try: sm.Init() log.debug(NAME, datetime_string() + ': ' + _('Checking SMS...')) except: log.error(NAME, _('SMS Modem plug-in') + ':\n' + traceback.format_exc()) self._sleep(60) if sms_options[ "use_strength"]: # print strength signal in status Window every check SMS signal = sm.GetSignalQuality( ) # list: SignalPercent, SignalStrength, BitErrorRate log.info( NAME, datetime_string() + ': ' + _('Signal') + ': ' + str(signal['SignalPercent']) + '% ' + str(signal['SignalStrength']) + 'dB') status = sm.GetSMSStatus() remain = status['SIMUsed'] + status['PhoneUsed'] + status['TemplatesUsed'] sms = [] start = True while remain > 0: if start: cursms = sm.GetNextSMS(Start=True, Folder=0) start = False else: cursms = sm.GetNextSMS(Location=cursms[0]['Location'], Folder=0) remain = remain - len(cursms) sms.append(cursms) data = gammu.LinkSMS(sms) for x in data: v = gammu.DecodeSMS(x) m = x[0] print '%-15s: %s' % ('Sender', m['Number']) print '%-15s: %s' % ('Date', str(m['DateTime'])) print '%-15s: %s' % ('State', m['State']) print '%-15s: %s' % ('SMS command', m['Text']) if (m['Number'] == tel1) or (m['Number'] == tel2): # If telephone is admin 1 or admin 2 log.info(NAME, datetime_string() + ': ' + _('SMS from admin')) if m['State'] == "UnRead": # If SMS is unread log.clear(NAME) if m['Text'] == comm1: # If command = comm1 (info - send SMS to admin phone1 and phone2) log.info( NAME, _('Command') + ' ' + comm1 + ' ' + _('is processed')) # send 1/2 SMS with text 1 up = helpers.uptime() temp = helpers.get_cpu_temp( options.temp_unit) + ' ' + options.temp_unit ip = str(helpers.get_ip()) ver = version.ver_date datastr = ('SMS 1/2. ' + datetime_string() + ', TEMP: ' + temp + ', IP: ' + ip + ', SW: ' + ver + ', UP: ' + up) message = { 'Text': datastr, 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) # send sms 1/2 log.info(NAME, datastr) # send 2/2 SMS with text 2 if inputs.rain_sensed(): rain = "Active" else: rain = "Inactive" try: from plugins import pressure_monitor state_press = pressure_monitor.get_check_pressure() if state_press: press = "High" else: press = "Low" except Exception: press = "N/A" finished = [ run for run in log.finished_runs() if not run['blocked'] ] if finished: last_prog = finished[-1]['start'].strftime( '%H:%M: ') + finished[-1]['program_name'] else: last_prog = 'None' datastr = ('SMS 2/2. ' + 'RAIN: ' + rain + ', PRESS: ' + press + ', LAST: ' + last_prog) message = { 'Text': datastr, 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) # send sms 2/2 log.info(NAME, datastr) log.info( NAME, _('Command') + ': ' + comm1 + ' ' + _('was processed and confirmation was sent as SMS to') + ': ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) # SMS deleted log.info(NAME, _('Received SMS was deleted')) elif m['Text'] == comm2: # If command = comm2 (stop - scheduler) log.info( NAME, _('Command') + ' ' + comm2 + ' ' + _('is processed')) options.scheduler_enabled = False log.finish_run(None) stations.clear() message = { 'Text': 'Command: ' + comm2 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) log.info( NAME, _('Command') + ': ' + comm2 + ' ' + _('was processed and confirmation was sent as SMS to') + ': ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) log.info(NAME, _('Received SMS was deleted')) elif m['Text'] == comm3: # If command = comm3 (start - scheduler) log.info( NAME, _('Command') + ' ' + comm3 + ' ' + _('is processed')) options.scheduler_enabled = True message = { 'Text': 'Command: ' + comm3 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) log.info( NAME, _('Command') + ': ' + comm3 + ' ' + _('was processed and confirmation was sent as SMS to') + ': ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) log.info(NAME, _('Received SMS was deleted')) elif m['Text'] == comm4: # If command = comm4 (reboot system) log.info( NAME, _('Command') + ' ' + comm4 + ' ' + _('is processed')) message = { 'Text': 'Command: ' + comm4 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) log.info( NAME, _('Command') + ': ' + comm4 + ' ' + _('was processed and confirmation was sent as SMS to') + ': ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) log.info( NAME, _('Received SMS was deleted and system is now reboot')) reboot() # restart linux system elif m['Text'] == comm5: # If command = comm5 (poweroff system) log.info( NAME, _('Command') + ' ' + comm5 + ' ' + _('is processed')) message = { 'Text': 'Command: ' + comm5 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) log.info( NAME, _('Command') + ': ' + comm5 + ' ' + _('was processed and confirmation was sent as SMS to') + ': ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) log.info( NAME, _('Received SMS was deleted and system is now poweroff' )) poweroff() # poweroff linux system elif m['Text'] == comm6: # If command = comm6 (update ospi system) log.info( NAME, _('Command') + ' ' + comm6 + ' ' + _('is processed')) message = { 'Text': 'Command: ' + comm6 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) log.info( NAME, _('Command') + ': ' + comm6 + ' ' + _('was processed and confirmation was sent as SMS to') + ': ' + m['Number']) try: from plugins.system_update import perform_update perform_update() log.info( NAME, _('Received SMS was deleted, update was performed and program will restart' )) except ImportError: log.info( NAME, _('Received SMS was deleted, but could not perform update' )) sm.DeleteSMS(m['Folder'], m['Location']) elif m['Text'] == comm7: # If command = comm7 (send email with foto from webcam) log.info( NAME, _('Command') + ' ' + comm7 + ' ' + _('is processed')) message = { 'Text': 'Command: ' + comm7 + ' was processed', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) log.info( NAME, _('Command') + ': ' + comm7 + ' ' + _('was processed and confirmation was sent as SMS to') + ': ' + m['Number']) try: from plugins.webcam import get_run_cam, get_image_location get_run_cam() # process save foto to ./data/image.jpg msg = _('SMS plug-in send image file from webcam.') send_email(msg, attach=get_image_location()) except ImportError: log.info( NAME, _('Received SMS was deleted, but could not send email with photo from webcam' )) message = { 'Text': 'Error: not send foto from webcam', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) sm.DeleteSMS(m['Folder'], m['Location']) elif m['Text'] == comm8: # If command = comm8 (send SMS with available commands) log.info( NAME, _('Command') + ' ' + comm8 + ' ' + _('is processed')) message = { 'Text': 'Available commands: ' + comm1 + ',' + comm2 + ',' + comm3 + ',' + comm4 + ',' + comm5 + ',' + comm6 + ',' + comm7 + ',' + comm8 + ',' + comm9 + 'xx', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) log.info( NAME, _('Command') + ': ' + comm8 + ' ' + _('was processed and confirmation was sent as SMS to') + ': ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) log.info(NAME, _('Received SMS was deleted')) elif m['Text'][0:len( comm9 )] == comm9: # If command = lenght char comm9 (run now program xx) num = m['Text'][len( comm9 ):] # number from sms text example: run36 -> num=36 log.info( NAME, _('Command') + ' ' + comm9 + ' ' + _('is processed')) index = int(num) if index <= programs.count( ): # if program number from sms text exists in program db log.finish_run(None) stations.clear() prog = int(index - 1) programs.run_now(prog) log.info( NAME, _('Program') + ': ' + str(index) + ' ' + _('now run')) message = { 'Text': 'Program: ' + str(index) + ' now run', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } else: message = { 'Text': 'Program: ' + str(index) + ' no exists!', 'SMSC': { 'Location': 1 }, 'Number': m['Number'], } sm.SendSMS(message) log.info( NAME, _('Command') + ': ' + str(m['Text']) + ' ' + _('was processed and confirmation was sent as SMS to') + ': ' + m['Number']) sm.DeleteSMS(m['Folder'], m['Location']) log.info(NAME, _('Received SMS was deleted')) else: # If SMS command is not defined sm.DeleteSMS(m['Folder'], m['Location']) log.info( NAME, _('Received command') + ' ' + m['Text'] + ' ' + _('is not defined!')) else: # If SMS was read sm.DeleteSMS(m['Folder'], m['Location']) log.info(NAME, _('Received SMS was deleted - SMS was read')) else: # If telephone number is not admin 1 or admin 2 phone number sm.DeleteSMS(m['Folder'], m['Location']) log.info(NAME, _('Received SMS was deleted - SMS was not from admin'))
def run(self): log.clear(NAME) disable_text = True while not self._stop_event.is_set(): try: if plugin_options['use_button']: # if button plugin is enabled disable_text = True actual_buttons = read_buttons() # led_outputs(actual_buttons) # for test for i in range(8): tb = "button" + str(i) if actual_buttons == i and plugin_options[ tb] == "reboot": log.info( NAME, datetime_string() + ': ' + _(u'System reboot')) stations.clear() report_rebooted() reboot(block=True) # Linux HW software self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "pwrOff": log.info( NAME, datetime_string() + ': ' + _(u'System shutdown')) stations.clear() report_poweroff() poweroff(wait=10, block=True) # shutdown HW system self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "stopAll": log.info( NAME, datetime_string() + ': ' + _(u'Selected stations now stopped')) set_stations_in_scheduler_off() self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "schedEn": log.info( NAME, datetime_string() + ': ' + _(u'Scheduler is now enabled')) options.scheduler_enabled = True self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "schedDis": log.info( NAME, datetime_string() + ': ' + _(u'Scheduler is now disabled')) options.scheduler_enabled = False self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "RunP1": log.info( NAME, datetime_string() + ': ' + _(u'Run now program 1')) for program in programs.get(): if (program.index == 0): # Run-now program 1 options.manual_mode = False if plugin_options['first_stop']: log.finish_run(None) stations.clear() programs.run_now(program.index) program.index + 1 self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "RunP2": log.info( NAME, datetime_string() + ': ' + _(u'Run now program 2')) for program in programs.get(): if (program.index == 1): # Run-now program 2 options.manual_mode = False if plugin_options['first_stop']: log.finish_run(None) stations.clear() programs.run_now(program.index) program.index + 1 self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "RunP3": log.info( NAME, datetime_string() + ': ' + _(u'Run now program 3')) for program in programs.get(): if (program.index == 2): # Run-now program 3 options.manual_mode = False if plugin_options['first_stop']: log.finish_run(None) stations.clear() programs.run_now(program.index) program.index + 1 self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "RunP4": log.info( NAME, datetime_string() + ': ' + _(u'Run now program 4')) for program in programs.get(): if (program.index == 3): # Run-now program 4 options.manual_mode = False if plugin_options['first_stop']: log.finish_run(None) stations.clear() programs.run_now(program.index) program.index + 1 self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "RunP5": log.info( NAME, datetime_string() + ': ' + _('Run now program 5')) for program in programs.get(): if (program.index == 4): # Run-now program 5 options.manual_mode = False if plugin_options['first_stop']: log.finish_run(None) stations.clear() programs.run_now(program.index) program.index + 1 self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "RunP6": log.info( NAME, datetime_string() + ': ' + _(u'Run now program 6')) for program in programs.get(): if (program.index == 5): # Run-now program 6 options.manual_mode = False if plugin_options['first_stop']: log.finish_run(None) stations.clear() programs.run_now(program.index) program.index + 1 self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "RunP7": log.info( NAME, datetime_string() + ': ' + _(u'Run now program 7')) for program in programs.get(): if (program.index == 6): # Run-now program 7 options.manual_mode = False if plugin_options['first_stop']: log.finish_run(None) stations.clear() programs.run_now(program.index) program.index + 1 self._sleep(1) if actual_buttons == i and plugin_options[ tb] == "RunP8": log.info( NAME, datetime_string() + ': ' + _(u'Run now program 8')) for program in programs.get(): if (program.index == 7): # Run-now program 8 options.manual_mode = False if plugin_options['first_stop']: log.finish_run(None) stations.clear() programs.run_now(program.index) program.index + 1 self._sleep(1) self._sleep(1) else: # text on the web if plugin is disabled if disable_text: log.clear(NAME) log.info(NAME, _(u'Button plug-in is disabled.')) disable_text = False self._sleep(1) except Exception: log.clear(NAME) log.error( NAME, _(u'Button plug-in') + ':\n' + traceback.format_exc()) self._sleep(60) pass
def on_message(client, userdata, message): log.clear(NAME) log.info(NAME, datetime_string() + ' ' + _('Message received') + ': ' + str(message.payload.decode("utf-8"))) #print("Message topic=",message.topic) #print("Message qos=",message.qos) #print("Message retain flag=",message.retain) try: cmd = json.loads(message.payload) except: cmd = [] status = "RunOnce Error" client.publish(plugin_options['publish_up_down'], status) pass try: log.info(NAME, datetime_string() + ' ' + _(u'Try-ing to processing command.')) num_sta = options.output_count if type(cmd) is list: # cmd is list if len(cmd) < num_sta: log.info(NAME, datetime_string() + ' ' + _(u'Not enough stations specified, assuming first {} of {}').format(len(cmd), num_sta)) rovals = cmd + ([0] * (num_sta - len(cmd))) elif len(cmd) > num_sta: log.info(NAME, datetime_string() + ' ' + _(u'Too many stations specified, truncating to {}').format(num_sta)) rovals = cmd[0:num_sta] else: rovals = cmd elif type(cmd) is dict: # cmd is dictionary rovals = [0] * num_sta snames = station_names() # Load station names from file jnames = json.loads(snames) # Load as json for k, v in list(cmd.items()): if k not in snames: # station name in dict is not in OSPy stations name (ERROR) log.warning(NAME, _(u'No station named') + (u': %s') % k) else: # station name in dict is in OSPy stations name (OK) # v is value for time, k is station name in dict rovals[jnames.index(k)] = v else: log.error(NAME, datetime_string() + ' ' + _(u'Unexpected command') + (u': %s') % message.payload) rovals = None status = "RunOnce Error" client.publish(plugin_options['publish_up_down'], status) if rovals is not None and any(rovals): for i in range(0, len(rovals)): sid = i start = datetime.datetime.now() try: end = datetime.datetime.now() + datetime.timedelta(seconds=int(rovals[i])) except: end = datetime.datetime.now() log.error(NAME, _(u'MQTT Run-once plug-in') + ':\n' + traceback.format_exc()) pass new_schedule = { 'active': True, 'program': -1, 'station': sid, 'program_name': _(u'MQTT Run-once'), 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': start, 'original_start': start, 'end': end, 'uid': '%s-%s-%d' % (str(start), "Manual", sid), 'usage': stations.get(sid).usage } log.start_run(new_schedule) stations.activate(new_schedule['station']) if int(rovals[i]) < 1: # station has no time for run (stoping) stations.deactivate(sid) active = log.active_runs() for interval in active: if interval['station'] == sid: log.finish_run(interval) status = "RunOnce Processing" client.publish(plugin_options['publish_up_down'], status) except Exception: log.clear(NAME) log.error(NAME, _(u'MQTT Run-once plug-in') + ':\n' + traceback.format_exc()) status = "RunOnce Error" client.publish(plugin_options['publish_up_down'], status) pass
def run(self): temperature_ds = [-127, -127, -127, -127, -127, -127] msg_a_on = True msg_a_off = True last_text = '' send = False temp_sw = None if plugin_options['use_footer']: temp_sw = showInFooter( ) # instantiate class to enable data in footer temp_sw.button = "pool_heating/settings" # button redirect on footer temp_sw.label = _('Pool Heating') # label on footer ds_a_on = -127.0 ds_a_off = -127.0 millis = 0 # timer for clearing status on the web pages after 5 sec last_millis = int(round(time.time() * 1000)) safety_start = datetime.datetime.now() safety_end = datetime.datetime.now() + datetime.timedelta( minutes=plugin_options['safety_mm']) a_state = -3 # for state in footer "Waiting." regulation_text = _(u'Waiting to turned on or off.') if not plugin_options['enabled_a']: a_state = -1 # for state in footer "Waiting (not enabled regulation in options)." log.info(NAME, datetime_string() + ' ' + _('Waiting.')) end = datetime.datetime.now() while not self._stop_event.is_set(): try: if plugin_options[ "sensor_probe"] == 2: # loading probe name from plugin air_temp_humi try: from plugins.air_temp_humi import plugin_options as air_temp_data self.status['ds_name_0'] = air_temp_data['label_ds0'] self.status['ds_name_1'] = air_temp_data['label_ds1'] self.status['ds_name_2'] = air_temp_data['label_ds2'] self.status['ds_name_3'] = air_temp_data['label_ds3'] self.status['ds_name_4'] = air_temp_data['label_ds4'] self.status['ds_name_5'] = air_temp_data['label_ds5'] self.status['ds_count'] = air_temp_data['ds_used'] from plugins.air_temp_humi import DS18B20_read_probe # value with temperature from probe DS1-DS6 temperature_ds = [ DS18B20_read_probe(0), DS18B20_read_probe(1), DS18B20_read_probe(2), DS18B20_read_probe(3), DS18B20_read_probe(4), DS18B20_read_probe(5) ] except: log.error( NAME, _('Unable to load settings from Air Temperature and Humidity Monitor plugin! Is the plugin Air Temperature and Humidity Monitor installed and set up?' )) pass # regulation if plugin_options['enabled_a'] and plugin_options[ "sensor_probe"] != 0: # enabled regulation and selected input for probes sensor/airtemp plugin if plugin_options["sensor_probe"] == 1 and sensors.count( ) > 0: sensor_on = sensors.get( int(plugin_options['probe_A_on_sens'])) # pool if sensor_on.sens_type == 5: # temperature sensor ds_a_on = self._try_read(sensor_on.last_read_value) elif sensor_on.sens_type == 6 and sensor_on.multi_type == 0: # multitemperature sensor DS1 ds_a_on = self._try_read( sensor_on.last_read_value[0]) elif sensor_on.sens_type == 6 and sensor_on.multi_type == 1: # multitemperature sensor DS2 ds_a_on = self._try_read( sensor_on.last_read_value[1]) elif sensor_on.sens_type == 6 and sensor_on.multi_type == 2: # multitemperature sensor DS3 ds_a_on = self._try_read( sensor_on.last_read_value[2]) elif sensor_on.sens_type == 6 and sensor_on.multi_type == 3: # multitemperature sensor DS4 ds_a_on = self._try_read( sensor_on.last_read_value[3]) else: ds_a_on = -127.0 sensor_off = sensors.get( int(plugin_options['probe_A_off_sens'])) # solar if sensor_off.sens_type == 5: # temperature sensor ds_a_off = self._try_read( sensor_off.last_read_value) elif sensor_off.sens_type == 6 and sensor_off.multi_type == 0: # multitemperature sensor DS1 ds_a_off = self._try_read( sensor_off.last_read_value[0]) elif sensor_off.sens_type == 6 and sensor_off.multi_type == 1: # multitemperature sensor DS2 ds_a_off = self._try_read( sensor_off.last_read_value[1]) elif sensor_off.sens_type == 6 and sensor_off.multi_type == 2: # multitemperature sensor DS3 ds_a_off = self._try_read( sensor_off.last_read_value[2]) elif sensor_off.sens_type == 6 and sensor_off.multi_type == 3: # multitemperature sensor DS4 ds_a_off = self._try_read( sensor_off.last_read_value[3]) else: ds_a_off = -127.0 elif plugin_options["sensor_probe"] == 2: ds_a_on = temperature_ds[ plugin_options['probe_A_on']] # pool ds_a_off = temperature_ds[ plugin_options['probe_A_off']] # solar station_a = stations.get( plugin_options['control_output_A']) # only for testing... without airtemp plugin or sensors #ds_a_on = 15 #ds_a_off = 25 probes_ok = True if ds_a_on == -127.0 or ds_a_off == -127.0: probes_ok = False a_state = -2 # The station switches off if the sensors has a fault sid = station_a.index active = log.active_runs() for interval in active: if interval['station'] == sid: stations.deactivate(sid) log.finish_run(interval) regulation_text = datetime_string() + ' ' + _( 'Regulation set OFF.') + ' ' + ' (' + _( 'Output') + ' ' + str(station_a.index + 1) + ').' log.clear(NAME) log.info(NAME, regulation_text) # release msg_a_on and msg_a_off to true for future regulation (after probes is ok) msg_a_on = True msg_a_off = True if (ds_a_off - ds_a_on ) > plugin_options['temp_a_on'] and probes_ok: # ON a_state = 1 if msg_a_on: msg_a_on = False msg_a_off = True regulation_text = datetime_string() + ' ' + _( 'Regulation set ON.') + ' ' + ' (' + _( 'Output') + ' ' + str(station_a.index + 1) + ').' log.clear(NAME) log.info(NAME, regulation_text) start = datetime.datetime.now() sid = station_a.index end = datetime.datetime.now() + datetime.timedelta( seconds=plugin_options['reg_ss'], minutes=plugin_options['reg_mm']) new_schedule = { 'active': True, 'program': -1, 'station': sid, 'program_name': _(u'Pool Heating'), 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': start, 'original_start': start, 'end': end, 'uid': '%s-%s-%d' % (str(start), "Manual", sid), 'usage': stations.get(sid).usage } log.start_run(new_schedule) stations.activate(new_schedule['station']) if plugin_options[ 'enabled_safety']: # safety check safety_end = datetime.datetime.now( ) + datetime.timedelta( minutes=plugin_options['safety_mm']) if (ds_a_off - ds_a_on ) < plugin_options['temp_a_off'] and probes_ok: # OFF a_state = 0 if msg_a_off: msg_a_off = False msg_a_on = True regulation_text = datetime_string() + ' ' + _( 'Regulation set OFF.') + ' ' + ' (' + _( 'Output') + ' ' + str(station_a.index + 1) + ').' log.clear(NAME) log.info(NAME, regulation_text) sid = station_a.index stations.deactivate(sid) active = log.active_runs() for interval in active: if interval['station'] == sid: log.finish_run(interval) if plugin_options[ 'enabled_safety']: # safety check safety_end = datetime.datetime.now( ) + datetime.timedelta( minutes=plugin_options['safety_mm']) ### if "pool" end in schedule release msg_a_on to true in regulation for next scheduling ### now = datetime.datetime.now() if now > end: msg_a_off = False msg_a_on = True if probes_ok: a_state = -3 if plugin_options['enabled_safety']: # safety check safety_start = datetime.datetime.now() if safety_start > safety_end and probes_ok: # is time for check if (ds_a_off - ds_a_on) > plugin_options[ 'temp_safety']: # temperature difference is bigger a_state = -4 msg_a_off = False msg_a_on = True regulation_text = datetime_string() + ' ' + _( 'Safety shutdown!' ) + ' ' + ' (' + _('Output') + ' ' + str( station_a.index + 1) + ').\n' + _('Regulation disabled!') log.clear(NAME) log.info(NAME, regulation_text) sid = station_a.index stations.deactivate(sid) active = log.active_runs() for interval in active: # stop stations if interval['station'] == sid: log.finish_run(interval) send = True # send e-mail plugin_options[ 'enabled_a'] = False # disabling plugin else: if a_state != -4: # if safety error not print waiting also safety shutdown! a_state = -1 # footer text tempText = ' ' if a_state == 0: tempText += regulation_text if a_state == 1: tempText += regulation_text if a_state == -1: tempText = _( 'Waiting (not enabled regulation in options, or not selected input).' ) if a_state == -2: tempText = _( 'Some probe shows a fault, regulation is blocked!') if a_state == -3: tempText = _('Waiting.') if a_state == -4: tempText = _('Safety shutdown!') if plugin_options['use_footer']: if temp_sw is not None: temp_sw.val = tempText.encode('utf8').decode( 'utf8') # value on footer self._sleep(2) millis = int(round(time.time() * 1000)) if (millis - last_millis ) > 5000: # 5 second to clearing status on the webpage last_millis = millis log.clear(NAME) if plugin_options["sensor_probe"] == 1: try: if options.temp_unit == 'C': log.info( NAME, datetime_string() + '\n' + sensor_on.name + ' (' + _('Pool') + ') %.1f \u2103 \n' % ds_a_on + sensor_off.name + ' (' + _('Solar') + ') %.1f \u2103' % ds_a_off) else: log.info( NAME, datetime_string() + '\n' + sensor_on.name + ' (' + _('Pool') + ') %.1f \u2109 \n' % ds_a_on + sensor_off.name + ' (' + _('Solar') + ') %.1f \u2103' % ds_a_off) except: pass elif plugin_options["sensor_probe"] == 2: log.info( NAME, datetime_string() + '\n' + _('Pool') + u' %.1f \u2103 \n' % ds_a_on + _('Solar') + ' %.1f \u2103' % ds_a_off) if last_text != tempText: log.info(NAME, tempText) last_text = tempText if send: msg = '<b>' + _( 'Pool Heating plug-in' ) + '</b> ' + '<br><p style="color:red;">' + _( 'System detected error: The temperature did not drop when the pump was switched on after the setuped time. Stations set to OFF. Safety shutdown!' ) + '</p>' msglog = _( 'System detected error: The temperature did not drop when the pump was switched on after the setuped time. Stations set to OFF. Safety shutdown!' ) send = False try: try_mail = None if plugin_options['eplug'] == 0: # email_notifications from plugins.email_notifications import try_mail if plugin_options[ 'eplug'] == 1: # email_notifications SSL from plugins.email_notifications_ssl import try_mail if try_mail is not None: try_mail( msg, msglog, attachment=None, subject=plugin_options['emlsubject'] ) # try_mail(text, logtext, attachment=None, subject=None) except Exception: log.error( NAME, _('Pool Heating plug-in') + ':\n' + traceback.format_exc()) self._sleep(2) except Exception: log.error( NAME, _('Pool Heating plug-in') + ':\n' + traceback.format_exc()) self._sleep(60)
def run(self): once_text = True two_text = True send = False mini = True while not self._stop.is_set(): try: if tank_options['use_sonic']: if two_text: log.clear(NAME) log.info(NAME, _('Water tank monitor is enabled.')) once_text = True two_text = False level_in_tank = get_sonic_tank_cm() if level_in_tank >= 0: # if I2C device exists log.info( NAME, datetime_string() + ' ' + _('Water level') + ': ' + str(level_in_tank) + ' ' + _('cm') + '.') if level_in_tank <= int( tank_options['water_minimum'] ) and mini and not options.manual_mode and level_in_tank > -1: if tank_options['use_send_email']: send = True mini = False log.info( NAME, datetime_string() + ' ' + _('ERROR: Water in Tank') + ' < ' + str(tank_options['water_minimum']) + ' ' + _('cm') + '!') options.scheduler_enabled = False # disable scheduler log.finish_run(None) # save log stations.clear() # set all station to off if level_in_tank > int(tank_options['water_minimum'] ) + 5 and not mini: mini = True else: log.info( NAME, datetime_string() + ' ' + _('Water level: Error I2C device not found.')) else: if once_text: log.info(NAME, 'Water tank monitor is disabled.') once_text = False two_text = True last_level = 0 if tank_options['use_freq_1']: humi1 = get_freq(1) if humi1 >= 0: humi1_lvl = maping(humi1, int(tank_options['minimum_freq']), int(tank_options['maximum_freq']), 0, 100) if humi1_lvl >= 100: humi1_lvl = 100 log.info( NAME, datetime_string() + ' F1: ' + str(humi1) + 'Hz H: ' + str(humi1_lvl) + '%.') else: log.info( NAME, datetime_string() + ' F1: ' + _('Error I2C device not found.')) if tank_options['use_freq_2']: humi2 = get_freq(2) if humi2 >= 0: humi2_lvl = maping(humi2, int(tank_options['minimum_freq']), int(tank_options['maximum_freq']), 0, 100) if humi2_lvl >= 100: humi2_lvl = 100 log.info( NAME, datetime_string() + ' F2: ' + str(humi2) + 'Hz H: ' + str(humi2_lvl) + '%.') else: log.info( NAME, datetime_string() + ' F2: ' + _('Error I2C device not found.')) if tank_options['use_freq_3']: humi3 = get_freq(3) if humi3 >= 0: humi3_lvl = maping(humi3, int(tank_options['minimum_freq']), int(tank_options['maximum_freq']), 0, 100) if humi3_lvl >= 100: humi3_lvl = 100 log.info( NAME, datetime_string() + ' F3: ' + str(humi3) + 'Hz H: ' + str(humi3_lvl) + '%.') else: log.info( NAME, datetime_string() + ' F3: ' + _('Error I2C device not found.')) if tank_options['use_freq_4']: humi4 = get_freq(4) if humi4 >= 0: humi4_lvl = maping(humi4, int(tank_options['minimum_freq']), int(tank_options['maximum_freq']), 0, 100) if humi4_lvl >= 100: humi4_lvl = 100 log.info( NAME, datetime_string() + ' F4: ' + str(humi4) + 'Hz H: ' + str(humi4_lvl) + '%.') else: log.info( NAME, datetime_string() + ' F4: ' + _('Error I2C device not found.')) if tank_options['use_freq_5']: humi5 = get_freq(5) if humi5 >= 0: humi5_lvl = maping(humi5, int(tank_options['minimum_freq']), int(tank_options['maximum_freq']), 0, 100) if humi5_lvl >= 100: humi5_lvl = 100 log.info( NAME, datetime_string() + ' F5: ' + str(humi5) + 'Hz H: ' + str(humi5_lvl) + '%.') else: log.info( NAME, datetime_string() + ' F5: ' + _('Error I2C device not found.')) if tank_options['use_freq_6']: humi6 = get_freq(6) if humi6 >= 0: humi6_lvl = maping(humi6, int(tank_options['minimum_freq']), int(tank_options['maximum_freq']), 0, 100) if humi6_lvl >= 100: humi6_lvl = 100 log.info( NAME, datetime_string() + ' F6: ' + str(humi6) + 'Hz H: ' + str(humi6_lvl) + '%.') else: log.info( NAME, datetime_string() + ' F6: ' + _('Error I2C device not found.')) if tank_options['use_freq_7']: humi7 = get_freq(7) if humi7 >= 0: humi7_lvl = maping(humi7, int(tank_options['minimum_freq']), int(tank_options['maximum_freq']), 0, 100) if humi7_lvl >= 100: humi7_lvl = 100 log.info( NAME, datetime_string() + ' F7: ' + str(humi7) + 'Hz H: ' + str(humi7_lvl) + '%.') else: log.info( NAME, datetime_string() + ' F7: ' + _('Error I2C device not found.')) if tank_options['use_freq_8']: humi8 = get_freq(8) if humi8 >= 0: humi8_lvl = maping(humi8, int(tank_options['minimum_freq']), int(tank_options['maximum_freq']), 0, 100) if humi8_lvl >= 100: humi8_lvl = 100 log.info( NAME, datetime_string() + ' F8: ' + str(humi8) + 'Hz H: ' + str(humi8_lvl) + '%.') else: log.info( NAME, datetime_string() + ' F8: ' + _('Error I2C device not found.')) if send: msg = (datetime_string() + '\n' + _( 'System detected error: Water Tank has minimum Water Level' ) + ': ' + str( tank_options['water_minimum'] ) + _('cm') + '.\n' + _( 'Scheduler is now disabled and all Stations turn Off.') ) try: send_email(msg) log.info(NAME, _('Email was sent') + ': ' + msg) send = False except Exception as err: log.error(NAME, _('Email was not sent') + '! ' + str(err)) self._sleep(10) # 2 for tested log.clear(NAME) except Exception: log.error( NAME, _('Water tank and humidity Monitor plug-in') + ':\n' + traceback.format_exc()) self._sleep(60)
def run(self): send = False once_text = True two_text = True three_text = True four_text = True five_text = True last_time = int(time.time()) actual_time = int(time.time()) while not self._stop.is_set(): try: if pressure_options[ 'use_press_monitor']: # if pressure plugin is enabled four_text = True if get_master_is_on(): # if master station is on three_text = True if once_text: # text on the web if master is on log.clear(NAME) log.info(NAME, _('Master station is ON.')) once_text = False if get_check_pressure(): # if pressure sensor is on actual_time = int(time.time()) count_val = int(pressure_options['time']) log.clear(NAME) log.info( NAME, _('Time to test pressure sensor') + ': ' + str(count_val - (actual_time - last_time)) + ' ' + _('sec')) if actual_time - last_time > int( pressure_options['time'] ): # wait for activated pressure sensor (time delay) last_time = actual_time if get_check_pressure( ): # if pressure sensor is actual on # options.scheduler_enabled = False # set scheduler to off log.finish_run(None) # save log stations.clear() # set all station to off log.clear(NAME) log.info( NAME, _('Pressure sensor is not activated in time -> stops all stations and send email.' )) if pressure_options[ 'sendeml']: # if enabled send email send = True if not get_check_pressure(): last_time = int(time.time()) if five_text: once_text = True five_text = False else: if stations.master is not None: if two_text: log.clear(NAME) log.info(NAME, _('Master station is OFF.')) two_text = False five_text = True last_time = int(time.time()) else: once_text = True two_text = True if four_text: # text on the web if plugin is disabled log.clear(NAME) log.info(NAME, _('Pressure monitor plug-in is disabled.')) four_text = False if stations.master is None: # text on the web if master station is none if three_text: log.clear(NAME) log.info(NAME, _('Not used master station.')) three_text = False if send: msg = (datetime_string() + ': ' + _('System detected error: pressure sensor.')) try: send_email(msg) log.info(NAME, _('Email was sent') + ': ' + msg) send = False except Exception: log.error( NAME, _('Email was not sent') + '! ' + traceback.format_exc()) if get_check_pressure(): self.status['Pstate%d'] = _('INACTIVE') else: self.status['Pstate%d'] = _('ACTIVE') self._sleep(1) except Exception: log.error( NAME, _('Pressure monitor plug-in') + ':\n' + traceback.format_exc()) self._sleep(60)
def run(self): try: import smbus # for PCF 8583 self.bus = smbus.SMBus(1 if get_rpi_revision() >= 2 else 0) except ImportError: log.warning(NAME, _('Could not import smbus.')) if self.bus is not None: self.pcf = set_counter(self.bus) # set pcf8583 as counter log.clear(NAME) send = False # send email disable_text = True val = 0.0 maxval = 0.0 timer_reset = 0 while not self._stop.is_set(): try: if self.bus is not None and wind_options[ 'use_wind_monitor']: # if wind plugin is enabled disable_text = True puls = counter( self.bus) / 10.0 # counter value is value/10sec val = puls / (wind_options['pulses'] * 1.0) val = val * wind_options['metperrot'] if val > maxval: maxval = val if timer_reset >= 86400: # 1 day timer_reset = 0 maxval = 0.0 self.status['meter'] = round(val, 2) self.status['kmeter'] = round(val * 3.6, 2) log.clear(NAME) log.info(NAME, _('Please wait 10 sec...')) log.info( NAME, _('Speed') + ' ' + str(round(val, 2)) + ' ' + _('m/sec')) log.info( NAME, _('Speed Peak 24 hour') + ' ' + str(round(maxval, 2)) + ' ' + _('m/sec')) log.info( NAME, _('Pulses') + ' ' + str(puls) + ' ' + _('pulses/sec')) if val >= 42: log.error(NAME, _('Wind speed > 150 km/h (42 m/sec)')) if get_station_is_on(): # if station is on if val >= int( wind_options['maxspeed'] ): # if wind speed is > options max speed log.clear(NAME) log.finish_run(None) # save log stations.clear() # set all station to off log.clear(NAME) log.info( NAME, _('Stops all stations and sends email if enabled sends email.' )) if wind_options[ 'sendeml']: # if enabled send email send = True else: # text on the web if plugin is disabled if disable_text: log.clear(NAME) log.info(NAME, _('Wind speed monitor plug-in is disabled.')) disable_text = False if send: TEXT = (datetime_string() + ': ' + _( 'System detected error: wind speed monitor. All stations set to OFF. Wind is' ) + ': ' + str(round(val * 3.6, 2)) + ' km/h.') try: from plugins.email_notifications import email email(TEXT) # send email without attachments log.info(NAME, _('Email was sent') + ': ' + TEXT) send = False except Exception: log.clear(NAME) log.error( NAME, _('Email was not sent') + '! ' + traceback.format_exc()) timer_reset += 10 # measure is 10 sec long except Exception: log.clear(NAME) log.error( NAME, _('Wind Speed monitor plug-in') + ':\n' + traceback.format_exc()) self._sleep(60) self.pcf = set_counter(self.bus) # set pcf8583 as counter
def run(self): log.clear(NAME) if not plugin_options['enabled']: log.info(NAME, _('Pressurizer is disabled.')) else: log.info(NAME, _('Pressurizer is enabled.')) start_master = False # for master station ON/OFF pressurizer_master_relay_off.send( ) # send signal relay off from this plugin while not self._stop_event.is_set(): try: if plugin_options['enabled']: # plugin is enabled current_time = datetime.datetime.now() user_pre_time = current_time + datetime.timedelta( seconds=int(plugin_options['pre_time'])) check_start = current_time - datetime.timedelta(days=1) check_end = current_time + datetime.timedelta(days=1) schedule = predicted_schedule(check_start, check_end) rain = not options.manual_mode and ( rain_blocks.block_end() > datetime.datetime.now() or inputs.rain_sensed()) if stations.master is None: start_master = False log.clear(NAME) log.info( NAME, datetime_string() + ' ' + _('This plugin requires setting master station to enabled. Setup this in options! And also enable the relay as master station in options!' )) self._sleep(10) for entry in schedule: if entry['start'] <= user_pre_time < entry[ 'end']: # is possible program in this interval? if not rain and not entry[ 'blocked']: # is not blocked and not ignored rain? if stations.master is not None: log.clear(NAME) log.info( NAME, datetime_string() + ' ' + _('Is time for pump running...')) start_master = True if start_master: # is time for run relay pname = _('Pressurizer plug-in') program_name = "%s " % pname.encode( "utf-8", errors="ignore").decode( "utf-8") # program name sname = 0 for station in stations.get(): if station.is_master: sname = station.index # master pump index pend = current_time + datetime.timedelta( seconds=int(plugin_options['run_time'])) _entry = { 'active': None, 'program': -1, 'program_name': program_name, 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': datetime.datetime.now(), 'original_start': datetime.datetime.now(), 'end': pend, 'uid': '%s-%s-%d' % (datetime.datetime.now(), str(program_name), sname), 'usage': 2.0, 'station': sname } if plugin_options['relay']: pressurizer_master_relay_on.send( ) # send signal relay on from this plugin self._sleep(0.5) outputs.relay_output = True # activate relay log.info(NAME, _('Activating relay.')) log.start_run(_entry) wait_for_run = plugin_options[ 'run_time'] # pump run time if wait_for_run > plugin_options[ 'pre_time']: # is not run time > pre run time? wait_for_run = plugin_options[ 'pre_time'] # scheduller tick is 1 second log.info( NAME, datetime_string() + ' ' + _('Waiting') + ' ' + str(wait_for_run) + ' ' + _('second.')) self._sleep( int(wait_for_run)) # waiting on run time pressurizer_master_relay_off.send( ) # send signal relay off from this plugin self._sleep(0.5) outputs.relay_output = False # deactivate relay log.info(NAME, _('Deactivating relay.')) log.finish_run(_entry) log.info(NAME, datetime_string() + ' ' + _('Ready.')) start_master = False seconds = int( plugin_options['mm'] or 0) * 60 + int( plugin_options['ss'] or 0) # (mm:ss) log.info( NAME, datetime_string() + ' ' + _('Waiting') + ' ' + str(seconds) + ' ' + _('second.')) self._sleep( seconds ) # How long after the relay is activated wait for another stations else: self._sleep(2) else: self._sleep(5) self._sleep(1) except Exception: log.error( NAME, _('Pressurizer plug-in') + ':\n' + traceback.format_exc()) self._sleep(60)
def run(self): temperature_ds = [-127, -127, -127, -127, -127, -127] msg_a_on = True msg_a_off = True msg_b_on = True msg_b_off = True msg_c_on = True msg_c_off = True temp_sw = None if plugin_options['use_footer']: temp_sw = showInFooter( ) # instantiate class to enable data in footer temp_sw.button = "temperature_switch/settings" # button redirect on footer temp_sw.label = _(u'Temperature Switch') # label on footer millis = int(round( time.time() * 1000)) # timer for clearing status on the web pages after 60 sec last_millis = millis a_state = -1 # for state in footer (-1 disable regulation A, 0 = Aoff, 1 = Aon) b_state = -1 c_state = -1 helper_text = '' while not self._stop_event.is_set(): try: try: from plugins.air_temp_humi import plugin_options as air_temp_data plugin_options['ds_name_0'] = air_temp_data['label_ds0'] plugin_options['ds_name_1'] = air_temp_data['label_ds1'] plugin_options['ds_name_2'] = air_temp_data['label_ds2'] plugin_options['ds_name_3'] = air_temp_data['label_ds3'] plugin_options['ds_name_4'] = air_temp_data['label_ds4'] plugin_options['ds_name_5'] = air_temp_data['label_ds5'] plugin_options['ds_count'] = air_temp_data['ds_used'] from plugins.air_temp_humi import DS18B20_read_probe temperature_ds = [ DS18B20_read_probe(0), DS18B20_read_probe(1), DS18B20_read_probe(2), DS18B20_read_probe(3), DS18B20_read_probe(4), DS18B20_read_probe(5) ] except: log.error( NAME, _(u'Unable to load settings from Air Temperature and Humidity Monitor plugin! Is the plugin Air Temperature and Humidity Monitor installed and set up?' )) self._sleep(60) # regulation A if plugin_options['enabled_a']: ds_a_on = temperature_ds[plugin_options['probe_A_on']] ds_a_off = temperature_ds[plugin_options['probe_A_off']] station_a = stations.get( plugin_options['control_output_A']) if ds_a_on > plugin_options[ 'temp_a_on']: # if DSxx > temperature AON a_state = 1 if msg_a_on: msg_a_on = False msg_a_off = True log.info( NAME, datetime_string() + ' ' + u'%s' % station_a.name + ' ' + _(u'was turned on.')) start = datetime.datetime.now() sid = station_a.index end = datetime.datetime.now() + datetime.timedelta( seconds=plugin_options['reg_ss_a'], minutes=plugin_options['reg_mm_a']) new_schedule = { 'active': True, 'program': -1, 'station': sid, 'program_name': _('Temperature Switch A'), 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': start, 'original_start': start, 'end': end, 'uid': '%s-%s-%d' % (str(start), "Manual", sid), 'usage': stations.get(sid).usage } log.start_run(new_schedule) stations.activate(new_schedule['station']) if ds_a_off < plugin_options[ 'temp_a_off']: # if DSxx < temperature AOFF a_state = 0 if msg_a_off: msg_a_off = False msg_a_on = True log.info( NAME, datetime_string() + ' ' + u'%s' % station_a.name + ' ' + _(u'was turned off.')) sid = station_a.index stations.deactivate(sid) active = log.active_runs() for interval in active: if interval['station'] == sid: log.finish_run(interval) else: a_state = -1 # regulation B if plugin_options['enabled_b']: ds_b_on = temperature_ds[plugin_options['probe_B_on']] ds_b_off = temperature_ds[plugin_options['probe_B_off']] station_b = stations.get( plugin_options['control_output_B']) if ds_b_on > plugin_options[ 'temp_b_on']: # if DSxx > temperature BON b_state = 1 if msg_b_on: msg_b_on = False msg_b_off = True log.info( NAME, datetime_string() + ' ' + u'%s' % station_b.name + ' ' + _(u'was turned on.')) start = datetime.datetime.now() sid = station_b.index end = datetime.datetime.now() + datetime.timedelta( seconds=plugin_options['reg_ss_b'], minutes=plugin_options['reg_mm_b']) new_schedule = { 'active': True, 'program': -1, 'station': sid, 'program_name': _('Temperature Switch B'), 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': start, 'original_start': start, 'end': end, 'uid': '%s-%s-%d' % (str(start), "Manual", sid), 'usage': stations.get(sid).usage } log.start_run(new_schedule) stations.activate(new_schedule['station']) if ds_b_off < plugin_options[ 'temp_b_off']: # if DSxx < temperature BOFF b_state = 0 if msg_b_off: msg_b_off = False msg_b_on = True log.info( NAME, datetime_string() + ' ' + u'%s' % station_b.name + ' ' + _(u'was turned off.')) sid = station_b.index stations.deactivate(sid) active = log.active_runs() for interval in active: if interval['station'] == sid: log.finish_run(interval) else: b_state = -1 # regulation C if plugin_options['enabled_c']: ds_c_on = temperature_ds[plugin_options['probe_C_on']] ds_c_off = temperature_ds[plugin_options['probe_C_off']] station_c = stations.get( plugin_options['control_output_C']) if ds_c_on > plugin_options[ 'temp_c_on']: # if DSxx > temperature CON c_state = 1 if msg_c_on: msg_c_on = False msg_c_off = True log.info( NAME, datetime_string() + ' ' + u'%s' % station_c.name + ' ' + _(u'was turned on.')) start = datetime.datetime.now() sid = station_c.index end = datetime.datetime.now() + datetime.timedelta( seconds=plugin_options['reg_ss_c'], minutes=plugin_options['reg_mm_c']) new_schedule = { 'active': True, 'program': -1, 'station': sid, 'program_name': _('Temperature Switch C'), 'fixed': True, 'cut_off': 0, 'manual': True, 'blocked': False, 'start': start, 'original_start': start, 'end': end, 'uid': '%s-%s-%d' % (str(start), "Manual", sid), 'usage': stations.get(sid).usage } log.start_run(new_schedule) stations.activate(new_schedule['station']) if ds_c_off < plugin_options[ 'temp_c_off']: # if DSxx < temperature COFF c_state = 0 if msg_c_off: msg_c_off = False msg_c_on = True log.info( NAME, datetime_string() + ' ' + u'%s' % station_c.name + ' ' + _(u'was turned off.')) sid = station_c.index stations.deactivate(sid) active = log.active_runs() for interval in active: if interval['station'] == sid: log.finish_run(interval) else: c_state = -1 # footer text tempText = ' ' if a_state == 0: tempText += _(u'Regulation A set OFF') + '. ' if a_state == 1: tempText += _(u'Regulation A set ON') + '. ' if b_state == 0: tempText += ' ' + _(u'Regulation B set OFF') + '. ' if b_state == 1: tempText += ' ' + _(u'Regulation B set ON') + '. ' if c_state == 0: tempText += ' ' + _(u'Regulation C set OFF') + '. ' if c_state == 1: tempText += ' ' + _(u'Regulation C set ON') + '. ' if (a_state == -1) and (b_state == -1) and (c_state == -1): tempText = _(u'No change') + '. ' if plugin_options['use_footer']: if temp_sw is not None: if tempText != helper_text: temp_sw.val = tempText.encode('utf8').decode( 'utf8') # value on footer helper_text = tempText self._sleep(2) millis = int(round(time.time() * 1000)) if (millis - last_millis ) > 60000: # 60 second to clearing status on the webpage last_millis = millis log.clear(NAME) except Exception: log.error( NAME, _(u'Temperature Switch plug-in') + ':\n' + traceback.format_exc()) self._sleep(60)