from sl3 import *
import utime

# The sampler has a limited number of bottles.
bottles_capacity = 24

# We count how many bottles are in use.
bottles_used = 0

# Time sampler was triggered last.
time_last_sample = 0.0


def trigger_sampler_digital():
    """ Function triggers DOUT2 for two seconds in order to trigger a sampler"""
    output_control('OUTPUT2', True)
    utime.sleep(2.0)
    output_control('OUTPUT2', False)


def triggered_today():
    """Have we triggered the sampler today?"""
    if time_last_sample == 0.0:
        return False  # we never triggered
    else:
        # what is the day today?
        today = utime.localtime()[6]  # returns the weekday (value from 0 to 6)

        # and what day did we last trigger?
        last = utime.localtime(time_last_sample)[6]

        if today == last:
            return True  # yes we triggered today
        else:
            return False


def trigger_sampler_master():
    """Triggers the sampler immediately and logs it."""

    global bottles_used
    global time_last_sample

    # increment the number of bottles used
    bottles_used += 1

    # update the time of the last trigger
    time_last_sample = utime.time()

    # trigger sampler via the digital output line
    trigger_sampler_digital()

    # write a log entry
    reading = Reading(label="Triggered", time=time_scheduled(),
                      etype='E', value=bottles_used,
                      right_digits=0, quality='G')
    reading.write_log()


def stage_sufficient():
    """Returns true if the last measured stage is sufficient
    to trigger the sampler"""

    stage = measure("STAGE", READING_LAST).value  # what is the current stage?

    if stage > 2.0:
        return True  # yes there is enough water to sample
    else:
        return False  # water level too low to sample


def trigger_sampler():
    """
    Call to attempt to trigger the sampler.
    Certain conditions may prevent the triggering.

    :return: True if sampler was triggered.
    """
    global bottles_capacity
    global bottles_used
    global time_last_sample

    trigger = True

    if bottles_used >= bottles_capacity:
        trigger = False  # out of bottles
    elif triggered_today():
        trigger = False  # already triggered today
    elif not stage_sufficient():
        trigger = False  # not enough water to sample

    if trigger:
        trigger_sampler_master()  # Call routine that controls sampler.
        return True

    else:
        return False  # Sampler was NOT triggered.


def update_status():
    """Call routine to update the script status with the bottle count and
    time of last sampler trigger"""
    global bottles_capacity
    global bottles_used
    global time_last_sample

    # add diagnostic info to the script status
    print("Bottles used: {}".format(bottles_used))
    print("Bottle capacity: {}".format(bottles_capacity))
    if time_last_sample:
        print("Last trigger: {}".format(ascii_time(time_last_sample)))
        if triggered_today():
            print("   Which was today")
        else:
            print("   No trigger today")
    else:
        print("Not triggered since bootup")


@TASK
def trigger_task():
    """
    This function should be associated with a script task scheduled for a certain time every day.
    If the sampler has not been triggered today, this function will trigger it.
    """

    if trigger_sampler():
        # sampler was triggered

        # Write a log entry indicating why sampler was triggered.
        reading = Reading(label="DailyTrig", time=time_scheduled(),
                          etype='E', quality='G')
        reading.write_log()

    # Update the script status
    update_status()


@MEASUREMENT
def stage_sampler_check(stage):
    """ This function needs to be associated with the stage measurement.
    It will compare the current stage reading with the threshold.
    If the stage exceeds the threshold, it will try to trigger the sampler."""

    if stage > 5.5:
        if trigger_sampler():
            # sampler was triggered

            # Write a log entry indicating why sampler was triggered.
            reading = Reading(label="StageTrig", time=time_scheduled(),
                              etype='E', value=stage, quality='G')
            reading.write_log()

    # Update the script status
    update_status()

    # makes sure the return the stage reading so the system can log it
    return stage


