示例#1
0
def CheckActivateNotify(element,waitingtime,value,mailtype,sensor,sensorvalue):
	global AUTO_data
	# check if time between watering events is larger that the waiting time (minutes)
	lastactiontime=statusdataDBmod.read_status_data(AUTO_data,element,"lastactiontime")
	print(' Previous action: ' , lastactiontime , ' Now: ', datetime.utcnow())
	timedifference=sensordbmod.timediffinminutes(lastactiontime,datetime.utcnow())
	print('Time interval between actions', timedifference ,'. threshold', waitingtime)
	logger.info('Time interval between Actions %d threshold %d', timedifference,waitingtime)		
	if timedifference>=waitingtime: # sufficient time between actions
		print(" Sufficient waiting time")
		logger.info('Sufficient waiting time')	
		# action					
		print("Implement Actuator Value ", value)
		logger.info('Procedure to start actuator %s, for value = %s', element, value)		
		isok=activateactuator(element, value)
			
		# invia mail, considered as info, not as alert
		if (mailtype!="warningonly")and(mailtype!="none"):
			textmessage="INFO: " + sensor + " value " + str(sensorvalue) + ", activating:" + element + " with Value " + str(value)
			emailmod.sendallmail("alert", textmessage)
		if isok:
			statusdataDBmod.write_status_data(AUTO_data,element,"lastactiontime",datetime.utcnow())
			statusdataDBmod.write_status_data(AUTO_data,element,"actionvalue",value)

	else:
		logger.info('Need to wait more time')		
示例#2
0
def CheckActivateNotify(element, waitingtime, value, mailtype, sensor,
                        sensorvalue):
    global AUTO_data
    # check if time between watering events is larger that the waiting time (minutes)
    print ' Previous action: ', AUTO_data[element][
        "lastactiontime"], ' Now: ', datetime.now()
    timedifference = sensordbmod.timediffinminutes(
        AUTO_data[element]["lastactiontime"], datetime.now())
    print 'Time interval between actions', timedifference, '. threshold', waitingtime
    logger.info('Time interval between Actions %d threshold %d',
                timedifference, waitingtime)
    if timedifference >= waitingtime:  # sufficient time between actions
        print " Sufficient waiting time"
        logger.info('Sufficient waiting time')
        # action
        print "Implement Actuator Value ", value
        logger.info('Procedure to start actuator %s, for value = %s', element,
                    value)
        isok = activateactuator(element, value)

        # invia mail, considered as info, not as alert
        if mailtype != "warningonly":
            textmessage = "INFO: " + sensor + " value " + str(
                sensorvalue
            ) + ", activating:" + element + " with Value " + str(value)
            emailmod.sendallmail("alert", textmessage)
        if isok:
            AUTO_data[element]["lastactiontime"] = datetime.now()
            AUTO_data[element]["actionvalue"] = value
    else:
        logger.info('Need to wait more time')
示例#3
0
def CheckActivateNotify(element,waitingtime,value,mailtype,sensor,sensorvalue):
	global AUTO_data
	# check if time between watering events is larger that the waiting time (minutes)
	lastactiontime=statusdataDBmod.read_status_data(AUTO_data,element,"lastactiontime")
	print ' Previous action: ' , lastactiontime , ' Now: ', datetime.now()
	timedifference=sensordbmod.timediffinminutes(lastactiontime,datetime.now())
	print 'Time interval between actions', timedifference ,'. threshold', waitingtime
	logger.info('Time interval between Actions %d threshold %d', timedifference,waitingtime)		
	if timedifference>=waitingtime: # sufficient time between actions
		print " Sufficient waiting time"
		logger.info('Sufficient waiting time')	
		# action					
		print "Implement Actuator Value ", value
		logger.info('Procedure to start actuator %s, for value = %s', element, value)		
		isok=activateactuator(element, value)
			
		# invia mail, considered as info, not as alert
		if mailtype!="warningonly":
			textmessage="INFO: " + sensor + " value " + str(sensorvalue) + ", activating:" + element + " with Value " + str(value)
			emailmod.sendallmail("alert", textmessage)
		if isok:
			statusdataDBmod.write_status_data(AUTO_data,element,"lastactiontime",datetime.now())
			statusdataDBmod.write_status_data(AUTO_data,element,"actionvalue",value)

	else:
		logger.info('Need to wait more time')		
示例#4
0
def heartbeat():
    print("start heartbeat check", " ", datetime.now())
    logger.info('Start heartbeat routine %s',
                datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    # check wifi connection
    connectedssid = networkmod.connectedssid()
    connected = False
    if len(connectedssid) == 0:

        if not networkmod.WIFIENDIS == "Disabled":
            logger.warning(
                'Heartbeat check , no network connected -------------- try to connect'
            )
            print(
                'Heartbeat check , no network connected -------------- try to connect'
            )
            connected = networkmod.connect_network()
        else:
            logger.info('Heartbeat check , wifi disabled')
    else:
        logger.info('Heartbeat check , Connected Wifi Network: %s ',
                    connectedssid[0])
        if connectedssid[0] == networkmod.localwifisystem:
            logger.info(
                'Heartbeat check , Configured as wifi access point, check if possible to connect to wifi network'
            )
            connected = networkmod.connect_network()
            networkmod.DHCP_COUNTER = 0
        else:  # Connected to wifi network
            reachgoogle = networkmod.check_internet_connection(1)

            if not reachgoogle:
                logger.warning(
                    'Heartbeat check wifi SSID ok, but test ping not able to reach Google'
                )
                print('Heartbeat check , no IP connection')
                #connected=networkmod.connect_network() # use this in case you require the system to try connect wifi again in case no internet is reached
                #logger.warning('Heartbeat check , DHCP reset counter %s' , str(networkmod.DHCP_COUNTER))
                # DHCP reset
                #if (networkmod.DHCP_COUNTER % 16)==0: # try to reset every 16x15min =4 hours
                # try to reset DHCP
                #logger.warning('Heartbeat check , reset DHCP')
                #print 'Heartbeat check , reset DHCP'
                #networkmod.resetDHCP()

                #networkmod.DHCP_COUNTER=networkmod.DHCP_COUNTER+1

                goON, GWipaddr = networkmod.checkGWsubnet("wlan0")
                if GWipaddr == "":
                    logger.info(
                        'Gateway IP address NOT found, back to AP mode')
                    # back to AP mode! kind of risky business
                    networkmod.connect_AP()

                else:
                    logger.info('Gateway IP address found %s', GWipaddr)

                connected = False
            else:
                logger.info('Heartbeat check , wifi connection OK')
                print('Heartbeat check , wifi connection OK')
                #networkmod.DHCP_COUNTER=0
                connected = True

    if connected:
        # Check if remote IP address is changed compared to previous communication and in such case resend the mail
        ipext = networkmod.get_external_ip()
        logger.info(
            'Heartbeat check , Check IP address change -%s- and previously sent -%s-',
            ipext, emailmod.IPEXTERNALSENT)
        if (ipext != ""):
            if (emailmod.IPEXTERNALSENT != ""):
                if ipext != emailmod.IPEXTERNALSENT:
                    print(
                        "Heartbeat check, IP address change detected. Send email with updated IP address"
                    )
                    logger.info(
                        'Heartbeat check, IP address change detected. Send email with updated IP address'
                    )
                    emailmod.sendallmail(
                        "alert",
                        "System detected IP address change, below the updated links"
                    )
                else:
                    logger.info('Heartbeat check, IP address unchanged')
            else:
                # first mail has not been sent succesfully of IPEXTERNALSENT was not available by the time
                print("System has been reconnected")
                logger.info(
                    "System has been reconnected, IPEXTERNALSENT was empty")
                emailmod.sendallmail("alert", "System has been reconnected")

    else:
        print("not able to establish an internet connection")
        logger.warning("not able to establish an internet connection")

    # check clock with NTP and reset master scheduler in case of clock change
    if CheckNTPandAdjustClockandResetSched():
        return True

    #check the static IP address
    currentipaddr = networkmod.get_local_ip_raw()
    logger.info('Target IP address= %s. Current access point IP addresses= %s',
                networkmod.IPADDRESS, currentipaddr)
    if networkmod.IPADDRESS not in currentipaddr:
        #set IP address
        logger.warning(
            'Local Static IP address not in the list, Set Target IP address')
        networkmod.addIP("wlan0")
    else:
        logger.info('Local Statip IP address OK')

    # check master job has a next run"
    isok, datenextrun = SchedulerMod.get_next_run_time("master")
    if isok:
        datenow = datetime.utcnow()
        datenextrun = datenextrun.replace(tzinfo=None)
        print("Master Scheduler Next run ", datenextrun, " Now (UTC) ",
              datenow)
        if datenextrun > datenow:
            print("Masterschedule next RUN confirmed")
            logger.info('Heartbeat check , Master Scheduler OK')
        else:
            isok = False

    if not isok:
        print("No next run for master scheduler")
        logger.warning('Heartbeat check , Master Scheduler Interrupted')
        #emailmod.sendallmail("alert","Master Scheduler has been interrupted, try to restart scheduler")
        resetmastercallback()
        return True

    # check if there have been errors in Syslog
    if DEBUGMODE:
        logger.info('Heartbeat check , check errors in Syslog file')
        Errortextlist = debuggingmod.searchsyslogkeyword("error")
        if Errortextlist:
            print("found error in syslog")
            logger.warning(
                "ERROR: found error in syslog -------------------------")
            #send notification mail
            if debuggingmod.SENTERRORTEXT != Errortextlist[0]:
                emailmod.sendallmail("alert", "Error found in Syslog",
                                     Errortextlist)
                debuggingmod.SENTERRORTEXT = Errortextlist[0]
        else:
            print("No error found in syslog")
            logger.info('Heartbeat check , SYSLOG ok')

    # check if there have been errors in Schedulerlog
    if DEBUGMODE:
        logger.info('Heartbeat check , check errors in Sched log file')
        filename = "logfiles/apscheduler_hydrosystem.log"
        MYPATH = hardwaremod.get_path()
        filenameandpath = os.path.join(MYPATH, filename)
        Errortextlist = debuggingmod.searchLOGkeyword(filenameandpath, "error")
        if Errortextlist:
            print("found error in LOG ", filename)
            logger.warning(
                "ERROR: found error in LOG , %s -------------------------",
                filename)
            #send notification mail
            if debuggingmod.SENTERRORTEXT != Errortextlist[0]:
                emailmod.sendallmail("alert", "Error found in LOG",
                                     Errortextlist)
                debuggingmod.SENTERRORTEXT = Errortextlist[0]
        else:
            print("No error found in LOG", filename)
            logger.info('Heartbeat check , LOG ok')

    return True
示例#5
0
def connect_network(internetcheck=False, backtoAP=False):
	# this is the procedure that disable the AP and connect to wifi network 
	connected=False
	print " try to connect to wifi network"
	thessid=connect_preconditions() # get the first SSID of saved wifi network to connect with and see if the SSID is on air
	
	
	
	if not thessid=="":
		print "preconditions to connect to wifi network are met"				
		logger.info('preconditions to connect to wifi network are met')
		ssids=connectedssid() # get the SSID currently connected
		if len(ssids)>0:
			ssid=ssids[0]
		else:
			ssid=""		
				


			
		if not ssid==thessid:
			print "try to connect to wifi network"
			logger.info('try to connect to wifi network %s ' ,thessid)			
			print "try to stop AP services, hostapd, dnsmasq"
			logger.info('try to stop AP services, hostapd, dnsmasq ')
			i=0
			done=False
			while (i<2) and (not done):
				done=stop_hostapd()
				i=i+1
			i=0
			done=False
			while (i<2) and (not done):
				done=stop_dnsmasq()
				i=i+1			
						

			done=False
			ssids=[]
			i=0
			while (i<3) and (len(ssids)==0):
				done=connect_savedwifi(thessid) # return true when the command is executed
				i=i+1					
				if done:
					time.sleep(1+i*5)				
					print "wifi connection attempt ",i
					print "check connected SSID"
					logger.info('Connection command executed attempt %d, check connected SSID ',i)
				else:
					print "Connection command NOT executed properly , attempt ",i
					logger.info('Connection command NOT executed properly , attempt %d ',i)							
				ssids=connectedssid()
		

			if len(ssids)>0:
				ssid=ssids[0]
			else:
				ssid=""
				logger.info('NO connected SSID')
			print "Connected to the SSID ", ssid
			logger.info('Connected SSID: %s -- ', ssid)

		else:
			print "already connected to the SSID ", ssid
		
		
		if len(ssids)==0:
			print "No SSID established, fallback to AP mode"
			# go back and connect in Access point Mode
			logger.info('No Wifi Network connected, no AP connected, going back to Access Point mode')
			connect_AP()
			connected=False
		else:
			logger.info('Connected to Wifi Network %s' , ssid )
			print 'Connected to Wifi Network '  , ssid 

		
			
			# here it is needed to have a real check of the internet connection as for example google 
			if internetcheck:
				connected=check_internet_connection(3)
				if connected:
					print "Google is reacheable !"
					logger.info('Google is reacheable ! ')
					#send first mail
					print "Send first mail !"
					logger.info('Send first mail ! ')
					emailmod.sendallmail("alert", "System has been reconnected to wifi network")				
				else:
					if backtoAP:
						print "Connectivity problem with WiFi network " ,ssid[0] , "going back to wifi access point mode"
						logger.info('Connectivity problem with WiFi network, %s, gong back to wifi access point mode' ,ssid )
						connect_AP()
			else:
				connected=True
			logger.info('wait and check if the heartbeat job is still scheduled')				
			#pulsesecond=180
			#selectedplanmod.waitandcheckheartbeat(pulsesecond)
			#use CPU cycles as way to delay, cannot be based on clock info, clock jumps happen as soon as NTP is providing the datatime to the system
			pausecycles=10000000
			for i in range(1,pausecycles):
				b=i*0.1
			selectedplanmod.checkheartbeat()

	else:
		print "No Saved Wifi Network available"
		logger.info('No Saved Wifi Network available')	
		print "try to fallback to AP mode"
		# go back and connect in Access point Mode
		#logger.info('Going back to Access Point mode')
		#connect_AP()
		connected=False
			
	return connected
示例#6
0
def connect_network():
    # this is the procedure that disable the AP and connect to wifi network
    connected = False
    print " try to connect to wifi network"
    thessid = connect_preconditions(
    )  # get the first SSID of saved wifi network to connect with

    if not thessid == "":
        print "preconditions to connect to wifi network are met"
        logger.info('preconditions to connect to wifi network are met')
        ssids = connectedssid()  # get the SSID currently connected
        if len(ssids) > 0:
            ssid = ssids[0]
        else:
            ssid = ""

        if not ssid == thessid:
            print "try to connect to wifi network"

            print "try to stop AP services, hostapd, dnsmasq"

            i = 0
            done = False
            while (i < 2) and (not done):
                done = stop_hostapd()
                i = i + 1
            i = 0
            done = False
            while (i < 2) and (not done):
                done = stop_dnsmasq()
                i = i + 1

            i = 0
            done = False
            while (i < 3) and (not done):
                done = connect_savedwifi(thessid)
                i = i + 1
                print " wifi connection attempt ", i

            print "check connected SSID"

            logger.info('check connected SSID ')

            ssids = connectedssid()
            i = 0
            while (i < 2) and (len(ssids) == 0):
                time.sleep(1 + i * 5)
                ssids = connectedssid()
                i = i + 1

            if len(ssids) > 0:
                ssid = ssids[0]
            else:
                ssid = ""
            print "connected to the SSID ", ssid
            logger.info('connected SSID %s ', ssid)

        else:
            print "already connected to the SSID ", ssid

        if len(ssids) == 0:
            print "No SSID established, fallback to AP mode"
            # go back and connect in Access point Mode
            logger.info(
                'No Wifi Network connected, no AP connected, going back to Access Point mode'
            )
            connect_AP()
            connected = False
        else:
            logger.info(
                'Connected to Wifi Network %s, now testing connectivity', ssid)
            print 'Connected to Wifi Network ', ssid, ' now testing connectivity'
            # here it is needed to have a real check of the internet connection as for example google
            connected = check_internet_connection(3)

            if connected:
                print "Google is reacheable !"
                logger.info('Google is reacheable ! ')
                #send first mail
                print "Send first mail !"
                logger.info('Send first mail ! ')
                emailmod.sendallmail(
                    "alert", "System has been reconnected to wifi network")
            else:
                print "Connectivity problem with WiFi network ", ssid[
                    0], "going back to wifi access point mode"
                logger.info(
                    'Connectivity problem with WiFi network, %s, gong back to wifi access point mode',
                    ssid)
                connect_AP()

    else:
        print "No Saved Wifi Network available"
        logger.info('No Saved Wifi Network available')
        print "try to fallback to AP mode"
        # go back and connect in Access point Mode
        logger.info('Going back to Access Point mode')
        connect_AP()
        connected = False

    return connected
示例#7
0
def heartbeat():
    print "start heartbeat check", " ", datetime.now()
    logger.info('Start heartbeat routine %s',
                datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    connectedssid = networkmod.connectedssid()
    connected = False
    if len(connectedssid) == 0:
        logger.warning(
            'Heartbeat check , no network connected -------------- try to connect'
        )
        print 'Heartbeat check , no network connected -------------- try to connect'
        connected = networkmod.connect_network()
    else:
        logger.info('Heartbeat check , Connected Wifi Network: %s ',
                    connectedssid[0])
        if connectedssid[0] == networkmod.localwifisystem:
            logger.info(
                'Heartbeat check , Configured as wifi access point, check if possible to connect to wifi network'
            )
            connected = networkmod.connect_network()
        else:
            reachgoogle = networkmod.check_internet_connection(3)

            if not reachgoogle:
                logger.warning(
                    'Heartbeat check , test ping not able to reach Google -------------- try to connect'
                )
                print 'Heartbeat check , no IP connection-------------- try to connect'
                connected = networkmod.connect_network()
            else:
                logger.info('Heartbeat check , wifi connection OK')
                print 'Heartbeat check , wifi connection OK'
                connected = True

    if connected:
        # Check if remote IP address is changed compared to previous communication and in such case resend the mail
        ipext = networkmod.get_external_ip()
        logger.info('Heartbeat check , Check IP address change %s', ipext)
        if ipext != "":
            if ipext != emailmod.IPEXTERNALSENT:
                print "Heartbeat check, IP address change detected. Send email with updated IP address"
                logger.info(
                    'Heartbeat check, IP address change detected. Send email with updated IP address'
                )
                emailmod.sendallmail(
                    "alert",
                    "System detected IP address change, below the updated links"
                )

        # Check current time is less than 60 second different from NTP information
        # try to get the clock from network
        print "check system clock"
        logger.info('Heartbeat check, check clock')
        networktime = clockmod.getNTPTime()
        logger.info('Heartbeat check , Network time NTP: %s ', networktime)
        systemtime = clockmod.readsystemdatetime()
        logger.info('Heartbeat check , System time NTP: %s ', systemtime)
        if not networktime == '':
            diffsec = clockmod.timediffinsec(networktime, systemtime)
            logger.info(
                'Heartbeat check , difference between system time and network time, diffsec =  %d ',
                diffsec)
            if diffsec > 60:
                print "Heartbeat check , warning difference between system time and network time >60 sec, diffsec = ", diffsec
                logger.warning(
                    'Heartbeat check , warning difference between system time and network time >60 sec, diffsec =  %d ',
                    diffsec)
                print "Heartbeat check , Apply network datetime to system"
                logger.warning(
                    'Heartbeat check , Apply network datetime to system ')
                clockmod.setHWclock(networktime)
                clockmod.setsystemclock(networktime)
            else:
                print "Heartbeat check , Clock OK"
                logger.info('Heartbeat check , Clock OK')
        else:
            print "not able to get network time"
            logger.warning('Heartbeat check , not able to get network time')
    else:
        print "not able to establish an internet connection"
        logger.warning("not able to establish an internet connection")

    # check master job has a next run"
    isok, datenextrun = SchedulerMod.get_next_run_time("master")
    if isok:
        datenow = datetime.utcnow()
        datenextrun = datenextrun.replace(tzinfo=None)
        print "Master Scheduler Next run ", datenextrun, " Now (UTC) ", datenow
        if datenextrun > datenow:
            print "Masterschedule next RUN confirmed"
            logger.info('Heartbeat check , Master Scheduler OK')
        else:
            isok = False

    if not isok:
        print "No next run for master scheduler"
        logger.warning('Heartbeat check , Master Scheduler Interrupted')
        emailmod.sendallmail(
            "alert",
            "Master Scheduler has been interrupted, try to restart scheduler")
        setmastercallback()

    return True
示例#8
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
示例#9
0
def CheckActivateNotify(element, sensor, preemptiontime, actuatoroutput,
                        actionmodeafterfirst, actuatoroutputfollowup, mailtype,
                        interrupt_triggernumber, interrupt_validinterval):
    value = actuatoroutput
    isok = False
    global AUTO_data
    # check if in blocking state
    lasteventtime = statusdataDBmod.read_status_data(AUTO_data, element,
                                                     "lasteventtime")
    blockingstate = statusdataDBmod.read_status_data(AUTO_data, element,
                                                     "blockingstate")
    #print ' Previous event: ' , lasteventtime , ' Now: ', datetime.utcnow()
    #timedifference=sensordbmod.timediffinminutes(lasteventtime,datetime.utcnow())
    #print 'Time interval between actions', timedifference ,'. threshold', preemptiontime
    #logger.info('Time interval between Actions %d threshold %d', timedifference,preemptiontime)

    # count the interrupt that are fast enough to stay in the valid interrupt period

    #print "autodata" ,AUTO_data[element]
    lastinterrupttime = statusdataDBmod.read_status_data(
        AUTO_data, element, "lastinterrupttime")
    nowtime = datetime.utcnow()
    #print ' Previous interrupt: ' , lastinterrupttime , ' Now: ', nowtime
    diffseconds = (nowtime - lastinterrupttime).total_seconds()

    statusdataDBmod.write_status_data(AUTO_data, element, "lastinterrupttime",
                                      nowtime)
    validinterruptcount = statusdataDBmod.read_status_data(
        AUTO_data, element, "validinterruptcount")

    if diffseconds <= interrupt_validinterval:  #valid interval between interrupt, increase counter
        validinterruptcount = validinterruptcount + 1
        statusdataDBmod.write_status_data(AUTO_data, element,
                                          "validinterruptcount",
                                          validinterruptcount)
    else:  # time between interrupt too long, restart counter
        # save on database
        #x = threading.Thread(target=savedata, args=(sensor,validinterruptcount))
        #x.start()
        #reset counter and events
        validinterruptcount = 1
        statusdataDBmod.write_status_data(AUTO_data, element,
                                          "validinterruptcount",
                                          validinterruptcount)

    WaitandRegister(element, sensor, interrupt_validinterval,
                    validinterruptcount)

    #print "********" ,validinterruptcount , "******"

    if not blockingstate:  # outside the preemption period , first activation
        #print " outside the preemption period "
        #logger.info('outside the preemption period')
        # before action, evaluate if trigger number is reached

        if validinterruptcount == interrupt_triggernumber:

            # action
            print "Implement Actuator Value ", value
            logger.info('Procedure to start actuator %s, for value = %s',
                        element, value)
            isok = activateactuator(element, value)

            # invia mail, considered as info, not as alert
            if mailtype != "none":
                if mailtype != "warningonly":
                    textmessage = "INFO: " + sensor + " event , activating:" + element + " with Value " + str(
                        value)
                    emailmod.sendallmail("alert", textmessage)
                if isok:
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "lasteventtime",
                                                      datetime.utcnow())
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "lastactiontime",
                                                      datetime.utcnow())
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "actionvalue", value)

            # start the blocking state
            print "Start blocking state"
            startblockingstate(element, preemptiontime)

    else:
        # inside blocking state
        #print " inside the preemption period, starting followup actions: " , actionmodeafterfirst
        #logger.info('inside the preemption period, check followup actions %s :', actionmodeafterfirst)

        if actionmodeafterfirst == "None":
            return

        if actionmodeafterfirst == "Extend blocking state":  # extend only the pre-emption blocking period, no action
            print "Extend blocking state"
            startblockingstate(element, preemptiontime)

        if actionmodeafterfirst == "Remove blocking state" or actionmodeafterfirst == "Remove and Follow-up":  # remove the pre-emption blocking period, no action
            print "Remove blocking state"
            endblocking(element, preemptiontime)

        if actionmodeafterfirst == "Follow-up action" or actionmodeafterfirst == "Remove and Follow-up":  # execute the action followup, no variation in the preemption period
            value = actuatoroutputfollowup
            # followup action
            print "Implement Actuator Value followup", value
            logger.info(
                'Procedure to start actuator followup %s, for value = %s',
                element, value)
            isok = activateactuator(element, value)

            # invia mail, considered as info, not as alert
            if mailtype != "none":
                if mailtype != "warningonly":
                    textmessage = "INFO: " + sensor + " event , activating:" + element + " with Value " + str(
                        value)
                    emailmod.sendallmail("alert", textmessage)
                if isok:
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "lastactiontime",
                                                      datetime.utcnow())
                    statusdataDBmod.write_status_data(AUTO_data, element,
                                                      "actionvalue", value)

    return isok
示例#10
0
def heartbeat():
	print "start heartbeat check", " " , datetime.now()
	logger.info('Start heartbeat routine %s', datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
	connectedssid=networkmod.connectedssid()
	connected=False
	if len(connectedssid)==0:
		logger.warning('Heartbeat check , no network connected -------------- try to connect')
		print 'Heartbeat check , no network connected -------------- try to connect'
		connected=networkmod.connect_network()
	else:
		logger.info('Heartbeat check , Connected Wifi Network: %s ', connectedssid[0])
		if connectedssid[0]==networkmod.localwifisystem:
			logger.info('Heartbeat check , Configured as wifi access point, check if possible to connect to wifi network')
			connected=networkmod.connect_network()
		else:		
			reachgoogle=networkmod.check_internet_connection(1)

			if not reachgoogle:
				logger.warning('Heartbeat check , test ping not able to reach Google -------------- No action')
				print 'Heartbeat check , no IP connection-------------- No action'
				#connected=networkmod.connect_network() # use this in case you require the system to try connect wifi again in case no internet is reached
				connected=False
			else:
				logger.info('Heartbeat check , wifi connection OK')
				print 'Heartbeat check , wifi connection OK'
				connected=True			

	if connected:
		# Check if remote IP address is changed compared to previous communication and in such case resend the mail	
		ipext=networkmod.get_external_ip()
		logger.info('Heartbeat check , Check IP address change -%s- and previously sent -%s-', ipext , emailmod.IPEXTERNALSENT)
		if (ipext!=""):
			if (emailmod.IPEXTERNALSENT!=""):
				if ipext!=emailmod.IPEXTERNALSENT:
					print "Heartbeat check, IP address change detected. Send email with updated IP address"
					logger.info('Heartbeat check, IP address change detected. Send email with updated IP address')
					emailmod.sendallmail("alert","System detected IP address change, below the updated links")
				else:
					logger.info('Heartbeat check, IP address unchanged')	
			else:
				# first mail has not been sent succesfully of IPEXTERNALSENT was not available by the time
				print "System has been reconnected"
				logger.info("System has been reconnected, IPEXTERNALSENT was empty")
				emailmod.sendallmail("alert","System has been reconnected")							

		# Check current time is less than 60 second different from NTP information
		# try to get the clock from network
		print "check system clock"
		logger.info('Heartbeat check, check clock')
		networktime=clockmod.getNTPTime()
		logger.info('Heartbeat check , Network time NTP: %s ', networktime)
		systemtime=clockmod.readsystemdatetime()
		logger.info('Heartbeat check , System time NTP: %s ', systemtime)
		if not networktime=='':
			diffsec=clockmod.timediffinsec(networktime, systemtime)
			logger.info('Heartbeat check , difference between system time and network time, diffsec =  %d ', diffsec)
			if diffsec>60:
				print "Heartbeat check , warning difference between system time and network time >60 sec, diffsec = " , diffsec
				logger.warning('Heartbeat check , warning difference between system time and network time >60 sec, diffsec =  %d ', diffsec)
				print "Heartbeat check , Apply network datetime to system"
				logger.warning('Heartbeat check , Apply network datetime to system ')
				clockmod.setHWclock(networktime)
				clockmod.setsystemclock(networktime)
			else:
				print "Heartbeat check , Clock OK"
				logger.info('Heartbeat check , Clock OK')
		else:
			print "not able to get network time"
			logger.warning('Heartbeat check , not able to get network time')
	else:
		print "not able to establish an internet connection"
		logger.warning("not able to establish an internet connection")			
	
	# check master job has a next run"
	isok, datenextrun = SchedulerMod.get_next_run_time("master")
	if isok:
		datenow=datetime.utcnow()
		datenextrun = datenextrun.replace(tzinfo=None)
		print "Master Scheduler Next run " , datenextrun , " Now (UTC) ", datenow
		if datenextrun>datenow:
			print "Masterschedule next RUN confirmed"
			logger.info('Heartbeat check , Master Scheduler OK')
		else:
			isok=False
			
	if not isok:
		print "No next run for master scheduler"
		logger.warning('Heartbeat check , Master Scheduler Interrupted')
		emailmod.sendallmail("alert","Master Scheduler has been interrupted, try to restart scheduler")
		resetmastercallback()
	
	# check if there have been errors in Syslog
	if DEBUGMODE:
		Errortextlist=debuggingmod.searchsyslogkeyword("error")
		if Errortextlist:
			print "found error in syslog"
			logger.warning("ERROR: found error in syslog -------------------------")	
			#send notification mail 
			if debuggingmod.SENTERRORTEXT!=Errortextlist[0]:
				emailmod.sendallmail("alert","Error found in Syslog",Errortextlist)
				debuggingmod.SENTERRORTEXT=Errortextlist[0]
		else:
			print "No error found in syslog"
			logger.info('Heartbeat check , SYSLOG ok')		
			
	# check if there have been errors in Schedulerlog
	if DEBUGMODE:
		filename="logfiles/apscheduler_hydrosystem.log"
		MYPATH=hardwaremod.get_path()
		filenameandpath=os.path.join(MYPATH, filename)
		Errortextlist=debuggingmod.searchLOGkeyword(filenameandpath,"error")
		if Errortextlist:
			print "found error in LOG ",filename
			logger.warning("ERROR: found error in LOG , %s -------------------------",filename)	
			#send notification mail 
			if debuggingmod.SENTERRORTEXT!=Errortextlist[0]:
				emailmod.sendallmail("alert","Error found in LOG",Errortextlist)
				debuggingmod.SENTERRORTEXT=Errortextlist[0]
		else:
			print "No error found in LOG", filename
			logger.info('Heartbeat check , LOG ok')					
				
				
		
	return True
示例#11
0
def heartbeat():
    print "start heartbeat check", " ", datetime.now()
    logger.info('Start heartbeat routine %s',
                datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    connectedssid = networkmod.connectedssid()
    connected = False
    if len(connectedssid) == 0:
        logger.warning(
            'Heartbeat check , no network connected -------------- try to connect'
        )
        print 'Heartbeat check , no network connected -------------- try to connect'
        connected = networkmod.connect_network()
    else:
        logger.info('Heartbeat check , Connected Wifi Network: %s ',
                    connectedssid[0])
        if connectedssid[0] == networkmod.localwifisystem:
            logger.info(
                'Heartbeat check , Configured as wifi access point, check if possible to connect to wifi network'
            )
            connected = networkmod.connect_network()
        else:
            reachgoogle = networkmod.check_internet_connection(1)

            if not reachgoogle:
                logger.warning(
                    'Heartbeat check , test ping not able to reach Google -------------- No action'
                )
                print 'Heartbeat check , no IP connection-------------- No action'
                #connected=networkmod.connect_network() # use this in case you require the system to try connect wifi again in case no internet is reached
                connected = False
            else:
                logger.info('Heartbeat check , wifi connection OK')
                print 'Heartbeat check , wifi connection OK'
                connected = True

    if connected:
        # Check if remote IP address is changed compared to previous communication and in such case resend the mail
        ipext = networkmod.get_external_ip()
        logger.info(
            'Heartbeat check , Check IP address change -%s- and previously sent -%s-',
            ipext, emailmod.IPEXTERNALSENT)
        if (ipext != ""):
            if (emailmod.IPEXTERNALSENT != ""):
                if ipext != emailmod.IPEXTERNALSENT:
                    print "Heartbeat check, IP address change detected. Send email with updated IP address"
                    logger.info(
                        'Heartbeat check, IP address change detected. Send email with updated IP address'
                    )
                    emailmod.sendallmail(
                        "alert",
                        "System detected IP address change, below the updated links"
                    )
                else:
                    logger.info('Heartbeat check, IP address unchanged')
            else:
                # first mail has not been sent succesfully of IPEXTERNALSENT was not available by the time
                print "System has been reconnected"
                logger.info(
                    "System has been reconnected, IPEXTERNALSENT was empty")
                emailmod.sendallmail("alert", "System has been reconnected")

        # Check current time is less than 60 second different from NTP information
        # try to get the clock from network
        print "check system clock"
        logger.info('Heartbeat check, check clock')
        networktime = clockmod.getNTPTime()
        logger.info('Heartbeat check , Network time NTP: %s ', networktime)
        systemtime = clockmod.readsystemdatetime()
        logger.info('Heartbeat check , System time NTP: %s ', systemtime)
        if not networktime == '':
            diffsec = clockmod.timediffinsec(networktime, systemtime)
            logger.info(
                'Heartbeat check , difference between system time and network time, diffsec =  %d ',
                diffsec)
            if diffsec > 60:
                print "Heartbeat check , warning difference between system time and network time >60 sec, diffsec = ", diffsec
                logger.warning(
                    'Heartbeat check , warning difference between system time and network time >60 sec, diffsec =  %d ',
                    diffsec)
                print "Heartbeat check , Apply network datetime to system"
                logger.warning(
                    'Heartbeat check , Apply network datetime to system ')
                clockmod.setHWclock(networktime)
                clockmod.setsystemclock(networktime)
            else:
                print "Heartbeat check , Clock OK"
                logger.info('Heartbeat check , Clock OK')
        else:
            print "not able to get network time"
            logger.warning('Heartbeat check , not able to get network time')
    else:
        print "not able to establish an internet connection"
        logger.warning("not able to establish an internet connection")

    # check master job has a next run"
    isok, datenextrun = SchedulerMod.get_next_run_time("master")
    if isok:
        datenow = datetime.utcnow()
        datenextrun = datenextrun.replace(tzinfo=None)
        print "Master Scheduler Next run ", datenextrun, " Now (UTC) ", datenow
        if datenextrun > datenow:
            print "Masterschedule next RUN confirmed"
            logger.info('Heartbeat check , Master Scheduler OK')
        else:
            isok = False

    if not isok:
        print "No next run for master scheduler"
        logger.warning('Heartbeat check , Master Scheduler Interrupted')
        emailmod.sendallmail(
            "alert",
            "Master Scheduler has been interrupted, try to restart scheduler")
        resetmastercallback()

    # check if there have been errors in Syslog
    if DEBUGMODE:
        Errortextlist = debuggingmod.searchsyslogkeyword("error")
        if Errortextlist:
            print "found error in syslog"
            logger.warning(
                "ERROR: found error in syslog -------------------------")
            #send notification mail
            if debuggingmod.SENTERRORTEXT != Errortextlist[0]:
                emailmod.sendallmail("alert", "Error found in Syslog",
                                     Errortextlist)
                debuggingmod.SENTERRORTEXT = Errortextlist[0]
        else:
            print "No error found in syslog"
            logger.info('Heartbeat check , SYSLOG ok')

    # check if there have been errors in Schedulerlog
    if DEBUGMODE:
        filename = "logfiles/apscheduler_hydrosystem.log"
        MYPATH = hardwaremod.get_path()
        filenameandpath = os.path.join(MYPATH, filename)
        Errortextlist = debuggingmod.searchLOGkeyword(filenameandpath, "error")
        if Errortextlist:
            print "found error in LOG ", filename
            logger.warning(
                "ERROR: found error in LOG , %s -------------------------",
                filename)
            #send notification mail
            if debuggingmod.SENTERRORTEXT != Errortextlist[0]:
                emailmod.sendallmail("alert", "Error found in LOG",
                                     Errortextlist)
                debuggingmod.SENTERRORTEXT = Errortextlist[0]
        else:
            print "No error found in LOG", filename
            logger.info('Heartbeat check , LOG ok')

    return True
def CheckActivateNotify(element, sensor, preemptiontime, actuatoroutput,
                        actionmodeafterfirst, actuatoroutputfollowup,
                        mailtype):
    value = actuatoroutput
    isok = False
    global AUTO_data
    # check if in blocking state
    lasteventtime = statusdataDBmod.read_status_data(AUTO_data, element,
                                                     "lasteventtime")
    blockingstate = statusdataDBmod.read_status_data(AUTO_data, element,
                                                     "blockingstate")
    print ' Previous event: ', lasteventtime, ' Now: ', datetime.utcnow()
    #timedifference=sensordbmod.timediffinminutes(lasteventtime,datetime.utcnow())
    #print 'Time interval between actions', timedifference ,'. threshold', preemptiontime
    #logger.info('Time interval between Actions %d threshold %d', timedifference,preemptiontime)
    if not blockingstate:  # outside the preemption period , first activation
        print " outside the preemption period "
        logger.info('outside the preemption period')
        # action
        print "Implement Actuator Value ", value
        logger.info('Procedure to start actuator %s, for value = %s', element,
                    value)
        isok = activateactuator(element, value)

        # invia mail, considered as info, not as alert
        if mailtype != "warningonly":
            textmessage = "INFO: " + sensor + " event , activating:" + element + " with Value " + str(
                value)
            emailmod.sendallmail("alert", textmessage)
        if isok:
            statusdataDBmod.write_status_data(AUTO_data,
                                              element, "lasteventtime",
                                              datetime.utcnow())
            statusdataDBmod.write_status_data(AUTO_data, element,
                                              "lastactiontime",
                                              datetime.utcnow())
            statusdataDBmod.write_status_data(AUTO_data, element,
                                              "actionvalue", value)

            # start the blocking state
            startblockingstate(element, preemptiontime)

    else:
        # inside blocking state
        print " inside the preemption period, starting followup actions: ", actionmodeafterfirst
        logger.info(
            'inside the preemption period, check followup actions %s :',
            actionmodeafterfirst)

        if actionmodeafterfirst == "None":
            return

        if actionmodeafterfirst == "Extend blocking state" or actionmodeafterfirst == "Extend and Follow-up":  # extend only the pre-emption blocking period, no action
            print "Extend blocking state"
            startblockingstate(element, preemptiontime)

        if actionmodeafterfirst == "Remove blocking state" or actionmodeafterfirst == "Remove and Follow-up":  # remove the pre-emption blocking period, no action
            print "Remove blocking state"
            endblocking(element, preemptiontime)

        if actionmodeafterfirst == "Follow-up action" or actionmodeafterfirst == "Extend and Follow-up" or actionmodeafterfirst == "Remove and Follow-up":  # execute the action followup, no variation in the preemption period
            value = actuatoroutputfollowup
            # followup action
            print "Implement Actuator Value followup", value
            logger.info(
                'Procedure to start actuator followup %s, for value = %s',
                element, value)
            isok = activateactuator(element, value)

            # invia mail, considered as info, not as alert
            if mailtype != "warningonly":
                textmessage = "INFO: " + sensor + " event , activating:" + element + " with Value " + str(
                    value)
                emailmod.sendallmail("alert", textmessage)
            if isok:
                statusdataDBmod.write_status_data(AUTO_data, element,
                                                  "lastactiontime",
                                                  datetime.utcnow())
                statusdataDBmod.write_status_data(AUTO_data, element,
                                                  "actionvalue", value)

    return isok
示例#13
0
def automationexecute(refsensor,element):		
	sensor=automationdbmod.searchdata("element",element,"sensor")
	# check the sensor
	if refsensor==sensor:		
		logger.info('automation Pairing OK ---> Actuator: %s , Sensor: %s', element, sensor)
		# check the watering mode
		modelist=["None", "Full Auto" , "Emergency Activation" , "Alert Only"]
		workmode=checkworkmode(element)

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

		if (workmode==""):
			logger.info("Not able to get the workmode: %s " , element)
			return

		logger.info('Automantion, Get all the parameters')
		sensormaxthreshold=hardwaremod.tonumber(automationdbmod.searchdata("element",element,"sensor_threshold")[1],0)
		sensorminthreshold=hardwaremod.tonumber(automationdbmod.searchdata("element",element,"sensor_threshold")[0],sensormaxthreshold)
		actuatormaxthreshold=hardwaremod.tonumber(automationdbmod.searchdata("element",element,"actuator_threshold")[1],0)
		actuatorminthreshold=hardwaremod.tonumber(automationdbmod.searchdata("element",element,"actuator_threshold")[0],actuatormaxthreshold)

		# evaluate variables for operational period check
		now = datetime.now()
		nowtime = now.time()
		starttimeh=hardwaremod.toint(automationdbmod.searchdata("element",element,"allowedperiod")[0].split(":")[0],0)
		starttimem=hardwaremod.toint(automationdbmod.searchdata("element",element,"allowedperiod")[0].split(":")[1],0)
		endtimeh=hardwaremod.toint(automationdbmod.searchdata("element",element,"allowedperiod")[1].split(":")[0],1)
		endtimem=hardwaremod.toint(automationdbmod.searchdata("element",element,"allowedperiod")[1].split(":")[1],0)
		starttime=time(starttimeh,starttimem)
		endtime=time(endtimeh,endtimem)		
		
		# get other parameters
		maxstepnumber=hardwaremod.toint(automationdbmod.searchdata("element",element,"stepnumber"),1)
		waitingtime=hardwaremod.toint(automationdbmod.searchdata("element",element,"pausebetweenwtstepsmin"),1)
		mailtype=automationdbmod.searchdata("element",element,"mailalerttype")
		averageminutes=hardwaremod.tonumber(automationdbmod.searchdata("element",element,"averagesample"),1)
		mathoperation=automationdbmod.searchdata("element",element,"mathoperation")

		# check sensor timetrigger
		sensorcontrolcommand=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,refsensor,hardwaremod.HW_CTRL_CMD)
		logger.info('Sensor control command: %s , Sensor: %s', sensorcontrolcommand, sensor)
		if sensorcontrolcommand=="returnzero":
			logger.info('Modify parameter for the timetrigger')			
			#adjust the parameters in the way the activation condition is always obtained
			sensormaxthreshold=1
			sensorminthreshold=-1
			maxstepnumber=1
			averageminutes=0

		
		# Calculated Variables
		if maxstepnumber<1:
			# not possible to proceed
			print "No Action required, maxstepnumber <1, element: " , element
			logger.info("No Action required, maxstepnumber <1, element: %s " , element)
			return
		interval=(sensormaxthreshold-sensorminthreshold)/maxstepnumber
		actuatorinterval=(actuatormaxthreshold-actuatorminthreshold)/maxstepnumber
		P=[]
		for I in range(0, maxstepnumber+1):
			P.append(actuatorminthreshold+I*actuatorinterval)
		
		
		
		
		# ------------------------ Automation alghoritm
		if workmode=="Full Auto":
			# 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
			if timeok:
				logger.info('inside allowed time')
				isok,sensorvalue=sensorreading(sensor,averageminutes,mathoperation) # operation of sensor readings for a number of sample
				if isok:
					print "Sensor Value ", sensorvalue
					
					if sensorminthreshold<=sensormaxthreshold:
						print "Algorithm , element: " , element
						logger.info("Forward algorithm  , element: %s " , element)
						
					
						Inde=0
						maxs=sensorminthreshold+Inde*interval
						if sensorvalue<=maxs:
							status="belowthreshold"
							logger.info('below Minthreshold')
							value=P[Inde]
							# do relevant stuff	
							CheckActivateNotify(element,waitingtime,value,mailtype,sensor,sensorvalue)
						
						Inde=1
						for I in range(Inde, maxstepnumber):
							mins=sensorminthreshold+(I-1)*interval
							maxs=sensorminthreshold+I*interval
							if mins<sensorvalue<=maxs:
								value=P[I]			
								logger.info('inside Range')		
								# do relevant stuff	
								CheckActivateNotify(element,waitingtime,value,mailtype,sensor,sensorvalue)		
						
						Inde=maxstepnumber
						mins=sensorminthreshold+(Inde-1)*interval										
						if mins<sensorvalue:
							print "INDE:",Inde
							value=P[Inde]
							logger.info('beyond Range')
							# do relevant stuff	
							CheckActivateNotify(element,waitingtime,value,mailtype,sensor,sensorvalue)
						# END MAIN ALGORITHM
						
					else: # to be added case of inverse sensor condition, where the sensorminthreshold is higher than the sensormaxthreshold
						print "Reverse Algorithm , element: " , element
						logger.info("Reverse Algorithm  , element: %s " , element)						
									
						Inde=0
						maxs=sensorminthreshold+Inde*interval
						if sensorvalue>=maxs:
							status="belowthreshold"
							logger.info('Above MAXthreshold')
							value=P[Inde]
							# do relevant stuff	
							CheckActivateNotify(element,waitingtime,value,mailtype,sensor,sensorvalue)
						
						Inde=Inde+1
						for I in range(Inde, maxstepnumber):
							mins=sensorminthreshold+(I-1)*interval
							maxs=sensorminthreshold+I*interval
							if mins>sensorvalue>=maxs:
								value=P[I]					
								# do relevant stuff	
								CheckActivateNotify(element,waitingtime,value,mailtype,sensor,sensorvalue)		
						
						Inde=maxstepnumber
						mins=sensorminthreshold+(Inde-1)*interval										
						if mins>sensorvalue:
							print "INDE:",Inde
							value=P[Inde]
							# do relevant stuff	
							CheckActivateNotify(element,waitingtime,value,mailtype,sensor,sensorvalue)
						# END MAIN ALGORITHM - Reverse				
			else:
				logger.info('No valid calculation operation on the stored sensor data')
				
		elif workmode=="Emergency Activation":
			print "Emergency Activation"		
		
		elif workmode=="Alert Only":
			print "Alert Only"					
							


		# implment Critical alert message in case the sensor value is one interval more than Max_threshold

		isok,sensorvalue=sensorreading(sensor,averageminutes,mathoperation) # operation of sensor readings for a number of sample
		if isok:
			if sensorminthreshold<=sensormaxthreshold:
				if sensorvalue>sensormaxthreshold+interval:
					logger.info('sensor %s exceeding limits', sensor)
					textmessage="CRITICAL: "+ sensor + " reading " + str(sensorvalue) + " exceeding threshold limits, need to check the " + element
					print textmessage
					#send alert mail notification
					alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
					if alertcounter<2:
						emailmod.sendallmail("alert", textmessage)							
						logger.error(textmessage)
						statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)

			else:
				if sensorvalue<sensormaxthreshold+interval:
					logger.info('sensor %s exceeding limits', sensor)
					textmessage="CRITICAL: "+ sensor + " reading " + str(sensorvalue) + " exceeding threshold limits, need to check the " + element
					print textmessage
					#send alert mail notification
					alertcounter=statusdataDBmod.read_status_data(AUTO_data,element,"alertcounter")
					if alertcounter<2:
						emailmod.sendallmail("alert", textmessage)							
						logger.error(textmessage)
						statusdataDBmod.write_status_data(AUTO_data,element,"alertcounter",alertcounter+1)

	return
示例#14
0
def automationexecute(refsensor, element):
    sensor = automationdbmod.searchdata("element", element, "sensor")
    # check the sensor
    if refsensor == sensor:
        logger.info('automation Pairing OK ---> Actuator: %s , Sensor: %s',
                    element, sensor)
        # check the watering mode
        modelist = ["None", "Full Auto", "Emergency Activation", "Alert Only"]
        workmode = checkworkmode(element)

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

        if (workmode == ""):
            logger.info("Not able to get the workmode: %s ", element)
            return

        logger.info('Automantion, Get all the parameters')
        sensormaxthreshold = hardwaremod.tonumber(
            automationdbmod.searchdata("element", element,
                                       "sensor_threshold")[1], 0)
        sensorminthreshold = hardwaremod.tonumber(
            automationdbmod.searchdata("element", element,
                                       "sensor_threshold")[0],
            sensormaxthreshold)
        actuatormaxthreshold = hardwaremod.tonumber(
            automationdbmod.searchdata("element", element,
                                       "actuator_threshold")[1], 0)
        actuatorminthreshold = hardwaremod.tonumber(
            automationdbmod.searchdata("element", element,
                                       "actuator_threshold")[0],
            actuatormaxthreshold)

        # evaluate variables for operational period check

        starttime = datetime.strptime(
            automationdbmod.searchdata("element", element, "allowedperiod")[0],
            '%H:%M').time()
        endtime = datetime.strptime(
            automationdbmod.searchdata("element", element, "allowedperiod")[1],
            '%H:%M').time()

        # get other parameters
        maxstepnumber = hardwaremod.toint(
            automationdbmod.searchdata("element", element, "stepnumber"), 1)
        waitingtime = hardwaremod.toint(
            automationdbmod.searchdata("element", element,
                                       "pausebetweenwtstepsmin"), 1)
        mailtype = automationdbmod.searchdata("element", element,
                                              "mailalerttype")
        averageminutes = hardwaremod.tonumber(
            automationdbmod.searchdata("element", element, "averagesample"), 1)
        mathoperation = automationdbmod.searchdata("element", element,
                                                   "mathoperation")

        # check sensor timetrigger
        sensorcontrolcommand = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,
                                                      refsensor,
                                                      hardwaremod.HW_CTRL_CMD)
        logger.info('Sensor control command: %s , Sensor: %s',
                    sensorcontrolcommand, sensor)
        if sensorcontrolcommand == "returnzero":
            logger.info('Modify parameter for the timetrigger')
            #adjust the parameters in the way the activation condition is always obtained
            sensormaxthreshold = 1
            sensorminthreshold = -1
            maxstepnumber = 1
            averageminutes = 0

        # Calculated Variables
        if maxstepnumber < 1:
            # not possible to proceed
            print "No Action required, maxstepnumber <1, element: ", element
            logger.info("No Action required, maxstepnumber <1, element: %s ",
                        element)
            return
        interval = (sensormaxthreshold - sensorminthreshold) / maxstepnumber
        actuatorinterval = (actuatormaxthreshold -
                            actuatorminthreshold) / maxstepnumber
        P = []
        for I in range(0, maxstepnumber + 1):
            P.append(actuatorminthreshold + I * actuatorinterval)

        # ------------------------ Automation alghoritm
        if workmode == "Full Auto":
            # check if inside the allowed time period
            print "full Auto Mode"
            logger.info('full auto mode --> %s', element)
            timeok = isNowInTimePeriod(
                starttime, endtime,
                datetime.now().time())  # don't use UTC here!
            print "inside allowed time ", timeok, " starttime ", starttime, " endtime ", endtime
            if timeok:
                logger.info('inside allowed time')
                isok, sensorvalue = sensorreading(
                    sensor, averageminutes, mathoperation
                )  # operation of sensor readings for a number of sample
                if isok:
                    print "Sensor Value ", sensorvalue

                    if sensorminthreshold <= sensormaxthreshold:
                        print "Algorithm , element: ", element
                        logger.info("Forward algorithm  , element: %s ",
                                    element)

                        Inde = 0
                        maxs = sensorminthreshold + Inde * interval
                        if sensorvalue <= maxs:
                            status = "belowthreshold"
                            logger.info('below Minthreshold')
                            value = P[Inde]
                            # do relevant stuff
                            CheckActivateNotify(element, waitingtime, value,
                                                mailtype, sensor, sensorvalue)

                        Inde = 1
                        for I in range(Inde, maxstepnumber):
                            mins = sensorminthreshold + (I - 1) * interval
                            maxs = sensorminthreshold + I * interval
                            if mins < sensorvalue <= maxs:
                                value = P[I]
                                logger.info('inside Range')
                                # do relevant stuff
                                CheckActivateNotify(element, waitingtime,
                                                    value, mailtype, sensor,
                                                    sensorvalue)

                        Inde = maxstepnumber
                        mins = sensorminthreshold + (Inde - 1) * interval
                        if mins < sensorvalue:
                            print "INDE:", Inde
                            value = P[Inde]
                            logger.info('beyond Range')
                            # do relevant stuff
                            CheckActivateNotify(element, waitingtime, value,
                                                mailtype, sensor, sensorvalue)
                        # END MAIN ALGORITHM

                    else:  # to be added case of inverse sensor condition, where the sensorminthreshold is higher than the sensormaxthreshold
                        print "Reverse Algorithm , element: ", element
                        logger.info("Reverse Algorithm  , element: %s ",
                                    element)

                        Inde = 0
                        maxs = sensorminthreshold + Inde * interval
                        if sensorvalue >= maxs:
                            status = "belowthreshold"
                            logger.info('Above MAXthreshold')
                            value = P[Inde]
                            # do relevant stuff
                            CheckActivateNotify(element, waitingtime, value,
                                                mailtype, sensor, sensorvalue)

                        Inde = Inde + 1
                        for I in range(Inde, maxstepnumber):
                            mins = sensorminthreshold + (I - 1) * interval
                            maxs = sensorminthreshold + I * interval
                            if mins > sensorvalue >= maxs:
                                value = P[I]
                                # do relevant stuff
                                CheckActivateNotify(element, waitingtime,
                                                    value, mailtype, sensor,
                                                    sensorvalue)

                        Inde = maxstepnumber
                        mins = sensorminthreshold + (Inde - 1) * interval
                        if mins > sensorvalue:
                            print "INDE:", Inde
                            value = P[Inde]
                            # do relevant stuff
                            CheckActivateNotify(element, waitingtime, value,
                                                mailtype, sensor, sensorvalue)
                        # END MAIN ALGORITHM - Reverse
                else:
                    logger.error(
                        'No valid calculation operation on the stored sensor data'
                    )
            else:
                logger.info('Outside allowed Time, Stop')

        elif workmode == "Emergency Activation":
            print "Emergency Activation"

        elif workmode == "Alert Only":
            print "Alert Only"

        # implment Critical alert message in case the sensor value is one interval more than Max_threshold

        isok, sensorvalue = sensorreading(
            sensor, averageminutes, mathoperation
        )  # operation of sensor readings for a number of sample
        if isok:
            if sensorminthreshold <= sensormaxthreshold:
                if sensorvalue > sensormaxthreshold + interval:
                    logger.info('sensor %s exceeding limits', sensor)
                    textmessage = "CRITICAL: " + sensor + " reading " + str(
                        sensorvalue
                    ) + " exceeding threshold limits, need to check the " + element
                    print textmessage
                    #send alert mail notification
                    alertcounter = statusdataDBmod.read_status_data(
                        AUTO_data, element, "alertcounter")
                    if alertcounter < 2:
                        if (mailtype != "none"):
                            emailmod.sendallmail("alert", textmessage)
                        logger.error(textmessage)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "alertcounter",
                            alertcounter + 1)

            else:
                if sensorvalue < sensormaxthreshold + interval:
                    logger.info('sensor %s exceeding limits', sensor)
                    textmessage = "CRITICAL: " + sensor + " reading " + str(
                        sensorvalue
                    ) + " exceeding threshold limits, need to check the " + element
                    print textmessage
                    #send alert mail notification
                    alertcounter = statusdataDBmod.read_status_data(
                        AUTO_data, element, "alertcounter")
                    if alertcounter < 2:
                        if (mailtype != "none"):
                            emailmod.sendallmail("alert", textmessage)
                        logger.error(textmessage)
                        statusdataDBmod.write_status_data(
                            AUTO_data, element, "alertcounter",
                            alertcounter + 1)

    return
示例#15
0
def connect_network(internetcheck=False, backtoAP=False):
    # this is the procedure that disable the AP and connect to wifi network
    connected = False
    print " try to connect to wifi network"
    thessid = connect_preconditions(
    )  # get the first SSID of saved wifi network to connect with and see if the SSID is on air

    if not thessid == "":
        print "preconditions to connect to wifi network are met"
        logger.info('preconditions to connect to wifi network are met')
        ssids = connectedssid()  # get the SSID currently connected
        if len(ssids) > 0:
            ssid = ssids[0]
        else:
            ssid = ""

        if not ssid == thessid:
            print "try to connect to wifi network"
            logger.info('try to connect to wifi network %s ', thessid)
            print "try to stop AP services, hostapd, dnsmasq"
            logger.info('try to stop AP services, hostapd, dnsmasq ')
            i = 0
            done = False
            while (i < 2) and (not done):
                done = stop_hostapd()
                i = i + 1
            i = 0
            done = False
            while (i < 2) and (not done):
                done = stop_dnsmasq()
                i = i + 1

            done = False
            ssids = []
            i = 0
            while (i < 3) and (len(ssids) == 0):
                done = connect_savedwifi(
                    thessid)  # return true when the command is executed
                i = i + 1
                if done:
                    time.sleep(1 + i * 5)
                    print "wifi connection attempt ", i
                    print "check connected SSID"
                    logger.info(
                        'Connection command executed attempt %d, check connected SSID ',
                        i)
                else:
                    print "Connection command NOT executed properly , attempt ", i
                    logger.info(
                        'Connection command NOT executed properly , attempt %d ',
                        i)
                ssids = connectedssid()

            if len(ssids) > 0:
                ssid = ssids[0]
            else:
                ssid = ""
                logger.info('NO connected SSID')
            print "Connected to the SSID ", ssid
            logger.info('Connected SSID: %s -- ', ssid)
            addIP("wlan0")

        else:
            print "already connected to the SSID ", ssid

        if len(ssids) == 0:
            print "No SSID established, fallback to AP mode"
            # go back and connect in Access point Mode
            logger.info(
                'No Wifi Network connected, no AP connected, going back to Access Point mode'
            )
            connect_AP()
            connected = False
        else:
            logger.info('Connected to Wifi Network %s', ssid)
            print 'Connected to Wifi Network ', ssid

            # here it is needed to have a real check of the internet connection as for example google
            if internetcheck:
                connected = check_internet_connection(3)
                if connected:
                    print "Google is reacheable !"
                    logger.info('Google is reacheable ! ')
                    #send first mail
                    print "Send first mail !"
                    logger.info('Send first mail ! ')
                    emailmod.sendallmail(
                        "alert", "System has been reconnected to wifi network")
                else:
                    if backtoAP:
                        print "Connectivity problem with WiFi network ", ssid[
                            0], "going back to wifi access point mode"
                        logger.info(
                            'Connectivity problem with WiFi network, %s, gong back to wifi access point mode',
                            ssid)
                        connect_AP()
            else:
                connected = True
            logger.info(
                'wait and check if the heartbeat job is still scheduled')
            #pulsesecond=180
            #selectedplanmod.waitandcheckheartbeat(pulsesecond)
            #use CPU cycles as way to delay, cannot be based on clock info, clock jumps happen as soon as NTP is providing the datatime to the system
            pausecycles = 10000000
            for i in range(1, pausecycles):
                b = i * 0.1
            selectedplanmod.checkheartbeat()

    else:
        print "No Saved Wifi Network available"
        logger.info('No Saved Wifi Network available')
        print "try to fallback to AP mode"
        # go back and connect in Access point Mode
        #logger.info('Going back to Access Point mode')
        #connect_AP()
        connected = False

    return connected
示例#16
0
def connect_network(internetcheck=False, backtoAP=False):
    # this is the procedure that disable the AP and connect to wifi network
    connected = False
    print " try to connect to wifi network"
    thessid = connect_preconditions(
    )  # get the first SSID of saved wifi network to connect with and see if the SSID is on air

    if not thessid == "":
        print "preconditions to connect to wifi network are met"
        logger.info('preconditions to connect to wifi network are met')
        ssids = connectedssid()  # get the SSID currently connected
        if len(ssids) > 0:
            ssid = ssids[0]
        else:
            ssid = ""

        if not ssid == thessid:
            print "try to connect to wifi network"
            logger.info('try to connect to wifi network %s ', thessid)
            print "try to stop AP services, hostapd, dnsmasq"
            logger.info('try to stop AP services, hostapd, dnsmasq ')
            i = 0
            done = False
            while (i < 2) and (not done):
                done = stop_hostapd()
                i = i + 1
            i = 0
            done = False
            while (i < 2) and (not done):
                done = stop_dnsmasq()
                i = i + 1

            done = False
            ssids = []
            i = 0
            while (i < 3) and (len(ssids) == 0):
                done = connect_savedwifi(
                    thessid)  # return true when the command is executed
                i = i + 1
                if done:
                    time.sleep(1 + i * 5)
                    print "wifi connection attempt ", i
                    print "check connected SSID"
                    logger.info(
                        'Connection command executed attempt %d, check connected SSID ',
                        i)
                else:
                    print "Connection command NOT executed properly , attempt ", i
                    logger.info(
                        'Connection command NOT executed properly , attempt %d ',
                        i)
                ssids = connectedssid()

            if len(ssids) > 0:
                ssid = ssids[0]
            else:
                ssid = ""
                logger.info('NO connected SSID')
            print "Connected to the SSID ", ssid
            logger.info('Connected SSID: %s -- ', ssid)
            addIP("wlan0")

        else:
            print "already connected to the SSID ", ssid

        if len(ssids) == 0:
            print "No SSID established, fallback to AP mode"
            # go back and connect in Access point Mode
            logger.info(
                'No Wifi Network connected, no AP connected, going back to Access Point mode'
            )
            connect_AP()
            connected = False
        else:
            logger.info('Connected to Wifi Network %s', ssid)
            print 'Connected to Wifi Network ', ssid

            # here it is needed to have a real check of the internet connection as for example google
            if internetcheck:
                connected = check_internet_connection(3)
                if connected:
                    print "Google is reacheable !"
                    logger.info('Google is reacheable ! ')
                    #send first mail
                    print "Send first mail !"
                    logger.info('Send first mail ! ')
                    emailmod.sendallmail(
                        "alert", "System has been reconnected to wifi network")
                else:
                    if backtoAP:
                        print "Connectivity problem with WiFi network ", ssid[
                            0], "going back to wifi access point mode"
                        logger.info(
                            'Connectivity problem with WiFi network, %s, gong back to wifi access point mode',
                            ssid)
                        connect_AP()
            else:
                connected = True

            # ALL below not needed anymore since I disabled the NTP network time protocal daemon *****

    else:
        print "No Saved Wifi Network available"
        logger.info('No Saved Wifi Network available')
        print "try to fallback to AP mode"
        # go back and connect in Access point Mode
        #logger.info('Going back to Access Point mode')
        #connect_AP()
        connected = False

    return connected
示例#17
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