Exemplo n.º 1
0
    def run(self):
        last_rain = False
        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 = (datetime_string() + ': System was powered on.')

            if email_options["emllog"]:
                self.try_mail(body, EVENT_FILE)
            else:
                self.try_mail(body)

        while not self._stop_event.is_set():
            try:
                # Send E-amil if rain is detected
                if email_options["emlrain"]:
                    if inputs.rain_sensed() and not last_rain:
                        body = (datetime_string() + ': System detected rain.')
                        self.try_mail(body)
                    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:
                        body = datetime_string() + ':\n'
                        for run in finished[finished_count:]:
                            duration = (run['end'] -
                                        run['start']).total_seconds()
                            minutes, seconds = divmod(duration, 60)
                            body += "Finished run:\n"
                            body += "  Program: %s\n" % run['program_name']
                            body += "  Station: %s\n" % stations.get(
                                run['station']).name
                            body += "  Start time: %s \n" % datetime_string(
                                run['start'])
                            body += "  Duration: %02d:%02d\n\n" % (minutes,
                                                                   seconds)

                        self.try_mail(body)

                    finished_count = len(finished)

                self._sleep(5)

            except Exception:
                log.error(NAME, 'E-mail plug-in:\n' + traceback.format_exc())
                self._sleep(60)
Exemplo n.º 2
0
    def GET(self):
        qdict = web.input()
        if 'clear' in qdict:
            log.clear_runs()
            raise web.seeother('/log')

        if 'clearEM' in qdict:
            logEM.clear_email()
            raise web.seeother('/log')

        if 'csv' in qdict:
            events = log.finished_runs() + log.active_runs()
            data = "Date, Start Time, Zone, Duration, Program\n"
            for interval in events:
                # return only records that are visible on this day:
                duration = (interval['end'] - interval['start']).total_seconds()
                minutes, seconds = divmod(duration, 60)

                data += ', '.join([
                    interval['start'].strftime("%Y-%m-%d"),
                    interval['start'].strftime("%H:%M:%S"),
                    str(interval['station']),
                    "%02d:%02d" % (minutes, seconds),
                    interval['program_name']
                ]) + '\n'

            web.header('Content-Type', 'text/csv')
            web.header('Content-Disposition', 'attachment; filename="log.csv"')
            return data

        if 'csvEM' in qdict:
            events = logEM.finished_email()
            data = "Date, Time, Subject, Body, Status\n"
            for interval in events:
                data += ', '.join([
                    interval['time'],
                    interval['date'],
                    str(interval['subject']),
                    str(interval['body']),
                    str(interval['status']),
                ]) + '\n'

            web.header('Content-Type', 'text/csv')
            web.header('Content-Disposition', 'attachment; filename="log_email.csv"')
            return data


        watering_records = log.finished_runs()
        email_records = logEM.finished_email()

        return self.core_render.log(watering_records, email_records)
Exemplo n.º 3
0
def combined_schedule(start_time, end_time):
    current_time = datetime.datetime.now()
    if current_time < start_time:
        result = predicted_schedule(start_time, end_time)
    elif current_time > end_time:
        result = [entry for entry in log.finished_runs() if start_time <= entry['start'] <= end_time or
                                                            start_time <= entry['end'] <= end_time]
    else:
        result = log.finished_runs()
        result += log.active_runs()
        predicted = predicted_schedule(start_time, end_time)
        result += [entry for entry in predicted if current_time <= entry['start'] <= end_time]

    return result
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
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'))
Exemplo n.º 6
0
    def GET(self):
        qdict = web.input()
        if 'clear' in qdict:
            log.clear_runs()
            raise web.seeother('/log')

        if 'csv' in qdict:
            events = log.finished_runs() + log.active_runs()
            data = "Date, Start Time, Zone, Duration, Program\n"
            for interval in events:
                # return only records that are visible on this day:
                duration = (interval['end'] - interval['start']).total_seconds()
                minutes, seconds = divmod(duration, 60)

                data += ', '.join([
                    interval['start'].strftime("%Y-%m-%d"),
                    interval['start'].strftime("%H:%M:%S"),
                    str(interval['station']),
                    "%02d:%02d" % (minutes, seconds),
                    interval['program_name']
                ]) + '\n'

            web.header('Content-Type', 'text/csv')
            web.header('Content-Disposition', 'attachment; filename="log.csv"')
            return data

        return self.core_render.log()
Exemplo n.º 7
0
def combined_schedule(start_time, end_time):
    current_time = datetime.datetime.now()
    if current_time < start_time:
        result = predicted_schedule(start_time, end_time)
    elif current_time > end_time:
        result = [
            entry for entry in log.finished_runs()
            if start_time <= entry['start'] <= end_time
            or start_time <= entry['end'] <= end_time
        ]
    else:
        result = log.finished_runs()
        result += log.active_runs()
        predicted = predicted_schedule(start_time, end_time)
        result += [
            entry for entry in predicted
            if current_time <= entry['start'] <= end_time
        ]

    return result
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
def FTP_upload(self):
    try:
        # create a file "stavy.php"
        cas = time.strftime('%d.%m.%Y (%H:%M:%S)', time.localtime(time.time()))

        text = "<?php\r\n$cas = \""  # actual time (ex: cas = dd.mm.yyyy (HH:MM:SS)
        text += cas + "\";\r\n"
        text += "$rain = \'"  # rain state (ex: rain = 0/1)
        text += str(1 if inputs.rain_sensed() else 0) + "\';\r\n"
        text += "$output = \'"  # use xx outputs count (ex: output = 8)
        text += str(options.output_count) + "\';\r\n"
        text += "$program = \'"  # use xx programs count (ex: program = 3)
        text += str(programs.count()) + "\';\r\n"

        text += "$masterstat = "  # master stations index
        for station in stations.get():
            if station.is_master:
                text += "\'" + str(station.index) + "\';\r\n"
        if stations.master is None:
            text += "\'\';\r\n"

        text += "$raindel = "  # rain delay
        if rain_blocks.seconds_left():
            m, s = divmod(int(rain_blocks.seconds_left()), 60)
            h, m = divmod(m, 60)
            text += "\'" + "%dh:%02dm:%02ds" % (h, m, s) + "\';\r\n"
        else:
            text += "\'\';\r\n"

        import unicodedata  # for only asci text in PHP WEB (stations name, program name...)

        namestations = []
        for num in range(0, options.output_count):  # stations name as array
            namestations.append(
                unicodedata.normalize('NFKD',
                                      stations.get(num).name).encode(
                                          'ascii', 'ignore'))
        text += "$name" + " = array"
        text += str(namestations) + ";\r\n"

        statestations = []
        for num in range(0, options.output_count):  # stations state as array
            statestations.append(1 if stations.get(num).active else 0)
        text += "$state" + " = array"
        text += str(statestations) + ";\r\n"

        progrname = []
        for program in programs.get():  # program name as array
            progrname.append(
                unicodedata.normalize('NFKD',
                                      program.name).encode('ascii', 'ignore'))
        text += "$progname" + " = array"
        text += str(progrname) + ";\r\n"

        text = text.replace('[', '(')
        text = text.replace(']', ')')

        text += "$schedul = \'"  # scheduller state (ex: schedul = 0 manual/ 1 scheduler)
        text += str(0 if options.manual_mode else 1) + "\';\r\n"
        text += "$system = \'"  # scheduller state (ex: system = 0 stop/ 1 scheduler)
        text += str(0 if options.scheduler_enabled else 1) + "\';\r\n"
        text += "$cpu = \'"  # cpu temp (ex: cpu  = 45.2)
        text += str(helpers.get_cpu_temp(options.temp_unit)) + "\';\r\n"
        text += "$unit = \'"  # cpu temp unit(ex: unit  = C/F) in Celsius or Fahrenheit
        text += str(options.temp_unit) + "\';\r\n"
        text += "$ver = \'"  # software version date (ex: ver  = 2016-07-30)
        text += str(version.ver_date) + "\';\r\n"
        text += "$id = \'"  # software OSPy ID (ex: id  = "opensprinkler")
        text += str(options.name) + "\';\r\n"
        text += "$ip = \'"  # OSPy IP address (ex: ip  = "192.168.1.1")
        text += str(helpers.get_ip()) + "\';\r\n"
        text += "$port = \'"  # OSPy port (ex: port  = "8080")
        text += str(options.web_port) + "\';\r\n"
        text += "$ssl = \'"  # OSPy use ssl port (ex: ssl  = "1" or "0")
        text += str(1 if options.use_ssl else 0) + "\';\r\n"

        tank = ''
        try:
            from plugins import tank_humi_monitor
            tank = tank_humi_monitor.get_sonic_tank_cm()
            if tank < 0:  # -1 is error I2C device for ping not found in tank_humi_monitor
                tank = ''
        except Exception:
            tank = ''

        text = text + "$tank = \'"  # from tank humi monitor plugins check water level (ex: tank  = "100" in cm or "")
        text = text + str(tank) + "\';\r\n"

        press = ''
        try:
            from plugins import pressure_monitor
            press = pressure_monitor.get_check_pressure()
        except Exception:
            press = ''

        text = text + "$press = \'"  # from pressure plugins check press (ex: press  = "1" or "0")
        text = text + str(press) + "\';\r\n"

        ups = ''
        try:
            from plugins import ups_adj
            ups = ups_adj.get_check_power(
            )  # read state power line from plugin ups adj
        except Exception:
            ups = ''

        text = text + "$ups = \'"
        text = text + str(ups) + "\';\r\n"

        result = ''
        finished = [run for run in log.finished_runs() if not run['blocked']]
        if finished:
            result = finished[-1]['start'].strftime(
                '%d-%m-%Y v %H:%M:%S program: ') + finished[-1]['program_name']
        else:
            result = ''

        text = text + "$lastrun = \'"  # last run program (ex: start d-m-r v h:m:s program: jmemo programu)
        text = text + str(result) + "\';\r\n"

        text = text + "$up = \'"  # system run uptime
        text = text + str(helpers.uptime()) + "\';\r\n"

        text = text + "?>\r\n"
        #print text
        """ example php code -----------
      <?php
      $cas = "09.08.2016 (15:28:10)";
      $rain = '0';
      $output = '3';
      $program = '3';
      $masterstat = '0';
      $raindel = '1:26:22'; // hod:min:sec
      $name = array('cerpadlo','test','out2');
      $state = array('0', '0', '0');
      $progname = array('cerpadlo v 5','test','out2');   
      $schedul = '1';
      $system = '1';
      $cpu = '40.1';
      $unit = 'C';
      $ver = '2016-07-30';
      $id = 'Zalevac chata';
      $ip = '192.168.1.253';
      $port = '80';
      $ssl = '1';
      $tank = '20';
      $press = '0';
      $ups = '1';
      $lastrun = '09.08.2016 v 15:28:10 program: bezi 5 minut)';
      $up = '6 days, 0:48:01'
      ?>
      ------------------------------- """

        try:
            fs = file("/home/pi/ramdisk/stavy.php", 'w')
            fs.write(text)
            fs.close()

        except:
            log.error(NAME, _(u'Could not save stavy.php to ramdisk!'))
            pass

        self.ftp.storbinary("STOR " + plugin_options['loc'] + 'stavy.php',
                            open("/home/pi/ramdisk/stavy.php", 'rb'))
        log.info(
            NAME,
            _(u'Data file stavy.php has send on to FTP server') + ': ' +
            str(cas))

        self.ftp.storbinary("STOR " + plugin_options['loc'] + 'data.txt',
                            open("/home/pi/ramdisk/data.txt", 'rb'))
        log.info(
            NAME,
            _(u'Data file data.txt has send on to FTP server') + ': ' +
            str(cas))

        self.ftp.close  # FTP end

    except Exception:
        log.info(
            NAME,
            _(u'Remote FTP control settings') + ':\n' + traceback.format_exc())
Exemplo n.º 10
0
Arquivo: api.py Projeto: Rimco/OSPy
 def GET(self):
     logger.debug('GET logs ' + self.__class__.__name__)
     return [self._runlog_to_dict(fr) for fr in log.finished_runs()]
Exemplo n.º 11
0
    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
Exemplo n.º 12
0
def predicted_schedule(start_time, end_time):
    """Determines all schedules for the given time range.
    To calculate what should currently be active, a start time of some time (a day) ago should be used."""

    adjustment = level_adjustments.total_adjustment()
    max_usage = options.max_usage
    delay_delta = datetime.timedelta(seconds=options.station_delay)

    rain_block_start = datetime.datetime.now()
    rain_block_end = rain_blocks.block_end()

    skip_intervals = log.finished_runs() + log.active_runs()
    current_active = [
        interval for interval in skip_intervals if not interval['blocked']
    ]

    usage_changes = {}
    for active in current_active:
        start = active['start']
        end = active['end']
        if start not in usage_changes:
            usage_changes[start] = 0
        if end not in usage_changes:
            usage_changes[end] = 0

        usage_changes[start] += active['usage']
        usage_changes[end] -= active['usage']

    station_schedules = {}

    # Get run-once information:
    for station in stations.enabled_stations():
        run_once_intervals = run_once.active_intervals(start_time, end_time,
                                                       station.index)
        for interval in run_once_intervals:
            if station.index not in station_schedules:
                station_schedules[station.index] = []

            program_name = _('Run-Once')

            new_schedule = {
                'active':
                None,
                'program':
                -1,
                'program_name':
                program_name,
                'fixed':
                True,
                'cut_off':
                0,
                'manual':
                True,
                'blocked':
                False,
                'start':
                interval['start'],
                'original_start':
                interval['start'],
                'end':
                interval['end'],
                'uid':
                '%s-%s-%d' %
                (str(interval['start']), str(program_name), station.index),
                'usage':
                station.usage
            }
            station_schedules[station.index].append(new_schedule)

    # Get run-now information:
    if programs.run_now_program is not None:
        program = programs.run_now_program
        for station in sorted(program.stations):
            run_now_intervals = program.active_intervals(
                start_time, end_time, station)
            for interval in run_now_intervals:
                if station >= stations.count(
                ) or stations.master == station or stations.master_two == station or not stations[
                        station].enabled:
                    continue

                if station not in station_schedules:
                    station_schedules[station] = []

                program_name = "%s " % program.name + _('Run-Now')

                new_schedule = {
                    'active':
                    None,
                    'program':
                    -1,
                    'program_name':
                    program_name,
                    'fixed':
                    program.
                    fixed,  # True for ignore water level else program.fixed for use water level in run now-program xx
                    'cut_off':
                    0,
                    'manual':
                    True,
                    'blocked':
                    False,
                    'start':
                    interval['start'],
                    'original_start':
                    interval['start'],
                    'end':
                    interval['end'],
                    'uid':
                    '%s-%s-%d' %
                    (str(interval['start']), str(program_name), station),
                    'usage':
                    stations.get(station).usage
                }
                station_schedules[station].append(new_schedule)

    # Aggregate per station:
    for program in programs.get():
        if not program.enabled:
            continue

        for station in sorted(program.stations):
            program_intervals = program.active_intervals(
                start_time, end_time, station)
            if station >= stations.count(
            ) or stations.master == station or stations.master_two == station or not stations[
                    station].enabled:
                continue

            if station not in station_schedules:
                station_schedules[station] = []

            for interval in program_intervals:
                if current_active and current_active[-1][
                        'original_start'] > interval['start']:
                    continue

                new_schedule = {
                    'active':
                    None,
                    'program':
                    program.index,
                    'program_name':
                    program.name,  # Save it because programs can be renamed
                    'fixed':
                    program.fixed,
                    'cut_off':
                    program.cut_off / 100.0,
                    'manual':
                    program.manual,
                    'blocked':
                    False,
                    'start':
                    interval['start'],
                    'original_start':
                    interval['start'],
                    'end':
                    interval['end'],
                    'uid':
                    '%s-%d-%d' %
                    (str(interval['start']), program.index, station),
                    'usage':
                    stations.get(station).usage
                }
                station_schedules[station].append(new_schedule)

    # Make lists sorted on start time, check usage
    for station in station_schedules:
        if 0 < max_usage < stations.get(station).usage:
            station_schedules[station] = []  # Impossible to schedule
        else:
            station_schedules[station].sort(key=lambda inter: inter['start'])

    all_intervals = []
    # Adjust for weather and remove overlap:
    for station, schedule in station_schedules.iteritems():
        for interval in schedule:
            if not interval['fixed']:
                time_delta = interval['end'] - interval['start']
                time_delta = datetime.timedelta(
                    seconds=(time_delta.days * 24 * 3600 +
                             time_delta.seconds) * adjustment)
                interval['end'] = interval['start'] + time_delta
                interval['adjustment'] = adjustment
            else:
                interval['adjustment'] = 1.0

        last_end = datetime.datetime(2000, 1, 1)
        for interval in schedule:
            if last_end > interval['start']:
                time_delta = last_end - interval['start']
                interval['start'] += time_delta
                interval['end'] += time_delta
            last_end = interval['end']

            new_interval = {'station': station}
            new_interval.update(interval)

            all_intervals.append(new_interval)

    # Make list of entries sorted on duration and time (stable sorted on station #)
    all_intervals.sort(key=lambda inter: inter['end'] - inter['start'])
    all_intervals.sort(key=lambda inter: inter['start'])

    # If we have processed some intervals before, we should skip all that were scheduled before them
    for to_skip in skip_intervals:
        index = 0
        while index < len(all_intervals):
            interval = all_intervals[index]

            if interval['original_start'] < to_skip['original_start'] and (
                    not to_skip['blocked'] or interval['blocked']):
                del all_intervals[index]
            elif interval['uid'] == to_skip['uid']:
                del all_intervals[index]
                break
            else:
                index += 1

    # And make sure manual programs get priority:
    all_intervals.sort(key=lambda inter: not inter['manual'])

    # Try to add each interval
    for interval in all_intervals:
        if not interval['manual'] and not options.scheduler_enabled:
            interval['blocked'] = 'disabled scheduler'
            continue
        elif not interval['manual'] and not stations.get(interval['station']).ignore_rain and \
                rain_block_start <= interval['start'] < rain_block_end:
            interval['blocked'] = 'rain delay'
            continue
        elif not interval['manual'] and not stations.get(
                interval['station']).ignore_rain and inputs.rain_sensed():
            interval['blocked'] = 'rain sensor'
            continue
        elif not interval[
                'fixed'] and interval['adjustment'] < interval['cut_off']:
            interval['blocked'] = 'cut-off'
            continue

        if max_usage > 0:
            usage_keys = sorted(usage_changes.keys())
            start_usage = 0
            start_key_index = -1

            for index, key in enumerate(usage_keys):
                if key > interval['start']:
                    break
                start_key_index = index
                start_usage += usage_changes[key]

            failed = False
            finished = False
            while not failed and not finished:
                parallel_usage = 0
                parallel_current = 0
                for index in range(start_key_index + 1, len(usage_keys)):
                    key = usage_keys[index]
                    if key >= interval['end']:
                        break
                    parallel_current += usage_changes[key]
                    parallel_usage = max(parallel_usage, parallel_current)

                if start_usage + parallel_usage + interval[
                        'usage'] <= max_usage:

                    start = interval['start']
                    end = interval['end']
                    if start not in usage_changes:
                        usage_changes[start] = 0
                    if end not in usage_changes:
                        usage_changes[end] = 0

                    usage_changes[start] += interval['usage']
                    usage_changes[end] -= interval['usage']
                    finished = True
                else:
                    while not failed:
                        # Shift this interval to next possibility
                        start_key_index += 1

                        # No more options
                        if start_key_index >= len(usage_keys):
                            failed = True
                        else:
                            next_option = usage_keys[start_key_index]
                            next_change = usage_changes[next_option]
                            start_usage += next_change

                            # Lower usage at this starting point:
                            if next_change < 0:
                                skip_delay = False
                                if options.min_runtime > 0:
                                    # Try to determine how long we have been running at this point:
                                    min_runtime_delta = datetime.timedelta(
                                        seconds=options.min_runtime)
                                    temp_usage = 0
                                    running_since = next_option
                                    not_running_since = next_option
                                    for temp_index in range(
                                            0, start_key_index):
                                        temp_usage_key = usage_keys[temp_index]
                                        if temp_usage < 0.01 and usage_changes[
                                                temp_usage_key] > 0 and temp_usage_key - not_running_since > datetime.timedelta(
                                                    seconds=3):
                                            running_since = temp_usage_key
                                        temp_usage += usage_changes[
                                            temp_usage_key]
                                        if temp_usage < 0.01 and usage_changes[
                                                temp_usage_key] < 0:
                                            not_running_since = temp_usage_key
                                    if next_option - running_since < min_runtime_delta:
                                        skip_delay = True

                                if skip_delay:
                                    time_to_next = next_option - interval[
                                        'start']
                                else:
                                    time_to_next = next_option + delay_delta - interval[
                                        'start']

                                interval['start'] += time_to_next
                                interval['end'] += time_to_next
                                break

            if failed:
                logging.warning('Could not schedule %s.', interval['uid'])
                interval['blocked'] = 'scheduler error'

    all_intervals.sort(key=lambda inter: inter['start'])

    return all_intervals
Exemplo n.º 13
0
 def GET(self):
     logger.debug('GET logs ' + self.__class__.__name__)
     return [self._runlog_to_dict(fr) for fr in log.finished_runs()]
Exemplo n.º 14
0
    def run(self):
        send_msg = False  # send get data if change (rain, end program ....
        last_rain = False 
        en_rain = True
        en_line = True
        en_line2 = True
  
        # ex: tank=100&rain=1&humi=55&line=1&lastrun=15.4.2016&station=kurnik&duration=5min 3sec&api=a1b2v5f4  
        rain = 0          # rain status for rain=0 or rain=1 in get data
        lastrun = ""      # date and time for lastrun=xxxxx in get data
        tank = ""         # actual %0-100 in water tank for tank=xx in get data
        duration = ""     # duration in last program for duration=xx:yy in get data
        station = ""      # name end station for station=abcde in get data
        humi = ""         # humidity in station for humi=xx in get data
        line = ""         # actual state from UPS plugin for line=0 or line=1 in get data
        temper = ""       # temperature  from air temp plugin 

        finished_count = len([run for run in log.finished_runs() if not run['blocked']]) 

        while not self._stop.is_set():
            try:
               
                # Send data if rain detected, power line state a new finished run is found
                if remote_options["use"]:   
                    ### water tank level ###
                    try:
                       from plugins import tank_humi_monitor
                       tank = tank_humi_monitor.get_tank()
                       if tank < 0: # -1 is error I2C device for ping not found in tank_humi_monitor
                         tank = ""
                    except Exception:
                       tank = ""

                    ### power line state ###
                    try:
                       from plugins import ups_adj
                       lin = ups_adj.get_check_power() # read state power line from plugin
                       if lin==1: 
                          if en_line:  # send only if change 
                              send_msg = True 
                              en_line = False
                              en_line2 = True 
                          line = 0 # no power on web
                           
                       if lin==0:
                          if en_line2: # send only if change
                             send_msg = True
                             en_line2 = False
                             en_line = True
                          line = 1 # power ok on web
       
                    except Exception:
                       line = ""

                    ### rain state ###
                    if inputs.rain_sensed() and not last_rain:
                        send_msg = True
                        last_rain = inputs.rain_sensed()
                    if inputs.rain_sensed():
                        rain = 1
                        en_rain = True
                    else:
                        rain = 0 
                        if en_rain: # send data if no rain (only if change rain/norain...)
                           send_msg = True
                           en_rain = False

                    if not options.rain_sensor_enabled: # if rain sensor not used
                        rain = ""
                                        
                    ### program and station ###
                    finished = [run for run in log.finished_runs() if not run['blocked']]                    
                    if len(finished) > finished_count:
                        las = datetime_string()
                        lastrun = re.sub(" ", "_", las) # eliminate gap in the title to _
                        send_msg = True
                        ### humidity in station ###
                        try:
                            from plugins import tank_humi_monitor
                            humi = int(tank_humi_monitor.get_humidity((stations.get(run['station']).index)+1)) # 0-7 to 1-8 humidity  
                            if humi < 0:
                               humi = "" 
                                
                        except Exception:
                            humi = ""

                        ### temperature ###
                        try:
                            from plugins import air_temp_humi
                            temper = air_temp_humi.DS18B20_read_string_data()
                        except Exception:
                            temper = " "
   
                        for run in finished[finished_count:]:
                            dur = (run['end'] - run['start']).total_seconds()
                            minutes, seconds = divmod(dur, 60)
                            sta = "%s" % stations.get(run['station']).name 
                            station = re.sub(" ", "_", sta)  # eliminate gap in the title to _
                            duration = "%02d:%02d" % (minutes, seconds)                       

                    finished_count = len(finished)

                if (send_msg): # if enabled send data
                    body = ('tank=' + str(tank))
                    body += ('&rain=' + str(rain))
                    body += ('&humi=' + str(humi))
                    body += ('&line=' + str(line))
                    body += ('&lastrun=' + str(lastrun)) 
                    body += ('&station=' + sanity_msg(station))
                    body += ('&duration=' + str(duration))
                    body += ('&temper=' + sanity_msg(temper))
                    body += ('&api=' + remote_options['api'])  # API password
                    self.try_send(body)                        # Send GET data to remote server 
                    send_msg = False                           # Disable send data    
                    
                self._sleep(2)

            except Exception:
                log.error(NAME, _('Remote plug-in') + ':\n' + traceback.format_exc())
                self._sleep(60)
Exemplo n.º 15
0
    def run(self):
        last_rain = False
        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 = (datetime_string() + ': ' + _('System was powered on.'))

            if email_options["emllog"]:
                file_exists = os.path.exists(EVENT_FILE)
                if file_exists:
                    self.try_mail(body, EVENT_FILE)
                else:
                    body += '\n' + _('Error -  events.log file not exists!')
                    print body
                    self.try_mail(body)
            else:
                self.try_mail(body)

        while not self._stop.is_set():
            try:
                # Send E-amil if rain is detected
                if email_options["emlrain"]:
                    if inputs.rain_sensed() and not last_rain:
                        body = (datetime_string() + ': ' +
                                _('System detected rain.'))
                        self.try_mail(body)
                    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:
                        body = datetime_string() + ':\n'
                        for run in finished[finished_count:]:
                            duration = (run['end'] -
                                        run['start']).total_seconds()
                            minutes, seconds = divmod(duration, 60)
                            cm = None
                            try:
                                from plugins import tank_humi_monitor
                                cm = tank_humi_monitor.get_sonic_tank_cm()
                                if cm > 0:
                                    cm = str(cm) + " cm"
                                else:
                                    cm = _('Error - I2C device not found!')
                            except Exception:
                                cm = _('Not available')

                            body += _('Finished run') + ':\n'
                            body += '<br>' + _(
                                'Program') + ': %s\n' % run['program_name']
                            body += '<br>' + _(
                                'Station') + ': %s\n' % stations.get(
                                    run['station']).name
                            body += '<br>' + _(
                                'Start time') + ': %s \n' % datetime_string(
                                    run['start'])
                            body += '<br>' + _(
                                'Duration') + ': %02d:%02d\n\n' % (minutes,
                                                                   seconds)
                            body += '<br>' + _(
                                'Water level in tank') + ': %s \n\n' % (cm)

                        self.try_mail(body)

                    self._sleep(3)
                    finished_count = len(finished)

                self._sleep(5)

            except Exception:
                log.error(NAME,
                          _('E-mail plug-in') + ':\n' + traceback.format_exc())
                self._sleep(60)
Exemplo n.º 16
0
def get_report(index):
    result = None
    station_state = False
    station_result = ''

    for station in stations.get():  # check if station runing
        if station.active:
            station_state = True  # yes runing
            station_result += str(
                station.index +
                1) + ', '  # station number runing ex: 2, 6, 20,

    if (options.lang == 'cs_CZ'):
        if station_state and lcd_options[
                'd_running_stations']:  # print on LCD only this text
            if index == 0 or index == 2 or index == 4 or index == 6 or index == 8 or index == 10 or index == 12 or index == 14 or index == 16 or index == 18 or index == 20:  # start text to 16x1
                result = "Stanice v chodu:"
            elif index == 1 or index == 3 or index == 5 or index == 7 or index == 9 or index == 11 or index == 13 or index == 15 or index == 17 or index == 19 or index == 21:
                result = station_result
            return result

        else:
            if index == 0:  # start text to 16x1
                if lcd_options['d_system_name']:
                    result = "ID systemu:"
                else:
                    result = None
            elif index == 1:
                if lcd_options['d_system_name']:
                    result = options.name
                else:
                    result = None

            elif index == 2:
                if lcd_options['d_sw_version_date']:
                    result = "FW Verze:"
                else:
                    result = None
            elif index == 3:
                if lcd_options['d_sw_version_date']:
                    result = version.ver_str + ' (' + version.ver_date + ')'
                else:
                    result = None

            elif index == 4:
                if lcd_options['d_ip']:
                    result = "IP adresa:"
                else:
                    result = None
            elif index == 5:
                if lcd_options['d_ip']:
                    ip = helpers.get_ip()
                    result = str(ip)
                else:
                    result = None

            elif index == 6:
                if lcd_options['d_port']:
                    result = "Port:"
                else:
                    result = None
            elif index == 7:
                if lcd_options['d_port']:
                    result = str(options.web_port)
                else:
                    result = None

            elif index == 8:
                if lcd_options['d_cpu_temp']:
                    result = "Teplota CPU:"
                else:
                    result = None
            elif index == 9:
                if lcd_options['d_cpu_temp']:
                    result = helpers.get_cpu_temp(
                        options.temp_unit) + ' ' + options.temp_unit
                else:
                    result = None

            elif index == 10:
                if lcd_options['d_time_date']:
                    result = datetime.now().strftime('Dat %d.%m.%Y')
                else:
                    result = None
            elif index == 11:
                if lcd_options['d_time_date']:
                    result = datetime.now().strftime('Cas %H:%M:%S')
                else:
                    result = None

            elif index == 12:
                if lcd_options['d_uptime']:
                    result = "V provozu:"
                else:
                    result = None
            elif index == 13:
                if lcd_options['d_uptime']:
                    result = helpers.uptime()
                else:
                    result = None

            elif index == 14:
                if lcd_options['d_rain_sensor']:
                    result = "Cidlo deste:"
                else:
                    result = None
            elif index == 15:
                if lcd_options['d_rain_sensor']:
                    if inputs.rain_sensed():
                        result = "aktivni"
                    else:
                        result = "neaktivni"
                else:
                    result = None

            elif index == 16:
                if lcd_options['d_last_run']:
                    result = 'Naposledy bezel'
                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:
                        result = finished[-1]['start'].strftime(
                            '%d-%m-%Y v %H:%M:%S program: '
                        ) + finished[-1]['program_name']
                        result = result.replace('Run-Once', 'Jednorazovy')
                        result = result.replace('Manual', 'Rucne')
                    else:
                        result = 'zadny program'
                else:
                    result = None

            elif index == 18:
                if lcd_options['d_pressure_sensor']:
                    result = "Cidlo tlaku:"
                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 = "neaktivni"
                        else:
                            result = "aktivni"

                    except Exception:
                        result = "neni k dispozici"
                else:
                    result = None

            elif index == 20:
                if lcd_options['d_water_tank_level']:
                    result = "Nadrz s vodou:"
                else:
                    result = None
            elif index == 21:
                if lcd_options['d_water_tank_level']:
                    try:
                        from plugins import tank_humi_monitor
                        cm = tank_humi_monitor.get_sonic_tank_cm()
                        if cm > 0:
                            result = str(cm) + ' cm'
                        else:
                            result = "chyba - I2C zarizeni nenalezeno!"

                    except Exception:
                        result = "neni k dispozici"
                else:
                    result = None

            return ASCI_convert(result)

    if (options.lang == 'en_US') or (options.lang == 'default'):
        if station_state and lcd_options[
                'd_running_stations']:  # print on LCD only this text
            if index == 0 or index == 2 or index == 4 or index == 6 or index == 8 or index == 10 or index == 12 or index == 14 or index == 16 or index == 18 or index == 20:  # start text to 16x1
                result = "Running stations:"
            elif index == 1 or index == 3 or index == 5 or index == 7 or index == 9 or index == 11 or index == 13 or index == 15 or index == 17 or index == 19 or index == 21:
                result = station_result
            return result

        else:

            if index == 0:
                if lcd_options['d_system_name']:
                    result = options.name
                else:
                    result = None
            elif index == 1:
                if lcd_options['d_system_name']:
                    result = "Irrigation system"
                else:
                    result = None

            elif index == 2:
                if lcd_options['d_sw_version_date']:
                    result = "SW Version:"
                else:
                    result = None
            elif index == 3:
                if lcd_options['d_sw_version_date']:
                    result = version.ver_str + ' (' + version.ver_date + ')'
                else:
                    result = None

            elif index == 4:
                if lcd_options['d_ip']:
                    result = "My IP is:"
                else:
                    result = None
            elif index == 5:
                if lcd_options['d_ip']:
                    ip = helpers.get_ip()
                    result = str(ip)
                else:
                    result = None

            elif index == 6:
                if lcd_options['d_port']:
                    result = "My Port is:"
                else:
                    result = None
            elif index == 7:
                if lcd_options['d_port']:
                    result = str(options.web_port)
                else:
                    result = None

            elif index == 8:
                if lcd_options['d_cpu_temp']:
                    result = "CPU Temperature:"
                else:
                    result = None
            elif index == 9:
                if lcd_options['d_cpu_temp']:
                    result = helpers.get_cpu_temp(
                        options.temp_unit) + ' ' + options.temp_unit
                else:
                    result = None

            elif index == 10:
                if lcd_options['d_time_date']:
                    result = datetime.now().strftime('Date: %d.%m.%Y')
                else:
                    result = None
            elif index == 11:
                if lcd_options['d_time_date']:
                    result = datetime.now().strftime('Time: %H:%M:%S')
                else:
                    result = None

            elif index == 12:
                if lcd_options['d_uptime']:
                    result = "System Uptime:"
                else:
                    result = None
            elif index == 13:
                if lcd_options['d_uptime']:
                    result = helpers.uptime()
                else:
                    result = None

            elif index == 14:
                if lcd_options['d_rain_sensor']:
                    result = "Rain Sensor:"
                else:
                    result = None
            elif index == 15:
                if lcd_options['d_rain_sensor']:
                    if inputs.rain_sensed():
                        result = "Active"
                    else:
                        result = "Inactive"
                else:
                    result = None

            elif index == 16:
                if lcd_options['d_last_run']:
                    result = '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:
                        result = finished[-1]['start'].strftime(
                            '%H:%M: ') + finished[-1]['program_name']
                        result = result.replace('Run-Once', 'Jednorazovy')
                    else:
                        result = 'None'
                else:
                    result = None

            elif index == 18:
                if lcd_options['d_pressure_sensor']:
                    result = "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 = "GPIO is HIGH"
                        else:
                            result = "GPIO is LOW"

                    except Exception:
                        result = "Not Available"
                else:
                    result = None

            elif index == 20:
                if lcd_options['d_water_tank_level']:
                    result = "Water Tank Level:"
                else:
                    result = None
            elif index == 21:
                if lcd_options['d_water_tank_level']:
                    try:
                        from plugins import tank_humi_monitor
                        cm = tank_humi_monitor.get_sonic_tank_cm()
                        if cm > 0:
                            result = str(cm) + ' cm'
                        else:
                            result = "Error - I2C Device Not Found!"

                    except Exception:
                        result = "Not Available"
                else:
                    result = None

            return result
Exemplo n.º 17
0
def predicted_schedule(start_time, end_time):
    """Determines all schedules for the given time range.
    To calculate what should currently be active, a start time of some time (a day) ago should be used."""

    adjustment = level_adjustments.total_adjustment()
    max_usage = options.max_usage
    delay_delta = datetime.timedelta(seconds=options.station_delay)

    rain_block_start = datetime.datetime.now()
    rain_block_end = rain_blocks.block_end()

    skip_intervals = log.finished_runs() + log.active_runs()
    current_active = [interval for interval in skip_intervals if not interval['blocked']]

    usage_changes = {}
    for active in current_active:
        start = active['start']
        end = active['end']
        if start not in usage_changes:
            usage_changes[start] = 0
        if end not in usage_changes:
            usage_changes[end] = 0

        usage_changes[start] += active['usage']
        usage_changes[end] -= active['usage']

    station_schedules = {}

    # Get run-once information:
    for station in stations.enabled_stations():
        run_once_intervals = run_once.active_intervals(start_time, end_time, station.index)
        for interval in run_once_intervals:
            if station.index not in station_schedules:
                station_schedules[station.index] = []

            new_schedule = {
                'active': None,
                'program': -1,
                'program_name': "Run-Once",
                'fixed': True,
                'cut_off': 0,
                'manual': True,
                'blocked': False,
                'start': interval['start'],
                'original_start': interval['start'],
                'end': interval['end'],
                'uid': '%s-%s-%d' % (str(interval['start']), "Run-Once", station.index),
                'usage': station.usage
            }
            station_schedules[station.index].append(new_schedule)

    # Get run-now information:
    if programs.run_now_program is not None:
        program = programs.run_now_program
        for station in sorted(program.stations):
            run_now_intervals = program.active_intervals(start_time, end_time, station)
            for interval in run_now_intervals:
                if station >= stations.count() or stations.master == station or not stations[station].enabled:
                    continue

                if station not in station_schedules:
                    station_schedules[station] = []

                program_name = "%s (Run-Now)" % program.name

                new_schedule = {
                    'active': None,
                    'program': -1,
                    'program_name': program_name,
                    'fixed': True,
                    'cut_off': 0,
                    'manual': True,
                    'blocked': False,
                    'start': interval['start'],
                    'original_start': interval['start'],
                    'end': interval['end'],
                    'uid': '%s-%s-%d' % (str(interval['start']), program_name, station),
                    'usage': stations.get(station).usage
                }
                station_schedules[station].append(new_schedule)

    # Aggregate per station:
    for program in programs.get():
        if not program.enabled:
            continue

        for station in sorted(program.stations):
            program_intervals = program.active_intervals(start_time, end_time, station)

            if station >= stations.count() or stations.master == station or not stations[station].enabled:
                continue

            if station not in station_schedules:
                station_schedules[station] = []

            for interval in program_intervals:
                if current_active and current_active[-1]['original_start'] > interval['start']:
                    continue

                new_schedule = {
                    'active': None,
                    'program': program.index,
                    'program_name': program.name, # Save it because programs can be renamed
                    'fixed': program.fixed,
                    'cut_off': program.cut_off/100.0,
                    'manual': program.manual,
                    'blocked': False,
                    'start': interval['start'],
                    'original_start': interval['start'],
                    'end': interval['end'],
                    'uid': '%s-%d-%d' % (str(interval['start']), program.index, station),
                    'usage': stations.get(station).usage
                }
                station_schedules[station].append(new_schedule)

    # Make lists sorted on start time, check usage
    for station in station_schedules:
        if 0 < max_usage < stations.get(station).usage:
            station_schedules[station] = []  # Impossible to schedule
        else:
            station_schedules[station].sort(key=lambda inter: inter['start'])

    all_intervals = []
    # Adjust for weather and remove overlap:
    for station, schedule in station_schedules.iteritems():
        for interval in schedule:
            if not interval['fixed']:
                time_delta = interval['end'] - interval['start']
                time_delta = datetime.timedelta(seconds=(time_delta.days * 24 * 3600 + time_delta.seconds) * adjustment)
                interval['end'] = interval['start'] + time_delta
                interval['adjustment'] = adjustment
            else:
                interval['adjustment'] = 1.0

        last_end = datetime.datetime(2000, 1, 1)
        for interval in schedule:
            if last_end > interval['start']:
                time_delta = last_end - interval['start']
                interval['start'] += time_delta
                interval['end'] += time_delta
            last_end = interval['end']

            new_interval = {
                'station': station
            }
            new_interval.update(interval)

            all_intervals.append(new_interval)

    # Make list of entries sorted on duration and time (stable sorted on station #)
    all_intervals.sort(key=lambda inter: inter['end'] - inter['start'])
    all_intervals.sort(key=lambda inter: inter['start'])

    # If we have processed some intervals before, we should skip all that were scheduled before them
    for to_skip in skip_intervals:
        index = 0
        while index < len(all_intervals):
            interval = all_intervals[index]

            if interval['original_start'] < to_skip['original_start'] and (not to_skip['blocked'] or interval['blocked']):
                del all_intervals[index]
            elif interval['uid'] == to_skip['uid']:
                del all_intervals[index]
                break
            else:
                index += 1

    # And make sure manual programs get priority:
    all_intervals.sort(key=lambda inter: not inter['manual'])

    # Try to add each interval
    for interval in all_intervals:
        if not interval['manual'] and not options.scheduler_enabled:
            interval['blocked'] = 'disabled scheduler'
            continue
        elif not interval['manual'] and not stations.get(interval['station']).ignore_rain and \
                rain_block_start <= interval['start'] < rain_block_end:
            interval['blocked'] = 'rain delay'
            continue
        elif not interval['manual'] and not stations.get(interval['station']).ignore_rain and inputs.rain_sensed():
            interval['blocked'] = 'rain sensor'
            continue
        elif not interval['fixed'] and interval['adjustment'] < interval['cut_off']:
            interval['blocked'] = 'cut-off'
            continue

        if max_usage > 0:
            usage_keys = sorted(usage_changes.keys())
            start_usage = 0
            start_key_index = -1

            for index, key in enumerate(usage_keys):
                if key > interval['start']:
                    break
                start_key_index = index
                start_usage += usage_changes[key]

            failed = False
            finished = False
            while not failed and not finished:
                parallel_usage = 0
                parallel_current = 0
                for index in range(start_key_index+1, len(usage_keys)):
                    key = usage_keys[index]
                    if key >= interval['end']:
                        break
                    parallel_current += usage_changes[key]
                    parallel_usage = max(parallel_usage, parallel_current)

                if start_usage + parallel_usage + interval['usage'] <= max_usage:

                    start = interval['start']
                    end = interval['end']
                    if start not in usage_changes:
                        usage_changes[start] = 0
                    if end not in usage_changes:
                        usage_changes[end] = 0

                    usage_changes[start] += interval['usage']
                    usage_changes[end] -= interval['usage']
                    finished = True
                else:
                    while not failed:
                        # Shift this interval to next possibility
                        start_key_index += 1

                        # No more options
                        if start_key_index >= len(usage_keys):
                            failed = True
                        else:
                            next_option = usage_keys[start_key_index]
                            next_change = usage_changes[next_option]
                            start_usage += next_change

                            # Lower usage at this starting point:
                            if next_change < 0:
                                skip_delay = False
                                if options.min_runtime > 0:
                                    # Try to determine how long we have been running at this point:
                                    min_runtime_delta = datetime.timedelta(seconds=options.min_runtime)
                                    temp_usage = 0
                                    running_since = next_option
                                    not_running_since = next_option
                                    for temp_index in range(0, start_key_index):
                                        temp_usage_key = usage_keys[temp_index]
                                        if temp_usage < 0.01 and usage_changes[temp_usage_key] > 0 and temp_usage_key - not_running_since > datetime.timedelta(seconds=3):
                                            running_since = temp_usage_key
                                        temp_usage += usage_changes[temp_usage_key]
                                        if temp_usage < 0.01 and usage_changes[temp_usage_key] < 0:
                                            not_running_since = temp_usage_key
                                    if next_option - running_since < min_runtime_delta:
                                        skip_delay = True

                                if skip_delay:
                                    time_to_next = next_option - interval['start']
                                else:
                                    time_to_next = next_option + delay_delta - interval['start']

                                interval['start'] += time_to_next
                                interval['end'] += time_to_next
                                break

            if failed:
                logging.warning('Could not schedule %s.', interval['uid'])
                interval['blocked'] = 'scheduler error'



    all_intervals.sort(key=lambda inter: inter['start'])

    return all_intervals
Exemplo n.º 18
0
    def calculate_balances(self):
        from scheduler import predicted_schedule
        now = datetime.datetime.now()
        for station in stations.get():
            station.balance = {key: value for key, value in station.balance.iteritems()
                               if key >= now.date() - datetime.timedelta(days=21)}

            if not station.balance or (now.date() - datetime.timedelta(days=21)) not in station.balance:
                station.balance[now.date() - datetime.timedelta(days=21)] = {
                    'eto': 0.0,
                    'rain': 0.0,
                    'intervals': [],
                    'total': 0.0,
                    'valid': True
                }

            runs = log.finished_runs() + log.active_runs()
            calc_day = now.date() - datetime.timedelta(days=20)
            while calc_day < now.date() + datetime.timedelta(days=7):
                if calc_day not in station.balance:
                    station.balance[calc_day] = {
                        'eto': 4.0,
                        'rain': 0.0,
                        'intervals': [],
                        'total': 0.0,
                        'valid': False
                    }
                try:
                    if not station.balance[calc_day]['valid'] or calc_day >= now.date() - datetime.timedelta(days=1):
                        station.balance[calc_day]['eto'] = station.eto_factor * weather.get_eto(calc_day)
                        station.balance[calc_day]['rain'] = 0.0 if station.ignore_rain else weather.get_rain(calc_day)
                        station.balance[calc_day]['valid'] = True
                except Exception:
                    station.balance[calc_day]['valid'] = False
                    logging.warning('Could not get weather information, using fallbacks:\n' + traceback.format_exc())

                intervals = []
                while runs and runs[0]['start'].date() <= calc_day:
                    run = runs[0]
                    if runs[0]['start'].date() == calc_day and not run['blocked'] and run['station'] == station.index:
                        irrigation = (run['end'] - run['start']).total_seconds() / 3600 * station.precipitation
                        if run['manual']:
                            irrigation *= 0.5  # Only count half in case of manual runs
                        intervals.append({
                            'program': run['program'],
                            'program_name': run['program_name'],
                            'done': True,
                            'irrigation': irrigation
                        })
                    del runs[0]

                if calc_day >= now.date():
                    if calc_day == now.date():
                        date_time_start = now
                    else:
                        date_time_start = datetime.datetime.combine(calc_day, datetime.time.min)
                    date_time_end = datetime.datetime.combine(calc_day, datetime.time.max)
                    for run in predicted_schedule(date_time_start, date_time_end):
                        if not run['blocked'] and run['station'] == station.index:
                            irrigation = (run['end'] - run['start']).total_seconds() / 3600 * station.precipitation
                            intervals.append({
                                'program': run['program'],
                                'program_name': run['program_name'],
                                'done': False,
                                'irrigation': irrigation
                            })

                if len(intervals) > len(station.balance[calc_day]['intervals']) or calc_day >= now.date():
                    station.balance[calc_day]['intervals'] = intervals

                station.balance[calc_day]['total'] = station.balance[calc_day - datetime.timedelta(days=1)]['total'] \
                                                     - station.balance[calc_day]['eto'] \
                                                     + station.balance[calc_day]['rain'] \
                                                     + sum(interval['irrigation'] for interval in station.balance[calc_day]['intervals'])

                station.balance[calc_day]['total'] = max(-100, min(station.balance[calc_day]['total'], station.capacity))

                calc_day += datetime.timedelta(days=1)

            station.balance = station.balance # Force saving
Exemplo n.º 19
0
    def run(self):
        send_msg = False  # send get data if change (rain, end program ....
        last_rain = False
        en_rain = True
        en_line = True
        en_line2 = True

        rain = 0  # rain status for rain=0 or rain=1 in get data
        lastrun = ""  # date and time for lastrun=xxxxx in get data
        tank = ""  # actual level cm in water tank
        percent = ""  # actual level % in water tank
        ping = ""  # actual level ping cm water level
        volume = ""  # actual level volume in m3 water level
        duration = ""  # duration in last program for duration=xx:yy in get data
        station = ""  # name end station for station=abcde in get data
        humi = ""  # humidity in station for humi=xx in get data
        line = ""  # actual state from UPS plugin for line=0 or line=1 in get data
        temp1 = ""  # temperature 1 from air temp plugin DS18B20
        temp2 = ""  # temperature 2 from air temp plugin DS18B20
        temp3 = ""  # temperature 3 from air temp plugin DS18B20
        temp4 = ""  # temperature 4 from air temp plugin DS18B20
        temp5 = ""  # temperature 5 from air temp plugin DS18B20
        temp6 = ""  # temperature 6 from air temp plugin DS18B20
        tempDHT = ""  # temperature  from air temp plugin DHT probe
        humiDHT = ""  # humidity from air temp plugin DHT probe

        finished_count = len(
            [run for run in log.finished_runs() if not run['blocked']])

        while not self._stop_event.is_set():
            try:

                # Send data if rain detected, power line state a new finished run is found
                if remote_options["use"]:
                    ### water tank level ###
                    try:
                        from plugins import tank_monitor
                        tank = 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]

                    except Exception:
                        tank = ""
                        percent = ""
                        ping = ""
                        volume = ""

                    ### power line state ###
                    try:
                        from plugins import ups_adj
                        lin = ups_adj.get_check_power(
                        )  # read state power line from plugin
                        if lin == 1:
                            if en_line:  # send only if change
                                send_msg = True
                                en_line = False
                                en_line2 = True
                            line = 0  # no power on web

                        if lin == 0:
                            if en_line2:  # send only if change
                                send_msg = True
                                en_line2 = False
                                en_line = True
                            line = 1  # power ok on web

                    except Exception:
                        line = ""

                    ### rain state ###
                    if inputs.rain_sensed() and not last_rain:
                        send_msg = True
                        last_rain = inputs.rain_sensed()
                    if inputs.rain_sensed():
                        rain = 1
                        en_rain = True
                    else:
                        rain = 0
                        if en_rain:  # send data if no rain (only if change rain/norain...)
                            send_msg = True
                            en_rain = False

                    if not options.rain_sensor_enabled:  # if rain sensor not used
                        rain = ""

                    ### program and station ###
                    finished = [
                        run for run in log.finished_runs()
                        if not run['blocked']
                    ]
                    if len(finished) > finished_count:
                        las = datetime_string()
                        lastrun = re.sub(
                            " ", "_", las)  # eliminate gap in the title to _
                        send_msg = True
                        ### humidity in station ###
                        try:
                            from plugins import humi_monitor
                            humi = int(
                                humi_monitor.get_humidity(
                                    (stations.get(run['station']).index) +
                                    1))  # 0-7 to 1-8 humidity
                            if humi < 0:
                                humi = ""

                        except Exception:
                            humi = ""

                        ### temperature ###
                        try:
                            from plugins import air_temp_humi
                            temp1 = air_temp_humi.DS18B20_read_probe(0)
                            temp2 = air_temp_humi.DS18B20_read_probe(1)
                            temp3 = air_temp_humi.DS18B20_read_probe(2)
                            temp4 = air_temp_humi.DS18B20_read_probe(3)
                            temp5 = air_temp_humi.DS18B20_read_probe(4)
                            temp6 = air_temp_humi.DS18B20_read_probe(5)
                            tempDHT = air_temp_humi.DHT_read_temp_value()
                            humiDHT = air_temp_humi.DHT_read_humi_value()
                        except Exception:
                            temp1 = ""
                            temp2 = ""
                            temp3 = ""
                            temp4 = ""
                            temp5 = ""
                            temp6 = ""
                            tempDHT = ""
                            humiDHT = ""

                        for run in finished[finished_count:]:
                            dur = (run['end'] - run['start']).total_seconds()
                            minutes, seconds = divmod(dur, 60)
                            sta = "%s" % stations.get(run['station']).name
                            station = re.sub(
                                " ", "_",
                                sta)  # eliminate gap in the title to _
                            duration = "%02d:%02d" % (minutes, seconds)

                    finished_count = len(finished)

                if (send_msg):  # if enabled send data
                    body = ('tank=' + str(tank))
                    body += ('&percent=' + str(percent))
                    body += ('&ping=' + str(ping))
                    body += ('&volume=' + str(volume))
                    body += ('&rain=' + str(rain))
                    body += ('&humi=' + str(humi))
                    body += ('&line=' + str(line))
                    body += ('&lastrun=' + str(lastrun))
                    body += ('&station=' + sanity_msg(station))
                    body += ('&duration=' + str(duration))
                    body += ('&temp1=' + str(temp1))
                    body += ('&temp2=' + str(temp2))
                    body += ('&temp3=' + str(temp3))
                    body += ('&temp4=' + str(temp4))
                    body += ('&temp5=' + str(temp5))
                    body += ('&temp6=' + str(temp6))
                    body += ('&tempDHT=' + str(tempDHT))
                    body += ('&humiDHT=' + str(humiDHT))
                    body += ('&api=' + remote_options['api'])  # API password
                    log.clear(NAME)
                    log.info(NAME, _(u'Test data...'))
                    self.try_send(body)  # Send GET data to remote server
                    send_msg = False  # Disable send data

                self._sleep(2)

            except Exception:
                log.error(
                    NAME,
                    _(u'Remote plug-in') + ':\n' + traceback.format_exc())
                self._sleep(60)
Exemplo n.º 20
0
def get_report(index):
    result = None
    if (options.lang == 'cs_CZ'):
           if index == 0:  # start text to 16x1
             if lcd_options['d_system_name']:
                result = "ID systemu:"
             else: 
                result = None
           elif index == 1:
             if lcd_options['d_system_name']:
                result = options.name
             else:
                result = None 

           elif index == 2:
             if lcd_options['d_sw_version_date']:
                result = "FW Verze:"
             else: 
                result = None
           elif index == 3:
             if lcd_options['d_sw_version_date']:
                result = version.ver_str + ' (' + version.ver_date + ')' 
             else: 
                result = None

           elif index == 4:
             if lcd_options['d_ip']:
                result = "IP adresa:" 
             else: 
                result = None
           elif index == 5:
             if lcd_options['d_ip']:
                 ip = helpers.get_ip()
                 result = str(ip)
             else: 
                result = None

           elif index == 6:
             if lcd_options['d_port']:
                result = "Port:"
             else: 
                result = None
           elif index == 7:
             if lcd_options['d_port']:
                result = str(options.web_port)
             else: 
                result = None

           elif index == 8:
             if lcd_options['d_cpu_temp']:
                result = "Teplota CPU:"
             else: 
                result = None
           elif index == 9:
             if lcd_options['d_cpu_temp']:
                result = helpers.get_cpu_temp(options.temp_unit) + ' ' + options.temp_unit
             else: 
                result = None

           elif index == 10:
             if lcd_options['d_time_date']:
                result = datetime.now().strftime('Dat %d.%m.%Y')
             else: 
                result = None
           elif index == 11:
             if lcd_options['d_time_date']:
                result = datetime.now().strftime('Cas %H:%M:%S')
             else: 
                result = None

           elif index == 12:
             if lcd_options['d_uptime']:
                result = "V provozu:"
             else: 
                result = None
           elif index == 13:
             if lcd_options['d_uptime']:
                result = helpers.uptime() 
             else: 
                result = None

           elif index == 14:
             if lcd_options['d_rain_sensor']:
                result = "Cidlo deste:"
             else: 
                result = None
           elif index == 15:
             if lcd_options['d_rain_sensor']:
                if inputs.rain_sensed():
                    result = "aktivni"
                else:
                    result = "neaktivni"
             else: 
                result = None

           elif index == 16:
             if lcd_options['d_last_run']:
                result = 'Naposledy bezel'
             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:
                   result = finished[-1]['start'].strftime('%d-%m-%Y v %H:%M:%S program: ') + finished[-1]['program_name']
                   result = result.replace('Run-Once', 'Jednorazovy')
                   result = result.replace('Manual', 'Rucne')
                else:
                   result = 'zadny program'
             else: 
                result = None

           elif index == 18:
             if lcd_options['d_pressure_sensor']:
                result = "Cidlo tlaku:"
             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 = "neaktivni"
                   else:
                      result = "aktivni"

                except Exception:
                   result = "neni k dispozici"
             else: 
                result = None

           elif index == 20:    
             if lcd_options['d_water_tank_level']:    
                result = "Nadrz s vodou:"
             else: 
                result = None
           elif index == 21:
             if lcd_options['d_water_tank_level']:
                try:
                   from plugins import tank_humi_monitor
                   cm = tank_humi_monitor.get_sonic_tank_cm()
                   if cm > 0: 
                      result = str(cm) + ' cm'
                   else:
                      result = "chyba - I2C zarizeni nenalezeno!"

                except Exception:
                   result = "neni k dispozici"
             else: 
                result = None

           elif index == 22:    
             if lcd_options['d_temperature']:    
                result = "Teplota DS1-6:"
             else: 
                result = None
           elif index == 23:
             if lcd_options['d_temperature']:
                try:
                   from plugins import air_temp_humi
                 
                   result = air_temp_humi.DS18B20_read_string_data()
                  
                except Exception:
                   result = "neni k dispozici"
             else: 
                result = None

           elif index == 24:    
             if lcd_options['d_running_stations']:    
                result = "Stanice v chodu:"
             else: 
                result = None
           elif index == 25:
             if get_active_state()==False:   
                result = "nic nebezi" 
             else:
                result = get_active_state()

           return ASCI_convert(result)


    if (options.lang == 'sk_SK'):
           if index == 0:  # start text to 16x1
             if lcd_options['d_system_name']:
                result = "ID systemu:"
             else: 
                result = None
           elif index == 1:
             if lcd_options['d_system_name']:
                result = options.name
             else:
                result = None 

           elif index == 2:
             if lcd_options['d_sw_version_date']:
                result = "FW Verzia:"
             else: 
                result = None
           elif index == 3:
             if lcd_options['d_sw_version_date']:
                result = version.ver_str + ' (' + version.ver_date + ')' 
             else: 
                result = None

           elif index == 4:
             if lcd_options['d_ip']:
                result = "IP adresa:" 
             else: 
                result = None
           elif index == 5:
             if lcd_options['d_ip']:
                 ip = helpers.get_ip()
                 result = str(ip)
             else: 
                result = None

           elif index == 6:
             if lcd_options['d_port']:
                result = "Port:"
             else: 
                result = None
           elif index == 7:
             if lcd_options['d_port']:
                result = str(options.web_port)
             else: 
                result = None

           elif index == 8:
             if lcd_options['d_cpu_temp']:
                result = "Teplota CPU:"
             else: 
                result = None
           elif index == 9:
             if lcd_options['d_cpu_temp']:
                result = helpers.get_cpu_temp(options.temp_unit) + ' ' + options.temp_unit
             else: 
                result = None

           elif index == 10:
             if lcd_options['d_time_date']:
                result = datetime.now().strftime('Dat %d.%m.%Y')
             else: 
                result = None
           elif index == 11:
             if lcd_options['d_time_date']:
                result = datetime.now().strftime('Cas %H:%M:%S')
             else: 
                result = None

           elif index == 12:
             if lcd_options['d_uptime']:
                result = "V prevadzke:"
             else: 
                result = None
           elif index == 13:
             if lcd_options['d_uptime']:
                result = helpers.uptime() 
             else: 
                result = None

           elif index == 14:
             if lcd_options['d_rain_sensor']:
                result = "Cidlo dazda:"
             else: 
                result = None
           elif index == 15:
             if lcd_options['d_rain_sensor']:
                if inputs.rain_sensed():
                    result = "aktivny"
                else:
                    result = "neaktivny"
             else: 
                result = None

           elif index == 16:
             if lcd_options['d_last_run']:
                result = 'Naposledy bezal'
             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:
                   result = finished[-1]['start'].strftime('%d-%m-%Y v %H:%M:%S program: ') + finished[-1]['program_name']
                   result = result.replace('Run-Once', 'Jednorazovy')
                   result = result.replace('Manual', 'Rucne')
                else:
                   result = 'ziadny program'
             else: 
                result = None

           elif index == 18:
             if lcd_options['d_pressure_sensor']:
                result = "Cidlo tlaku:"
             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 = "neaktivny"
                   else:
                      result = "aktivny"

                except Exception:
                   result = "neni k dispozicii"
             else: 
                result = None

           elif index == 20:    
             if lcd_options['d_water_tank_level']:    
                result = "Nadrz s vodou:"
             else: 
                result = None
           elif index == 21:
             if lcd_options['d_water_tank_level']:
                try:
                   from plugins import tank_humi_monitor
                   cm = tank_humi_monitor.get_sonic_tank_cm()
                   if cm > 0: 
                      result = str(cm) + ' cm'
                   else:
                      result = "chyba - I2C zarizeni nenajdene!"

                except Exception:
                   result = "neni k dispozicii"
             else: 
                result = None

           elif index == 22:    
             if lcd_options['d_temperature']:    
                result = "Teplota DS1-6:"
             else: 
                result = None
           elif index == 23:
             if lcd_options['d_temperature']:
                try:
                   from plugins import air_temp_humi
                 
                   result = air_temp_humi.DS18B20_read_string_data()
                  
                except Exception:
                   result = "neni k dispozicii"
             else: 
                result = None

           elif index == 24:    
             if lcd_options['d_running_stations']:    
                result = "Stanice v chode:"
             else: 
                result = None
           elif index == 25:
             if get_active_state()==False:   
                result = "nic nebezi" 
             else:
                result = get_active_state()

           return ASCI_convert(result)

    if (options.lang == 'en_US') or (options.lang == 'default'):
          if index == 0:  
             if lcd_options['d_system_name']:
                result = options.name
             else: 
                result = None
          elif index == 1:
             if lcd_options['d_system_name']:
                result = "Irrigation system"
             else: 
                result = None

          elif index == 2:
             if lcd_options['d_sw_version_date']:
                result = "SW Version:"
             else: 
                result = None
          elif index == 3:
             if lcd_options['d_sw_version_date']:
                result = version.ver_str + ' (' + version.ver_date + ')'
             else: 
                result = None

          elif index == 4:
             if lcd_options['d_ip']:
                result = "My IP is:"
             else: 
                result = None
          elif index == 5:
             if lcd_options['d_ip']:
                ip = helpers.get_ip()
                result = str(ip)
             else: 
                result = None

          elif index == 6:
             if lcd_options['d_port']:
                result = "My Port is:"
             else: 
                result = None
          elif index == 7:
             if lcd_options['d_port']:
                result = str(options.web_port)
             else: 
                result = None

          elif index == 8:
             if lcd_options['d_cpu_temp']:
                result = "CPU Temperature:"
             else: 
                result = None
          elif index == 9:
             if lcd_options['d_cpu_temp']:
                result = helpers.get_cpu_temp(options.temp_unit) + ' ' + options.temp_unit
             else: 
                result = None

          elif index == 10:
             if lcd_options['d_time_date']:
                result = datetime.now().strftime('Date: %d.%m.%Y')
             else: 
                result = None
          elif index == 11:
             if lcd_options['d_time_date']:
                result = datetime.now().strftime('Time: %H:%M:%S')
             else: 
                result = None

          elif index == 12:
             if lcd_options['d_uptime']:
                result = "System Uptime:"
             else: 
                result = None
          elif index == 13:
             if lcd_options['d_uptime']:
                result = helpers.uptime()
             else: 
                result = None

          elif index == 14:
             if lcd_options['d_rain_sensor']:
                result = "Rain Sensor:"
             else: 
                result = None
          elif index == 15:
             if lcd_options['d_rain_sensor']:
                if inputs.rain_sensed():
                   result = "Active"
                else:
                   result = "Inactive"
             else: 
                result = None

          elif index == 16:
             if lcd_options['d_last_run']:
                result = '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:
                   result = finished[-1]['start'].strftime('%H:%M: ') + finished[-1]['program_name']
                   result = result.replace('Run-Once', 'Jednorazovy') 
                else:
                   result = 'None'
             else: 
                result = None

          elif index == 18:
             if lcd_options['d_pressure_sensor']:
                result = "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 = "GPIO is HIGH"
                   else:
                       result = "GPIO is LOW"

                except Exception:
                   result = "Not Available"
             else: 
                result = None


          elif index == 20:    
             if lcd_options['d_water_tank_level']:        
                result = "Water Tank Level:"
             else: 
                result = None
          elif index == 21:
             if lcd_options['d_water_tank_level']:    
                try:
                   from plugins import tank_humi_monitor
                   cm = tank_humi_monitor.get_sonic_tank_cm()
                   if cm > 0: 
                      result = str(cm) + ' cm'
                   else:
                      result = "Error - I2C Device Not Found!"

                except Exception:
                   result = "Not Available"
             else: 
                result = None

          elif index == 22:    
            if lcd_options['d_temperature']:    
               result = "DS Temperature:"
            else: 
               result = None
          elif index == 23:
            if lcd_options['d_temperature']:
               try:
                  from plugins import air_temp_humi
                 
                  result = air_temp_humi.DS18B20_read_string_data()
                                     
               except Exception:
                  result = "Not Available"
            else: 
               result = None

          elif index == 24:    
            if lcd_options['d_running_stations']:    
               result = "Station running:"
            else: 
                result = None
          elif index == 25:
            if get_active_state()==False:   
               result = "nothing running" 
            else:
               result = get_active_state()

          return result
Exemplo n.º 21
0
    def calculate_balances(self):
        from scheduler import predicted_schedule
        now = datetime.datetime.now()
        for station in stations.get():
            station.balance = {
                key: value
                for key, value in station.balance.iteritems()
                if key >= now.date() - datetime.timedelta(days=21)
            }

            if not station.balance or (now.date() - datetime.timedelta(days=21)
                                       ) not in station.balance:
                station.balance[now.date() - datetime.timedelta(days=21)] = {
                    'eto': 0.0,
                    'rain': 0.0,
                    'intervals': [],
                    'total': 0.0,
                    'valid': True
                }

            runs = log.finished_runs() + log.active_runs()
            calc_day = now.date() - datetime.timedelta(days=20)
            while calc_day < now.date() + datetime.timedelta(days=10):
                if calc_day not in station.balance:
                    station.balance[calc_day] = {
                        'eto': 4.0,
                        'rain': 0.0,
                        'intervals': [],
                        'total': 0.0,
                        'valid': False
                    }
                try:
                    if not station.balance[calc_day][
                            'valid'] or calc_day >= now.date():
                        station.balance[calc_day]['eto'] = weather.get_eto(
                            calc_day)
                        station.balance[calc_day]['rain'] = weather.get_rain(
                            calc_day)
                        station.balance[calc_day]['valid'] = True
                except Exception:
                    station.balance[calc_day]['valid'] = False
                    logging.warning(
                        'Could not get weather information, using fallbacks:\n'
                        + traceback.format_exc())

                intervals = []
                while runs and runs[0]['start'].date() <= calc_day:
                    run = runs[0]
                    if runs[0]['start'].date() == calc_day and not run[
                            'blocked'] and run['station'] == station.index:
                        irrigation = (run['end'] - run['start']).total_seconds(
                        ) / 3600 * station.precipitation
                        if run['manual']:
                            irrigation *= 0.5  # Only count half in case of manual runs
                        intervals.append({
                            'program': run['program'],
                            'program_name': run['program_name'],
                            'done': True,
                            'irrigation': irrigation
                        })
                    del runs[0]

                if calc_day >= now.date():
                    if calc_day == now.date():
                        date_time_start = now
                    else:
                        date_time_start = datetime.datetime.combine(
                            calc_day, datetime.time.min)
                    date_time_end = datetime.datetime.combine(
                        calc_day, datetime.time.max)
                    for run in predicted_schedule(date_time_start,
                                                  date_time_end):
                        if not run['blocked'] and run[
                                'station'] == station.index:
                            irrigation = (
                                run['end'] - run['start']
                            ).total_seconds() / 3600 * station.precipitation
                            intervals.append({
                                'program':
                                run['program'],
                                'program_name':
                                run['program_name'],
                                'done':
                                False,
                                'irrigation':
                                irrigation
                            })

                if len(intervals) > len(station.balance[calc_day]['intervals']
                                        ) or calc_day >= now.date():
                    station.balance[calc_day]['intervals'] = intervals

                station.balance[calc_day]['total'] = station.balance[calc_day - datetime.timedelta(days=1)]['total'] \
                                                     - station.balance[calc_day]['eto'] \
                                                     + station.balance[calc_day]['rain'] \
                                                     + sum(interval['irrigation'] for interval in station.balance[calc_day]['intervals'])

                station.balance[calc_day]['total'] = max(
                    -100,
                    min(station.balance[calc_day]['total'], station.capacity))

                calc_day += datetime.timedelta(days=1)

            station.balance = station.balance  # Force saving
Exemplo n.º 22
0
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'))
Exemplo n.º 23
0
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
Exemplo n.º 24
0
    def run(self):
        last_rain = False
        body = ""
        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 += '<b>' + _('System') + '</b> ' + datetime_string()
            body += '<br><p style="color:red;">' + _('System was powered on.') + '</p>'

            if email_options["emllog"]:
                file_exists = os.path.exists(EVENT_FILE)
                if file_exists:
                   self.try_mail(body, EVENT_FILE)
                else:
                   body += '<br>' + _('Error -  events.log file not exists!') 
                   #print body
                   self.try_mail(body)
            else:
                self.try_mail(body)

        while not self._stop.is_set():
            body = ""
            try:
                # Send E-amil if rain is detected
                if email_options["emlrain"]:
                    if inputs.rain_sensed() and not last_rain:
                        body += '<b>' + _('System') + '</b> ' + datetime_string() 
                        body += '<br><p style="color:red;">' + _('System detected rain.') + '</p>'
                        self.try_mail(body)
                    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)
                            body += '<b>' + _('System') + '</b> ' + datetime_string()
                            body += '<br><b>'  + _('Finished run') + '</b>'
                            body += '<br>' + _('Program') + ': %s\n' % run['program_name']
                            body += '<br>' + _('Station') + ': %s\n' % stations.get(run['station']).name
                            body += '<br>' + _('Start time') + ': %s \n' % datetime_string(run['start'])
                            body += '<br>' + _('Duration') + ': %02d:%02d\n' % (minutes, seconds)
                            
                            cm = None
                            try:
                                from plugins import tank_humi_monitor
                                cm = tank_humi_monitor.get_sonic_tank_cm()
                                if cm > 0:
                                    cm = str(cm) + " cm"
                                else: 
                                    cm = _('Error - I2C device not found!')

                                body += '<br><b>'  + _('Water') + '</b>'                                    
                                body += '<br>' + _('Water level in tank') + ': %s \n' % (cm)    
                            
                            except Exception:
                                pass
                                
                            result = None    
                            try:
                                from plugins import air_temp_humi    
                                body += '<br><b>' + _('Temperature DS1-DS6') + '</b>'
                                for i in range(0, air_temp_humi.plugin_options['ds_used']):  
                                    body += '<br>' + u'%s' % air_temp_humi.plugin_options['label_ds%d' % i] + ': ' + u'%.1f \u2103' % air_temp_humi.DS18B20_read_probe(i) + '\n'  
                
                            except Exception:
                                pass

                        self.try_mail(body)
                        
                    self._sleep(1)
                    finished_count = len(finished)

                self._sleep(1)

            except Exception:
                log.error(NAME, _('E-mail plug-in') + ':\n' + traceback.format_exc())
                self._sleep(60)