Exemple #1
0
def sensorreading(sensorname, MinutesOfAverage, operation):
    isok = False
    # operation "average", "min" , "max" , "sum"
    if sensorname:
        timelist = hardwaremod.gettimedata(sensorname)
        theinterval = timelist[1]  # minutes
        if theinterval > 0:
            samplesnumber = int(MinutesOfAverage / theinterval + 1)
        else:
            samplesnumber = 1
            theinterval = 15
        quantity = 0
        MinutesOfAverage = samplesnumber * theinterval
        if samplesnumber > 0:
            sensordata = []
            sensordbmod.getsensordbdatasamplesN(sensorname, sensordata,
                                                samplesnumber)
            datenow = datetime.now()  # dont put UTC here !!!
            starttimecalc = datenow - timedelta(
                minutes=(MinutesOfAverage + theinterval)
            )  #if Minutes of average is zero, it allows to have at least one sample
            isok, quantitylist = sensordbmod.EvaluateDataPeriod(
                sensordata, starttimecalc, datenow)
            quantity = quantitylist[operation]
            # sensor reading value
            logger.info('Sensor reading <%s>=<%s>', sensorname, str(quantity))
            print "sensor Reading ", sensorname, "=", quantity
    return isok, quantity
Exemple #2
0
def sensorlisttriggertime():
	tablelist=hardwaremod.searchdatalist(hardwaremod.HW_INFO_IOTYPE,"input",hardwaremod.HW_INFO_NAME)
	timetriggerlist=[]
	for item in tablelist:
		timelist=hardwaremod.gettimedata(item)	
		theinterval=timelist[1] # minutes
		timetriggerlist.append(theinterval)
	return timetriggerlist
Exemple #3
0
def sensorlisttriggertime():
	tablelist=hardwaremod.searchdatalist(hardwaremod.HW_INFO_IOTYPE,"input",hardwaremod.HW_INFO_NAME)
	timetriggerlist=[]
	for item in tablelist:
		timelist=hardwaremod.gettimedata(item)	
		theinterval=timelist[1] # minutes
		timetriggerlist.append(theinterval)
	return timetriggerlist
Exemple #4
0
def sensorreading(sensorname,MinutesOfAverage,operation):
	isok=False	
	# operation "average", "min" , "max" , "sum"
	if sensorname:
		timelist=hardwaremod.gettimedata(sensorname)	
		theinterval=timelist[1] # minutes
		if theinterval>0:
			samplesnumber=int(MinutesOfAverage/theinterval+1)
		else:
			samplesnumber=1
			theinterval=15
		quantity=0
		MinutesOfAverage=samplesnumber*theinterval
		if samplesnumber>0:
			sensordata=[]		
			sensordbmod.getsensordbdatasamplesN(sensorname,sensordata,samplesnumber)
			starttimecalc=datetime.now()-timedelta(minutes=(MinutesOfAverage+theinterval)) #if Minutes of average is zero, it allows to have at least one sample
			quantity=sensordbmod.EvaluateDataPeriod(sensordata,starttimecalc,datetime.now())[operation]	
			isok=True	
	return isok , quantity
Exemple #5
0
def sensorreading(sensorname):
	MinutesOfAverage=70 #about one hour, 4 samples at 15min samples rate
	if sensorname:
		# old
		#sensordata=[]		
		#sensordbmod.getsensordbdata(sensorname,sensordata)
		# get number of samples 
		timelist=hardwaremod.gettimedata(sensorname)	
		theinterval=timelist[1] # minutes
		if theinterval>0:
			samplesnumber=int(MinutesOfAverage/theinterval+1)
		else:
			samplesnumber=1	
		# new procedure should be faster on database reading for large amount of data
		sensordata=[]
		sensordbmod.getsensordbdatasamplesN(sensorname,sensordata,samplesnumber)
		# still necessary to filter the sample based on timestamp, due to the possibility of missing samples
		starttimecalc=datetime.now()-timedelta(minutes=int(MinutesOfAverage))
		quantity=sensordbmod.EvaluateDataPeriod(sensordata,starttimecalc,datetime.now())["max"]	
	return 	quantity
def sensorreading(sensorname):
    MinutesOfAverage = 70  #about one hour, 4 samples at 15min samples rate
    if sensorname:
        # old
        #sensordata=[]
        #sensordbmod.getsensordbdata(sensorname,sensordata)
        # get number of samples
        timelist = hardwaremod.gettimedata(sensorname)
        theinterval = timelist[1]  # minutes
        if theinterval > 0:
            samplesnumber = int(MinutesOfAverage / theinterval + 1)
        else:
            samplesnumber = 1
        # new procedure should be faster on database reading for large amount of data
        sensordata = []
        sensordbmod.getsensordbdatasamplesN(sensorname, sensordata,
                                            samplesnumber)
        # still necessary to filter the sample based on timestamp, due to the possibility of missing samples
        starttimecalc = datetime.now() - timedelta(
            minutes=int(MinutesOfAverage))
        quantity = sensordbmod.EvaluateDataPeriod(sensordata, starttimecalc,
                                                  datetime.now())["max"]
    return quantity
def sensorreading(sensorname, MinutesOfAverage, operation):
    isok = False
    # operation "average", "min" , "max" , "sum"
    if sensorname:
        timelist = hardwaremod.gettimedata(sensorname)
        theinterval = timelist[1]  # minutes
        if theinterval > 0:
            samplesnumber = int(MinutesOfAverage / theinterval + 1)
        else:
            samplesnumber = 1
            theinterval = 15
        quantity = 0
        MinutesOfAverage = samplesnumber * theinterval
        if samplesnumber > 0:
            sensordata = []
            sensordbmod.getsensordbdatasamplesN(sensorname, sensordata,
                                                samplesnumber)
            starttimecalc = datetime.now() - timedelta(
                minutes=(MinutesOfAverage + theinterval)
            )  #if Minutes of average is zero, it allows to have at least one sample
            quantity = sensordbmod.EvaluateDataPeriod(
                sensordata, starttimecalc, datetime.now())[operation]
            isok = True
    return isok, quantity
Exemple #8
0
def mastercallback(fromscheduledtime=False):
    print("master callback")
    if fromscheduledtime:  # check if the time this function is called is the same as the expected time it should be called (solar/legal time might mess with it)
        logger.info(
            'Master scheduler call at scheduled local time, expected time %s',
            MASTERSCHEDULERTIME)
        thedateloc = datetime.now()
        timelist = hardwaremod.separatetimestringint(MASTERSCHEDULERTIME)
        masterschedtime = thedateloc.replace(hour=timelist[0],
                                             minute=timelist[1],
                                             second=timelist[2])
        secondsdifference = abs((thedateloc - masterschedtime).total_seconds())
        logger.info(
            'Master scheduler, difference between expected time and local time %d',
            secondsdifference)
        if secondsdifference > 300:  # more than 5 minutes
            logger.warning(
                'Master scheduler, difference between expected time and local time greater than 5 minutes, RESET MASTER SCHEDULER'
            )
            resetmastercallback()
            return
        # clean old data of the database (pastdays)
        logger.info('Remove data exceeding one year')
        pastdays = hardwaremod.toint(STOREPASTDAYS, 364)
        logger.info('Sensor Remove data exceeding one year')
        sensordbmod.RemoveSensorDataPeriod(pastdays)
        logger.info('Actuator Remove data exceeding one year')
        actuatordbmod.RemoveActuatorDataPeriod(pastdays)
        logger.info('Photo Remove data exceeding one year')
        hardwaremod.removephotodataperiod(pastdays)
    else:
        logger.info('Master scheduler call not coming from scheduler')

    logger.info('Scheduling main activities')

    # remove all jobs except masterscheduler
    #for job in SchedulerMod.sched.get_jobs():
    #	if job.name != "master":
    #		try:
    #			job.remove()
    #		except:
    #			logger.error('Not able to remove Job %s', job.name)

    # set the individual callback of the day

    logger.info('Start other scheduler activities - heartbeat')

    # info file dedicate call-back --------------------------------------------- (heartbeat)

    #this callback is used only for system status periodic check

    calltype = "periodic"
    global HEARTBEATINTERVAL
    interval = HEARTBEATINTERVAL
    timelist = [0, interval, 900]  # 20 indicates to start after 15 minutes
    callback = "heartbeat"
    argument = []

    setschedulercallback(calltype, timelist, argument, callback, callback)

    logger.info('Start other scheduler activities - sensor')

    # info file dedicate call-back --------------------------------------------- (sensor)

    hwnamelist = hardwaremod.searchdatalist(hardwaremod.HW_INFO_IOTYPE,
                                            "input", hardwaremod.HW_INFO_NAME)

    # GPIO input can be considered at all the aspects a binary input, therefor their stat collection are possible as any other input
    # the input should be time periodic and time should be more than one minute

    callback = "sensor"
    timeshift = 300  # after wifi activation because of possible clock adjustment
    shiftstep = 7  #seconds
    # IMPORTANT
    # the shiftstep is necessary to avoid thread collision which brings to sqlite3 db failure "database is locked"
    # this number is giving a limit to the sensor reading that should be higher than 1min
    for hwname in hwnamelist:
        calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, hwname,
                                          hardwaremod.HW_FUNC_SCHEDTYPE)
        if calltype == "periodic":  #check the input to be periodic
            timelist = hardwaremod.gettimedata(hwname)
            timelist[
                2] = timeshift  # avoid all the sensor thread to be called in the same time
            argument = []
            argument.append(hwname)
            setschedulercallback(calltype, timelist, argument, callback,
                                 hwname)
            timeshift = timeshift + shiftstep
        else:
            logger.warning(
                'The scheduler for the input %s is not set to PERIODIC, no log record of this input will be taken',
                hwname)

    logger.info('Start other scheduler activities - photo')

    #<------>
    # info file dedicate quinto call-back ----------------------------------(takephoto)
    usedfor = "photocontrol"
    callback = "photo"
    hwnamelist = hardwaremod.searchdatalist(hardwaremod.HW_FUNC_USEDFOR,
                                            usedfor, hardwaremod.HW_INFO_NAME)
    for hwname in hwnamelist:
        calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, hwname,
                                          hardwaremod.HW_FUNC_SCHEDTYPE)
        timelist = hardwaremod.gettimedata(hwname)
        argument = []
        argument.append(hwname)
        setschedulercallback(calltype, timelist, argument, callback, hwname)

    logger.info('Start other scheduler activities - mail')

    # info ne file dedicate quarto call-back ---------------------------------------(sendmail)

    usedfor = "mailcontrol"
    callback = "mail"
    hwnamelist = hardwaremod.searchdatalist(hardwaremod.HW_FUNC_USEDFOR,
                                            usedfor, hardwaremod.HW_INFO_NAME)
    for hwname in hwnamelist:
        calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, hwname,
                                          hardwaremod.HW_FUNC_SCHEDTYPE)
        timelist = hardwaremod.gettimedata(hwname)
        argument = []
        argument.append(hwname)
        setschedulercallback(calltype, timelist, argument, callback, hwname)

    # info ne file dedicate quinto call-back ---------------------------------------(lightcheck)

    # empty
    #<---->

    logger.info('Start other scheduler activities - pump')

    # info file dedicate call-back ------------------------------------------------ (waterpump)

    callback = "waterpump"

    #water schedule table
    paramlist = wateringdbmod.getparamlist()  # name of the months ordered
    elementlist = wateringdbmod.getelementlist(
    )  # pump ordered (based on "watercontrol" field)
    table = wateringdbmod.gettable(
        1
    )  # table, each row is a pump, each column is a month, value is watering time multiplieer
    table1 = wateringdbmod.gettable(
        0
    )  # table, each row is a pump, each column is a month, value is watering scheme
    table2 = wateringdbmod.gettable(
        2
    )  # table, each row is a pump, each column is a month, value is time delay

    #print paramlist
    #print elementlistly
    #print table
    paramlistdrop = advancedmod.getparamlist()  # day of the week
    elementlistdrop = advancedmod.getelementlist()  # drops ordered
    tabledrop = advancedmod.gettable(
    )  # table, each row is a schema number (drop number), each column is a weekday

    for pumpnumber in range(len(elementlist)):
        #print "number =",pumpnumber
        pumpname = elementlist[pumpnumber]
        todaydate = date.today()
        # Monday is 0 and Sunday is 6
        weekday = todaydate.weekday()
        month = todaydate.month

        try:
            waterschemanumber = table1[pumpnumber][month - 1]
            waterdropnumber = hardwaremod.toint(table[pumpnumber][month - 1],
                                                0)
            watertimedelaysec = hardwaremod.toint(
                table2[pumpnumber][month - 1], 0)
        except IndexError:
            print("EXCEPTION: index out of range")
            waterdropnumber = 0
            watertimedelaysec = 0

        if waterdropnumber > 0:
            #print " month  " , month, " drop  " , waterdropnumber
            calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,
                                              pumpname,
                                              hardwaremod.HW_FUNC_SCHEDTYPE)
            for todayevent in tabledrop[waterschemanumber - 1][weekday]:

                timelist = hardwaremod.separatetimestringint(todayevent[0])
                timelist[2] = timelist[2] + watertimedelaysec
                argument = []
                argument.append(pumpname)
                durationinseconds = hardwaremod.toint(todayevent[1],
                                                      0) * waterdropnumber
                argument.append(durationinseconds)
                for i in range(2, len(todayevent)):
                    argument.append(todayevent[i])
                if durationinseconds > 0:  #check if the duration in second is >0
                    setschedulercallback(calltype, timelist, argument,
                                         callback, pumpname)

    logger.info('Start other scheduler activities - doser')
    # info file dedicate call-back ------------------------------------------------ (pulsenutrient)

    callback = "doser"

    #fertilizer schedule table
    paramlist = fertilizerdbmod.getparamlist()  # name of the months ordered
    elementlist = fertilizerdbmod.getelementlist(
    )  # element with "fertilizercontrol field" ordered
    table = fertilizerdbmod.gettable(
        1
    )  # table, each row is a doser, each column is a month, value is number of times in a month
    table1 = fertilizerdbmod.gettable(
        0
    )  # table, each row is a doser, each column is a month, value is pulse seconds

    for dosernumber in range(len(elementlist)):
        #print "number =",dosernumber
        dosername = elementlist[dosernumber]
        calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, dosername,
                                          hardwaremod.HW_FUNC_SCHEDTYPE)
        todaydate = date.today()
        # Monday is 0 and Sunday is 6
        year = todaydate.year
        month = todaydate.month
        day = todaydate.day
        fertilizerpulsenumber = hardwaremod.toint(
            table[dosernumber][month - 1], 0)
        fertilizerpulsesecond = hardwaremod.toint(
            table1[dosernumber][month - 1], 0)
        if (fertilizerpulsenumber > 0) and (fertilizerpulsesecond > 0):
            themonthdays = 30  #approximate number of days in a month
            dayinterval = old_div(themonthdays, fertilizerpulsenumber)
            halfinterval = old_div((dayinterval + 1), 2)
            print("day=", day, " dayinterval=", dayinterval, " half=",
                  halfinterval)
            if ((day + int(halfinterval)) % int(dayinterval)) == 0:
                #timelist=hardwaremod.gettimedata("06:00:00")
                timelist = autofertilizermod.timelist(dosername)
                argument = []
                argument.append(dosername)
                argument.append(fertilizerpulsesecond)
                if (fertilizerpulsesecond
                    ) > 0:  #check if the duration in second is >0
                    setschedulercallback(calltype, timelist, argument,
                                         callback, dosername)

    logger.info('Start other scheduler activities - finish')
    return True
Exemple #9
0
def mastercallback():

    # clean old data of the database (pastdays)

    pastdays = 364
    sensordbmod.RemoveSensorDataPeriod(pastdays)
    actuatordbmod.RemoveActuatorDataPeriod(pastdays)
    hardwaremod.removephotodataperiod(364)

    # remove all jobs except masterscheduler
    for job in SchedulerMod.sched.get_jobs():
        if job.name != "master":
            try:
                job.remove()
            except:
                logger.error('Not able to remove Job %s', job.name)

    # set the individual callback of the day

    # info file dedicate call-back --------------------------------------------- (heartbeat)

    #this callback is used only for system status periodic check

    calltype = "periodic"
    global HEARTBEATINTERVAL
    interval = HEARTBEATINTERVAL
    timelist = [0, interval, 900]  # 900 indicates to start after 15 minutes
    callback = "heartbeat"
    argument = []

    setschedulercallback(calltype, timelist, argument, callback, callback)

    # info file dedicate call-back --------------------------------------------- (sensor)

    hwnamelist = sensordbmod.gettablelist()
    callback = "sensor"
    timeshift = 300
    shiftstep = 2  #seconds
    for hwname in hwnamelist:
        calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, hwname,
                                          hardwaremod.HW_FUNC_SCHEDTYPE)
        timelist = hardwaremod.gettimedata(hwname)
        timelist[2] = timelist[
            2] + timeshift  # avoid all the sensor thread to be called in the same time
        argument = []
        argument.append(hwname)
        setschedulercallback(calltype, timelist, argument, callback, hwname)
        timeshift = timeshift + shiftstep

    #<------>
    # info file dedicate quinto call-back ----------------------------------(takephoto)
    usedfor = "photocontrol"
    callback = "photo"
    hwnamelist = hardwaremod.searchdatalist(hardwaremod.HW_FUNC_USEDFOR,
                                            usedfor, hardwaremod.HW_INFO_NAME)
    for hwname in hwnamelist:
        calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, hwname,
                                          hardwaremod.HW_FUNC_SCHEDTYPE)
        timelist = hardwaremod.gettimedata(hwname)
        argument = []
        argument.append(hwname)
        setschedulercallback(calltype, timelist, argument, callback, hwname)

    # info ne file dedicate quarto call-back ---------------------------------------(sendmail)

    usedfor = "mailcontrol"
    callback = "mail"
    hwnamelist = hardwaremod.searchdatalist(hardwaremod.HW_FUNC_USEDFOR,
                                            usedfor, hardwaremod.HW_INFO_NAME)
    for hwname in hwnamelist:
        calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, hwname,
                                          hardwaremod.HW_FUNC_SCHEDTYPE)
        timelist = hardwaremod.gettimedata(hwname)
        argument = []
        argument.append(hwname)
        setschedulercallback(calltype, timelist, argument, callback, hwname)

    # info ne file dedicate quinto call-back ---------------------------------------(lightcheck)

    # empty
    #<---->

    # info file dedicate call-back ------------------------------------------------ (waterpump)

    callback = "waterpump"

    #water schedule table
    paramlist = wateringdbmod.getparamlist()  # name of the months ordered
    elementlist = wateringdbmod.getelementlist(
    )  # pump ordered (based on "watercontrol" field)
    table = wateringdbmod.gettable(
        1
    )  # table, each row is a pump, each column is a month, value is watering time multiplieer
    table1 = wateringdbmod.gettable(
        0
    )  # table, each row is a pump, each column is a month, value is watering scheme
    table2 = wateringdbmod.gettable(
        2
    )  # table, each row is a pump, each column is a month, value is time delay

    #print paramlist
    #print elementlistly
    #print table
    paramlistdrop = advancedmod.getparamlist()  # day of the week
    elementlistdrop = advancedmod.getelementlist()  # drops ordered
    tabledrop = advancedmod.gettable(
    )  # table, each row is a schema number (drop number), each column is a weekday

    for pumpnumber in range(len(elementlist)):
        #print "number =",pumpnumber
        pumpname = elementlist[pumpnumber]
        todaydate = date.today()
        # Monday is 0 and Sunday is 6
        weekday = todaydate.weekday()
        month = todaydate.month

        try:
            waterschemanumber = table1[pumpnumber][month - 1]
            waterdropnumber = hardwaremod.toint(table[pumpnumber][month - 1],
                                                0)
            watertimedelaysec = hardwaremod.toint(
                table2[pumpnumber][month - 1], 0)
        except IndexError:
            print "EXCEPTION: index out of range"
            waterdropnumber = 0
            watertimedelaysec = 0

        if waterdropnumber > 0:
            #print " month  " , month, " drop  " , waterdropnumber
            calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,
                                              pumpname,
                                              hardwaremod.HW_FUNC_SCHEDTYPE)
            for todayevent in tabledrop[waterschemanumber - 1][weekday]:

                timelist = hardwaremod.separatetimestringint(todayevent[0])
                timelist[2] = timelist[2] + watertimedelaysec
                argument = []
                argument.append(pumpname)
                durationinseconds = hardwaremod.toint(todayevent[1],
                                                      0) * waterdropnumber
                argument.append(durationinseconds)
                for i in range(2, len(todayevent)):
                    argument.append(todayevent[i])
                if durationinseconds > 0:  #check if the duration in second is >0
                    setschedulercallback(calltype, timelist, argument,
                                         callback, pumpname)

    # info file dedicate call-back ------------------------------------------------ (pulsenutrient)

    callback = "doser"

    #fertilizer schedule table
    paramlist = fertilizerdbmod.getparamlist()  # name of the months ordered
    elementlist = fertilizerdbmod.getelementlist(
    )  # element with "fertilizercontrol field" ordered
    table = fertilizerdbmod.gettable(
        1
    )  # table, each row is a doser, each column is a month, value is number of times in a month
    table1 = fertilizerdbmod.gettable(
        0
    )  # table, each row is a doser, each column is a month, value is pulse seconds

    for dosernumber in range(len(elementlist)):
        #print "number =",dosernumber
        dosername = elementlist[dosernumber]
        calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, dosername,
                                          hardwaremod.HW_FUNC_SCHEDTYPE)
        todaydate = date.today()
        # Monday is 0 and Sunday is 6
        year = todaydate.year
        month = todaydate.month
        day = todaydate.day
        fertilizerpulsenumber = hardwaremod.toint(
            table[dosernumber][month - 1], 0)
        fertilizerpulsesecond = hardwaremod.toint(
            table1[dosernumber][month - 1], 0)
        if (fertilizerpulsenumber > 0) and (fertilizerpulsesecond > 0):
            themonthdays = 30  #approximate number of days in a month
            dayinterval = themonthdays / fertilizerpulsenumber
            halfinterval = (dayinterval + 1) / 2
            print "day=", day, " dayinterval=", dayinterval, " half=", halfinterval
            if ((day + int(halfinterval)) % int(dayinterval)) == 0:
                timelist = hardwaremod.gettimedata("06:00:00")
                argument = []
                argument.append(dosername)
                argument.append(fertilizerpulsesecond)
                if (fertilizerpulsesecond
                    ) > 0:  #check if the duration in second is >0
                    setschedulercallback(calltype, timelist, argument,
                                         callback, dosername)
Exemple #10
0
def autowateringexecute(refsensor, element):
    global AUTO_data
    sensor = autowateringdbmod.searchdata("element", element, "sensor")
    # check the sensor
    if refsensor == sensor:
        print "auto watering check -----------------------------------------> ", element
        logger.info('auto watering check --------------------------> %s',
                    element)
        # check the watering mode
        modelist = ["None", "Full Auto", "Emergency Activation", "Alert Only"]
        workmode = checkworkmode(element)

        if not (sensor in sensordbmod.gettablelist()):
            print "Sensor does not exist ", sensor, ", element: ", element
            logger.error("Sensor does not exist %s , element: %s ", sensor,
                         element)
            return "sensor not Exist"

        maxthreshold = hardwaremod.tonumber(
            autowateringdbmod.searchdata("element", element, "threshold")[1],
            0)
        minthreshold = hardwaremod.tonumber(
            autowateringdbmod.searchdata("element", element, "threshold")[0],
            maxthreshold)
        # exit condition in case of data inconsistency
        if minthreshold >= maxthreshold:
            print "Data inconsistency , element: ", element
            logger.error("Data inconsistency , element: %s ", element)
            return "data inconsistency"

        now = datetime.now()
        nowtime = now.time()
        starttimeh = hardwaremod.toint(
            autowateringdbmod.searchdata("element", element,
                                         "allowedperiod")[0].split(":")[0], 0)
        starttimem = hardwaremod.toint(
            autowateringdbmod.searchdata("element", element,
                                         "allowedperiod")[0].split(":")[1], 0)
        endtimeh = hardwaremod.toint(
            autowateringdbmod.searchdata("element", element,
                                         "allowedperiod")[1].split(":")[0], 1)
        endtimem = hardwaremod.toint(
            autowateringdbmod.searchdata("element", element,
                                         "allowedperiod")[1].split(":")[1], 0)
        starttime = time(starttimeh, starttimem)
        endtime = time(endtimeh, endtimem)

        duration = 1000 * hardwaremod.toint(
            autowateringdbmod.searchdata("element", element, "wtstepsec"), 0)
        maxstepnumber = hardwaremod.toint(
            autowateringdbmod.searchdata("element", element, "maxstepnumber"),
            0)
        maxdays = hardwaremod.toint(
            autowateringdbmod.searchdata("element", element,
                                         "maxdaysbetweencycles"), 0)
        waitingtime = hardwaremod.toint(
            autowateringdbmod.searchdata("element", element,
                                         "pausebetweenwtstepsmin"), 0)
        mailtype = autowateringdbmod.searchdata("element", element,
                                                "mailalerttype")
        minaccepted = hardwaremod.tonumber(
            autowateringdbmod.searchdata("element", element,
                                         "sensorminacceptedvalue"), 0.1)

        # ------------------------ Workmode split
        if workmode == "Full Auto":
            # block the wateringplan activation as by definition of "Full Auto"
            allowwateringplan[element] = False
            # check if inside the allowed time period
            print "full Auto Mode"
            logger.info('full auto mode --> %s', element)
            timeok = isNowInTimePeriod(starttime, endtime, nowtime)
            print "inside allowed time ", timeok, " starttime ", starttime, " endtime ", endtime
            logger.info('full auto mode')
            if timeok:
                logger.info('inside allowed time')
                belowthr, valid = checkminthreshold(sensor, minthreshold,
                                                    minaccepted)
                if valid:
                    if belowthr:
                        status = "lowthreshold"
                        logger.info('below threshold')
                        # wait to seek a more stable reading of hygrometer
                        # check if time between watering events is larger that the waiting time (minutes)
                        lastwateringtime = statusdataDBmod.read_status_data(
                            AUTO_data, element, "lastwateringtime")
                        print ' Previous watering: ', lastwateringtime, ' Now: ', datetime.now(
                        )
                        timedifference = sensordbmod.timediffinminutes(
                            lastwateringtime, datetime.now())
                        print 'Time interval between watering steps', timedifference, '. threshold', waitingtime
                        logger.info(
                            'Time interval between watering steps %d threshold %d',
                            timedifference, waitingtime)
                        if timedifference > waitingtime:
                            print " Sufficient waiting time"
                            logger.info('Sufficient waiting time')
                            # activate watering in case the maxstepnumber is not exceeded
                            watercounter = statusdataDBmod.read_status_data(
                                AUTO_data, element, "watercounter")
                            if maxstepnumber > watercounter:
                                #activate pump
                                activatewater(element, duration)
                                # invia mail, considered as info, not as alert
                                if mailtype != "warningonly":
                                    textmessage = "INFO: " + sensor + " value below the minimum threshold " + str(
                                        minthreshold
                                    ) + ", activating the watering :" + element
                                    emailmod.sendallmail("alert", textmessage)
                                statusdataDBmod.write_status_data(
                                    AUTO_data, element, "watercounter",
                                    watercounter + 1)
                                statusdataDBmod.write_status_data(
                                    AUTO_data, element, "lastwateringtime",
                                    datetime.now())
                            else:  # critical, sensor below minimum after all watering activations are done

                                logger.info(
                                    'Number of watering time per cycle has been exceeeded'
                                )
                                # read hystory data and calculate the slope
                                timelist = hardwaremod.gettimedata(sensor)
                                cyclestartdate = statusdataDBmod.read_status_data(
                                    AUTO_data, element, "cyclestartdate")
                                lastwateringtime = statusdataDBmod.read_status_data(
                                    AUTO_data, element, "lastwateringtime")
                                startdate = cyclestartdate - timedelta(
                                    minutes=timelist[1])
                                enddate = lastwateringtime + timedelta(
                                    minutes=waitingtime)
                                isslopeok = checkinclination(
                                    sensor, startdate, enddate
                                )  # still to decide if use the enddate

                                if isslopeok:
                                    # invia mail if couner alert is lower than 1
                                    alertcounter = statusdataDBmod.read_status_data(
                                        AUTO_data, element, "alertcounter")
                                    if alertcounter < 1:
                                        textmessage = "WARNING: Please consider to increase the amount of water per cycle, the " + sensor + " value below the MINIMUM threshold " + str(
                                            minthreshold
                                        ) + " still after activating the watering :" + element + " for " + str(
                                            maxstepnumber
                                        ) + " times. System will automatically reset the watering cycle to allow more water"
                                        print textmessage
                                        #send alert mail notification
                                        emailmod.sendallmail(
                                            "alert", textmessage)
                                        logger.error(textmessage)
                                        statusdataDBmod.write_status_data(
                                            AUTO_data, element, "alertcounter",
                                            alertcounter + 1)

                                    # reset watering cycle
                                    status = "done"
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "watercounter", 0)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "checkcounter", -1)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "alertcounter", 0)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "cyclestartdate",
                                        datetime.now())

                                else:  # slope not OK, probable hardware problem
                                    alertcounter = statusdataDBmod.read_status_data(
                                        AUTO_data, element, "alertcounter")
                                    if alertcounter < 3:
                                        textmessage = "CRITICAL: Possible hardware problem, " + sensor + " value below the MINIMUM threshold " + str(
                                            minthreshold
                                        ) + " still after activating the watering :" + element + " for " + str(
                                            maxstepnumber) + " times"
                                        print textmessage
                                        #send alert mail notification
                                        emailmod.sendallmail(
                                            "alert", textmessage)
                                        logger.error(textmessage)
                                        statusdataDBmod.write_status_data(
                                            AUTO_data, element, "alertcounter",
                                            alertcounter + 1)

                        # update the status
                        checkcounter = statusdataDBmod.read_status_data(
                            AUTO_data, element, "checkcounter")
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "cyclestatus", status)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "checkcounter",
                            checkcounter + 1)

                    # RAMPUP case above threshold but below maxthreshold
                    elif sensorreading(
                            sensor
                    ) < maxthreshold:  # intermediate state where the sensor is above the minthreshold but lower than the max threshold
                        # check the status of the automatic cycle
                        cyclestatus = statusdataDBmod.read_status_data(
                            AUTO_data, element, "cyclestatus")
                        if cyclestatus != "done":
                            status = "rampup"
                            # wait to seek a more stable reading of hygrometer
                            # check if time between watering events is larger that the waiting time (minutes)
                            lastwateringtime = statusdataDBmod.read_status_data(
                                AUTO_data, element, "lastwateringtime")
                            if sensordbmod.timediffinminutes(
                                    lastwateringtime,
                                    datetime.now()) > waitingtime:
                                watercounter = statusdataDBmod.read_status_data(
                                    AUTO_data, element, "watercounter")
                                if maxstepnumber > watercounter:
                                    #activate pump
                                    activatewater(element, duration)
                                    # invia mail, considered as info, not as alert
                                    if mailtype != "warningonly":
                                        textmessage = "INFO: " + sensor + " value below the Maximum threshold " + str(
                                            maxthreshold
                                        ) + ", activating the watering :" + element
                                        emailmod.sendallmail(
                                            "alert", textmessage)

                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "watercounter",
                                        watercounter + 1)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "lastwateringtime",
                                        datetime.now())

                                else:
                                    # give up to reache the maximum threshold, proceed as done, send alert
                                    logger.info(
                                        'Number of watering time per cycle has been exceeeded'
                                    )

                                    # invia mail if couner alert is lower than 1 --------------
                                    # only if the info is activated
                                    if mailtype != "warningonly":
                                        alertcounter = statusdataDBmod.read_status_data(
                                            AUTO_data, element, "alertcounter")
                                        if alertcounter < 2:
                                            textmessage = "INFO " + sensor + " value below the Maximum threshold " + str(
                                                maxthreshold
                                            ) + " still after activating the watering :" + element + " for " + str(
                                                maxstepnumber) + " times"
                                            print textmessage
                                            #send alert mail notification
                                            emailmod.sendallmail(
                                                "alert", textmessage)
                                            logger.error(textmessage)
                                            statusdataDBmod.write_status_data(
                                                AUTO_data, element,
                                                "alertcounter",
                                                alertcounter + 1)

                                    # reset watering cycle
                                    status = "done"
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "watercounter", 0)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "checkcounter", -1)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "alertcounter", 0)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "cyclestartdate",
                                        datetime.now())

                            # update the status
                            checkcounter = statusdataDBmod.read_status_data(
                                AUTO_data, element, "checkcounter")
                            statusdataDBmod.write_status_data(
                                AUTO_data, element, "cyclestatus", status)
                            statusdataDBmod.write_status_data(
                                AUTO_data, element, "checkcounter",
                                checkcounter + 1)

                    else:
                        # update the status, reset cycle
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "cyclestatus", "done")
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "checkcounter", 0)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "watercounter", 0)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "alertcounter", 0)

        elif workmode == "Emergency Activation":
            # check if inside the allow time period
            logger.info('Emergency Mode')
            timeok = isNowInTimePeriod(starttime, endtime, nowtime)
            print "inside allowed time ", timeok, " starttime ", starttime, " endtime ", endtime
            if timeok:
                belowthr, valid = checkminthreshold(sensor, minthreshold,
                                                    minaccepted)
                if valid:
                    if belowthr:
                        # wait to seek a more stable reading of hygrometer
                        # check if time between watering events is larger that the waiting time (minutes)

                        lastwateringtime = statusdataDBmod.read_status_data(
                            AUTO_data, element, "lastwateringtime")
                        if sensordbmod.timediffinminutes(
                                lastwateringtime,
                                datetime.now()) > waitingtime:
                            # activate watering in case the maxstepnumber is not exceeded
                            watercounter = statusdataDBmod.read_status_data(
                                AUTO_data, element, "watercounter")
                            if maxstepnumber > watercounter:
                                #activate pump
                                activatewater(element, duration)
                                # invia mail, considered as info, not as alert
                                if mailtype != "warningonly":
                                    textmessage = "INFO: " + sensor + " value below the minimum threshold " + str(
                                        minthreshold
                                    ) + ", activating the watering :" + element
                                    emailmod.sendallmail("alert", textmessage)

                                statusdataDBmod.write_status_data(
                                    AUTO_data, element, "watercounter",
                                    watercounter + 1)
                                statusdataDBmod.write_status_data(
                                    AUTO_data, element, "lastwateringtime",
                                    datetime.now())

                            else:

                                logger.info(
                                    'Number of watering time per cycle has been exceeeded'
                                )
                                # read hystory data and calculate the slope
                                timelist = hardwaremod.gettimedata(sensor)
                                cyclestartdate = statusdataDBmod.read_status_data(
                                    AUTO_data, element, "cyclestartdate")
                                lastwateringtime = statusdataDBmod.read_status_data(
                                    AUTO_data, element, "lastwateringtime")
                                startdate = cyclestartdate - timedelta(
                                    minutes=timelist[1])
                                enddate = lastwateringtime + timedelta(
                                    minutes=waitingtime)
                                isslopeok = checkinclination(
                                    sensor, startdate, enddate)

                                if isslopeok:
                                    # invia mail if couner alert is lower than 1
                                    alertcounter = statusdataDBmod.read_status_data(
                                        AUTO_data, element, "alertcounter")
                                    if alertcounter < 1:
                                        textmessage = "WARNING: Please consider to increase the amount of water per cycle, the " + sensor + " value below the MINIMUM threshold " + str(
                                            minthreshold
                                        ) + " still after activating the watering :" + element + " for " + str(
                                            maxstepnumber
                                        ) + " times. System will automatically reset the watering cycle to allow more water"
                                        print textmessage
                                        #send alert mail notification alertcounter
                                        emailmod.sendallmail(
                                            "alert", textmessage)
                                        logger.error(textmessage)
                                        statusdataDBmod.write_status_data(
                                            AUTO_data, element, "alertcounter",
                                            alertcounter + 1)

                                    # reset watering cycle
                                    status = "done"
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "watercounter", 0)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "checkcounter", -1)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "alertcounter", 0)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "cyclestartdate",
                                        datetime.now())

                                else:  # slope not OK, probable hardware problem
                                    alertcounter = statusdataDBmod.read_status_data(
                                        AUTO_data, element, "alertcounter")
                                    if alertcounter < 3:
                                        textmessage = "CRITICAL: Possible hardware problem, " + sensor + " value below the MINIMUM threshold " + str(
                                            minthreshold
                                        ) + " still after activating the watering :" + element + " for " + str(
                                            maxstepnumber) + " times"
                                        print textmessage
                                        #send alert mail notification
                                        emailmod.sendallmail(
                                            "alert", textmessage)
                                        logger.error(textmessage)
                                        statusdataDBmod.write_status_data(
                                            AUTO_data, element, "alertcounter",
                                            alertcounter + 1)

                        # update the status
                        checkcounter = statusdataDBmod.read_status_data(
                            AUTO_data, element, "checkcounter")
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "cyclestatus", "lowthreshold")
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "checkcounter",
                            checkcounter + 1)
                    else:
                        # update the status
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "cyclestatus", "done")
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "checkcounter", 0)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "watercounter", 0)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "alertcounter", 0)

        elif workmode == "under MIN over MAX":
            logger.info('under MIN over MAX')
            # normally watering plan is allowed unless over MAX threshold
            allowwateringplan[element] = True
            # check if inside the allow time period
            timeok = isNowInTimePeriod(starttime, endtime, nowtime)
            print "inside allowed time ", timeok, " starttime ", starttime, " endtime ", endtime
            if timeok:
                logger.info('Insede operative time')
                belowthr, valid = checkminthreshold(sensor, minthreshold,
                                                    minaccepted)
                if valid:
                    logger.info('valid sensor reading')
                    if belowthr:
                        logger.info('sensor reading below threshold')
                        # wait to seek a more stable reading of hygrometer
                        # check if time between watering events is larger that the waiting time (minutes)

                        lastwateringtime = statusdataDBmod.read_status_data(
                            AUTO_data, element, "lastwateringtime")
                        if sensordbmod.timediffinminutes(
                                lastwateringtime,
                                datetime.now()) > waitingtime:
                            # activate watering in case the maxstepnumber is not exceeded
                            watercounter = statusdataDBmod.read_status_data(
                                AUTO_data, element, "watercounter")
                            if maxstepnumber > watercounter:
                                logger.info('water Count not exceeded')
                                #activate pump
                                activatewater(element, duration)
                                # invia mail, considered as info, not as alert
                                if mailtype != "warningonly":
                                    textmessage = "INFO: " + sensor + " value below the minimum threshold " + str(
                                        minthreshold
                                    ) + ", activating the watering :" + element
                                    emailmod.sendallmail("alert", textmessage)
                                statusdataDBmod.write_status_data(
                                    AUTO_data, element, "watercounter",
                                    watercounter + 1)
                                statusdataDBmod.write_status_data(
                                    AUTO_data, element, "lastwateringtime",
                                    datetime.now())

                            else:

                                logger.info(
                                    'Number of watering time per cycle has been exceeeded'
                                )
                                # read hystory data and calculate the slope
                                timelist = hardwaremod.gettimedata(sensor)

                                cyclestartdate = statusdataDBmod.read_status_data(
                                    AUTO_data, element, "cyclestartdate")
                                lastwateringtime = statusdataDBmod.read_status_data(
                                    AUTO_data, element, "lastwateringtime")
                                startdate = cyclestartdate - timedelta(
                                    minutes=timelist[1])
                                enddate = lastwateringtime + timedelta(
                                    minutes=waitingtime)
                                isslopeok = checkinclination(
                                    sensor, startdate, enddate)

                                if isslopeok:
                                    # invia mail if couner alert is lower than 1
                                    alertcounter = statusdataDBmod.read_status_data(
                                        AUTO_data, element, "alertcounter")
                                    if alertcounter < 1:
                                        textmessage = "WARNING: Please consider to increase the amount of water per cycle, the " + sensor + " value below the MINIMUM threshold " + str(
                                            minthreshold
                                        ) + " still after activating the watering :" + element + " for " + str(
                                            maxstepnumber
                                        ) + " times. System will automatically reset the watering cycle to allow more water"
                                        print textmessage
                                        #send alert mail notification
                                        emailmod.sendallmail(
                                            "alert", textmessage)
                                        logger.error(textmessage)
                                        statusdataDBmod.write_status_data(
                                            AUTO_data, element, "alertcounter",
                                            alertcounter + 1)

                                    # reset watering cycle
                                    status = "done"
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "watercounter", 0)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "checkcounter", -1)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "alertcounter", 0)
                                    statusdataDBmod.write_status_data(
                                        AUTO_data, element, "cyclestartdate",
                                        datetime.now())

                                else:  # slope not OK, probable hardware problem
                                    alertcounter = statusdataDBmod.read_status_data(
                                        AUTO_data, element, "alertcounter")
                                    if alertcounter < 3:
                                        textmessage = "CRITICAL: Possible hardware problem, " + sensor + " value below the MINIMUM threshold " + str(
                                            minthreshold
                                        ) + " still after activating the watering :" + element + " for " + str(
                                            maxstepnumber) + " times"
                                        print textmessage
                                        #send alert mail notification
                                        emailmod.sendallmail(
                                            "alert", textmessage)
                                        logger.error(textmessage)
                                        statusdataDBmod.write_status_data(
                                            AUTO_data, element, "alertcounter",
                                            alertcounter + 1)

                        # update the status
                        checkcounter = statusdataDBmod.read_status_data(
                            AUTO_data, element, "checkcounter")
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "cyclestatus", "lowthreshold")
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "checkcounter",
                            checkcounter + 1)

                    else:  # above minimum threshold
                        logger.info('sensor reading above min threshold')
                        # update the status
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "cyclestatus", "done")
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "checkcounter", 0)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "watercounter", 0)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "alertcounter", 0)

                        if sensorreading(sensor) > maxthreshold:
                            logger.info(
                                'sensor reading above MAX threshold, deactivate scheduled irrigation'
                            )
                            # do not activate the irrigation scheduled in the time plan
                            allowwateringplan[element] = False

        elif workmode == "Alert Only":
            belowthr, valid = checkminthreshold(sensor, minthreshold,
                                                minaccepted)
            if valid:
                if belowthr:
                    # invia mail if couter alert is lower than
                    alertcounter = statusdataDBmod.read_status_data(
                        AUTO_data, element, "alertcounter")
                    if alertcounter < 2:
                        textmessage = "WARNING " + sensor + " value below the minimum threshold " + str(
                            minthreshold) + " watering system: " + element
                        print textmessage
                        #send alert mail notification
                        emailmod.sendallmail("alert", textmessage)
                        logger.error(textmessage)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "alertcounter",
                            alertcounter + 1)
                    # update the status
                    checkcounter = statusdataDBmod.read_status_data(
                        AUTO_data, element, "checkcounter")
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "cyclestatus",
                                                      "lowthreshold")
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "checkcounter",
                                                      checkcounter + 1)
                else:
                    # update the status
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "cyclestatus", "done")
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "checkcounter", 0)
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "watercounter", 0)
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "alertcounter", 0)

        else:  # None case
            print "No Action required, workmode set to None, element: ", element
            logger.info(
                "No Action required, workmode set to None, element: %s ",
                element)

        cyclestatus = statusdataDBmod.read_status_data(AUTO_data, element,
                                                       "cyclestatus")
        if cyclestatus == "lowthreshold":
            checkcounter = statusdataDBmod.read_status_data(
                AUTO_data, element, "checkcounter")
            if checkcounter == 1:
                statusdataDBmod.write_status_data(AUTO_data, element,
                                                  "cyclestartdate",
                                                  datetime.now())

        # implment alert message for the cycle exceeding days, and reset the cycle
        if workmode != "None":
            cyclestartdate = statusdataDBmod.read_status_data(
                AUTO_data, element, "cyclestartdate")
            timedeltadays = sensordbmod.timediffdays(datetime.now(),
                                                     cyclestartdate)
            if (timedeltadays > maxdays
                ):  #the upper limit is set in case of abrupt time change
                textmessage = "WARNING " + sensor + " watering cycle is taking too many days, watering system: " + element + ". Reset watering cycle"
                print textmessage
                # in case of full Auto, activate pump for minimum pulse period
                if workmode == "Full Auto":
                    if (
                            timedeltadays < maxdays + 2
                    ):  #the upper limit is set in case of abrupt time change
                        textmessage = "WARNING " + sensor + " watering cycle is taking too many days, watering system: " + element + ". Activate Min pulse + Reset watering cycle"
                        activatewater(element, duration)
                #send alert mail notification
                if mailtype != "warningonly":
                    emailmod.sendallmail("alert", textmessage)
                logger.error(textmessage)
                logger.error("Cycle started %s, Now is %s ",
                             cyclestartdate.strftime("%Y-%m-%d %H:%M:%S"),
                             datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
                # reset cycle
                statusdataDBmod.write_status_data(AUTO_data, element,
                                                  "cyclestatus", "done")
                statusdataDBmod.write_status_data(AUTO_data, element,
                                                  "checkcounter", 0)
                statusdataDBmod.write_status_data(AUTO_data, element,
                                                  "watercounter", 0)
                statusdataDBmod.write_status_data(AUTO_data, element,
                                                  "alertcounter", 0)
                statusdataDBmod.write_status_data(AUTO_data, element,
                                                  "cyclestartdate",
                                                  datetime.now())

        # implment Critical alert message in case the threshold is below the 0.5 of the minimum
        if workmode != "None":
            belowthr, valid = checkminthreshold(sensor, minthreshold * 0.5,
                                                minaccepted)
            if valid:
                if belowthr:
                    logger.info(
                        'sensor %s below half of the actual set threshold',
                        sensor)
                    textmessage = "CRITICAL: Plant is dying, " + sensor + " reading below half of the minimum threshold, need to check the " + element
                    print textmessage
                    #send alert mail notification
                    alertcounter = statusdataDBmod.read_status_data(
                        AUTO_data, element, "alertcounter")
                    if alertcounter < 5:
                        emailmod.sendallmail("alert", textmessage)
                        logger.error(textmessage)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "alertcounter",
                            alertcounter + 1)
            else:
                logger.info('sensor %s below valid data', sensor)
                textmessage = "WARNING: " + sensor + " below valid data range, need to check sensor"
                print textmessage
                #send alert mail notification
                alertcounter = statusdataDBmod.read_status_data(
                    AUTO_data, element, "alertcounter")
                if alertcounter < 3:
                    emailmod.sendallmail("alert", textmessage)
                    logger.error(textmessage)
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "alertcounter",
                                                      alertcounter + 1)
    return
Exemple #11
0
def mastercallback():
	
	# clean old data of the database (pastdays)
	logger.info('Remove data in exceed of one year')

	
	pastdays=364
	#sensordbmod.RemoveSensorDataPeriod(pastdays)
	logger.info('Sensor Remove data in exceed of one year')	
	#actuatordbmod.RemoveActuatorDataPeriod(pastdays)
	logger.info('Actuator Remove data in exceed of one year')
	#hardwaremod.removephotodataperiod(364)
	logger.info('Photo Remove data in exceed of one year')

	logger.info('Start other scheduler activities')
	
	# remove all jobs except masterscheduler
	#for job in SchedulerMod.sched.get_jobs():
	#	if job.name != "master":
	#		try:
	#			job.remove()	
	#		except:
	#			logger.error('Not able to remove Job %s', job.name)

	# set the individual callback of the day
	
	# info file dedicate call-back --------------------------------------------- (heartbeat)	
	
	#this callback is used only for system status periodic check 
	
	calltype="periodic"
	global HEARTBEATINTERVAL
	interval=HEARTBEATINTERVAL
	timelist=[0,interval,900] # 900 indicates to start after 15 minutes
	callback="heartbeat"
	argument=[]
	
	setschedulercallback(calltype,timelist,argument,callback,callback)
	
	logger.info('Start other scheduler activities - sensor')
	
	# info file dedicate call-back --------------------------------------------- (sensor)
	
	hwnamelist=sensordbmod.gettablelist()
	callback="sensor"
	timeshift=300
	shiftstep=5 #seconds	
	# IMPORTANT
	# the shiftstep is necessary to avoid thread collision which brings to sqlite3 db failure "database is locked" 
	# this number is giving a limit to the sensor reading that should be higher than 1min
	for hwname in hwnamelist:
		calltype=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,hwname,hardwaremod.HW_FUNC_SCHEDTYPE)
		timelist=hardwaremod.gettimedata(hwname)
		timelist[2]=timeshift # avoid all the sensor thread to be called in the same time
		argument=[]
		argument.append(hwname)
		setschedulercallback(calltype,timelist,argument,callback,hwname)
		timeshift=timeshift+shiftstep

	logger.info('Start other scheduler activities - photo')

	#<------>
	# info file dedicate quinto call-back ----------------------------------(takephoto)
	usedfor="photocontrol"
	callback="photo"	
	hwnamelist=hardwaremod.searchdatalist(hardwaremod.HW_FUNC_USEDFOR,usedfor,hardwaremod.HW_INFO_NAME)
	for hwname in hwnamelist:
		calltype=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,hwname,hardwaremod.HW_FUNC_SCHEDTYPE)
		timelist=hardwaremod.gettimedata(hwname)
		argument=[]
		argument.append(hwname)
		setschedulercallback(calltype,timelist,argument,callback,hwname)

	logger.info('Start other scheduler activities - mail')

	# info ne file dedicate quarto call-back ---------------------------------------(sendmail)
	
	usedfor="mailcontrol"
	callback="mail"	
	hwnamelist=hardwaremod.searchdatalist(hardwaremod.HW_FUNC_USEDFOR,usedfor,hardwaremod.HW_INFO_NAME)
	for hwname in hwnamelist:
		calltype=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,hwname,hardwaremod.HW_FUNC_SCHEDTYPE)
		timelist=hardwaremod.gettimedata(hwname)
		argument=[]
		argument.append(hwname)
		setschedulercallback(calltype,timelist,argument,callback,hwname)



	# info ne file dedicate quinto call-back ---------------------------------------(lightcheck)

	# empty
	#<---->
	
	logger.info('Start other scheduler activities - pump')
	
	# info file dedicate call-back ------------------------------------------------ (waterpump)
	

	callback="waterpump"
	
	#water schedule table
	paramlist= wateringdbmod.getparamlist()  # name of the months ordered
	elementlist= wateringdbmod.getelementlist()  # pump ordered (based on "watercontrol" field)
	table=wateringdbmod.gettable(1)# table, each row is a pump, each column is a month, value is watering time multiplieer
	table1=wateringdbmod.gettable(0)# table, each row is a pump, each column is a month, value is watering scheme
	table2=wateringdbmod.gettable(2)# table, each row is a pump, each column is a month, value is time delay 	
	
	#print paramlist
	#print elementlistly
	#print table
	paramlistdrop= advancedmod.getparamlist() # day of the week
	elementlistdrop= advancedmod.getelementlist() # drops ordered
	tabledrop=advancedmod.gettable() # table, each row is a schema number (drop number), each column is a weekday

	for pumpnumber in range(len(elementlist)):
		#print "number =",pumpnumber
		pumpname=elementlist[pumpnumber]
		todaydate = date.today()
		# Monday is 0 and Sunday is 6
		weekday = todaydate.weekday()
		month = todaydate.month	
		
		try:					
			waterschemanumber=table1[pumpnumber][month-1]
			waterdropnumber=hardwaremod.toint(table[pumpnumber][month-1],0)
			watertimedelaysec=hardwaremod.toint(table2[pumpnumber][month-1],0)
		except IndexError:
			print "EXCEPTION: index out of range" 		
			waterdropnumber=0
			watertimedelaysec=0		
		
		if waterdropnumber>0:			
			#print " month  " , month, " drop  " , waterdropnumber
			calltype=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,pumpname,hardwaremod.HW_FUNC_SCHEDTYPE)
			for todayevent in tabledrop[waterschemanumber-1][weekday]:
				
				timelist=hardwaremod.separatetimestringint(todayevent[0])
				timelist[2]=timelist[2]+watertimedelaysec
				argument=[]
				argument.append(pumpname)
				durationinseconds=hardwaremod.toint(todayevent[1],0)*waterdropnumber
				argument.append(durationinseconds)				
				for i in range(2,len(todayevent)):
						argument.append(todayevent[i])
				if durationinseconds>0: #check if the duration in second is >0
					setschedulercallback(calltype,timelist,argument,callback,pumpname)


	logger.info('Start other scheduler activities - doser')
	# info file dedicate call-back ------------------------------------------------ (pulsenutrient)
	

	callback="doser"

	
	#fertilizer schedule table
	paramlist= fertilizerdbmod.getparamlist()  # name of the months ordered
	elementlist= fertilizerdbmod.getelementlist()  # element with "fertilizercontrol field" ordered 
	table=fertilizerdbmod.gettable(1)# table, each row is a doser, each column is a month, value is number of times in a month	
	table1=fertilizerdbmod.gettable(0)# table, each row is a doser, each column is a month, value is pulse seconds	

	for dosernumber in range(len(elementlist)):
		#print "number =",dosernumber
		dosername=elementlist[dosernumber]
		calltype=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,dosername,hardwaremod.HW_FUNC_SCHEDTYPE)
		todaydate = date.today()
		# Monday is 0 and Sunday is 6
		year = todaydate.year
		month = todaydate.month	
		day = todaydate.day
		fertilizerpulsenumber=hardwaremod.toint(table[dosernumber][month-1],0)
		fertilizerpulsesecond=hardwaremod.toint(table1[dosernumber][month-1],0)
		if (fertilizerpulsenumber>0) and (fertilizerpulsesecond>0):			
			themonthdays=30 #approximate number of days in a month
			dayinterval=themonthdays/fertilizerpulsenumber
			halfinterval=(dayinterval+1)/2
			print "day=" , day , " dayinterval=", dayinterval, " half=", halfinterval		
			if ((day+int(halfinterval)) % int(dayinterval)) == 0:				
				#timelist=hardwaremod.gettimedata("06:00:00")
				timelist=autofertilizermod.timelist(dosername)
				argument=[]
				argument.append(dosername)
				argument.append(fertilizerpulsesecond)
				if (fertilizerpulsesecond)>0: #check if the duration in second is >0
					setschedulercallback(calltype,timelist,argument,callback,dosername)
					
	logger.info('Start other scheduler activities - finish')
	return True
Exemple #12
0
def getsensordbdatadaysV2(selsensor, sensordata, startdate,
                          enddate):  # V2 try to optimize access to database
    fieldlist = []
    fieldlist.append(TIMEFIELD)
    fieldlist.append(DATAFIELD)
    #sampletime=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,selsensor,hardwaremod.HW_FUNC_TIME)

    timelist = hardwaremod.gettimedata(
        selsensor)  # return list of int [0] sec, [1] min, [2] hours
    samplingintervalminutes = timelist[0] * 60 + timelist[1]

    schedtype = hardwaremod.searchdata(
        hardwaremod.HW_INFO_NAME, selsensor, hardwaremod.HW_FUNC_SCHEDTYPE
    )  # ["oneshot", "periodic"] #scheduling type
    #samplingintervalminutes=hardwaremod.toint(sampletime.split(":")[1],0)	# return zero in case of problems
    if (samplingintervalminutes >= 1) and (schedtype == "periodic"):

        #minutessperiod=((enddate-startdate).total_seconds()+1 ) // 60
        minutessperiod = ((datetime.now() - startdate).total_seconds() +
                          1) // 60  # sub optima approach
        # in this case we know the number of samples per day, so we query only the last samples of the database, this makes query way faster
        samplesnumber = minutessperiod // samplingintervalminutes
        # WARNING: with offset, there is an issue, every day the system loose some saple at midnight rescheduling only if the sample interval is less than 5 min.
        # in case of holes in the data sampling, it also provides wrong offset. Decided to use the non optimal approach
        offset = 0
        #lastdata=databasemod.returnrowdatafromfieldslimitV2(DBFILENAME,selsensor,fieldlist,1,0)
        #if lastdata:
        #	dateref=datetime.strptime(lastdata[0][0].split(".")[0],'%Y-%m-%d %H:%M:%S')
        #	print( " dataref ", dateref , " enddate ", enddate)
        #	if dateref>enddate:
        #		minutessoffset=int( (dateref-enddate).total_seconds() / 60)
        #		dayssoffset=minutessoffset//(24*60)
        #		print ("dayssoffset", dayssoffset , " minutessoffset ", minutessoffset)
        #		offset=int(minutessoffset/samplingintervalminutes) - (dayssoffset*10) # assume to loose max 10 samples per day
        #		samplesnumber=samplesnumber+ 2 * (dayssoffset*10) # allunga il periodo di samples
        #		offset=max(offset,0)
        #		print ("Defined samplesnumber ", samplesnumber , " offset ", offset)
        print(selsensor, " Get Database Data : samplesnumber ", samplesnumber,
              " offset ", offset, " Type ", schedtype,
              "samplingintervalminutes ", samplingintervalminutes)
        rowdata = databasemod.returnrowdatafromfieldslimitV2(
            DBFILENAME, selsensor, fieldlist, samplesnumber, offset)
        #print( " rowdata ", rowdata)
    else:
        # no info about number of samples per day try with a number
        samplingintervalminutes = 5  # assumption
        #samplesnumber=int(days*24*60/samplingintervalminutes)
        samplesnumber = 1000
        offset = 0
        lastitem = 2
        dateref = enddate
        rowdata = []
        while (dateref > startdate) and (lastitem > 0):
            print(selsensor, " Get Database Data : samplesnumber ",
                  samplesnumber, " offset ", offset)
            partrowdata = databasemod.returnrowdatafromfieldslimitV2(
                DBFILENAME, selsensor, fieldlist, samplesnumber, offset)
            lastitem = len(partrowdata)
            if lastitem >= samplesnumber:
                offset = offset + lastitem
                dateref = datetime.strptime(
                    partrowdata[lastitem - 1][0].split(".")[0],
                    '%Y-%m-%d %H:%M:%S')
            else:
                lastitem = 0
            #print( " dataref ", dateref)
            #print( " rowdata ", rowdata)
            print(selsensor, " Get Database Data : dateref ", dateref,
                  " DB part lenght ", lastitem)
            rowdata.extend(partrowdata)
        # check the last value of the returned array

    # return only the data in right datetime interval and in list form (instead of tuple)
    for data in rowdata:
        try:
            dateref = datetime.strptime(data[0].split(".")[0],
                                        '%Y-%m-%d %H:%M:%S')
            if (dateref >= startdate) and (dateref <= enddate):
                value = float(data[1])
                templist = [data[0], value]
                sensordata.append(templist)

        except:
            print("Error in database reading ")
Exemple #13
0
def autowateringexecute(refsensor,element):	
	global AUTO_data
	sensor=autowateringdbmod.searchdata("element",element,"sensor")	
	# check the sensor
	if refsensor==sensor:	
		print "auto watering check -----------------------------------------> ", element
		logger.info('auto watering check --------------------------> %s', element)
		# check the watering mode
		modelist=["None", "Full Auto" , "Emergency Activation" , "Alert Only"]
		workmode=checkworkmode(element)

		if not(sensor in sensordbmod.gettablelist()):
			print "Sensor does not exist " ,sensor , ", element: " , element
			logger.error("Sensor does not exist %s , element: %s " ,sensor, element)			
			return "sensor not Exist"
		
		maxthreshold=hardwaremod.tonumber(autowateringdbmod.searchdata("element",element,"threshold")[1],0)
		minthreshold=hardwaremod.tonumber(autowateringdbmod.searchdata("element",element,"threshold")[0],maxthreshold)
		# exit condition in case of data inconsistency
		if minthreshold>=maxthreshold:
			print "Data inconsistency , element: " , element
			logger.error("Data inconsistency , element: %s " , element)
			return "data inconsistency"
		
		now = datetime.now()
		nowtime = now.time()
		starttimeh=hardwaremod.toint(autowateringdbmod.searchdata("element",element,"allowedperiod")[0].split(":")[0],0)
		starttimem=hardwaremod.toint(autowateringdbmod.searchdata("element",element,"allowedperiod")[0].split(":")[1],0)
		endtimeh=hardwaremod.toint(autowateringdbmod.searchdata("element",element,"allowedperiod")[1].split(":")[0],1)
		endtimem=hardwaremod.toint(autowateringdbmod.searchdata("element",element,"allowedperiod")[1].split(":")[1],0)
		starttime=time(starttimeh,starttimem)
		endtime=time(endtimeh,endtimem)		
		
		duration=1000*hardwaremod.toint(autowateringdbmod.searchdata("element",element,"wtstepsec"),0)
		maxstepnumber=hardwaremod.toint(autowateringdbmod.searchdata("element",element,"maxstepnumber"),0)
		maxdays=hardwaremod.toint(autowateringdbmod.searchdata("element",element,"maxdaysbetweencycles"),0)
		waitingtime=hardwaremod.toint(autowateringdbmod.searchdata("element",element,"pausebetweenwtstepsmin"),0)
		mailtype=autowateringdbmod.searchdata("element",element,"mailalerttype")
		minaccepted=hardwaremod.tonumber(autowateringdbmod.searchdata("element",element,"sensorminacceptedvalue"),0.1)
		
		# ------------------------ Workmode split
		if workmode=="Full Auto":
			# block the wateringplan activation as by definition of "Full Auto"
			allowwateringplan[element]=False
			# check if inside the allowed time period
			print "full Auto Mode"
			logger.info('full auto mode --> %s', element)
			timeok=isNowInTimePeriod(starttime, endtime, nowtime)
			print "inside allowed time ", timeok , " starttime ", starttime , " endtime ", endtime
			logger.info('full auto mode')
			if timeok:
				logger.info('inside allowed time')
				belowthr,valid=checkminthreshold(sensor,minthreshold,minaccepted)
				if valid:
					if belowthr:
						status="lowthreshold"
						logger.info('below threshold')
						# wait to seek a more stable reading of hygrometer
						# check if time between watering events is larger that the waiting time (minutes)
						lastwateringtime=statusdataDBmod.read_status_data(AUTO_data,element,"lastwateringtime")
						print ' Previous watering: ' , lastwateringtime , ' Now: ', datetime.now()
						timedifference=sensordbmod.timediffinminutes(lastwateringtime,datetime.now())
						print 'Time interval between watering steps', timedifference ,'. threshold', waitingtime
						logger.info('Time interval between watering steps %d threshold %d', timedifference,waitingtime)		
						if timedifference>waitingtime:
							print " Sufficient waiting time"
							logger.info('Sufficient waiting time')	
							# activate watering in case the maxstepnumber is not exceeded	
							watercounter=statusdataDBmod.read_status_data(AUTO_data,element,"watercounter")				
							if maxstepnumber>watercounter:
								#activate pump		
								activatewater(element, duration)
								# invia mail, considered as info, not as alert
								if mailtype!="warningonly":
									textmessage="INFO: " + sensor + " value below the minimum threshold " + str(minthreshold) + ", activating the watering :" + element
									emailmod.sendallmail("alert", textmessage)
								statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",watercounter+1)
								statusdataDBmod.write_status_data(AUTO_data,element,"lastwateringtime",datetime.now())								
							else: # critical, sensor below minimum after all watering activations are done

								logger.info('Number of watering time per cycle has been exceeeded')
								# read hystory data and calculate the slope
								timelist=hardwaremod.gettimedata(sensor)
								cyclestartdate=statusdataDBmod.read_status_data(AUTO_data,element,"cyclestartdate")	
								lastwateringtime=statusdataDBmod.read_status_data(AUTO_data,element,"lastwateringtime")
								startdate=cyclestartdate - timedelta(minutes=timelist[1])
								enddate=lastwateringtime + timedelta(minutes=waitingtime)
								isslopeok=checkinclination(sensor,startdate,enddate) # still to decide if use the enddate 
								
								if isslopeok:
									# invia mail if couner alert is lower than 1
									alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
									if alertcounter<1:
										textmessage="WARNING: Please consider to increase the amount of water per cycle, the "+ sensor + " value below the MINIMUM threshold " + str(minthreshold) + " still after activating the watering :" + element + " for " + str(maxstepnumber) + " times. System will automatically reset the watering cycle to allow more water"
										print textmessage
										#send alert mail notification
										emailmod.sendallmail("alert", textmessage)							
										logger.error(textmessage)
										statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)
										
									# reset watering cycle
									status="done"
									statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",0)
									statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",-1)
									statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",0)
									statusdataDBmod.write_status_data(AUTO_data,element,"cyclestartdate",datetime.now())
																			
								else: # slope not OK, probable hardware problem
									alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
									if alertcounter<3:
										textmessage="CRITICAL: Possible hardware problem, "+ sensor + " value below the MINIMUM threshold " + str(minthreshold) + " still after activating the watering :" + element + " for " + str(maxstepnumber) + " times"
										print textmessage
										#send alert mail notification
										emailmod.sendallmail("alert", textmessage)							
										logger.error(textmessage)										
										statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)
									
											
						# update the status
						checkcounter=statusdataDBmod.read_status_data(AUTO_data,element,"checkcounter")
						statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus",status)
						statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",checkcounter+1)
						
					# RAMPUP case above threshold but below maxthreshold
					elif sensorreading(sensor)<maxthreshold: # intermediate state where the sensor is above the minthreshold but lower than the max threshold
						# check the status of the automatic cycle
						cyclestatus=statusdataDBmod.read_status_data(AUTO_data,element,"cyclestatus")
						if cyclestatus!="done":
							status="rampup"							
							# wait to seek a more stable reading of hygrometer
							# check if time between watering events is larger that the waiting time (minutes)
							lastwateringtime=statusdataDBmod.read_status_data(AUTO_data,element,"lastwateringtime")			
							if sensordbmod.timediffinminutes(lastwateringtime,datetime.now())>waitingtime:
								watercounter=statusdataDBmod.read_status_data(AUTO_data,element,"watercounter")
								if maxstepnumber>watercounter:
									#activate pump		
									activatewater(element, duration)
									# invia mail, considered as info, not as alert
									if mailtype!="warningonly":
										textmessage="INFO: " + sensor + " value below the Maximum threshold " + str(maxthreshold) + ", activating the watering :" + element
										emailmod.sendallmail("alert", textmessage)
										
									statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",watercounter+1)
									statusdataDBmod.write_status_data(AUTO_data,element,"lastwateringtime",datetime.now())										

								else:
									# give up to reache the maximum threshold, proceed as done, send alert
									logger.info('Number of watering time per cycle has been exceeeded')
									
									# invia mail if couner alert is lower than 1 --------------
									# only if the info is activated
									if mailtype!="warningonly":
										alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")	
										if alertcounter<2:
											textmessage="INFO "+ sensor + " value below the Maximum threshold " + str(maxthreshold) + " still after activating the watering :" + element + " for " + str(maxstepnumber) + " times"
											print textmessage
											#send alert mail notification
											emailmod.sendallmail("alert", textmessage)							
											logger.error(textmessage)	
											statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)								
									
									# reset watering cycle					
									status="done"	
									statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",0)
									statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",-1)
									statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",0)
									statusdataDBmod.write_status_data(AUTO_data,element,"cyclestartdate",datetime.now())

																	

							# update the status							
							checkcounter=statusdataDBmod.read_status_data(AUTO_data,element,"checkcounter")
							statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus",status)
							statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",checkcounter+1)
					
					else:
						# update the status, reset cycle
						statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus","done")
						statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",0)
						statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",0)
						statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",0)														
			
			
		elif workmode=="Emergency Activation":
			# check if inside the allow time period
			logger.info('Emergency Mode')
			timeok=isNowInTimePeriod(starttime, endtime, nowtime)
			print "inside allowed time ", timeok , " starttime ", starttime , " endtime ", endtime
			if timeok:			
				belowthr,valid=checkminthreshold(sensor,minthreshold,minaccepted)
				if valid:
					if belowthr:
						# wait to seek a more stable reading of hygrometer
						# check if time between watering events is larger that the waiting time (minutes)
						
						lastwateringtime=statusdataDBmod.read_status_data(AUTO_data,element,"lastwateringtime")			
						if sensordbmod.timediffinminutes(lastwateringtime,datetime.now())>waitingtime:
							# activate watering in case the maxstepnumber is not exceeded			
							watercounter=statusdataDBmod.read_status_data(AUTO_data,element,"watercounter")		
							if maxstepnumber>watercounter:			
								#activate pump		
								activatewater(element, duration)
								# invia mail, considered as info, not as alert
								if mailtype!="warningonly":
									textmessage="INFO: " + sensor + " value below the minimum threshold " + str(minthreshold) + ", activating the watering :" + element
									emailmod.sendallmail("alert", textmessage)

								statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",watercounter+1)
								statusdataDBmod.write_status_data(AUTO_data,element,"lastwateringtime",datetime.now())									
								
								
							else:

								logger.info('Number of watering time per cycle has been exceeeded')
								# read hystory data and calculate the slope
								timelist=hardwaremod.gettimedata(sensor)
								cyclestartdate=statusdataDBmod.read_status_data(AUTO_data,element,"cyclestartdate")	
								lastwateringtime=statusdataDBmod.read_status_data(AUTO_data,element,"lastwateringtime")	
								startdate=cyclestartdate - timedelta(minutes=timelist[1])
								enddate=lastwateringtime + timedelta(minutes=waitingtime)
								isslopeok=checkinclination(sensor,startdate,enddate)
								
								if isslopeok:
									# invia mail if couner alert is lower than 1
									alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
									if alertcounter<1:
										textmessage="WARNING: Please consider to increase the amount of water per cycle, the "+ sensor + " value below the MINIMUM threshold " + str(minthreshold) + " still after activating the watering :" + element + " for " + str(maxstepnumber) + " times. System will automatically reset the watering cycle to allow more water"
										print textmessage
										#send alert mail notification alertcounter
										emailmod.sendallmail("alert", textmessage)							
										logger.error(textmessage)
										statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)
										
									# reset watering cycle
									status="done"
									statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",0)
									statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",-1)
									statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",0)
									statusdataDBmod.write_status_data(AUTO_data,element,"cyclestartdate",datetime.now())
																			
								else: # slope not OK, probable hardware problem
									alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
									if alertcounter<3:
										textmessage="CRITICAL: Possible hardware problem, "+ sensor + " value below the MINIMUM threshold " + str(minthreshold) + " still after activating the watering :" + element + " for " + str(maxstepnumber) + " times"
										print textmessage
										#send alert mail notification
										emailmod.sendallmail("alert", textmessage)							
										logger.error(textmessage)
										statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)			
		
									
						# update the status
						checkcounter=statusdataDBmod.read_status_data(AUTO_data,element,"checkcounter")
						statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus","lowthreshold")
						statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",checkcounter+1)
					else:
						# update the status		
						statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus","done")
						statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",0)
						statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",0)
						statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",0)		
	
			
		elif workmode=="under MIN over MAX":
			logger.info('under MIN over MAX')
			# normally watering plan is allowed unless over MAX threshold
			allowwateringplan[element]=True
			# check if inside the allow time period
			timeok=isNowInTimePeriod(starttime, endtime, nowtime)
			print "inside allowed time ", timeok , " starttime ", starttime , " endtime ", endtime
			if timeok:			
				logger.info('Insede operative time')
				belowthr,valid=checkminthreshold(sensor,minthreshold,minaccepted)
				if valid:
					logger.info('valid sensor reading')
					if belowthr:
						logger.info('sensor reading below threshold')
						# wait to seek a more stable reading of hygrometer
						# check if time between watering events is larger that the waiting time (minutes)			

						lastwateringtime=statusdataDBmod.read_status_data(AUTO_data,element,"lastwateringtime")			
						if sensordbmod.timediffinminutes(lastwateringtime,datetime.now())>waitingtime:
							# activate watering in case the maxstepnumber is not exceeded			
							watercounter=statusdataDBmod.read_status_data(AUTO_data,element,"watercounter")		
							if maxstepnumber>watercounter:
								logger.info('water Count not exceeded')			
								#activate pump		
								activatewater(element, duration)
								# invia mail, considered as info, not as alert
								if mailtype!="warningonly":
									textmessage="INFO: " + sensor + " value below the minimum threshold " + str(minthreshold) + ", activating the watering :" + element
									emailmod.sendallmail("alert", textmessage)								
								statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",watercounter+1)
								statusdataDBmod.write_status_data(AUTO_data,element,"lastwateringtime",datetime.now())	
								
								
							else:

								logger.info('Number of watering time per cycle has been exceeeded')
								# read hystory data and calculate the slope
								timelist=hardwaremod.gettimedata(sensor)
								
								cyclestartdate=statusdataDBmod.read_status_data(AUTO_data,element,"cyclestartdate")	
								lastwateringtime=statusdataDBmod.read_status_data(AUTO_data,element,"lastwateringtime")
								startdate=cyclestartdate - timedelta(minutes=timelist[1])
								enddate=lastwateringtime + timedelta(minutes=waitingtime)
								isslopeok=checkinclination(sensor,startdate,enddate)
								
								if isslopeok:
									# invia mail if couner alert is lower than 1
									alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
									if alertcounter<1:
										textmessage="WARNING: Please consider to increase the amount of water per cycle, the "+ sensor + " value below the MINIMUM threshold " + str(minthreshold) + " still after activating the watering :" + element + " for " + str(maxstepnumber) + " times. System will automatically reset the watering cycle to allow more water"
										print textmessage
										#send alert mail notification
										emailmod.sendallmail("alert", textmessage)							
										logger.error(textmessage)
										statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)
										
									# reset watering cycle
									status="done"
									statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",0)
									statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",-1)
									statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",0)
									statusdataDBmod.write_status_data(AUTO_data,element,"cyclestartdate",datetime.now())
																			
								else: # slope not OK, probable hardware problem
									alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
									if alertcounter<3:
										textmessage="CRITICAL: Possible hardware problem, "+ sensor + " value below the MINIMUM threshold " + str(minthreshold) + " still after activating the watering :" + element + " for " + str(maxstepnumber) + " times"
										print textmessage
										#send alert mail notification
										emailmod.sendallmail("alert", textmessage)							
										logger.error(textmessage)
										statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)			
		
									
						# update the status
						checkcounter=statusdataDBmod.read_status_data(AUTO_data,element,"checkcounter")
						statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus","lowthreshold")
						statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",checkcounter+1)
						
					else: # above minimum threshold
						logger.info('sensor reading above min threshold')
						# update the status
						statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus","done")
						statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",0)
						statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",0)
						statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",0)		
						
						if sensorreading(sensor)>maxthreshold:
							logger.info('sensor reading above MAX threshold, deactivate scheduled irrigation')
							# do not activate the irrigation scheduled in the time plan
							allowwateringplan[element]=False
							
						

		elif workmode=="Alert Only":
			belowthr,valid=checkminthreshold(sensor,minthreshold,minaccepted)
			if valid:
				if belowthr:
					# invia mail if couter alert is lower than
					alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")	
					if alertcounter<2:
						textmessage="WARNING "+ sensor + " value below the minimum threshold " + str(minthreshold) + " watering system: " + element
						print textmessage
						#send alert mail notification
						emailmod.sendallmail("alert", textmessage)							
						logger.error(textmessage)
						statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)
					# update the status
					checkcounter=statusdataDBmod.read_status_data(AUTO_data,element,"checkcounter")
					statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus","lowthreshold")
					statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",checkcounter+1)
				else:
					# update the status	
					statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus","done")
					statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",0)
					statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",0)
					statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",0)						
							
			
		else: # None case
			print "No Action required, workmode set to None, element: " , element
			logger.info("No Action required, workmode set to None, element: %s " , element)

		cyclestatus=statusdataDBmod.read_status_data(AUTO_data,element,"cyclestatus")
		if cyclestatus=="lowthreshold":
			checkcounter=statusdataDBmod.read_status_data(AUTO_data,element,"checkcounter")
			if checkcounter==1:			
				statusdataDBmod.write_status_data(AUTO_data,element,"cyclestartdate",datetime.now())

		# implment alert message for the cycle exceeding days, and reset the cycle
		if workmode!="None":
			cyclestartdate=statusdataDBmod.read_status_data(AUTO_data,element,"cyclestartdate")
			timedeltadays=sensordbmod.timediffdays(datetime.now(),cyclestartdate)
			if (timedeltadays > maxdays): #the upper limit is set in case of abrupt time change
				textmessage="WARNING "+ sensor + " watering cycle is taking too many days, watering system: " + element + ". Reset watering cycle"
				print textmessage
				# in case of full Auto, activate pump for minimum pulse period
				if workmode=="Full Auto":
					if (timedeltadays < maxdays+2): #the upper limit is set in case of abrupt time change					
						textmessage="WARNING "+ sensor + " watering cycle is taking too many days, watering system: " + element + ". Activate Min pulse + Reset watering cycle"					
						activatewater(element, duration)
				#send alert mail notification
				if mailtype!="warningonly":
					emailmod.sendallmail("alert", textmessage)							
				logger.error(textmessage)
				logger.error("Cycle started %s, Now is %s ", cyclestartdate.strftime("%Y-%m-%d %H:%M:%S"), datetime.now().strftime("%Y-%m-%d %H:%M:%S"))			
				# reset cycle
				statusdataDBmod.write_status_data(AUTO_data,element,"cyclestatus","done")
				statusdataDBmod.write_status_data(AUTO_data,element,"checkcounter",0)
				statusdataDBmod.write_status_data(AUTO_data,element,"watercounter",0)
				statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",0)	
				statusdataDBmod.write_status_data(AUTO_data,element,"cyclestartdate",datetime.now())

		# implment Critical alert message in case the threshold is below the 0.5 of the minimum
		if workmode!="None":
			belowthr,valid=checkminthreshold(sensor,minthreshold*0.5,minaccepted)
			if valid:
				if belowthr:
					logger.info('sensor %s below half of the actual set threshold', sensor)
					textmessage="CRITICAL: Plant is dying, "+ sensor + " reading below half of the minimum threshold, need to check the " + element
					print textmessage
					#send alert mail notification
					alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
					if alertcounter<5:
						emailmod.sendallmail("alert", textmessage)							
						logger.error(textmessage)
						statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)
			else:
				logger.info('sensor %s below valid data', sensor)
				textmessage="WARNING: "+ sensor + " below valid data range, need to check sensor"
				print textmessage
				#send alert mail notification
				alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
				if alertcounter<3:
					emailmod.sendallmail("alert", textmessage)							
					logger.error(textmessage)
					statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)		
	return