mirror of
https://bitbucket.org/myhomie/mycorerepository.git
synced 2025-12-06 17:51:20 +00:00
263 lines
8.2 KiB
Python
263 lines
8.2 KiB
Python
import smbus
|
|
import time
|
|
import json
|
|
from ctypes import c_short
|
|
from ctypes import c_byte
|
|
from ctypes import c_ubyte
|
|
import paho.mqtt.client as mqtt
|
|
import socket
|
|
|
|
broker="192.168.31.118"
|
|
#username="oilkfgjy"
|
|
#password="lEyZb90q49Rf"
|
|
|
|
mqttc = mqtt.Client("SmartGarden_PiZero")
|
|
#mqttc.username_pw_set(username, password)
|
|
|
|
delayBetweenSending = 300
|
|
|
|
DEVICE = 0x76 # Default device I2C address
|
|
|
|
|
|
bus = smbus.SMBus(1) # Rev 2 Pi, Pi 2 & Pi 3ses bus 1
|
|
# Rev 1 Pi uses bus 0
|
|
|
|
def get_ip_address():
|
|
ip_address = '';
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
s.connect(("8.8.8.8",80))
|
|
ip_address = s.getsockname()[0]
|
|
s.close()
|
|
return ip_address
|
|
|
|
def getShort(data, index):
|
|
# return two bytes from data as a signed 16-bit value
|
|
return c_short((data[index+1] << 8) + data[index]).value
|
|
|
|
def getUShort(data, index):
|
|
# return two bytes from data as an unsigned 16-bit value
|
|
return (data[index+1] << 8) + data[index]
|
|
|
|
def getChar(data,index):
|
|
# return one byte from data as a signed char
|
|
result = data[index]
|
|
if result > 127:
|
|
result -= 256
|
|
return result
|
|
|
|
def getUChar(data,index):
|
|
# return one byte from data as an unsigned char
|
|
result = data[index] & 0xFF
|
|
return result
|
|
|
|
def readBME280ID(addr=DEVICE):
|
|
# Chip ID Register Address
|
|
REG_ID = 0xD0
|
|
(chip_id, chip_version) = bus.read_i2c_block_data(addr, REG_ID, 2)
|
|
return (chip_id, chip_version)
|
|
|
|
def readBME280All(addr=DEVICE):
|
|
# Register Addresses
|
|
REG_DATA = 0xF7
|
|
REG_CONTROL = 0xF4
|
|
REG_CONFIG = 0xF5
|
|
|
|
REG_CONTROL_HUM = 0xF2
|
|
REG_HUM_MSB = 0xFD
|
|
REG_HUM_LSB = 0xFE
|
|
|
|
# Oversample setting - page 27
|
|
OVERSAMPLE_TEMP = 2
|
|
OVERSAMPLE_PRES = 2
|
|
MODE = 1
|
|
|
|
# Oversample setting for humidity register - page 26
|
|
OVERSAMPLE_HUM = 2
|
|
bus.write_byte_data(addr, REG_CONTROL_HUM, OVERSAMPLE_HUM)
|
|
|
|
control = OVERSAMPLE_TEMP<<5 | OVERSAMPLE_PRES<<2 | MODE
|
|
bus.write_byte_data(addr, REG_CONTROL, control)
|
|
|
|
# Read blocks of calibration data from EEPROM
|
|
# See Page 22 data sheet
|
|
cal1 = bus.read_i2c_block_data(addr, 0x88, 24)
|
|
cal2 = bus.read_i2c_block_data(addr, 0xA1, 1)
|
|
cal3 = bus.read_i2c_block_data(addr, 0xE1, 7)
|
|
|
|
# Convert byte data to word values
|
|
dig_T1 = getUShort(cal1, 0)
|
|
dig_T2 = getShort(cal1, 2)
|
|
dig_T3 = getShort(cal1, 4)
|
|
|
|
dig_P1 = getUShort(cal1, 6)
|
|
dig_P2 = getShort(cal1, 8)
|
|
dig_P3 = getShort(cal1, 10)
|
|
dig_P4 = getShort(cal1, 12)
|
|
dig_P5 = getShort(cal1, 14)
|
|
dig_P6 = getShort(cal1, 16)
|
|
dig_P7 = getShort(cal1, 18)
|
|
dig_P8 = getShort(cal1, 20)
|
|
dig_P9 = getShort(cal1, 22)
|
|
|
|
dig_H1 = getUChar(cal2, 0)
|
|
dig_H2 = getShort(cal3, 0)
|
|
dig_H3 = getUChar(cal3, 2)
|
|
|
|
dig_H4 = getChar(cal3, 3)
|
|
dig_H4 = (dig_H4 << 24) >> 20
|
|
dig_H4 = dig_H4 | (getChar(cal3, 4) & 0x0F)
|
|
|
|
dig_H5 = getChar(cal3, 5)
|
|
dig_H5 = (dig_H5 << 24) >> 20
|
|
dig_H5 = dig_H5 | (getUChar(cal3, 4) >> 4 & 0x0F)
|
|
|
|
dig_H6 = getChar(cal3, 6)
|
|
|
|
# Wait in ms (Datasheet Appendix B: Measurement time and current calculation)
|
|
wait_time = 1.25 + (2.3 * OVERSAMPLE_TEMP) + ((2.3 * OVERSAMPLE_PRES) + 0.575) + ((2.3 * OVERSAMPLE_HUM)+0.575)
|
|
time.sleep(wait_time/1000) # Wait the required time
|
|
|
|
# Read temperature/pressure/humidity
|
|
data = bus.read_i2c_block_data(addr, REG_DATA, 8)
|
|
pres_raw = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4)
|
|
temp_raw = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4)
|
|
hum_raw = (data[6] << 8) | data[7]
|
|
|
|
#Refine temperature
|
|
var1 = ((((temp_raw>>3)-(dig_T1<<1)))*(dig_T2)) >> 11
|
|
var2 = (((((temp_raw>>4) - (dig_T1)) * ((temp_raw>>4) - (dig_T1))) >> 12) * (dig_T3)) >> 14
|
|
t_fine = var1+var2
|
|
temperature = float(((t_fine * 5) + 128) >> 8);
|
|
|
|
# Refine pressure and adjust for temperature
|
|
var1 = t_fine / 2.0 - 64000.0
|
|
var2 = var1 * var1 * dig_P6 / 32768.0
|
|
var2 = var2 + var1 * dig_P5 * 2.0
|
|
var2 = var2 / 4.0 + dig_P4 * 65536.0
|
|
var1 = (dig_P3 * var1 * var1 / 524288.0 + dig_P2 * var1) / 524288.0
|
|
var1 = (1.0 + var1 / 32768.0) * dig_P1
|
|
if var1 == 0:
|
|
pressure=0
|
|
else:
|
|
pressure = 1048576.0 - pres_raw
|
|
pressure = ((pressure - var2 / 4096.0) * 6250.0) / var1
|
|
var1 = dig_P9 * pressure * pressure / 2147483648.0
|
|
var2 = pressure * dig_P8 / 32768.0
|
|
pressure = pressure + (var1 + var2 + dig_P7) / 16.0
|
|
|
|
# Refine humidity
|
|
humidity = t_fine - 76800.0
|
|
humidity = (hum_raw - (dig_H4 * 64.0 + dig_H5 / 16384.0 * humidity)) * (dig_H2 / 65536.0 * (1.0 + dig_H6 / 67108864.0 * humidity * (1.0 + dig_H3 / 67108864.0 * humidity)))
|
|
humidity = humidity * (1.0 - dig_H1 * humidity / 524288.0)
|
|
if humidity > 100:
|
|
humidity = 100
|
|
elif humidity < 0:
|
|
humidity = 0
|
|
|
|
return temperature/100.0,pressure/100.0,humidity
|
|
|
|
import time
|
|
|
|
# Import the ADS1x15 module.
|
|
import Adafruit_ADS1x15
|
|
import RPi.GPIO as GPIO
|
|
|
|
#################### HERE IS THE MAIN CODE ####################
|
|
|
|
# Create an ADS1115 ADC (16-bit) instance.
|
|
adc = Adafruit_ADS1x15.ADS1115()
|
|
|
|
# bus by passing in these optional parameters:
|
|
#adc = Adafruit_ADS1x15.ADS1015(address=0x49, busnum=1)
|
|
|
|
# Choose a gain of 1 for reading voltages from 0 to 4.09V.
|
|
GAIN = 1
|
|
|
|
# GPIO Numbers instead of board numbers
|
|
GPIO.setmode(GPIO.BCM)
|
|
#Set the relay pin to 27
|
|
RELAIS_1_GPIO = 27
|
|
GPIO.setup(RELAIS_1_GPIO, GPIO.OUT) # GPIO Assign mode
|
|
GPIO.output(RELAIS_1_GPIO, GPIO.HIGH)
|
|
|
|
def on_message(mosq, obj, msg):
|
|
print(str(msg.payload, "utf-8"))
|
|
d = json.loads(str(msg.payload, "utf-8"))
|
|
print (d['Irrigate'])
|
|
if (d['Irrigate'] >= 2 and d['Irrigate'] < 10):
|
|
print('Im irrigating ! :)')
|
|
GPIO.output(RELAIS_1_GPIO, GPIO.LOW)
|
|
time.sleep(int(d['Irrigate']))
|
|
GPIO.output(RELAIS_1_GPIO, GPIO.HIGH)
|
|
else:
|
|
print("uncorrect payload")
|
|
|
|
mqttc.connect(broker, 1883)
|
|
|
|
mqttc.publish("IpAddress", get_ip_address())
|
|
|
|
mqttc.on_message=on_message
|
|
|
|
mqttc.loop_start() #start loop to process received messages
|
|
|
|
mqttc.subscribe("SmartGarden_WaterRelay")#subscribe
|
|
|
|
print('Reading ADS1x15 values, press Ctrl-C to quit...')
|
|
# Print nice channel column headers.
|
|
print('| {0:>6} | {1:>6} | {2:>6} | {3:>6} |'.format(*range(4)))
|
|
print('-' * 37)
|
|
try:
|
|
# Main loop.
|
|
while True:
|
|
# Read all the ADC channel values in a list.
|
|
values = [0]*4
|
|
for i in range(4):
|
|
# Read the specified ADC channel using the previously set gain value.
|
|
values[i] = adc.read_adc(i, gain=GAIN)
|
|
# Note you can also pass in an optional data_rate parameter that controls
|
|
# the ADC conversion time (in samples/second). Each chip has a different
|
|
# set of allowed data rate values, see datasheet Table 9 config register
|
|
# DR bit values.
|
|
#values[i] = adc.read_adc(i, gain=GAIN, data_rate=128)
|
|
# Each value will be a 12 or 16 bit signed integer value depending on the
|
|
# ADC (ADS1015 = 12-bit, ADS1115 = 16-bit).
|
|
# Print the ADC values.
|
|
|
|
#print ("values[0] : ", values[0])
|
|
|
|
#if values[0] < 15000 :
|
|
# print ("I'm in")
|
|
# GPIO.output(RELAIS_1_GPIO, GPIO.LOW)
|
|
#else:
|
|
# print ("I'm in 2")
|
|
# GPIO.output(RELAIS_1_GPIO, GPIO.HIGH)
|
|
|
|
temperature,pressure,humidity = readBME280All()
|
|
print('| {0:>6} | {1:>6} | {2:>6} | {3:>6} | '.format(*values), "Temperature : ", temperature, "C", " | Pressure : ", pressure, "hPa"," | Humidity : ", humidity, "%")
|
|
|
|
valuesToSend = '{"Temperature": ' + str(temperature) + ', "Pressure": '+ str(pressure) +', "Humidity": ' + str(humidity) + ', "Water": ' + str(values[0]) + ', "Light": ' + str(values[1]) + '}'
|
|
|
|
mqttc.publish("SmartGarden", valuesToSend)
|
|
#print ("Temperature : ", temperature, "C")
|
|
#print ("Pressure : ", pressure, "hPa")
|
|
#print ("Humidity : ", humidity, "%")
|
|
# Pause for one minute.
|
|
time.sleep(delayBetweenSending)
|
|
|
|
except KeyboardInterrupt:
|
|
# here you put any code you want to run before the program
|
|
# exits when you press CTRL+C
|
|
print ("It's a KeyboardInterrupt")
|
|
GPIO.output(RELAIS_1_GPIO, GPIO.HIGH) #ensure that the pump is close
|
|
|
|
except:
|
|
# this catches ALL other exceptions including errors.
|
|
# You won't get any error messages for debugging
|
|
# so only use it once your code is working
|
|
print ("Other error or exception occurred!")
|
|
|
|
finally:
|
|
GPIO.output(RELAIS_1_GPIO, GPIO.HIGH) #ensure that the pump is close
|
|
GPIO.cleanup() # this ensures a clean exit
|
|
|