예제 #1
0
파일: webpages.py 프로젝트: Rimco/OSPy
    def POST(self):
        qdict = web.input()

        save_to_options(qdict)

        if 'master' in qdict:
            m = int(qdict['master'])
            if m < 0:
                stations.master = None
            elif m < stations.count():
                stations.master = m

        if 'old_password' in qdict and qdict['old_password'] != "":
            try:
                if test_password(qdict['old_password']):
                    if qdict['new_password'] == "":
                        raise web.seeother('/options?errorCode=pw_blank')
                    elif qdict['new_password'] == qdict['check_password']:
                        options.password_salt = password_salt()  # Make a new salt
                        options.password_hash = password_hash(qdict['new_password'], options.password_salt)
                    else:
                        raise web.seeother('/options?errorCode=pw_mismatch')
                else:
                    raise web.seeother('/options?errorCode=pw_wrong')
            except KeyError:
                pass

        raise web.seeother('/')
예제 #2
0
파일: webpages.py 프로젝트: Rimco/OSPy
    def POST(self):
        qdict = web.input()

        recalc = False
        for s in xrange(0, stations.count()):
            stations[s].name = qdict["%d_name" % s]
            stations[s].usage = float(qdict.get("%d_usage" % s, 1.0))
            stations[s].precipitation = float(qdict.get("%d_precipitation" % s, 10.0))
            stations[s].capacity = float(qdict.get("%d_capacity" % s, 10.0))
            stations[s].eto_factor = float(qdict.get("%d_eto_factor" % s, 1.0))
            stations[s].enabled = True if qdict.get("%d_enabled" % s, 'off') == 'on' else False
            stations[s].ignore_rain = True if qdict.get("%d_ignore_rain" % s, 'off') == 'on' else False
            if stations.master is not None or options.master_relay:
                stations[s].activate_master = True if qdict.get("%d_activate_master" % s, 'off') == 'on' else False

            balance_adjust = float(qdict.get("%d_balance_adjust" % s, 0.0))
            if balance_adjust != 0.0:
                calc_day = datetime.datetime.now().date() - datetime.timedelta(days=1)
                stations[s].balance[calc_day]['intervals'].append({
                                'program': -1,
                                'program_name': 'Balance adjustment',
                                'done': True,
                                'irrigation': balance_adjust
                            })
                stations[s].balance[calc_day]['total'] += balance_adjust
                recalc = True

        if recalc:
            Timer(0.1, programs.calculate_balances).start()

        raise web.seeother('/')
예제 #3
0
    def POST(self):
        qdict = web.input()

        save_to_options(qdict)

        if 'master' in qdict:
            m = int(qdict['master'])
            if m < 0:
                stations.master = None
            elif m < stations.count():
                stations.master = m

        if 'old_password' in qdict and qdict['old_password'] != "":
            try:
                if test_password(qdict['old_password']):
                    if qdict['new_password'] == "":
                        raise web.seeother('/options?errorCode=pw_blank')
                    elif qdict['new_password'] == qdict['check_password']:
                        options.password_salt = password_salt()  # Make a new salt
                        options.password_hash = password_hash(qdict['new_password'], options.password_salt)
                    else:
                        raise web.seeother('/options?errorCode=pw_mismatch')
                else:
                    raise web.seeother('/options?errorCode=pw_wrong')
            except KeyError:
                pass

        raise web.seeother('/')
예제 #4
0
    def POST(self):
        qdict = web.input()

        for s in xrange(0, stations.count()):
            stations[s].name = qdict["%d_name" % s]
            stations[s].usage = float(qdict.get("%d_usage" % s, 1.0))
            stations[s].precipitation = float(qdict.get("%d_precipitation" % s, 10.0))
            stations[s].capacity = float(qdict.get("%d_capacity" % s, 10.0))
            stations[s].enabled = True if qdict.get("%d_enabled" % s, 'off') == 'on' else False
            stations[s].ignore_rain = True if qdict.get("%d_ignore_rain" % s, 'off') == 'on' else False
            if stations.master is not None or options.master_relay:
                stations[s].activate_master = True if qdict.get("%d_activate_master" % s, 'off') == 'on' else False

        raise web.seeother('/')
예제 #5
0
파일: webpages.py 프로젝트: Rimco/OSPy
    def GET(self):
        from ospy import server
        qdict = web.input()

        stop_all = get_input(qdict, 'stop_all', False, lambda x: True)
        scheduler_enabled = get_input(qdict, 'scheduler_enabled', None, lambda x: x == '1')
        manual_mode = get_input(qdict, 'manual_mode', None, lambda x: x == '1')
        rain_block = get_input(qdict, 'rain_block', None, float)
        level_adjustment = get_input(qdict, 'level_adjustment', None, float)
        toggle_temp = get_input(qdict, 'toggle_temp', False, lambda x: True)

        if stop_all:
            if not options.manual_mode:
                options.scheduler_enabled = False
                programs.run_now_program = None
                run_once.clear()
            log.finish_run(None)
            stations.clear()

        if scheduler_enabled is not None:
            options.scheduler_enabled = scheduler_enabled

        if manual_mode is not None:
            options.manual_mode = manual_mode

        if rain_block is not None:
            options.rain_block = datetime.datetime.now() + datetime.timedelta(hours=rain_block)

        if level_adjustment is not None:
            options.level_adjustment = level_adjustment / 100

        if toggle_temp:
            options.temp_unit = "F" if options.temp_unit == "C" else "C"

        set_to = get_input(qdict, 'set_to', None, int)
        sid = get_input(qdict, 'sid', 0, int) - 1
        set_time = get_input(qdict, 'set_time', 0, int)

        if set_to is not None and 0 <= sid < stations.count() and options.manual_mode:
            if set_to:  # if status is on
                start = datetime.datetime.now()
                new_schedule = {
                    'active': True,
                    'program': -1,
                    'station': sid,
                    'program_name': "Manual",
                    'fixed': True,
                    'cut_off': 0,
                    'manual': True,
                    'blocked': False,
                    'start': start,
                    'original_start': start,
                    'end': start + datetime.timedelta(days=3650),
                    'uid': '%s-%s-%d' % (str(start), "Manual", sid),
                    'usage': stations.get(sid).usage
                }
                if set_time > 0:  # if an optional duration time is given
                    new_schedule['end'] = datetime.datetime.now() + datetime.timedelta(seconds=set_time)

                log.start_run(new_schedule)
                stations.activate(new_schedule['station'])

            else:  # If status is off
                stations.deactivate(sid)
                active = log.active_runs()
                for interval in active:
                    if interval['station'] == sid:
                        log.finish_run(interval)

        self._redirect_back()
예제 #6
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
예제 #7
0
파일: scheduler.py 프로젝트: Rimco/OSPy
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
예제 #8
0
    def GET(self):
        from ospy import server
        qdict = web.input()

        stop_all = get_input(qdict, 'stop_all', False, lambda x: True)
        scheduler_enabled = get_input(qdict, 'scheduler_enabled', None, lambda x: x == '1')
        manual_mode = get_input(qdict, 'manual_mode', None, lambda x: x == '1')
        rain_block = get_input(qdict, 'rain_block', None, float)
        level_adjustment = get_input(qdict, 'level_adjustment', None, float)
        toggle_temp = get_input(qdict, 'toggle_temp', False, lambda x: True)

        if stop_all:
            if not options.manual_mode:
                options.scheduler_enabled = False
                programs.run_now_program = None
                run_once.clear()
            log.finish_run(None)
            stations.clear()

        if scheduler_enabled is not None:
            options.scheduler_enabled = scheduler_enabled

        if manual_mode is not None:
            options.manual_mode = manual_mode

        if rain_block is not None:
            options.rain_block = datetime.datetime.now() + datetime.timedelta(hours=rain_block)

        if level_adjustment is not None:
            options.level_adjustment = level_adjustment / 100

        if toggle_temp:
            options.temp_unit = "F" if options.temp_unit == "C" else "C"

        set_to = get_input(qdict, 'set_to', None, int)
        sid = get_input(qdict, 'sid', 0, int) - 1
        set_time = get_input(qdict, 'set_time', 0, int)

        if set_to is not None and 0 <= sid < stations.count() and options.manual_mode:
            if set_to:  # if status is on
                start = datetime.datetime.now()
                new_schedule = {
                    'active': True,
                    'program': -1,
                    'station': sid,
                    'program_name': "Manual",
                    'fixed': True,
                    'cut_off': 0,
                    'manual': True,
                    'blocked': False,
                    'start': start,
                    'original_start': start,
                    'end': start + datetime.timedelta(days=3650),
                    'uid': '%s-%s-%d' % (str(start), "Manual", sid),
                    'usage': stations.get(sid).usage
                }
                if set_time > 0:  # if an optional duration time is given
                    new_schedule['end'] = datetime.datetime.now() + datetime.timedelta(seconds=set_time)

                log.start_run(new_schedule)
                stations.activate(new_schedule['station'])

            else:  # If status is off
                stations.deactivate(sid)
                active = log.active_runs()
                for interval in active:
                    if interval['station'] == sid:
                        log.finish_run(interval)

        self._redirect_back()
예제 #9
0
def on_message(client, userdata, message):
    log.clear(NAME)
    log.info(
        NAME,
        datetime_string() + ' ' + _('Message received') + ': ' +
        str(message.payload.decode("utf-8")))
    #print("Message topic=",message.topic)
    #print("Message qos=",message.qos)
    #print("Message retain flag=",message.retain)

    if plugin_options["use_mqtt_secondary"]:
        if not options.manual_mode:  # check operation status
            log.info(
                NAME,
                datetime_string() + ' ' +
                _('You must this OSPy switch to manual mode!'))
            return

        if inputs.rain_sensed():  # check rain sensor
            log.info(
                NAME,
                datetime_string() + ' ' +
                _('Skipping command, rain sense is detected!'))
            return

        if rain_blocks.seconds_left():  # check rain delay
            log.info(
                NAME,
                datetime_string() + ' ' +
                _('Skipping command, rain delay is activated!'))
            return

        try:
            rec_data = str(message.payload)
            cmd = json.loads(rec_data)
        except ValueError as e:
            log.info(NAME,
                     _('Could not decode command:') + ':\n' + message.payload,
                     e)
            return

        first = int(
            plugin_options["first_station"]) - 1  # first secondary station
        count = int(plugin_options["station_count"])  # count secondary station

        try:
            for i in range(
                    first, first +
                    count):  # count of station (example on main OSPy: 5 to 10)
                zone = cmd[i]["status"]  # "off" or "on" state
                #station = cmd[i]["station"]
                #name    = cmd[i]["name"]
                #print station, name, zone

                sid = i - first
                if sid <= stations.count():  # local station size check
                    if zone == "on":
                        start = datetime.datetime.now()
                        mqn = _('MQTT Manual')
                        new_schedule = {
                            'active': True,
                            'program': -1,
                            'station': sid,
                            'program_name': mqn,
                            'fixed': True,
                            'cut_off': 0,
                            'manual': True,
                            'blocked': False,
                            'start': start,
                            'original_start': start,
                            'end': start + datetime.timedelta(days=3650),
                            'uid': '%s-%s-%d' % (str(start), mqn, sid),
                            'usage': stations.get(sid).usage
                        }
                        # if an optional duration time is given
                        #set_time = xxx second
                        #new_schedule['end'] = datetime.datetime.now() + datetime.timedelta(seconds=set_time)

                        log.start_run(new_schedule)
                        stations.activate(new_schedule['station'])
                    if zone == "off":
                        stations.deactivate(sid)
                        active = log.active_runs()
                        for interval in active:
                            if interval['station'] == i:
                                log.finish_run(interval)

                else:
                    log.error(
                        NAME,
                        _('MQTT plug-in') + ':\n' +
                        _('Setup stations count is smaler! Set correct first station and station count.'
                          ))
        except Exception:
            log.error(NAME, _('MQTT plug-in') + ':\n' + traceback.format_exc())

        time.sleep(1)
예제 #10
0
    def POST(self):
        qdict = web.input()
  
        change = False # if change language -> restart ospy

        if 'lang' in qdict and qdict['lang']:
            if options.lang != qdict['lang']:
               change = True

        qdict['name'] = qdict['name']
        qdict['location'] = qdict['location']
        qdict['darksky_key'] = qdict['darksky_key']
        qdict['HTTP_web_ip'] = qdict['HTTP_web_ip']

        save_to_options(qdict)

        if 'master' in qdict:
            m = int(qdict['master'])
            if m < 0:
                stations.master = None
            elif m < stations.count():
                stations.master = m

        if 'master_two' in qdict:
            m = int(qdict['master_two'])
            if m < 0:
                stations.master_two = None
            elif m < stations.count():
                stations.master_two = m

        if 'old_password' in qdict and qdict['old_password'] != "":
            try:
                if test_password(qdict['old_password']):
                    if qdict['new_password'] == "":
                        raise web.seeother('/options?errorCode=pw_blank')
                    elif qdict['new_password'] == qdict['check_password']:
                        options.password_salt = password_salt()  # Make a new salt
                        options.password_hash = password_hash(qdict['new_password'], options.password_salt)
                    else:
                        raise web.seeother('/options?errorCode=pw_mismatch')
                else:
                    raise web.seeother('/options?errorCode=pw_wrong')
            except KeyError:
                pass
   
        if 'rbt' in qdict and qdict['rbt'] == '1':
            report_rebooted()
            reboot(True) # Linux HW software 
            return self.core_render.home()

        if 'rstrt' in qdict and qdict['rstrt'] == '1':
            report_restarted()
            restart()    # OSPy software
            return self.core_render.restarting(home_page)
        
        if 'pwrdwn' in qdict and qdict['pwrdwn'] == '1':
            poweroff()   # shutdown HW system
            return self.core_render.restarting(home_page) 

        if 'deldef' in qdict and qdict['deldef'] == '1':
            OPTIONS_FILE = './ospy/data'
            try:
                import shutil, time
                shutil.rmtree(OPTIONS_FILE) # delete data folder
                time.sleep(2)
                os.makedirs(OPTIONS_FILE)   # create data folder
                report_restarted()
                restart()                   # restart OSPy software
                return self.core_render.restarting(home_page)
            except:
                pass 

        if change:
            report_restarted()
            restart()    # OSPy software
            return self.core_render.restarting(home_page)

        report_option_change()
        raise web.seeother('/')
예제 #11
0
    def POST(self):
        qdict = web.input()

        change = False  # if change language -> restart ospy

        if 'lang' in qdict and qdict['lang']:
            if options.lang != qdict['lang']:
                change = True

        newname = qdict['name']  # if name is asci char
        try:
            from ospy.helpers import ASCI_convert
            qdict['name'] = ASCI_convert(newname)
        except:
            qdict['name'] = ' '

        save_to_options(qdict)

        if 'master' in qdict:
            m = int(qdict['master'])
            if m < 0:
                stations.master = None
            elif m < stations.count():
                stations.master = m

        if 'master_two' in qdict:
            m = int(qdict['master_two'])
            if m < 0:
                stations.master_two = None
            elif m < stations.count():
                stations.master_two = m

        if 'old_password' in qdict and qdict['old_password'] != "":
            try:
                if test_password(qdict['old_password']):
                    if qdict['new_password'] == "":
                        raise web.seeother('/options?errorCode=pw_blank')
                    elif qdict['new_password'] == qdict['check_password']:
                        options.password_salt = password_salt(
                        )  # Make a new salt
                        options.password_hash = password_hash(
                            qdict['new_password'], options.password_salt)
                    else:
                        raise web.seeother('/options?errorCode=pw_mismatch')
                else:
                    raise web.seeother('/options?errorCode=pw_wrong')
            except KeyError:
                pass

        if 'rbt' in qdict and qdict['rbt'] == '1':
            reboot(True)  # Linux HW software
            return self.core_render.home()

        if 'rstrt' in qdict and qdict['rstrt'] == '1':
            restart()  # OSPy software
            return self.core_render.restarting(home_page)

        if 'pwrdwn' in qdict and qdict['pwrdwn'] == '1':
            poweroff()  # shutdown HW system
            return self.core_render.restarting(home_page)

        if 'deldef' in qdict and qdict['deldef'] == '1':
            OPTIONS_FILE = './ospy/data'
            try:
                import shutil, time
                shutil.rmtree(OPTIONS_FILE)  # delete data folder
                time.sleep(2)
                os.makedirs(OPTIONS_FILE)  # create data folder
                restart()  # restart OSPy software
                return self.core_render.restarting(home_page)
            except:
                pass

        if change:
            restart()  # OSPy software
            return self.core_render.restarting(home_page)

        raise web.seeother('/')