Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import serial
- import time
- import RPi.GPIO as GPIO
- import paho.mqtt.client as mqtt
- import logging
- import sys
- logging.basicConfig(filename='planty.log', level=logging.ERROR)
- MIN = 330
- MAX = 970
- ALERT_LOW = 10
- ALERT_HIGH = 90
- ALERT_THRESHOLD = 30
- MQTT_HOST = 'hostname
- MQTT_PORT = 1883
- MQTT_USER = 'root'
- MQTT_PASS = 'root'
- PIN_POT = {7:0}
- def read_sensor():
- """
- Read analog moisture reading from moisture probe via Arduino via USB.
- try exists as Arduino sometimes passes bogus readings which causes
- IndexErrors
- """
- try:
- ser = serial.Serial('/dev/ttyACM0', 9600)
- raw_reading = ser.readline().strip()
- print raw_reading
- if 8 > len(raw_reading) >= 5:
- # If reading is valid length do:
- reading = {'pot': int(raw_reading.split(':')[1]),
- 'moisture_raw': int(raw_reading.split(':')[0])}
- else:
- reading = {'invalid':1}
- except: # catch *all* exceptions
- e = 'Error:%s Reading: %s' % (str(sys.exc_info()[0]), raw_reading)
- logging.error(e)
- reading = {'invalid':1}
- finally:
- ser.close()
- return reading
- def validate(data):
- check = 0
- try:
- if 'invalid' not in data:
- # if there is no invalid key
- # print 'Invlaid key not detected'
- if 1024 > data['moisture_raw'] > 0:
- # Valid moisture reading
- # print 'Valid moisture reading'
- if data['pot'] in PIN_POT:
- # Valid serial reading of pin
- # print 'PIN_POT key exists'
- check = 1
- else:
- print 'PIN_POT key does not exist'
- else:
- print 'Invalid moisture reading'
- else:
- print 'Invalid key detected'
- except:
- e = 'Error:%s Reading: %s' % (str(sys.exc_info()[0]), raw_reading)
- logging.error(e)
- finally:
- return check
- def process_raw_data():
- """
- Calls read_sensor(), checks if the reading is valid (sometimes over 1023 or null)
- Assigns the correct Pot for the Pin used via PIN_POT dictionary
- Normalizes the reading if it falls outside the ranges
- """
- valid = 0
- while valid == 0:
- data = read_sensor()
- valid = validate(data)
- data['pot'] = PIN_POT[data['pot']]
- # Set moisture_adj
- if data['moisture_raw'] < MIN:
- data['moisture_adj'] = MIN
- elif data['moisture_raw'] > MAX:
- data['moisture_adj'] = MAX
- else:
- data['moisture_adj'] = 0
- data['moisture'] = moisture(data['moisture_raw'])
- print data
- return data
- data['moisture'] = moisture(data['moisture_adj'])
- print data
- return data
- def moisture(data):
- return int(round(100-(100/float(MAX-MIN))*(data-MIN), 0))
- def pub_mqtt(output, topic):
- """Publish to MQTT for given topic"""
- mqtt_client = mqtt.Client()
- mqtt_client.username_pw_set(MQTT_USER, MQTT_PASS)
- mqtt_client.connect(MQTT_HOST, MQTT_PORT)
- mqtt_client.publish(topic, output)
- def alerts(data):
- """Generates alerts that are humanly readable for certain moisture thresholds"""
- if data['moisture'] <= ALERT_LOW:
- output = 'LOW ALERT'
- relay(data['pot'])
- time.sleep(60*5)
- elif ALERT_LOW > data['moisture'] <= ALERT_THRESHOLD:
- output = 'THRESHOLD ALERT'
- relay(data['pot'])
- time.sleep(60*5)
- elif data['moisture'] >= ALERT_HIGH:
- output = 'HIGH ALERT'
- else:
- return
- pub_mqtt(output, 'Planty/alerts')
- def relay(pin):
- try:
- GPIO.setmode(GPIO.BCM)
- GPIO.setwarnings(False)
- GPIO.setup(pin, GPIO.OUT, initial=1)
- # Message pin on
- pub_mqtt(str(pin) + ':1', 'Planty/relay')
- GPIO.output(pin, 0)
- time.sleep(5)
- # Message pin off
- pub_mqtt(str(pin) + ':0', 'Planty/relay')
- GPIO.output(pin, 1)
- finally:
- GPIO.cleanup()
- def debugger(data):
- """This is just to test each reading if there are issues"""
- output ='n=====DEBUG LOG=====n'
- 'raw is: {}n'
- 'raw_adjusted is: {}n'
- 'soil moisture is: {}%n'
- .format(data['moisture_raw'],
- data['moisture_adj'],
- data['moisture'])
- pub_mqtt(output, 'Planty/debug')
- def main():
- while 1:
- data = process_raw_data()
- output = '%d:%d:%d:%d'
- % (data['pot'],
- data['moisture_raw'],
- data['moisture_adj'],
- data['moisture'])
- pub_mqtt(output, 'Planty/moisture_readings')
- # alerts(data)
- # debugger(data)
- if __name__ == '__main__':
- main()
- import paho.mqtt.client as mqtt
- from influxdb import InfluxDBClient
- INFLUX_HOST = 'hostname'
- INFLUX_PORT = 8086
- INFLUX_DB = 'Planty'
- INFLUX_USER = 'root'
- INFLUX_PASS = 'root'
- MQTT_HOST = 'hostname'
- MQTT_PORT = 1883
- MQTT_USER = 'root'
- MQTT_PASS = 'root'
- MQTT_TOPIC = 'Planty/moisture_readings'
- def on_message(client, userdata, msg):
- raw_message = msg.payload.split(':')
- data = {}
- print raw_message
- data['pot'] = raw_message[0]
- data['moisture_raw'] = raw_message[1]
- data['moisture_adj'] = raw_message[2]
- data['moisture'] = raw_message[3]
- json_body = [
- {
- "measurement": "moisture_readings",
- "tags": {
- "pot": data['pot']
- },
- "fields": {
- "moisture_raw": data['moisture_raw'],
- "moisture_adj": data['moisture_adj'],
- "moisture": data['moisture']
- }
- }
- ]
- client = InfluxDBClient(INFLUX_HOST,INFLUX_PORT, INFLUX_USER, INFLUX_PASS, INFLUX_DB)
- client.write_points(json_body)
- def main():
- mqttc = mqtt.Client()
- mqttc.username_pw_set(MQTT_USER, MQTT_PASS)
- mqttc.connect(MQTT_HOST, MQTT_PORT)
- mqttc.subscribe(MQTT_TOPIC)
- mqttc.on_message = on_message
- mqttc.loop_forever()
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement