def get_report(index): result = None if index == 0: if lcd_options['d_system_name']: result = ASCI_convert(_('System:')) else: result = None elif index == 1: if lcd_options['d_system_name']: result = ASCI_convert(options.name) else: result = None elif index == 2: if lcd_options['d_sw_version_date']: result = ASCI_convert(_('SW Version:')) else: result = None elif index == 3: if lcd_options['d_sw_version_date']: result = ASCI_convert('{} {}'.format(version.ver_str, version.ver_date)) else: result = None elif index == 4: if lcd_options['d_ip']: result = ASCI_convert(_('My IP is:')) else: result = None elif index == 5: if lcd_options['d_ip']: if options.use_ssl: result = ASCI_convert( ('https://{}:{}').format(helpers.get_ip(), options.web_port)) else: result = ASCI_convert( ('http://{}:{}').format(helpers.get_ip(), options.web_port)) else: result = None elif index == 6: if lcd_options['d_port']: result = ASCI_convert(_('My Port is:')) else: result = None elif index == 7: if lcd_options['d_port']: result = ASCI_convert('{}'.format(options.web_port)) else: result = None elif index == 8: if lcd_options['d_cpu_temp']: result = ASCI_convert(_('CPU Temperature:')) else: result = None elif index == 9: if lcd_options['d_cpu_temp']: result = ASCI_convert('{} {}'.format( helpers.get_cpu_temp(options.temp_unit), options.temp_unit)) else: result = None elif index == 10: if lcd_options['d_time_date']: result = ASCI_convert( _('Date:') + ' {}'.format(datetime.now().strftime('%d.%m.%Y'))) else: result = None elif index == 11: if lcd_options['d_time_date']: result = ASCI_convert( _('Time:') + ' {}'.format(datetime.now().strftime('%H:%M:%S'))) else: result = None elif index == 12: if lcd_options['d_uptime']: result = ASCI_convert(_('System Uptime:')) else: result = None elif index == 13: if lcd_options['d_uptime']: result = ASCI_convert(helpers.uptime()) else: result = None elif index == 14: if lcd_options['d_rain_sensor']: result = ASCI_convert(_('Rain Sensor:')) else: result = None elif index == 15: if lcd_options['d_rain_sensor']: if inputs.rain_sensed(): result = ASCI_convert(_('Active')) else: result = ASCI_convert(_('Inactive')) else: result = None elif index == 16: if lcd_options['d_last_run']: result = ASCI_convert(_('Last Program:')) else: result = None elif index == 17: if lcd_options['d_last_run']: finished = [ run for run in log.finished_runs() if not run['blocked'] ] if finished: str_fin = '{}{}'.format( finished[-1]['program_name'], finished[-1]['start'].strftime(' %d.%m.%Y %H:%M:%S')) result = ASCI_convert(str_fin) else: result = ASCI_convert(_('None')) else: result = None elif index == 18: if lcd_options['d_pressure_sensor']: result = ASCI_convert(_('Pressure Sensor:')) else: result = None elif index == 19: if lcd_options['d_pressure_sensor']: try: from plugins import pressure_monitor state_press = pressure_monitor.get_check_pressure() if state_press: result = ASCI_convert(_('Inactive')) else: result = ASCI_convert(_('Active')) except Exception: result = ASCI_convert(_('Not Available')) else: result = None elif index == 20: if lcd_options['d_water_tank_level']: result = ASCI_convert(_('Water Tank Level:')) else: result = None elif index == 21: if lcd_options['d_water_tank_level']: try: from plugins import tank_monitor cm = tank_monitor.get_all_values()[0] percent = tank_monitor.get_all_values()[1] ping = tank_monitor.get_all_values()[2] volume = tank_monitor.get_all_values()[3] units = tank_monitor.get_all_values()[4] except Exception: cm = -1 percent = 0 ping = -1 volume = 0 units = -1 if cm > 0 and units != -1: result = ASCI_convert( _('Level') + ' {}'.format(cm) + _('cm') + ' {}'.format(percent) + _('%') + ' {}'.format(int(volume))) if units: result += ASCI_convert(_('liter')) else: result += ASCI_convert(_('m3')) elif units == -1: result = ASCI_convert(_('Not Available')) else: result = ASCI_convert(_('Error - I2C Device Not Found!')) else: result = None elif index == 22: if lcd_options['d_temperature']: result = ASCI_convert(_('DS Temperature:')) else: result = None elif index == 23: if lcd_options['d_temperature']: try: from plugins import air_temp_humi air_options = air_temp_humi.plugin_options if air_options['ds_enabled']: air_result = '' for i in range(0, air_options['ds_used']): air_result += '{}:{} '.format( air_options['label_ds%d' % i], air_temp_humi.DS18B20_read_probe(i)) result = ASCI_convert(air_result) else: result = ASCI_convert(_('DS temperature not use')) except Exception: result = ASCI_convert(_('Not Available')) else: result = None elif index == 24: if lcd_options['d_running_stations']: result = ASCI_convert(_('Station running:')) else: result = None elif index == 25: if lcd_options['d_running_stations']: if get_active_state() == False: result = ASCI_convert(_('Nothing running')) else: result = ASCI_convert(get_active_state()) else: result = None elif index == 26: if lcd_options['d_sched_manu']: result = ASCI_convert(_('Control:')) else: result = None elif index == 27: if lcd_options['d_sched_manu']: if options.manual_mode: result = ASCI_convert(_('Manual mode')) else: result = ASCI_convert(_('Scheduler')) else: result = None elif index == 28: if lcd_options['d_syst_enabl']: result = ASCI_convert(_('Scheduler:')) else: result = None elif index == 29: if lcd_options['d_syst_enabl']: if options.scheduler_enabled: result = ASCI_convert(_('Enabled')) else: result = ASCI_convert(_('Disabled')) else: result = None ### OSPy sensors ### elif index == 30: if lcd_options['d_sensors']: result = ASCI_convert(_('Sensors:')) else: result = None elif index == 31: if lcd_options['d_sensors']: try: if sensors.count() > 0: sensor_result = '' for sensor in sensors.get(): if sensor.enabled: if sensor.response == 1: sensor_result += sensor.name + ': ' if sensor.sens_type == 1: # dry contact if sensor.last_read_value[4] == 1: sensor_result += _('Contact Closed') elif sensor.last_read_value[4] == 0: sensor_result += _('Contact Open') else: sensor_result += _('Probe Error') if sensor.sens_type == 2: # leak detector if sensor.last_read_value[5] != -127: sensor_result += '{}'.format( sensor.last_read_value[5] ) + ' ' + _('l/s') else: sensor_result += _('Probe Error') if sensor.sens_type == 3: # moisture if sensor.last_read_value[6] != -127: sensor_result += '{}'.format( sensor.last_read_value[6]) + _('%') else: sensor_result += _('Probe Error') if sensor.sens_type == 4: # motion if sensor.last_read_value[7] != -127: sensor_result += _( 'Motion Detected') if int( sensor.last_read_value[7] ) == 1 else _('No Motion') else: sensor_result += _('Probe Error') if sensor.sens_type == 5: # temperature if sensor.last_read_value[0] != -127: sensor_result += '{}'.format( sensor.last_read_value[0]) else: sensor_result += _('Probe Error') if sensor.sens_type == 6: # multi sensor if sensor.multi_type >= 0 and sensor.multi_type < 4: # multi temperature DS1-DS4 if sensor.last_read_value[ sensor.multi_type] != -127: sensor_result += '{}'.format( sensor.last_read_value[ sensor.multi_type]) else: sensor_result += _('Probe Error') if sensor.multi_type == 4: # multi dry contact if sensor.last_read_value[4] != -127: sensor_result += _( 'Contact Closed') if int( sensor.last_read_value[4] ) == 1 else _('Contact Open') else: sensor_result += _('Probe Error') if sensor.multi_type == 5: # multi leak detector if sensor.last_read_value[5] != -127: sensor_result += '{}'.format( sensor.last_read_value[5] ) + ' ' + _('l/s') else: sensor_result += _('Probe Error') if sensor.multi_type == 6: # multi moisture if sensor.last_read_value[6] != -127: sensor_result += '{}'.format( sensor.last_read_value[6] ) + ' ' + _('%') else: sensor_result += _('Probe Error') if sensor.multi_type == 7: # multi motion if sensor.last_read_value[7] != -127: sensor_result += _( 'Motion Detected') if int( sensor.last_read_value[7] ) == 1 else _('No Motion') else: sensor_result += _('Probe Error') if sensor.multi_type == 8: # multi ultrasonic if sensor.last_read_value[8] != -127: get_level = get_tank_cm( sensor.last_read_value[8], sensor.distance_bottom, sensor.distance_top) get_perc = get_percent( get_level, sensor.distance_bottom, sensor.distance_top) sensor_result += '{}'.format( get_level) + ' ' + _( 'cm') + ' (' + '{}'.format( get_perc) + ' %)' else: sensor_result += _('Probe Error') if sensor.multi_type == 9: # multi soil moisture err_check = 0 calculate_soil = [0.0] * 16 state = [-127] * 16 for i in range(0, 16): if type(sensor. soil_last_read_value[i] ) == float: state[ i] = sensor.soil_last_read_value[ i] ### voltage from probe to humidity 0-100% with calibration range (for footer info) if sensor.soil_invert_probe_in[ i]: # probe: rotated state 0V=100%, 3V=0% humidity calculate_soil[i] = maping( state[i], float( sensor. soil_calibration_max[ i]), float( sensor. soil_calibration_min[ i]), 0.0, 100.0) calculate_soil[i] = round( calculate_soil[i], 1 ) # round to one decimal point calculate_soil[ i] = 100.0 - calculate_soil[ i] # ex: 90% - 90% = 10%, 10% is output in invert probe mode else: # probe: normal state 0V=0%, 3V=100% calculate_soil[i] = maping( state[i], float( sensor. soil_calibration_min[ i]), float( sensor. soil_calibration_max[ i]), 0.0, 100.0) calculate_soil[i] = round( calculate_soil[i], 1 ) # round to one decimal point if state[i] > 0.1: if sensor.soil_show_in_footer[ i]: sensor_result += '{} {}% ({}V) '.format( sensor. soil_probe_label[ i], round( calculate_soil[ i], 2), round(state[i], 2)) else: err_check += 1 if err_check > 15: sensor_result += _('Probe Error') else: sensor_result += sensor.name + ': ' + _( 'No response!') else: sensor_result += sensor.name + ': ' + _('Disabled') if sensors.count() > 1: sensor_result += ', ' result = ASCI_convert(sensor_result) else: result = ASCI_convert(_('No sensors available')) except Exception: result = ASCI_convert(_('Not Available')) else: result = None return result
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 GET(self): web.header('Access-Control-Allow-Origin', '*') web.header('Content-Type', 'application/json') data = [] try: from plugins import air_temp_humi data.append(air_temp_humi.DS18B20_read_probe(0)) data.append(air_temp_humi.DS18B20_read_probe(1)) data.append(air_temp_humi.DS18B20_read_probe(2)) data.append(air_temp_humi.DS18B20_read_probe(3)) data.append(air_temp_humi.DS18B20_read_probe(4)) data.append(air_temp_humi.DS18B20_read_probe(5)) except: data.append(-127) data.append(-127) data.append(-127) data.append(-127) data.append(-127) data.append(-127) pass try: from plugins import tank_monitor data.append(tank_monitor.get_all_values()[1]) data.append(tank_monitor.get_all_values()[3]) except: data.append(-127) data.append(-127) pass try: from plugins import wind_monitor data.append(round(wind_monitor.get_all_values()[0], 2)) except: data.append(-127) pass if sensors.count()>0: for sensor in sensors.get(): try: if sensor.sens_type > 0 and sensor.sens_type < 6: # 1-5 is sensor (Dry Contact, Leak Detector, Moisture, Motion, Temperature) if sensor.sens_type == 1: data.append(sensor.last_read_value[4]) elif sensor.sens_type == 2: data.append(sensor.last_read_value[5]) elif sensor.sens_type == 3: data.append(sensor.last_read_value[6]) elif sensor.sens_type == 4: data.append(sensor.last_read_value[7]) elif sensor.sens_type == 5: data.append(sensor.last_read_value[0]) else: data.append(-127) elif sensor.sens_type == 6: # 6 is multisensor if sensor.multi_type >= 0 and sensor.multi_type <4: # multisensor temperature DS1-DS4 data.append(sensor.last_read_value[sensor.multi_type]) elif sensor.multi_type == 4: # multisensor Dry Contact data.append(sensor.last_read_value[4]) elif sensor.multi_type == 5: # multisensor Leak Detector data.append(sensor.last_read_value[5]) elif sensor.multi_type == 6: # multisensor Moisture data.append(sensor.last_read_value[6]) elif sensor.multi_type == 7: # multisensor Motion data.append(sensor.last_read_value[7]) elif sensor.multi_type == 8: # multisensor Ultrasonic data.append(sensor.last_read_value[8]) else: data.append(-127) # any errors else: # any errors data.append(-127) except: log.error(NAME, _(u'Weather stations plug-in') + ':\n' + traceback.format_exc()) data.append(-127) # any errors pass return json.dumps(data) # example data list [-127, -127, -127, -127, -127, -127, -127, -127, -127, 25]
def run(self): time.sleep( randint(3, 10) ) # Sleep some time to prevent printing before startup information send_interval = 10000 # default time for sending between e-mails (ms) last_millis = 0 # timer for repeating sending e-mails (ms) last_rain = False body = u'' logtext = u'' finished_count = len([run for run in log.finished_runs() if not run['blocked']]) if email_options["emlpwron"]: # if eml_power_on send email is enable (on) body += u'<b>' + _(u'System') + u'</b> ' + datetime_string() body += u'<br><p style="color:red;">' + _(u'System was powered on.') + u'</p>' logtext = _(u'System was powered on.') if email_options["emllog"]: file_exists = os.path.exists(EVENT_FILE) if file_exists: try_mail(body, logtext, EVENT_FILE) else: body += u'<br>' + _(u'Error - events.log file not exists!') try_mail(body, logtext) else: try_mail(body, logtext) while not self._stop_event.is_set(): body = u'' logtext = u'' try: # Send E-amil if rain is detected if email_options["emlrain"]: if inputs.rain_sensed() and not last_rain: body += u'<b>' + _(u'System') + u'</b> ' + datetime_string() body += u'<br><p style="color:red;">' + _(u'System detected rain.') + u'</p><br>' logtext = _(u'System detected rain.') try_mail(body, logtext) last_rain = inputs.rain_sensed() # Send E-mail if a new finished run is found if email_options["emlrun"]: finished = [run for run in log.finished_runs() if not run['blocked']] if len(finished) > finished_count: for run in finished[finished_count:]: duration = (run['end'] - run['start']).total_seconds() minutes, seconds = divmod(duration, 60) pname = run['program_name'] sname = stations.get(run['station']).name body += u'<br>' body += u'<b>' + _(u'System') + u'</b> ' + datetime_string() body += u'<br><b>' + _(u'Finished run') + u'</b>' body += u'<ul><li>' + _(u'Program') + u': %s \n' % pname + u'</li>' body += u'<li>' + _(u'Station') + u': %s \n' % sname + u'</li>' body += u'<li>' + _(u'Start time') + u': %s \n' % datetime_string(run['start']) + u'</li>' body += u'<li>' + _(u'Duration') + u': %02d:%02d\n' % (minutes, seconds) + u'</li></ul>' logtext = _(u'Finished run') + u'-> \n' + _(u'Program') + u': %s\n' % pname logtext += _(u'Station') + u': %s\n' % sname logtext += _(u'Start time') + u': %s \n' % datetime_string(run['start']) logtext += _(u'Duration') + u': %02d:%02d\n' % (minutes, seconds) # Water Tank Monitor try: from plugins import tank_monitor cm = tank_monitor.get_all_values()[0] percent = tank_monitor.get_all_values()[1] ping = tank_monitor.get_all_values()[2] volume = tank_monitor.get_all_values()[3] units = tank_monitor.get_all_values()[4] msg = ' ' if cm > 0: msg = _(u'Level') + u': ' + str(cm) + u' ' + _(u'cm') msg += u' (' + str(percent) + u' %), ' msg += _(u'Ping') + u': ' + str(ping) + u' ' + _(u'cm') if units: msg += u', ' + _(u'Volume') + u': ' + str(volume) + u' ' + _(u'liters') else: msg += u', ' + _(u'Volume') + u': ' + str(volume) + u' ' + _(u'm3') else: msg = _(u'Error - I2C device not found!') body += u'<b>' + _(u'Water') + u'</b>' body += u'<br><ul><li>' + _(u'Water level in tank') + u': %s \n</li></ul>' % (msg) logtext += _(u'Water') + u'-> \n' + _(u'Water level in tank') + u': %s \n' % (msg) except ImportError: log.debug(NAME, _(u'Cannot import plugin: tank monitor.')) pass # Water Consumption Counter try: from plugins import water_consumption_counter self._sleep(2) # wait for the meter to save consumption consum_from = water_consumption_counter.get_all_values()[0] consum_one = float(water_consumption_counter.get_all_values()[1]) consum_two = float(water_consumption_counter.get_all_values()[2]) msg = u' ' msg += _(u'Measured from day') + u': ' + str(consum_from) + u', ' msg += _(u'Master Station') + u': ' if consum_one < 1000.0: msg += str(consum_one) + u' ' msg += _(u'Liter') + u', ' else: msg += str(round((consum_one/1000.0), 2)) + u' ' msg += _(u'm3') + ', ' msg += _(u'Second Master Station') + u': ' if consum_two < 1000.0: msg += str(consum_two) + u' ' msg += _(u'Liter') else: msg += str(round((consum_two/1000.0), 2)) + u' ' msg += _(u'm3') body += u'<br><b>' + _(u'Water Consumption Counter') + u'</b>' body += u'<br><ul><li>%s \n</li></ul>' % (msg) logtext += _(u'Water Consumption Counter') + u': %s \n' % (msg) except ImportError: log.debug(NAME, _(u'Cannot import plugin: water consumption counter.')) pass # Air Temperature and Humidity Monitor try: from plugins import air_temp_humi body += u'<br><b>' + _(u'Temperature DS1-DS6') + u'</b><ul>' logtext += _(u'Temperature DS1-DS6') + u'-> \n' for i in range(0, air_temp_humi.plugin_options['ds_used']): body += u'<li>' + u'%s' % air_temp_humi.plugin_options['label_ds%d' % i] + u': ' + u'%.1f \u2103' % air_temp_humi.DS18B20_read_probe(i) + u'\n</li>' logtext += u'%s' % air_temp_humi.plugin_options['label_ds%d' % i] + u': ' + u'%.1f \u2103\n' % air_temp_humi.DS18B20_read_probe(i) body += u'</ul>' except ImportError: log.debug(NAME, _(u'Cannot import plugin: air temp humi.')) pass # OSPy Sensors try: body += u'<br><b>' + _(u'Sensors') + u'</b>' logtext += _(u'Sensors') + u'-> \n' sensor_result = '' if sensors.count() > 0: body += u'<ul>' for sensor in sensors.get(): sensor_result = '' body += u'<li>' sensor_result += u'{}: '.format(sensor.name) if sensor.enabled: if sensor.response == 1: if sensor.sens_type == 1: # dry contact if sensor.last_read_value[4] == 1: sensor_result += _(u'Contact Closed') elif sensor.last_read_value[4] == 0: sensor_result += _(u'Contact Open') else: sensor_result += _(u'Probe Error') if sensor.sens_type == 2: # leak detector if sensor.last_read_value[5] != -127: sensor_result += str(sensor.last_read_value[5]) + ' ' + _(u'l/s') else: sensor_result += _(u'Probe Error') if sensor.sens_type == 3: # moisture if sensor.last_read_value[6] != -127: sensor_result += str(sensor.last_read_value[6]) + ' ' + _(u'%') else: sensor_result += _(u'Probe Error') if sensor.sens_type == 4: # motion if sensor.last_read_value[7] != -127: sensor_result += _(u'Motion Detected') if int(sensor.last_read_value[7]) == 1 else _(u'No Motion') else: sensor_result += _(u'Probe Error') if sensor.sens_type == 5: # temperature if sensor.last_read_value[0] != -127: sensor_result += u'%.1f \u2103' % sensor.last_read_value[0] else: sensor_result += _(u'Probe Error') if sensor.sens_type == 6: # multi sensor if sensor.multi_type >= 0 and sensor.multi_type < 4:# multi temperature DS1-DS4 if sensor.last_read_value[sensor.multi_type] != -127: sensor_result += u'%.1f \u2103' % sensor.last_read_value[sensor.multi_type] else: sensor_result += _(u'Probe Error') if sensor.multi_type == 4: # multi dry contact if sensor.last_read_value[4] != -127: sensor_result += _(u'Contact Closed') if int(sensor.last_read_value[4]) == 1 else _(u'Contact Open') else: sensor_result += _(u'Probe Error') if sensor.multi_type == 5: # multi leak detector if sensor.last_read_value[5] != -127: sensor_result += str(sensor.last_read_value[5]) + ' ' + _(u'l/s') else: sensor_result += _(u'Probe Error') if sensor.multi_type == 6: # multi moisture if sensor.last_read_value[6] != -127: sensor_result += str(sensor.last_read_value[6]) + ' ' + _(u'%') else: sensor_result += _(u'Probe Error') if sensor.multi_type == 7: # multi motion if sensor.last_read_value[7] != -127: sensor_result += _(u'Motion Detected') if int(sensor.last_read_value[7])==1 else _(u'No Motion') else: sensor_result += _(u'Probe Error') if sensor.multi_type == 8: # multi ultrasonic if sensor.last_read_value[8] != -127: get_level = get_tank_cm(sensor.last_read_value[8], sensor.distance_bottom, sensor.distance_top) get_perc = get_percent(get_level, sensor.distance_bottom, sensor.distance_top) sensor_result += u'{} '.format(get_level) + _(u'cm') + u' ({} %)'.format(get_perc) else: sensor_result += _(u'Probe Error') if sensor.multi_type == 9: # multi soil moisture err_check = 0 calculate_soil = [0.0]*16 state = [-127]*16 for i in range(0, 16): if type(sensor.soil_last_read_value[i]) == float: state[i] = sensor.soil_last_read_value[i] ### voltage from probe to humidity 0-100% with calibration range (for footer info) if sensor.soil_invert_probe_in[i]: # probe: rotated state 0V=100%, 3V=0% humidity calculate_soil[i] = maping(state[i], float(sensor.soil_calibration_max[i]), float(sensor.soil_calibration_min[i]), 0.0, 100.0) calculate_soil[i] = round(calculate_soil[i], 1) # round to one decimal point calculate_soil[i] = 100.0 - calculate_soil[i] # ex: 90% - 90% = 10%, 10% is output in invert probe mode else: # probe: normal state 0V=0%, 3V=100% calculate_soil[i] = maping(state[i], float(sensor.soil_calibration_min[i]), float(sensor.soil_calibration_max[i]), 0.0, 100.0) calculate_soil[i] = round(calculate_soil[i], 1) # round to one decimal point if state[i] > 0.1: if sensor.soil_show_in_footer[i]: sensor_result += '{} {}% ({}V) '.format(sensor.soil_probe_label[i], round(calculate_soil[i], 2), round(state[i], 2)) else: err_check += 1 if err_check > 15: sensor_result += _(u'Probe Error') if sensor.com_type == 0: # Wi-Fi/LAN sensor_result += u' ' + _(u'Last Wi-Fi signal: {}%, Source: {}V.').format(sensor.rssi, sensor.last_battery) if sensor.com_type == 1: # Radio sensor_result += u' ' + _(u'Last Radio signal: {}%, Source: {}V.').format(sensor.rssi, sensor.last_battery) else: sensor_result += _(u'No response!') else: sensor_result += _(u'Disabled') body += sensor_result body += u'</li>' logtext += sensor_result logtext += u'\n' body += u'</ul>' body += u'<br>' else: sensor_result += _(u'No sensors available') body += u'<ul><li>' body += sensor_result body += u'</li></ul>' body += u'<br>' logtext += sensor_result logtext += u'\n' except: log.debug(NAME, _(u'E-mail plug-in') + ':\n' + traceback.format_exc()) pass try_mail(body, logtext) finished_count = len(finished) ###Repeating sending e-mails### if email_options["emlrepeater"]: # saving e-mails is enabled try: millis = int(round(time.time() * 1000)) # actual time in ms if(millis - last_millis) > send_interval: # sending timer last_millis = millis # save actual time ms try: # exists file: saved_emails.json? saved_emails = read_saved_emails() # read from file except: # no! create empty file write_email([]) # create file saved_emails = read_saved_emails() # read from file len_saved_emails = len(saved_emails) if len_saved_emails > 0: # if there is something in json log.clear(NAME) log.info(NAME, _(u'Unsent E-mails in queue (in file)') + ': ' + str(len_saved_emails)) try: # try send e-mail sendtext = u'%s' % saved_emails[0]["text"] sendsubject = u'%s' % (saved_emails[0]["subject"] + '-' + _(u'sending from queue.')) sendattachment = u'%s' % saved_emails[0]["attachment"] email(sendtext, sendsubject, sendattachment) # send e-mail send_interval = 10000 # repetition of 10 seconds del saved_emails[0] # delete sent email in file write_email(saved_emails) # save to file after deleting an item if len(saved_emails) == 0: log.clear(NAME) log.info(NAME, _(u'All unsent E-mails in the queue have been sent.')) except Exception: #print traceback.format_exc() send_interval = 60000 # repetition of 60 seconds except: log.error(NAME, _(u'E-mail plug-in') + ':\n' + traceback.format_exc()) self._sleep(2) except Exception: log.error(NAME, _(u'E-mail plug-in') + ':\n' + traceback.format_exc()) self._sleep(60)