import influxdb_client, os, time
from influxdb_client import InfluxDBClient, Point, WritePrecision
from influxdb_client.client.exceptions import InfluxDBError
from influxdb_client.client.write_api import SYNCHRONOUS
import pygame
from pygame.locals import *
import time, sys
from pantry_wrapper import *
from time import sleep, time
from datetime import datetime
from arrow import *
import threading
from threading import Timer
import board
import busio
import subprocess
import re
import qwiic_vl53l1x
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
import RPi.GPIO as GPIO
token = "your token here"
org = "your email"
url = "https://eastus-1.azure.cloud2.influxdata.com"
client = InfluxDBClient(url="https://eastus-1.azure.cloud2.influxdata.com", token=token, org=org)
bucket="RODI"
write_api = client.write_api(write_options=SYNCHRONOUS)
ToF = qwiic_vl53l1x.QwiicVL53L1X()
if (ToF.sensor_init() == None):# Begin returns 0 on a good init
print("Sensor online!\n")
# Setup inputs/outputs
output1 = 7 # Flush Valve
output2 = 8 # Rinse Valve
output3 = 18 # Cooling Fan
input1 = 23 # Concentrate Flow Sensor
input2 = 24 # Permeate Flow Sensor
input3 = 17 # Softener Vessel 1 Flow Sensor
input4 = 26 # Softener Vessel 2 Flow Sensor
input5 = 13 # Softener Vessel 1 Lmit Switch
input6 = 19 # Softener Vessel 1 Lmit Switch
input7 = 27 # Softener Vessel 2 Lmit Switch
input8 = 22 # Softener Vessel 2 Lmit Switch
# Setup GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(input1, GPIO.IN, pull_up_down = GPIO.PUD_UP) # concentrate flow sensor
GPIO.setup(input2, GPIO.IN, pull_up_down = GPIO.PUD_UP) # permeate flow sensor
GPIO.setup(input3, GPIO.IN, pull_up_down = GPIO.PUD_UP) # vessel 1 flow sensor
GPIO.setup(input4, GPIO.IN, pull_up_down = GPIO.PUD_UP) # vessel 2 flow sensor
GPIO.setup(input5, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(input6, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(input7, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(input8, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.setup(output1, GPIO.OUT) # Flush Valve
GPIO.setup(output2, GPIO.OUT) # Rinse Valve
GPIO.setup(output3, GPIO.OUT)
GPIO.output(output2,1)
startTime = int(time())
# Setup setpoints
flush = 0.1
Tank_H = 80 #Tank height in cm
Tank1_H = 42.5 #Sump Depth in cm
DATA_SAVING_INTERVAL = 10 # secs
POLL_INTERVAL = 0.5 # sec
# Create the I2C bus
i2c = busio.I2C(board.SCL, board.SDA)
GAIN=2
# Create the ADC object using the I2C bus
ads1 = ADS.ADS1115(i2c, address=0x48,mode=0x0000)
ads2 = ADS.ADS1115(i2c, address=0x49,gain=GAIN,mode=0x0000)
ADS1x15_CONFIG_GAIN = {
2/3: 0x0000,
1: 0x0200,
2: 0x0400,
4: 0x0600,
8: 0x0800,
16: 0x0A00
}
# Create single-ended input on channel 0
chan0 = AnalogIn(ads1, ADS.P0)
chan1 = AnalogIn(ads1, ADS.P1)
chan2 = AnalogIn(ads1, ADS.P2)
chan3 = AnalogIn(ads1, ADS.P3)
chan4 = AnalogIn(ads2, ADS.P0)
chan5 = AnalogIn(ads2, ADS.P1)
chan6 = AnalogIn(ads2, ADS.P2)
chan7 = AnalogIn(ads2, ADS.P3)
#####################################################################################
# pygame
pygame.init()
# setup screen
screenDimentions = (2048, 1450)
screen = pygame.display.set_mode((screenDimentions))
pygame.display.set_caption('REVERSE OSMOSIS')
view_mode = 'Normal'
done = False
# setup font size
FONTSIZE = 45
LINEHEIGHT = 32
basicFont = pygame.font.SysFont(None, FONTSIZE)
Alarm = ''
# setup font colors
BLACK = (255,255,255)
WHITE = (0,0,0)
GREY = (200,200,200)
DKGREY = (169,169,169)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GRAY = (0, 0, 55)
# Background
bg = pygame.image.load('SOFT-bg4(3).png')
alarm_bg = pygame.image.load('Alarm1.png')
# setup the flow arrows
in_arrow = arrow(675, 1020, 700, 1020)
di_in_arrow = arrow(1015, 550, 1035, 550)
di_out_arrow = arrow(1650, 670, 1650, 670)
soft_in_arrow = arrow(185, 340, 210, 340)
soft_out_arrow = arrow2(390, 975, 415, 975)
class UltraSonic():
# Ultrasonic sensor class
def __init__(self, TRIG, ECHO, offset = 0.5):
# Create a new sensor instance
self.TRIG = TRIG
self.ECHO = ECHO
self.offset = offset # Sensor calibration factor
GPIO.setmode(GPIO.BCM)
GPIO.setup(self.TRIG, GPIO.OUT) # Set pin as GPIO output
GPIO.setup(self.ECHO, GPIO.IN) # Set pin as GPIO input
def __str__(self):
# Return string representation of sensor
return "Ultrasonic Sensor: TRIG - {0}, ECHO - {1}, Offset: {2} cm".format(self.TRIG, self.ECHO, self.offset)
def ping(self):
maxTime = 0.04
# Get distance measurement
GPIO.output(self.TRIG, GPIO.LOW) # Set TRIG LOW
sleep(0.2) # Min gap between measurements
# Create 10 us pulse on TRIG
GPIO.output(self.TRIG, GPIO.HIGH) # Set TRIG HIGH
sleep(0.00001) # Delay 10 us
GPIO.output(self.TRIG, GPIO.LOW) # Set TRIG LOW
# Measure return echo pulse duration
pulse_start = time()
timeout = pulse_start + maxTime
while GPIO.input(self.ECHO) == GPIO.LOW and pulse_start < timeout: # Wait until ECHO is LOW
pulse_start = time() # Save pulse start time
pulse_end = time()
timeout = pulse_end + maxTime
while GPIO.input(self.ECHO) == GPIO.HIGH and pulse_end < timeout: # Wait until ECHO is HIGH
pulse_end = time() # Save pulse end time
pulse_duration = pulse_end - pulse_start
# Distance = 17160.5 * Time (unit cm) at sea level and 20C
distance1 = pulse_duration * 17160.5 # Calculate distance
distance = round(distance1, 2) # Round to two decimal points
if distance > 2 and distance < 400: # Check distance is in sensor range
distance = distance + self.offset
#print("Distance: ", distance," cm")
else:
distance = 0
#print("No obstacle") # Nothing detected by sensor
return distance
def calibrate(self):
# Calibrate sensor distance measurement
while True:
self.ping()
response = input("Enter Offset (q = quit): ")
if response == __QUIT:
break;
sensor.offset = float(response)
print(sensor)
@staticmethod
def low_pass_filter(value, previous_value, beta):
# Simple infinite-impulse-response (IIR) single-pole low-pass filter.
# ß = discrete-time smoothing parameter (determines smoothness). 0 < ß < 1
# LPF: Y(n) = (1-ß)*Y(n-1) + (ß*X(n))) = Y(n-1) - (ß*(Y(n-1)-X(n)))
smooth_value = previous_value - (beta * (previous_value - value))
return smooth_value
sensor = UltraSonic(10, 9) # create a new sensor instance on GPIO pins 9 & 10
print(sensor)
# Flow Meter Class
class FlowMeter():
gallons_per_liter = 0.264172
seconds_per_minute = 60
MS_per_second = 1000
displayFormat = 'metric'
enabled = True
clicks = 0
lastClick = 0
clickDelta = 0
hertz = 0.0
flow = 0
flow1 = 0# in Liters per second
thisflow = 0.0
thisflow1 = 0# in Liters
total = 0.0
total1 = 0.0# in Liters
constant = 0.5
constant1 = .0037854
def __init__(self, displayFormat, enabled):
self.displayFormat = displayFormat
self.clicks = 0
self.lastClick = int(time() * FlowMeter.MS_per_second)
self.clickDelta = 0
self.hertz = 0.0
self.flow = 0.0
self.thisflow = 0.0
self.total = 0.0
self.flow1 = 0.0
self.thisflow1 = 0.0
self.total1 = 0.0
self.enabled = True
def update(self, currentTime):
self.clicks += 1
# get the time delta
self.clickDelta = max((currentTime - self.lastClick), 1)
# calculate the instantaneous speed
if (self.enabled == True): # and self.clickDelta < 1000)
self.hertz = FlowMeter.MS_per_second / self.clickDelta
self.flow = self.hertz / (FlowMeter.seconds_per_minute * FlowMeter.constant)
self.flow1 = self.hertz / (FlowMeter.seconds_per_minute * FlowMeter.constant1)# In Liters per second
instflow = self.flow * (self.clickDelta / FlowMeter.MS_per_second)
instflow1 = self.flow1 * (self.clickDelta / FlowMeter.MS_per_second)
self.thisflow += instflow
self.thisflow1 += instflow1
self.total += instflow
self.total1 += instflow1
# Update the last click
self.lastClick = currentTime
def getFormattedClickDelta(self):
return str(self.clickDelta) + ' ms'
def getFormattedHertz(self):
return str(round(self.hertz,3)) + ' Hz'
def getFormattedFlow(self):
if(self.displayFormat == 'metric'):
return str(round(self.flow,3)) + ' L/s'
else:
return str(round(self.flow * FlowMeter.gallons_per_liter, 3)) + ' gallons/s'
def getFormattedThisflow(self):
if(self.displayFormat == 'metric'):
return str(round(self.thisflow,3)) + ' L'
else:
return str(round(self.thisflow * FlowMeter.gallons_per_liter, 3)) + ' gallons'
def getFormattedTotalflow(self):
if(self.displayFormat == 'metric'):
return str(round(self.total,3)) + ' L'
else:
return str(round(self.total * FlowMeter.gallons_per_liter, 3)) + ' gallons'
def clear(self):
self.thisflow = 0;
self.total = 0;
# Flow, on Pin 24.
def doAClick1(channel):
currentTime = int(time() * FlowMeter.MS_per_second)
if fm.enabled == True:
fm.update(currentTime)
# Flow, on Pin 23.
def doAClick2(channel):
currentTime = int(time() * FlowMeter.MS_per_second)
if fm2.enabled == True:
fm2.update(currentTime)
# Flow, on Pin 17.
def doAClick3(channel):
currentTime = int(time() * FlowMeter.MS_per_second)
if fm3.enabled == True:
fm3.update(currentTime)
# Flow, on Pin 27.
def doAClick4(channel):
currentTime = int(time() * FlowMeter.MS_per_second)
if fm4.enabled == True:
fm4.update(currentTime)
GPIO.add_event_detect(24, GPIO.RISING, callback=doAClick1, bouncetime=20)
GPIO.add_event_detect(23, GPIO.RISING, callback=doAClick2, bouncetime=20)
GPIO.add_event_detect(17, GPIO.RISING, callback=doAClick3, bouncetime=20)
GPIO.add_event_detect(26, GPIO.RISING, callback=doAClick4, bouncetime=20)
fm = FlowMeter('metric', 'enabled')
fm2 = FlowMeter('metric', 'enabled')
fm3 = FlowMeter('metric', 'enabled')
fm4 = FlowMeter('metric', 'enabled')
# Button Class
class Button():
def __init__(self, txt, location, action, bg=DKGREY, fg=WHITE, size=(160, 60), font_name="Segoe Print", font_size=32):
self.color = bg # the static (normal) color
self.bg = bg # actual background color, can change on mouseover
self.fg = fg # text color
self.size = size
self.font = pygame.font.SysFont(font_name, font_size)
self.txt = txt
self.txt_surf = self.font.render(self.txt, 1, self.fg)
self.txt_rect = self.txt_surf.get_rect(center=[s//2 for s in self.size])
self.surface = pygame.surface.Surface(size)
self.rect = self.surface.get_rect(center=location)
self.call_back_ = action
def draw(self):
self.mouseover()
self.surface.fill(self.bg)
self.surface.blit(self.txt_surf, self.txt_rect)
screen.blit(self.surface, self.rect)
def mouseover(self):
self.bg = self.color
pos = pygame.mouse.get_pos()
if self.rect.collidepoint(pos):
self.bg = GREY # mouseover color
def call_back(self):
self.call_back_()
def DrawBar(pos, size, borderC, barC):
pygame.draw.rect(screen, borderC, (*pos, *size), 1)
innerPos = (pos[0]+3, pos[1]+3)
innerSize = ((size[0]-6) * size[1]-6)
def mousebuttondown():
pos = pygame.mouse.get_pos()
for button in buttons:
if button.rect.collidepoint(pos):
button.call_back()
def drawText(surface, text, color, rect, font, aa=False, bkg=None):
rect = Rect(rect)
y = rect.bottom
lineSpacing = -2
# get the height of the font
fontHeight = font.size("Tg")[1]
while text:
i = 1
# determine if the row of text will be outside our area
if y + fontHeight > rect.bottom:
break
# determine maximum width of line
while font.size(text[:i])[0] < rect.width and i < len(text):
i += 1
# if we've wrapped the text, then adjust the wrap to the last word
if i < len(text):
i = text.rfind(" ", 0, i) + 1
# render the line and blit it to the surface
if bkg:
image = font.render(text[:i], 1, color, bkg)
image.set_colorkey(bkg)
else:
image = font.render(text[:i], aa, color)
screen.blit(image, (rect.left, y))
y += fontHeight + lineSpacing
# remove the text we just blitted
text = text[i:]
return text
class Bar():
def __init__(self, rect, bar = BLUE, outline = GRAY):
self.rect = pygame.Rect(rect)
self.bar = bar
self.outline = outline
self.value = 0
def draw(self, surf):
length = round(self.value * self.rect.height / 100)
top = self.rect.height - length
pygame.draw.rect(surf, self.bar, (self.rect.x, self.rect.y + top, self.rect.width, length))
pygame.draw.rect(surf, self.outline, self.rect, 2)
txt =basicFont .render((str(round(self.value, 2)) + ' %'), True, GRAY)
txt_rect = txt.get_rect(bottomleft = (self.rect.x + 60, self.rect.y + 250))
screen.blit(txt, txt_rect)
def draw1(self, surf):
length = round(self.value * self.rect.height / 100)
top = self.rect.height - length
pygame.draw.rect(surf, self.bar, (self.rect.x, self.rect.y + top, self.rect.width, length))
pygame.draw.rect(surf, self.outline, self.rect, 2)
txt =basicFont .render((str(round(self.value, 2)) + ' %'), True, GRAY)
txt_rect = txt.get_rect(bottomleft = (self.rect.x + 60, self.rect.y + 150))
screen.blit(txt, txt_rect)
bar = Bar((150, 625, 40, 250))
bar1 = Bar((1284, 248, 40, 150))
# Point Setups
def distance():
ToF.start_ranging()# Write configuration bytes to initiate measurement
sleep(.005)
distance = ToF.get_distance()# Get the result of the measurement from the sensor
sleep(.005)
ToF.stop_ranging()
return(distance)
DEVICESDIR = "/sys/bus/w1/devices/"
#class for holding temperature values
class Temperature():
def __init__(self, rawData):
self.rawData = rawData
@property
def C(self):
return float(self.rawData) / 1000
@property
def F(self):
return self.C * 9.0 / 5.0 + 32.0
#class for controlling the temperature sensor
class TempSensorController(threading.Thread):
def __init__(self, sensorId, timeToSleep, name):
threading.Thread.__init__(self)
threading.Thread.name = 'tempcontrol'
#persist the file location
self.tempSensorFile = DEVICESDIR + sensorId + "/w1_slave"
#persist properties
self.sensorId = sensorId
self.timeToSleep = timeToSleep
self.name = name
#update the temperature
self.updateTemp()
def run(self):
#loop until its set to stopped
self.running = True
while(self.running):
#update temperature
self.updateTemp()
#sleep
sleep(self.timeToSleep)
self.running = False
def stopController(self):
self.running = False
def readFile(self):
sensorFile = open(self.tempSensorFile, "r")
lines = sensorFile.readlines()
sensorFile.close()
return lines
def updateTemp(self):
data = self.readFile()
#the output from the tempsensor looks like this
#f6 01 4b 46 7f ff 0a 10 eb : crc=eb YES
#f6 01 4b 46 7f ff 0a 10 eb t=31375
#has a YES been returned?
if (len(data) < 1 or data[0].strip()[-3:] == "YES" or "00 00 00 00 00 00 00 00 00" in data[0]):
#if data[0].strip()[-3:] == "YES" or "00 00 00 00 00 00 00 00 00" in data[0]:
#can I find a temperature (t=)
sleep(0.2)
try:
equals_pos = data[1].find("t=")
if equals_pos != -1:
tempData = data[1][equals_pos+2:]
#update temperature
self.temperature = Temperature(tempData)
#update success status
self.updateSuccess = True
else:
print(self.name, 'failed to update.... Trying Again')
sleep(5)
self.updateTemp()
except IndexError:
print(self.name, 'failed to update Index.... Trying Again')
sleep(1)
self.updateTemp()
else:
print(self.name, 'failed to update.... Trying Again')
sleep(5)
self.updateTemp()
tempcontrol = TempSensorController("28-01144f668faa", 5, 'temp1')
tempcontrol1 = TempSensorController("28-03191180f6aa", 5, 'temp2')
tempcontrol.start()
tempcontrol1.start()
def ROOMTMP():
ROOMTMP = round(tempcontrol1.temperature.C, 1)
return(ROOMTMP)
def WATERTMP():
WATERTMP = round(tempcontrol.temperature.C, 1)
return(WATERTMP)
def FAN_STATUS():
FAN_STATUS = 'ON'
if GPIO.input(18) == 0:
FAN_STATUS = 'OFF'
return(FAN_STATUS)
def parse_output(pattern, args):
try:
out_str = subprocess.check_output(args)
if isinstance(out_str, bytes):
out_str = out_str.decode()
except Exception:
out_str = ''
match = re.search(pattern, out_str)
return match.group(1) if match else None
def cpu_temp():
t_str = parse_output(r'temp=(\S*)\'C', ['vcgencmd', 'measure_temp'])
return float(t_str) if t_str else None
def Vessel1():
vessel1 = 'REGEN'
if GPIO.input(13) == 1 and GPIO.input(22) == 1:
Vessel1 = 'IN SERVICE'
if GPIO.input(13) == 0 and GPIO.input(22) == 0:
Vessel1 = 'STANDBY'
if GPIO.input(13) == 1 and GPIO.input(22) == 0:
Vessel1 = 'REGEN'
if GPIO.input(13) == 0 and GPIO.input(22) == 1:
Vessel1 = 'REGEN'
return(Vessel1)
def Vessel2():
vessel2 = 'REGEN'
if GPIO.input(19) == 1 and GPIO.input(27) == 1:
Vessel2 = 'IN SERVICE'
if GPIO.input(19) == 0 and GPIO.input(27) == 0:
Vessel2 = 'STANDBY'
if GPIO.input(19) == 1 and GPIO.input(27) == 0:
Vessel2 = 'REGEN'
if GPIO.input(19) == 0 and GPIO.input(27) == 1:
Vessel2 = 'REGEN'
return(Vessel2)
def FLOW1():
currentTime = int(time() * FlowMeter.MS_per_second)
if (currentTime - fm.lastClick > 1000):
fm.flow = 0.0
FLOW1 = round(fm.flow,3)
return(FLOW1)
def FLOW1T():
currentTime = startTime * FlowMeter.MS_per_second
FLOW1T = round((fm.total / 60),3)
return(FLOW1T)
def FLOW2():
currentTime = int(time() * FlowMeter.MS_per_second)
if (currentTime - fm2.lastClick > 1000):
fm2.flow = 0.0
FLOW2 = round(fm2.flow,3)
return(FLOW2)
def FLOW2T():
currentTime = int(time() * FlowMeter.MS_per_second)
FLOW2T = round((fm2.total / 60),3)
return(FLOW2T)
def FLOW():
FLOW = round(fm.flow + fm2.flow,3)
return(FLOW)
def FLOWT():
FLOWT = round(((fm.total + fm2.total) / 60),3)
return(FLOWT)
def FLOW3():
currentTime = int(time() * FlowMeter.MS_per_second)
if (currentTime - fm3.lastClick > 1000):
fm3.flow1 = 0.0
FLOW3 = round(fm3.flow1,3)
return(FLOW3)
def FLOW3T():
if Vessel1 == 'STANDBY':
fm3.total1 = 0.0
currentTime = startTime * FlowMeter.MS_per_second
FLOW3T = round((fm3.total1 / 60),3)
return(FLOW3T)
def FLOW4():
currentTime = int(time() * FlowMeter.MS_per_second)
if (currentTime - fm4.lastClick > 1000):
fm4.flow1 = 0.0
FLOW4 = round(fm4.flow1,3)
return(FLOW4)
def FLOW4T():
if Vessel2 == 'STANDBY':
fm4.total1 = 0.0
currentTime = int(time() * FlowMeter.MS_per_second)
FLOW4T = round((fm4.total1 / 60),3)
return(FLOW4T)
def FLOW5():
FLOW5 = round(fm3.flow1 + fm4.flow1,3)
return(FLOW5)
def FLOW5T():
FLOW5T = round(((fm3.total1 + fm4.total1) / 60),3)
return(FLOW5T)
def filtered_value():
beta = .75
filtered_value = 2
filtered_value = sensor.low_pass_filter(sensor.ping(), filtered_value, float(beta))
filtered_value = round(filtered_value, 2)
#print("Filtered: ", filtered_value, " cm")
return (filtered_value)
def LEVEL():
LEVEL = round((1000 - distance())/10/80*100,1) # Salt Level
return(LEVEL)
def LEVEL1():
LEVEL1 = round((Tank1_H - filtered_value() - 10)/30*100,1) # Water Level
return(LEVEL1)
def PRESS1():
PRESS1 = round(((chan2.voltage - 0.5) * 25),1) # RO Inlet Pressure
return (PRESS1)
def PRESS2():
PRESS2 = round(((chan1.voltage - 0.5) * 25),1) # RO System Pressure
return (PRESS2)
def PRESS3():
PRESS3 = round(((chan0.voltage - 0.5) * 50),1) # System Inlet Pressure
return (PRESS3)
def TDSVALUE1():
TDS1CALC = round(chan6.value * 6.19 / 65536,5)
TEMPCOMP1 = 1.0 + (0.02 * (WATERTMP - 25))
COMPVOLT1 = round(TDS1CALC / TEMPCOMP1,5)
TDSVALUE1 = round((((133.42 * COMPVOLT1 * COMPVOLT1 * COMPVOLT1) - (255.86 * COMPVOLT1 * COMPVOLT1) + (857.39 * COMPVOLT1)) * 0.5),1)
return (TDSVALUE1)
def TDSVALUE2():
TDS2CALC = round(chan5.value * 6.19 / 65536,5)
TEMPCOMP2 = 1.0 + (0.02 * (WATERTMP - 25))
COMPVOLT2 = round(TDS2CALC / TEMPCOMP2,5)
TDSVALUE2 = round((((133.42 * COMPVOLT2 * COMPVOLT2 * COMPVOLT2) - (255.86 * COMPVOLT2 * COMPVOLT2) + (857.39 * COMPVOLT2)) * 0.5),1)
return (TDSVALUE2)
def TDSVALUE3(): # DI Outlet TDS
TDS3CALC = round(chan4.value * 6.19 / 65536,5)
TEMPCOMP3 = 1.0 + (0.02 * (WATERTMP - 25))
COMPVOLT3 = round(TDS3CALC / TEMPCOMP3,5)
TDSVALUE3 = round(((((133.42 * COMPVOLT3 * COMPVOLT3 * COMPVOLT3) - (255.86 * COMPVOLT3 * COMPVOLT3) + (857.39 * COMPVOLT3)) * 0.5) - 3),1)
return (TDSVALUE3)
#####################################################################################
# main loop
##################################################################################
while not done:
##################################################################################
# pygame loop
##################################################################################
try:
save_timer = 0
while True:
ROOMTMP = round(tempcontrol1.temperature.C,1)
WATERTMP = round(tempcontrol.temperature.C,1)
CPU_TEMP = cpu_temp
screen.blit(bg,(0,0))
##################################################################################
# time
##################################################################################
#print("Time: " + datetime.now().strftime('%Y-%m-%d,%H:%M:%S,'))
##################################################################################
# performance
##################################################################################
if FLOW() >= flush:
recovery = round((FLOW1() / FLOW()) * 100,0)
else:
recovery = 0
if FLOW() >= flush and TDSVALUE1() >= 10:
SLTREJ = round((TDSVALUE1() - TDSVALUE2()) / TDSVALUE1() * 100,1)
else:
SLTREJ = 0
##################################################################################
# Auto Rinse
##################################################################################
def Valve_RI():
GPIO.output(output2, 1)
RI.cancel()
RI = Timer(15,Valve_RI)
def Valve_AR():
GPIO.output(output2, 1)
AR.cancel()
AR = Timer(30,Valve_AR)
def manual_rinse_membrane():
if RI.is_alive() is False:
RI.start()
GPIO.output(output2, 0)
if GPIO.input(output2) == False or AR.is_alive() is True or RI.is_alive() is True:
pygame.draw.rect(screen, (255, 0, 0), pygame.Rect(1524, 1045, 42, 45))
text = basicFont.render("RINSING", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (1520, 1200 + (1 * LINEHEIGHT)))
else:
if AR.is_alive() or RI.is_alive() is False:
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(1524, 1045, 42, 45))
if FLOW() >= flush and TDSVALUE2() >= 15:
if AR.is_alive()is False:
AR.start()
GPIO.output(output2, 0)
##################################################################################
# Auto Flush
##################################################################################
# def Valve_AF():
# GPIO.output(output1, 1)
# AF.cancel()
# timer.cancel()
#
# def Valve_AFC():
# GPIO.output(output1, 1)
# timer.cancel()
# AF.cancel()
#
#
# AF = Timer(10,Valve_AF)
#
# class RepeatTimer(Timer):
# def run(self):
# while not self.finished.wait(self.interval):
# self.function(*self.args,**self.kwargs)
# GPIO.output(output1, 0)
#
#
# timer = RepeatTimer(5, Valve_AFC)
#
# if FLOW() >= flush:
#
#
# timer.start()
# #GPIO.output(output1, 0)
# AF.start()
#
# else:
# GPIO.output(output1, 1)
# timer.cancel()
# AF.cancel()
##################################################################################
# Manual Flush Button
##################################################################################
def Valve_F():
GPIO.output(output1, 1)
F.cancel()
F = Timer(10,Valve_F)
def manual_flush_membrane():
if F.is_alive() is False:
F.start()
GPIO.output(output1, 0)
if GPIO.input(output1) == False or F.is_alive() is True:
pygame.draw.rect(screen, (255, 0, 0), pygame.Rect(1372, 1045, 42, 45))
text = basicFont.render("FLUSHING", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (1295, 1200 + (1 * LINEHEIGHT)))
else:
if F.is_alive() is False:
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(1372, 1045, 42, 45))
# print(F.is_alive())
# print(threading.active_count())
##################################################################################
# Manual Rinse Button
##################################################################################
##################################################################################
# Totalizer Reset Buttons
##################################################################################
def reset_totalizer():
fm.total = 0
fm2.total = 0
def reset_soft_totalizer():
fm3.total1 = 0
fm4.total1 = 0
def FAN_ON():
GPIO.output(output3,1)
def FAN_OFF():
GPIO.output(output3,0)
#####################################################################################
# Buttons
#####################################################################################
button_01 = Button("MAN FLUSH", (1370, 1200), manual_flush_membrane)
button_02 = Button("RINSE", (1590, 1200), manual_rinse_membrane)
button_03 = Button("RESET", (800, 50), reset_totalizer)
button_04 = Button("RESET", (600, 50), reset_soft_totalizer)
button_05 = Button("FAN ON", (625, 1325), FAN_ON)
button_06 = Button("FAN OFF", (625, 1400), FAN_OFF)
buttons = [button_01, button_02, button_03, button_04, button_05, button_06]
for button in buttons:
button.draw()
#Draw the flow arrows
if FLOW() >= flush:
in_arrow.update()
screen.blit(in_arrow.image,(in_arrow.x, in_arrow.y))
di_in_arrow.update()
screen.blit(di_in_arrow.image,(di_in_arrow.x, di_in_arrow.y))
di_out_arrow.update()
screen.blit(di_out_arrow.image,(di_out_arrow.x, di_out_arrow.y))
#draw the flow arrows
if FLOW5() >= 2:
soft_in_arrow.update()
screen.blit(soft_in_arrow.image,(soft_in_arrow.x, soft_in_arrow.y))
soft_out_arrow.update()
screen.blit(soft_out_arrow.image,(soft_out_arrow.x, soft_out_arrow.y))
# Draw Vessel1 Status Box
if GPIO.input(19) == 1 and GPIO.input(27) == 1:
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(418, 353, 70, 22))
if GPIO.input(19) == 0 and GPIO.input(27) == 0:
pygame.draw.rect(screen, (255, 0, 0), pygame.Rect(418, 353, 70, 22))
if GPIO.input(19) == 1 and GPIO.input(27) == 0:
pygame.draw.rect(screen, (0, 255, 255), pygame.Rect(418, 353, 70, 22))
if GPIO.input(19) == 0 and GPIO.input(27) == 1:
pygame.draw.rect(screen, (0, 255, 255), pygame.Rect(418, 353, 70, 22))
# Draw Vessel2 Status Box
if GPIO.input(22) == 1 and GPIO.input(13) == 1:
pygame.draw.rect(screen, (0, 255, 0), pygame.Rect(572, 353, 70, 22))
if GPIO.input(22) == 0 and GPIO.input(13) == 0:
pygame.draw.rect(screen, (255, 0, 0), pygame.Rect(572, 353, 70, 22))
if GPIO.input(22) == 1 and GPIO.input(13) == 0:
pygame.draw.rect(screen, (0, 255, 255), pygame.Rect(572, 353, 70, 22))
if GPIO.input(22) == 0 and GPIO.input(13) == 1:
pygame.draw.rect(screen, (0, 255, 255), pygame.Rect(572, 353, 70, 22))
text = basicFont.render("FAN STATUS", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (350, 1265 + ((LINEHEIGHT))))
if GPIO.input(18) == 0:
text = basicFont.render("OFF", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (400, 1265 + (2 * (LINEHEIGHT))))
if GPIO.input(18) == 1:
text = basicFont.render("ON", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (400, 1265 + (2 * (LINEHEIGHT))))
if CPU_TEMP() >= 50:
GPIO.output(output3,1)
elif CPU_TEMP() <= 45:
GPIO.output(output3,0)
text = basicFont.render("CPU TEMP", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (350, 1280 + (3 * (LINEHEIGHT))))
text = basicFont.render((str(CPU_TEMP())), True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (400, 1280 + (4 * (LINEHEIGHT))))
text = basicFont.render("ACTIVE THREADS", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (1750, 1265 + (1 * (LINEHEIGHT))))
text = basicFont.render(str(threading.active_count()), True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (1875, 1265 + (2 * (LINEHEIGHT))))
text = basicFont.render("SALT", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (218, 670 - LINEHEIGHT))
text = basicFont.render("LEVEL", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (210, 700 - LINEHEIGHT))
#Draw Pressure 1
text = basicFont.render("SUPPLY", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (145, 250 + LINEHEIGHT))
#Draw Suppy Pressure
text = basicFont.render((str(PRESS3()) + ' PSI'), True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (140, 250 + (2 * LINEHEIGHT)))
text = basicFont.render("SYSTEM", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (130, 980 + LINEHEIGHT))
#Draw Total flow
text = basicFont.render((str(FLOW5()) + ' L/min'), True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (120, 980 + (2 *LINEHEIGHT)))
#Draw Vessel1 flow
text = basicFont.render((str(FLOW3()) + ' L/min'), True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (360, 265 + LINEHEIGHT))
#Draw Vessel2 flow
text = basicFont.render((str(FLOW4()) + ' L/min'), True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (600, 265 + LINEHEIGHT))
# Draw Totalizers
text = basicFont.render("TOTALIZERS", True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (110, 40 - LINEHEIGHT))
text = basicFont.render('VESSEL 1 ' + (str(FLOW3T()) + ' Liters'), True, WHITE, BLACK)
textRect = text.get_rect()
screen.blit(text, (80, 10 + (LINEHEIGHT)))
text = basicFont.render('VESSEL 2 ' + (str(FLOW4T()) + ' Liters'), True, WHITE, BLACK)
...
This file has been truncated, please download it to see its full contents.
Comments