Thank you for taking the time to view my post. Below is my first Python script I’ve wrote over the last day so pardon any oversights.
I posted this on stackoverflow a few days ago, but have gotten very little input so far. This is basically a copy and paste from the post. With @wendell posting several videos mentioning automation I figured I’d give this forum a try.
https:// stackoverflow .com/questions/62900058/peer-review-questions-of-rv-automation-script
Goal: To run the script on a Raspberry Pi with four relay hats and each hat having four relays to empty and rinse out the tanks on my RV automatically based on parameters entered on a simple webpage. Using a script like this will allow me to save water… I have forgotten about the water being on and the gate open before causing unnecessary water usage. Getting a general review of the code for optimization and/recommendations.
Background: I travel in my RV for work and have recently started making some quality of life changes and fun tweaks to it. I replaced the manual cable gates on my RV with electronic gates after one of the cables started jamming up and, disgustingly, I discovered my black tank was leaking at the tank exit connection. Another plus is that I can stay inside in the winter when needing to rinse and empty the tanks. I currently have a remote control relay board I use to open and close the three tanks on my RV and a switch to kill the ground for the electronic gates. The reason for the switch is because I installed the manual switches that came with the gates as a “just in case”, but the fuse blows when I use the switches with the remote relay board having power. I cannot figure out what I wired wrong. I am going to install aftermarket tank rinsers in all of the tanks with a manifold that has a NC water valve for each rinser and the factory installed black tank rinser for a total of four rinsing options (I probably won’t use the factory one much once the aftermarket one is install, but want the option). The white water will have a ball valve that is controlled by an electric motor.
Current roadblocks:
- I cannot figure out a good search term to find how to interface the script with a webpage. Almost all search results show how to write a webpage in python, but not how to pipe things into a python script from a webpage. Links to tutorials for solutions would be appreciated.
- How to write a full error catchall so the power is cut in case something goes wrong with the script or Pi. All of the water valves that fill tanks are going to be NC aka the water valves that could cause flooding.
- Two timers on the webpage. One for the total remaining time of the script and one for the current task.
- A graceful way to be able to activate the White Water valve during the flush and fill process for a set amount of time so I could wash my hands or other things that briefly require water. I prefer to keep the white water closed any time I am flushing the tanks, even though I use two hoses out of sanitary caution.
- If possible, a way to name each relay address as a parameter. This will cut back on a lot of the comments and make the code easier to read. Something like PosPow = (board0, relay1)?
- Same as 4, but for i2cbus.write_byte_data, an easy parameter to make the code cleaner.
- This is probably a bit out of scope for the post, but I might as well mention it. The switches that came with the gates have a blinking light to indicate they are open, I’d like to use that light pulse to put a status of open or closed on the webpage. If a pulse isn’t received within one second the gate is closed. This could also be used to replace the manual Gate Toggle Time parameter. The white water ball valve also has a status light.
- I am using Thonny on the Raspberry Pi over VNC to write this code, is there a more intelligent software I could be using? Preferably free. Something like a Notepad++ maybe. The two biggest pet peeves I’m having is how the CTRL &/or Shift works for keyboard editing text and how Tabs are sometimes spaces instead of Tabs.
- Probably something else I forgot while writing this and will edit once I remember.
Products referenced above:
Electronic Tank Gate: https://www.amazon.com/gp/product/B003VAYMB4 I have 2x 3" and 1x 1.5". That’s why there is a variance in the Grey2 Gate Toggle Time.
Electric Ball Valve: https://www.amazon.com/gp/product/B06Y11B8VN
NC Valve: https://www.amazon.com/gp/product/B06XW8MSTX
Pi Relay Board: https://www.amazon.com/gp/product/B07Q2P9D7K
Current Remote Control Relay Board: https://www.amazon.com/gp/product/B01D5XWDYO
I believe I have blabbed on enough so here is the code. Thank you again for your time.
#https://wiki.52pi.com/index.php/DockerPi_4_Channel_Relay_SKU:_EP-0099
import time
from smbus import SMBus
import sys
#BEGIN PARAMETERS-----------------------------------------------------------------------
#I2C Reference
i2cbus = SMBus(1)
#I2C Write
#i2cbuswrite = i2cbus.write_byte_data
#White Water Close Time
WWC = 8+1 #Time to be Web Based
#White Water Open Time
WWO = 8+1 #Time to be Web Based
#White Water Override During Script. Using Water During Flushing Process Effects Overall Water Pressure and Will Prevent Proper Tank Filling and Flushing
WWOVER = False #T/F to be Web Based #???? Wrap Whole Script in an Override
#White Water Override During Script Time
WWOVERT = 2*60 #Time to be Web Based
#Black1 Rinse
B1R = True #T/F to be Web Based
#Black1 Use Factory Fill
B1FF = True #T/F to be Web Based
#Black1 Use Added Fill
B1AF = False #T/F to be Web Based
#Black1 Close/Fill Time
B1CT = 13*60 #Time to be Web Based
#Black1 Open/Drain Time
B1OT = 5*60 #Time to be Web Based
#Black1 Gate Toggle Time
B1GTT = 10 #Time to be Web Based
#Black1 Gate Cycles
B1GC = 5 #Cycles to be Web Based
#Black1 Tank Stir Time
B1TST = 15 #Time to be Web Based
#Black1 Post Fill Tank
B1PF = True #T/F to be Web Based
#Black1 Post Fill Time
B1PFT = 2*60 #Time to be Web Based
#Grey1 Rinse
G1R = False
#Grey1 Close/Fill Time
G1CT = 10*60
#Grey1 Open/Drain Time
G1OT = 5*60
#Grey1 Gate Toggle Time
G1GTT = 10
#Grey1 Gate Cycles
G1GC = 5
#Grey1 Tank Stir Time
G1TST = 15
#Grey1 Post Fill Tank
G1PF = True
#Grey1 Post Fill Time
G1PFT = 2*60
#Grey2 Rinse
G2R = False
#Grey2 Close/Fill Time
G2CT = 10*60
#Grey2 Open/Drain Time
G2OT = 5*60
#Grey2 Gate Toggle Time
G2GTT = 7
#Grey2 Gate Cycles
G2GC = 5
#Grey2 Tank Stir Time
G2TST = 15
#Grey2 Post Fill Tank
G2PF = True
#Grey2 Post Fill Time
G2PFT = 2*60
#Relay Function
ron = 0xFF
roff = 0x00
#Relay Addresses
relay1 = 0x01
relay2 = 0x02
relay3 = 0x03
relay4 = 0x04
relays = [relay1, relay2, relay3, relay4]
#Relay Board Address
board0 = 0x10
board1 = 0x11
board2 = 0x12
board3 = 0x13
boards = [board0, board1, board2, board3]
#Positive Power (board0, relay1
#Negative Power (board0, relay2
#White Water Close (board0, relay3
#White Water Open (board0, relay4
#Black Gate Close (board1, relay1
#Black Gate Open (board1, relay2
#Black Gate Added Water Tank Fill (board1, relay3
#Black Gate Factory Water Tank Fill (board1, relay4
#Grey1 Gate Close (board2, relay1
#Grey1 Gate Open (board2, relay2
#Grey1 Gate Added Water Tank Fill (board2, relay3
# (board2, relay4
#Grey2 Gate Close (board3, relay1
#Grey2 Gate Open (board3, relay2
#Grey2 Gate Added Water Tank Fill (board3, relay3
# (board4, relay4
#END PARAMETERS-----------------------------------------------------------------------
#BEGIN DEBUG RESET RELAYS BEFORE SCRIPT-----------------------------------------------
#Loop to turn off all gates
for x in boards:
currentboard = x
for y in relays:
currentrelay = y
i2cbus.write_byte_data(x, y, roff)
time.sleep(.025)
time.sleep(1)
#END DEBUG RESET RELAYS BEFORE SCRIPT--------------------------------------------------
#Turn On Power
#Positive Power On (board0, relay1
i2cbus.write_byte_data(board0, relay1, ron)
#Negative Power On (board0, relay2
i2cbus.write_byte_data(board0, relay2, ron)
time.sleep(.025)
#White Water Close (board0, relay3
i2cbus.write_byte_data(board0, relay3, ron)
time.sleep(WWC)
i2cbus.write_byte_data(board0, relay3, roff)
time.sleep(1)
#Sync All Gates to Off
#Close Black1 (board1, relay1
i2cbus.write_byte_data(board1, relay1, ron)
time.sleep(B1GTT)
i2cbus.write_byte_data(board1, relay1, roff)
#Close Grey1 (board2, relay1
i2cbus.write_byte_data(board2, relay1, ron)
time.sleep(G1GTT)
i2cbus.write_byte_data(board2, relay1, roff)
#Close Grey2 (board3, relay1
i2cbus.write_byte_data(board3, relay1, ron)
time.sleep(G2GTT)
i2cbus.write_byte_data(board3, relay1, roff)
try: #Grey1 & Grey2 Will Be Added Under this Try After Black1 is Fully Configured.
#Rinse Black1 (board1, relay1 & (board1, relay2
if B1R is True:
#Black1 Factory Water Tank Fill (board1, relay4 Used as Water Source
if B1FF is True:
#Turn On Factory Water Tank Fill
i2cbus.write_byte_data(board1, relay4, ron)
#Black1 Added Water Tank Fill (board1, relay3 Used as Water Source
if B1AF is True:
#Turn On Added Water Tank Fill
i2cbus.write_byte_data(board1, relay3, ron)
#Time to Stir Up Tank
time.sleep(B1TST)
#Black1 Open for Intial Drain
i2cbus.write_byte_data(board1, relay2, ron)
time.sleep(B1GTT)
i2cbus.write_byte_data(board1, relay2, roff)
#Black1 Drain
time.sleep(B1OT)
#Black1 Rinse Cycle
for x in range(B1GC):
#Black1 Close
i2cbus.write_byte_data(board1, relay1, ron)
time.sleep(B1GTT)
i2cbus.write_byte_data(board1, relay1, roff)
#Black1 Fill
time.sleep(B1CT)
#Black1 Open
i2cbus.write_byte_data(board1, relay2, ron)
time.sleep(B1GTT)
i2cbus.write_byte_data(board1, relay2, roff)
#Black1 Drain
time.sleep(B1OT)
#Black1 Close
i2cbus.write_byte_data(board1, relay1, ron)
time.sleep(B1GTT)
i2cbus.write_byte_data(board1, relay1, roff)
#Black1 Water Post Flush Fill
if B1PF is True:
time.sleep(B1PFT)
#Black1 Factory Water Tank Fill (board1, relay4 Used as Water Source
if B1FF is True:
#Turn Off Factory Water Tank Fill
i2cbus.write_byte_data(board1, relay4, roff)
#Black1 Added Water Tank Fill (board1, relay3 Used as Water Source
if B1AF is True:
#Turn Off Added Water Tank Fill
i2cbus.write_byte_data(board1, relay3, roff)
except KeyboardInterrupt:
print("Keyboard Quit the Loop")
for x in boards: #Loop to turn off all gates
currentboard = x
for y in relays:
currentrelay = y
i2cbus.write_byte_data(x, y, roff)
finally:
#Loop to turn off all gates
for x in boards:
currentboard = x
for y in relays:
currentrelay = y
i2cbus.write_byte_data(x, y, roff)
#White Water Open (board0, relay4
i2cbus.write_byte_data(board0, relay3, ron)
time.sleep(WWO)
i2cbus.write_byte_data(board0, relay3, roff)
#Turn Off Power
#Positive Power Off (board0, relay1
i2cbus.write_byte_data(board0, relay1, roff)
#Negative Power Off (board0, relay2
i2cbus.write_byte_data(board0, relay2, roff)
sys.exit()
```code