Beispiel #1
0
def sensorsysinfomatrix():
	# first row includes headers
	matrix=[]
	row=[]
	row.append("Name")
	row.append("Use")
	row.append("Unit")
	row.append("Average 24H")	
	matrix.append(row)
	
	namelist=hardwaremod.searchdatalist(hardwaremod.HW_CTRL_CMD,"pulse",hardwaremod.HW_INFO_NAME)
	for name in namelist:
		row=[]
		row.append(name)
		row.append(hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,name,hardwaremod.HW_FUNC_USEDFOR))
		row.append(hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,name,hardwaremod.HW_INFO_MEASUREUNIT))

		endtime=datetime.now()
		starttime= endtime - timedelta(days=1)
		data=[]
		getActuatordbdata(name,data)
		evaluateddata=EvaluateDataPeriod(data,starttime,endtime)	#set date interval for average

		row.append(str('%.1f' % (evaluateddata["sum"]/1000)))

		matrix.append(row)
	
	return matrix
def checkstopcondition(element):
    print "Evaluating End of Blocking period ++++++++++++"
    actionmodeafterfirst = interruptdbmod.searchdata("element", element,
                                                     "actionmode_afterfirst")
    print actionmodeafterfirst
    if actionmodeafterfirst == "Extend blocking state" or actionmodeafterfirst == "Extend and Follo-up":  # extend only the pre-emption blocking period, no action
        seonsormode = interruptdbmod.searchdata("element", element,
                                                "sensor_mode")
        print seonsormode
        if seonsormode == "Edge + Level":
            sensor = interruptdbmod.searchdata("element", element, "sensor")
            recordkey = hardwaremod.HW_INFO_NAME
            recordvalue = sensor
            keytosearch = hardwaremod.HW_CTRL_PIN
            PIN = hardwaremod.searchdata(recordkey, recordvalue, keytosearch)
            reading = hardwaremod.readinputpin(PIN)
            keytosearch = hardwaremod.HW_CTRL_LOGIC
            logic = hardwaremod.searchdata(recordkey, recordvalue, keytosearch)
            # pin high according to the set logic
            print "logic:", logic, " reading:", reading
            if logic == "pos" and reading == "1":
                return False
            if logic == "neg" and reading == "0":
                return False

    return True
Beispiel #3
0
def sensorsysinfomatrix():
    # first row includes headers
    matrix = []
    row = []
    row.append("Name")
    row.append("Use")
    row.append("Unit")
    row.append("Average 24H")
    matrix.append(row)

    namelist = hardwaremod.searchdatalist(hardwaremod.HW_CTRL_CMD, "pulse",
                                          hardwaremod.HW_INFO_NAME)
    for name in namelist:
        row = []
        row.append(name)
        row.append(
            hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, name,
                                   hardwaremod.HW_FUNC_USEDFOR))
        row.append(
            hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, name,
                                   hardwaremod.HW_INFO_MEASUREUNIT))

        endtime = datetime.now()
        starttime = endtime - timedelta(days=1)
        data = []
        getActuatordbdata(name, data)
        isok, evaluateddata = EvaluateDataPeriod(
            data, starttime, endtime)  #set date interval for average

        row.append(str('%.1f' % (evaluateddata["sum"])))

        matrix.append(row)

    return matrix
Beispiel #4
0
def sensorsysinfomatrix():
    # first row includes headers
    matrix = []
    row = []
    row.append("Sensor Name")
    row.append("Measure")
    row.append("Unit")
    row.append("Average 24H")
    row.append("Min 24H")
    row.append("Max 24H")
    matrix.append(row)

    namelist = gettablelist()
    for name in namelist:
        row = []
        row.append(name)
        row.append(
            hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, name,
                                   hardwaremod.HW_INFO_MEASURE))
        row.append(
            hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, name,
                                   hardwaremod.HW_INFO_MEASUREUNIT))

        sensordata = []
        getsensordbdatadays(name, sensordata, 1)
        #set date interval for average
        endtime = datetime.now()
        starttime = endtime - timedelta(days=1)
        evaluateddata = EvaluateDataPeriod(sensordata, starttime, endtime)
        row.append(str('%.1f' % evaluateddata["average"]))
        row.append(str('%.1f' % evaluateddata["min"]))
        row.append(str('%.1f' % evaluateddata["max"]))
        matrix.append(row)

    return matrix
Beispiel #5
0
def checkstopcondition(element):
	#print "Evaluating End of Blocking period ++++++++++++"
	actionmodeafterfirst=interruptdbmod.searchdata("element",element,"actionmode_afterfirst")
	#print "actionafter " , actionmodeafterfirst
	sensor=interruptdbmod.searchdata("element",element,"sensor")


	
	if actionmodeafterfirst=="Extend blocking state" or actionmodeafterfirst=="Extend and Follow-up": # extend the pre-emption blocking period
		seonsormode=interruptdbmod.searchdata("element",element,"sensor_mode")
		#print "SENSORMODE" , seonsormode
		recordkey=hardwaremod.HW_INFO_NAME
		recordvalue=sensor	
		keytosearch=hardwaremod.HW_CTRL_PIN
		PIN=hardwaremod.searchdata(recordkey,recordvalue,keytosearch)
		reading=hardwaremod.readinputpin(PIN)		

		if seonsormode=="First Edge + Level":	
			keytosearch=hardwaremod.HW_CTRL_LOGIC
			logic=hardwaremod.searchdata(recordkey,recordvalue,keytosearch)			
			# pin high according to the set logic
			#print "logic:", logic , " reading:"  ,reading
			if (logic=="pos" and reading=="1")or(logic=="neg" and reading=="0"):
				return False

		elif seonsormode=="Second Edge + Level (inv)":
			keytosearch=hardwaremod.HW_CTRL_LOGIC
			logic=hardwaremod.searchdata(recordkey,recordvalue,keytosearch)			
			#pin LOW according to the set logic
			#print "logic:", logic , " reading:"  ,reading
			if (logic=="pos" and reading=="0")or(logic=="neg" and reading=="1"):
				return False


	return True		
Beispiel #6
0
def sendmail(hwname,mailtype,intromessage,bodytextlist=[]):
	address=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,hwname,hardwaremod.HW_CTRL_ADDR)
	
	if not address=="":
		print "mail recipient ", address
		title=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,hwname,hardwaremod.HW_CTRL_TITLE)
		print "mail title " , title
		cmd=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,hwname,hardwaremod.HW_CTRL_CMD)
		print "mail type " , cmd
		issent=send_email_main(address,title,cmd,mailtype,intromessage,bodytextlist)
		return issent
	else:
		print "No address specified"
		logger.warning('No address specified')
		return False
Beispiel #7
0
def sendmail(hwname,mailtype,intromessage,bodytextlist=[]):
	address=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,hwname,hardwaremod.HW_CTRL_MAILADDR)
	
	if not address=="":
		print "mail recipient ", address
		title=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,hwname,hardwaremod.HW_CTRL_MAILTITLE)
		print "mail title " , title
		cmd=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,hwname,hardwaremod.HW_CTRL_CMD)
		print "mail type " , cmd
		issent=send_email_main(address,title,cmd,mailtype,intromessage,bodytextlist)
		return issent
	else:
		print "No address specified"
		logger.error('No address specified')
		return False
Beispiel #8
0
def activateactuator(target, value):  # return true in case the state change: activation is >0 or a different position from prevoius position.
	# check the actuator 
	isok=False
	actuatortype=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,target,hardwaremod.HW_CTRL_CMD)
	supportedactuators=["pulse","servo","stepper"]
	# stepper motor
	if actuatortype=="stepper":
		out, isok = hardwaremod.GO_stepper_position(target,value)
		if isok:
			actuatordbmod.insertdataintable(target,value)
	
	# pulse
	if actuatortype=="pulse":
		duration=1000*hardwaremod.toint(value,0)
		# check the fertilizer doser flag before activating the pulse
		doseron=autofertilizermod.checkactivate(target,duration)
		# start pulse
		pulseok=hardwaremod.makepulse(target,duration)	
		# salva su database
		if "Started" in pulseok:
			actuatordbmod.insertdataintable(target,duration)
			isok=True
		
	# servo motor 
	if actuatortype=="servo":
		out, isok = hardwaremod.servoangle(target,value,0.5)
		if isok:
			actuatordbmod.insertdataintable(target,value)
			
	return isok
Beispiel #9
0
def activateactuator(
    target, value
):  # return true in case the state change: activation is >0 or a different position from prevoius position.
    # check the actuator
    isok = False
    actuatortype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, target,
                                          hardwaremod.HW_CTRL_CMD)
    supportedactuators = ["pulse", "servo", "stepper"]
    # stepper motor
    if actuatortype == "stepper":
        out, isok = hardwaremod.GO_stepper_position(target, value)
        if isok:
            actuatordbmod.insertdataintable(target, value)

    # pulse
    if actuatortype == "pulse":
        duration = 1000 * hardwaremod.toint(value, 0)
        # check the fertilizer doser flag before activating the pulse
        doseron = autofertilizermod.checkactivate(element, duration)
        # start pulse
        pulseok = hardwaremod.makepulse(target, duration)
        # salva su database
        if "Started" in pulseok:
            actuatordbmod.insertdataintable(target, duration)
            isok = True

    # servo motor
    if actuatortype == "servo":
        out, isok = hardwaremod.servoangle(target, value, 0.5)
        if isok:
            actuatordbmod.insertdataintable(target, value)

    return isok
Beispiel #10
0
def activateactuator(target, value):  # return true in case the state change: activation is >0 or a different position from prevoius position.
	# check the actuator 
	isok=False
	actuatortype=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,target,hardwaremod.HW_CTRL_CMD)
	actuatortypelist=actuatortype.split("/")
	if actuatortypelist:
		actuatortype=actuatortypelist[0]
	print (" Automation Actuator " + actuatortype + "  target " +  target)
	supportedactuators=["pulse","servo","stepper"]
	# stepper motor
	if actuatortype=="stepper":
		out, isok = hardwaremod.GO_stepper_position(target,value)
		if isok:
			actuatordbmod.insertdataintable(target,value)

	# hbridge motor
	if actuatortype=="hbridge":
		out, isok = hardwaremod.GO_hbridge_position(target,value)
		if isok:
			actuatordbmod.insertdataintable(target,value)
			
	# pulse
	if actuatortype=="pulse":
		duration=hardwaremod.toint(value,0)
		# check the fertilizer doser flag before activating the pulse
		doseron=autofertilizermod.checkactivate(target,duration)
		# start pulse
		pulseok=hardwaremod.makepulse(target,duration)	
		# salva su database
		if "Started" in pulseok:
			actuatordbmod.insertdataintable(target,duration)
			isok=True
		
	# servo motor 
	if actuatortype=="servo":
		out, isok = hardwaremod.servoangle(target,value,0.5)
		if isok:
			actuatordbmod.insertdataintable(target,value)
			
	# photo 
	if actuatortype=="photo":
		duration=hardwaremod.toint(value,0)
		if duration>0:
			isok=hardwaremod.takephoto(True)
			# save action in database
			if isok:
				actuatordbmod.insertdataintable(target,1)	

	# mail 
	if (actuatortype=="mail+info+link")or(actuatortype=="mail+info"):
		if value>0:
			mailtext=str(value)			
			isok=emailmod.sendmail(target,"info","Automation Value:" + mailtext)
			# save action in database
			if isok:
				actuatordbmod.insertdataintable(target,1)				
				
			
	return isok
Beispiel #11
0
def activateactuator(target, value):  # return true in case the state change: activation is >0 or a different position from prevoius position.
	# check the actuator 
	isok=False
	actuatortype=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,target,hardwaremod.HW_CTRL_CMD)
	supportedactuators=["pulse","servo","stepper"]
	# stepper motor
	if actuatortype=="stepper":
		out, isok = hardwaremod.GO_stepper_position(target,value,priority=ACTIONPRIORITYLEVEL)
		if isok:
			actuatordbmod.insertdataintable(target,value)
	
	# hbridge motor
	if actuatortype=="hbridge":
		out, isok = hardwaremod.GO_hbridge_position(target,value)
		if isok:
			actuatordbmod.insertdataintable(target,value)
	
	# pulse
	if actuatortype=="pulse":
		duration=hardwaremod.toint(value,0)
		if duration>0:
			# check the fertilizer doser flag before activating the pulse
			doseron=autofertilizermod.checkactivate(target,duration)
			# start pulse
			pulseok=hardwaremod.makepulse(target,duration,priority=ACTIONPRIORITYLEVEL)	
			# salva su database
			if "Started" in pulseok:
				actuatordbmod.insertdataintable(target,duration)
				isok=True
		else:
			pulseok=hardwaremod.stoppulse(target)
		
	# servo motor 
	if actuatortype=="servo":
		out, isok = hardwaremod.servoangle(target,value,0.5,priority=ACTIONPRIORITYLEVEL)
		if isok:
			actuatordbmod.insertdataintable(target,value)

	# photo 
	if actuatortype=="photo":
		duration=hardwaremod.toint(value,0)
		if duration>0:
			isok=hardwaremod.takephoto(True) # True override the daily activation
			# save action in database
			if isok:
				actuatordbmod.insertdataintable(target,1)	
				
	# mail 
	if (actuatortype=="mail+info+link")or(actuatortype=="mail+info"):
		if value>0:
			mailtext=str(value)	
			isok=emailmod.sendmail(target,"info","Interrupt Value:" + mailtext)
			# save action in database
			if isok:
				actuatordbmod.insertdataintable(target,1)

			
	return isok
Beispiel #12
0
def getsensordbdatadays(selsensor, sensordata, days):
    fieldlist = []
    fieldlist.append(TIMEFIELD)
    fieldlist.append(DATAFIELD)
    sampletime = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, selsensor,
                                        hardwaremod.HW_FUNC_TIME)
    samplingintervalminutes = int(sampletime.split(":")[1])
    samplesnumber = (days * 24 * 60) / samplingintervalminutes
    databasemod.getdatafromfieldslimit(DBFILENAME, selsensor, fieldlist,
                                       sensordata, samplesnumber)
Beispiel #13
0
def getsensordbdatadays(selsensor, sensordata, days):
    fieldlist = []
    fieldlist.append(TIMEFIELD)
    fieldlist.append(DATAFIELD)
    sampletime = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, selsensor,
                                        hardwaremod.HW_FUNC_TIME)
    schedtype = hardwaremod.searchdata(
        hardwaremod.HW_INFO_NAME, selsensor, hardwaremod.HW_FUNC_SCHEDTYPE
    )  # ["oneshot", "periodic"] #scheduling type
    if (sampletime != "") and (schedtype == "periodic"):
        samplingintervalminutes = int(sampletime.split(":")[1])
        if samplingintervalminutes >= 1:
            samplesnumber = old_div((days * 24 * 60), samplingintervalminutes)
            databasemod.getdatafromfieldslimit(DBFILENAME, selsensor,
                                               fieldlist, sensordata,
                                               samplesnumber)
        else:
            databasemod.getdatafromfields(DBFILENAME, selsensor, fieldlist,
                                          sensordata)
    else:
        databasemod.getdatafromfields(DBFILENAME, selsensor, fieldlist,
                                      sensordata)
def setinterruptevents():

    hardwaremod.removeallinterruptevents()

    print "load interrupt list "
    interruptlist = interruptdbmod.sensorlist()
    print "len interrupt list ", len(interruptlist)
    for item in interruptlist:
        print "got into the loop "
        # get PIN number

        recordkey = hardwaremod.HW_INFO_NAME
        recordvalue = item
        keytosearch = hardwaremod.HW_CTRL_PIN
        PINstr = hardwaremod.searchdata(recordkey, recordvalue, keytosearch)
        print "set event for the PIN ", PINstr
        PIN = hardwaremod.toint(PINstr, -1)
        if PIN > -1:

            keytosearch = hardwaremod.HW_CTRL_LOGIC
            logic = hardwaremod.searchdata(recordkey, recordvalue, keytosearch)
            # set Sw pull up / down mode

            if logic == "pos":
                hardwaremod.GPIO_setup(PIN, "in", "pull_down")
                evenslopetype = "both"
            else:
                hardwaremod.GPIO_setup(PIN, "in", "pull_up")
                evenslopetype = "both"

            #GPIO.RISING, GPIO.FALLING or GPIO.BOTH.
            # ignoring further edges for 200ms for switch bounce handling
            # link to the callback function
            hardwaremod.GPIO_add_event_detect(PIN, evenslopetype,
                                              eventcallback)

    return ""
def eventcallback(PIN):
    t.sleep(0.05)
    reading = hardwaremod.readinputpin(PIN)
    recordkey = hardwaremod.HW_CTRL_PIN
    recordvalue = str(PIN)
    keytosearch = hardwaremod.HW_INFO_NAME
    refsensor = hardwaremod.searchdata(recordkey, recordvalue, keytosearch)
    print "reference sensor:", refsensor
    if reading == "1":
        print "*************************  Rising edge detected on PIN:", PIN
        if refsensor != "":
            interruptcheck(refsensor)
    else:
        print "Falling edge detected on PIN", PIN
    if refsensor != "":
        x = threading.Thread(target=savedata, args=(refsensor, reading))
        x.start()
Beispiel #16
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
Beispiel #17
0
def getsensordbdatadaysV2(selsensor, sensordata, startdate,
                          enddate):  # V2 try to optimize access to database
    fieldlist = []
    fieldlist.append(TIMEFIELD)
    fieldlist.append(DATAFIELD)
    #sampletime=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,selsensor,hardwaremod.HW_FUNC_TIME)

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

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

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

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

        except:
            print("Error in database reading ")
Beispiel #18
0
def mastercallback(fromscheduledtime=False):
    print("master callback")
    if fromscheduledtime:  # check if the time this function is called is the same as the expected time it should be called (solar/legal time might mess with it)
        logger.info(
            'Master scheduler call at scheduled local time, expected time %s',
            MASTERSCHEDULERTIME)
        thedateloc = datetime.now()
        timelist = hardwaremod.separatetimestringint(MASTERSCHEDULERTIME)
        masterschedtime = thedateloc.replace(hour=timelist[0],
                                             minute=timelist[1],
                                             second=timelist[2])
        secondsdifference = abs((thedateloc - masterschedtime).total_seconds())
        logger.info(
            'Master scheduler, difference between expected time and local time %d',
            secondsdifference)
        if secondsdifference > 300:  # more than 5 minutes
            logger.warning(
                'Master scheduler, difference between expected time and local time greater than 5 minutes, RESET MASTER SCHEDULER'
            )
            resetmastercallback()
            return
        # clean old data of the database (pastdays)
        logger.info('Remove data exceeding one year')
        pastdays = hardwaremod.toint(STOREPASTDAYS, 364)
        logger.info('Sensor Remove data exceeding one year')
        sensordbmod.RemoveSensorDataPeriod(pastdays)
        logger.info('Actuator Remove data exceeding one year')
        actuatordbmod.RemoveActuatorDataPeriod(pastdays)
        logger.info('Photo Remove data exceeding one year')
        hardwaremod.removephotodataperiod(pastdays)
    else:
        logger.info('Master scheduler call not coming from scheduler')

    logger.info('Scheduling main activities')

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

    # set the individual callback of the day

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

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

    #this callback is used only for system status periodic check

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

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

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

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

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

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

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

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

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

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

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

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

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

    # empty
    #<---->

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

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

    callback = "waterpump"

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

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

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

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

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

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

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

    callback = "doser"

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

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

    logger.info('Start other scheduler activities - finish')
    return True
Beispiel #19
0
def interruptexecute(refsensor, element):

    sensor = refsensor
    #logger.info('interrupt Pairing OK ---> Actuator: %s , Sensor: %s', element, sensor)

    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('Interrupt, Get all the parameters')
    interrupt_validinterval = hardwaremod.tonumber(
        interruptdbmod.searchdata("element", element,
                                  "interrupt_validinterval"), 0)
    #"Counter Only"
    if workmode == "Counter Only":
        CounterOnlyNew(element, sensor, interrupt_validinterval)
        return

    interrupt_triggernumber = hardwaremod.tonumber(
        interruptdbmod.searchdata("element", element,
                                  "interrupt_triggernumber"), 1)
    actuatoroutput = hardwaremod.tonumber(
        interruptdbmod.searchdata("element", element, "actuator_output"), 0)
    actuatoroutputfollowup = hardwaremod.tonumber(
        interruptdbmod.searchdata("element", element, "folloup_output"), 0)

    # evaluate variables for operational period check
    starttime = datetime.strptime(
        interruptdbmod.searchdata("element", element, "allowedperiod")[0],
        '%H:%M').time()
    endtime = datetime.strptime(
        interruptdbmod.searchdata("element", element, "allowedperiod")[1],
        '%H:%M').time()

    # get other parameters
    seonsormode = interruptdbmod.searchdata("element", element, "sensor_mode")

    triggermode = interruptdbmod.searchdata("element", element, "trigger_mode")

    preemptiontimemin = hardwaremod.toint(
        interruptdbmod.searchdata("element", element, "preemptive_period"), 0)

    if preemptiontimemin == 0:
        # if relay, meaning cmd = pulse
        actuatortype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,
                                              element, hardwaremod.HW_CTRL_CMD)
        if actuatortype == "pulse":
            preemptiontime = actuatoroutput  # if set to zero then get the time as the actuator (in case of relay)
        else:
            preemptiontime = 0
    else:
        preemptiontime = preemptiontimemin * 60

    mailtype = interruptdbmod.searchdata("element", element, "mailalerttype")

    actionmodeafterfirst = interruptdbmod.searchdata("element", element,
                                                     "actionmode_afterfirst")

    # time check

    # ------------------------ interrupt alghoritm

    if workmode == "Pre-emptive Blocking":
        # check if inside the allowed time period
        #print "Pre-emptive Blocking Mode"
        #logger.info('Pre-emptive Blocking 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:

            CheckActivateNotify(element, sensor, preemptiontime,
                                actuatoroutput, actionmodeafterfirst,
                                actuatoroutputfollowup, mailtype,
                                interrupt_triggernumber,
                                interrupt_validinterval, triggermode)

        else:
            logger.info('out of allowed operational time')

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

    return
Beispiel #20
0
def setinterruptevents():

    hardwaremod.removeallinterruptevents()

    print("load interrupt list ")
    interruptlist = interruptdbmod.sensorlist()
    print("len interrupt list ", len(interruptlist))
    for item in interruptlist:
        print("got into the loop ")
        # get PIN number

        recordkey = hardwaremod.HW_INFO_NAME
        recordvalue = item
        keytosearch = hardwaremod.HW_CTRL_PIN
        PINstr = hardwaremod.searchdata(recordkey, recordvalue, keytosearch)
        print("set event for the PIN ", PINstr)
        if not PINstr == "":

            keytosearch = hardwaremod.HW_CTRL_LOGIC
            logic = hardwaremod.searchdata(recordkey, recordvalue, keytosearch)
            # set Sw pull up / down mode

            if logic == "pos":
                hardwaremod.GPIO_setup(PINstr, "in", "pull_down")
                evenslopetype = "both"
            else:
                hardwaremod.GPIO_setup(PINstr, "in", "pull_up")
                evenslopetype = "both"

            #GPIO.RISING, GPIO.FALLING or GPIO.BOTH.
            # link to the callback function

            # the bouncetime is set by the frequency parameter, if this parameter is empty, the default bouncetime would be 200

            keytosearch = hardwaremod.HW_CTRL_FREQ
            frequency = hardwaremod.searchdata(recordkey, recordvalue,
                                               keytosearch)
            if frequency == "":
                bouncetimeINT = 200
            else:
                frequencyINT = hardwaremod.toint(frequency, 5)
                bouncetimeINT = old_div(
                    1000, frequencyINT
                )  # in ms. this is ok to be trunk of the int. For frequencies higher than 1000 the bouncetime is exactly zero

            # RPI.GPIO library does not accept bouncetime=0, it gives runtime error
            if bouncetimeINT <= 0:
                bouncetimeINT = 1  #ms
            hardwaremod.GPIO_add_event_detect(PINstr, evenslopetype,
                                              eventcallback, bouncetimeINT)

            # set fast reference call indexed with the PIN number which is the variable used when interrupt is called:
            # search now to avoid searching later

            global PIN_attributes

            PIN = hardwaremod.toint(PINstr, 0)

            statusdataDBmod.write_status_data(PIN_attributes, PIN, "logic",
                                              logic)

            recordkey = hardwaremod.HW_CTRL_PIN
            recordvalue = PINstr
            keytosearch = hardwaremod.HW_INFO_NAME
            refsensor = hardwaremod.searchdata(
                recordkey, recordvalue, keytosearch)  # return first occurence

            statusdataDBmod.write_status_data(PIN_attributes, PIN, "refsensor",
                                              refsensor)
            statusdataDBmod.write_status_data(
                PIN_attributes, PIN, "bouncetimeSec",
                0.4 * float(bouncetimeINT) / 1000)

    # code below to enable blocking for N sec, it is necessary to trigger the bloccking status in case of levels already present when starting.
    elementlist = interruptdbmod.getelementlist()
    #print elementlist
    for element in elementlist:
        workmode = checkworkmode(element)
        if (workmode != "None") and (workmode != ""):
            sensor = interruptdbmod.searchdata("element", element, "sensor")
            #saveblockingdiff(sensor)
            print(" what a sensor ", sensor)
            if sensor != "":
                startblockingstate(element, 10, False)
                t.sleep(0.02)

    return ""
Beispiel #21
0
def setinterruptevents():

    hardwaremod.removeallinterruptevents()

    print "load interrupt list "
    interruptlist = interruptdbmod.sensorlist()
    print "len interrupt list ", len(interruptlist)
    for item in interruptlist:
        print "got into the loop "
        # get PIN number

        recordkey = hardwaremod.HW_INFO_NAME
        recordvalue = item
        keytosearch = hardwaremod.HW_CTRL_PIN
        PINstr = hardwaremod.searchdata(recordkey, recordvalue, keytosearch)
        print "set event for the PIN ", PINstr
        if not PINstr == "":

            keytosearch = hardwaremod.HW_CTRL_LOGIC
            logic = hardwaremod.searchdata(recordkey, recordvalue, keytosearch)
            # set Sw pull up / down mode

            if logic == "pos":
                hardwaremod.GPIO_setup(PINstr, "in", "pull_down")
                evenslopetype = "both"
            else:
                hardwaremod.GPIO_setup(PINstr, "in", "pull_up")
                evenslopetype = "both"

            #GPIO.RISING, GPIO.FALLING or GPIO.BOTH.
            # link to the callback function

            # the bouncetime is set by the frequency parameter, if this parameter is empty, the default bouncetime would be 200

            keytosearch = hardwaremod.HW_CTRL_FREQ
            frequency = hardwaremod.searchdata(recordkey, recordvalue,
                                               keytosearch)
            if frequency == "":
                bouncetimeINT = 200
            else:
                frequencyINT = hardwaremod.toint(frequency, 5)
                bouncetimeINT = 1000 / frequencyINT  # this is ok to be trunk of the int. For frequencies higher than 1000 the bouncetime is exactly zero

            # RPI.GPIO library does not accept bouncetime=0, it gives runtime error
            if bouncetimeINT <= 0:
                bouncetimeINT = 1
            hardwaremod.GPIO_add_event_detect(PINstr, evenslopetype,
                                              eventcallback, bouncetimeINT)

            # set fast reference call indexed with the PIN number which is the variable used when interrupt is called:
            # search now to avoid searching later

            global PIN_attributes

            PIN = hardwaremod.toint(PINstr, 0)

            statusdataDBmod.write_status_data(PIN_attributes, PIN, "logic",
                                              logic)

            recordkey = hardwaremod.HW_CTRL_PIN
            recordvalue = PINstr
            keytosearch = hardwaremod.HW_INFO_NAME
            refsensor = hardwaremod.searchdata(
                recordkey, recordvalue, keytosearch)  # return first occurence

            statusdataDBmod.write_status_data(PIN_attributes, PIN, "refsensor",
                                              refsensor)

    return ""
Beispiel #22
0
def mastercallback():

    # clean old data of the database (pastdays)

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

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

    # set the individual callback of the day

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

    #this callback is used only for system status periodic check

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

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

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

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

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

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

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

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

    # empty
    #<---->

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

    callback = "waterpump"

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

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

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

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

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

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

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

    callback = "doser"

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

    for dosernumber in range(len(elementlist)):
        #print "number =",dosernumber
        dosername = elementlist[dosernumber]
        calltype = hardwaremod.searchdata(hardwaremod.HW_INFO_NAME, dosername,
                                          hardwaremod.HW_FUNC_SCHEDTYPE)
        todaydate = date.today()
        # Monday is 0 and Sunday is 6
        year = todaydate.year
        month = todaydate.month
        day = todaydate.day
        fertilizerpulsenumber = hardwaremod.toint(
            table[dosernumber][month - 1], 0)
        fertilizerpulsesecond = hardwaremod.toint(
            table1[dosernumber][month - 1], 0)
        if (fertilizerpulsenumber > 0) and (fertilizerpulsesecond > 0):
            themonthdays = 30  #approximate number of days in a month
            dayinterval = themonthdays / fertilizerpulsenumber
            halfinterval = (dayinterval + 1) / 2
            print "day=", day, " dayinterval=", dayinterval, " half=", halfinterval
            if ((day + int(halfinterval)) % int(dayinterval)) == 0:
                timelist = hardwaremod.gettimedata("06:00:00")
                argument = []
                argument.append(dosername)
                argument.append(fertilizerpulsesecond)
                if (fertilizerpulsesecond
                    ) > 0:  #check if the duration in second is >0
                    setschedulercallback(calltype, timelist, argument,
                                         callback, dosername)
Beispiel #23
0
def mastercallback():
	
	# clean old data of the database (pastdays)
	logger.info('Remove data in exceed of one year')

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

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

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

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

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

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

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



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

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

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

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


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

	callback="doser"

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

	for dosernumber in range(len(elementlist)):
		#print "number =",dosernumber
		dosername=elementlist[dosernumber]
		calltype=hardwaremod.searchdata(hardwaremod.HW_INFO_NAME,dosername,hardwaremod.HW_FUNC_SCHEDTYPE)
		todaydate = date.today()
		# Monday is 0 and Sunday is 6
		year = todaydate.year
		month = todaydate.month	
		day = todaydate.day
		fertilizerpulsenumber=hardwaremod.toint(table[dosernumber][month-1],0)
		fertilizerpulsesecond=hardwaremod.toint(table1[dosernumber][month-1],0)
		if (fertilizerpulsenumber>0) and (fertilizerpulsesecond>0):			
			themonthdays=30 #approximate number of days in a month
			dayinterval=themonthdays/fertilizerpulsenumber
			halfinterval=(dayinterval+1)/2
			print "day=" , day , " dayinterval=", dayinterval, " half=", halfinterval		
			if ((day+int(halfinterval)) % int(dayinterval)) == 0:				
				#timelist=hardwaremod.gettimedata("06:00:00")
				timelist=autofertilizermod.timelist(dosername)
				argument=[]
				argument.append(dosername)
				argument.append(fertilizerpulsesecond)
				if (fertilizerpulsesecond)>0: #check if the duration in second is >0
					setschedulercallback(calltype,timelist,argument,callback,dosername)
					
	logger.info('Start other scheduler activities - finish')
	return True
Beispiel #24
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