Skip to content

Commit

Permalink
black code style applied
Browse files Browse the repository at this point in the history
  • Loading branch information
jpizquierdo committed Jul 5, 2023
1 parent 50cb7b6 commit 75199fe
Show file tree
Hide file tree
Showing 15 changed files with 306 additions and 214 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
*.pyc
.vscode
59 changes: 36 additions & 23 deletions draco.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,19 @@ def main(manager) -> int:
success = True
processes = None
pid = os.getpid()
GPIO.cleanup() # cleanup will be made in main application only
GPIO.cleanup() # cleanup will be made in main application only
try:
# Get static configuration for the program
parser = argparse.ArgumentParser()
parser.add_argument(
"-c", "--config",
default="config.json",
help="Path to static configuration"
"-c", "--config", default="config.json", help="Path to static configuration"
)

with open(Path(parser.parse_args().config), "r") as jsonfile:
config = json.load(jsonfile)

# Creation of Manager proxy and Manager Lock: Manager Server Process with common data for multiprocessing. Not shared memory
system_status_proxy = manager.dict(Status()._asdict()) # create a proxy dict
system_status_proxy = manager.dict(Status()._asdict()) # create a proxy dict
system_status_lock = manager.Lock()
# shared memory queue
q_telegram_log = Queue(maxsize=20)
Expand All @@ -39,32 +37,46 @@ def main(manager) -> int:
# Creation of processes
processes = []
# Telegram bot
processes.append(TelegramBot(config=config,
memory_proxy=(system_status_proxy, system_status_lock),
telegram_queue=q_telegram_log,
name="telegram_bot"))
processes.append(
TelegramBot(
config=config,
memory_proxy=(system_status_proxy, system_status_lock),
telegram_queue=q_telegram_log,
name="telegram_bot",
)
)
# Relay shield
processes.append(GPIOHandler(config=config,
memory_proxy=(system_status_proxy, system_status_lock),
telegram_queue=q_telegram_log,
name="relayshield"))
#System Scheduler
processes.append(SystemScheduler(config=config,
memory_proxy=(system_status_proxy, system_status_lock),
telegram_queue=q_telegram_log,
name="scheduler"))
processes.append(
GPIOHandler(
config=config,
memory_proxy=(system_status_proxy, system_status_lock),
telegram_queue=q_telegram_log,
name="relayshield",
)
)
# System Scheduler
processes.append(
SystemScheduler(
config=config,
memory_proxy=(system_status_proxy, system_status_lock),
telegram_queue=q_telegram_log,
name="scheduler",
)
)

# Start processes
for process in processes:
process.start()

# main loop for monitoring processes
while success:
for process in processes:
if process.exitcode == 1:
raise Exception("A critical process exited with error, terminating all other processes")
raise Exception(
"A critical process exited with error, terminating all other processes"
)
sleep(1)

except Exception as error:
print(f"Process {pid} - " + repr(error))
success = False
Expand All @@ -75,7 +87,8 @@ def main(manager) -> int:
[p.kill() for p in processes if p.is_alive()]
return int(not success)


if __name__ == "__main__":
manager = Manager()
exit_code = main(manager)
sys.exit(exit_code)
sys.exit(exit_code)
47 changes: 26 additions & 21 deletions draco/interfaces/relay_shield_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import RPi.GPIO as GPIO
from enum import IntEnum, unique


@unique
class GPIO_Mode(IntEnum):
BCM_MODE = 11
BOARD_MODE = 10


class KS0212Interface(object):
"""
KS0212 keyestudio RPI 4-channel Relay Shield interface.
Expand All @@ -17,10 +19,10 @@ class KS0212Interface(object):
----------
Control Signal: TTL Level
Rated Load:
10A 250VAC
10A 125VAC
10A 30VDC
10A 28VDC
10A 250VAC
10A 125VAC
10A 30VDC
10A 28VDC
Rated Current: 10A(NO) 5A(NC)
Max Switching Voltage: 250VAC 30VDC
Contact Time: under 10ms
Expand All @@ -33,16 +35,17 @@ class KS0212Interface(object):
J3 GPIO pin: 22
J4 GPIO pin: 6
J5 GPIO pin: 26
https://wiki.keyestudio.com/KS0212_keyestudio_RPI_4-channel_Relay_Shield
"""

def __init__(
self,
config: Mapping[str, Any] = {},
memory_proxy: tuple = (),
telegram_queue: Queue = None,
name: str = "relayshield"
name: str = "relayshield",
) -> None:
"""
KS0212 keyestudio RPI 4-channel Relay Shield interface constructor.
Expand Down Expand Up @@ -89,18 +92,22 @@ def init(
if GPIO.getmode() == None:
GPIO.setmode(GPIO.BCM)
self._gpio_setup(**self._config)
self.Channel = IntEnum('Channel', {"WATERPUMP" : self._config["WaterPump"],
"VALVE1" : self._config["Valve1"],
"VALVE2" : self._config["Valve2"],
"VALVE3" : self._config["Valve3"],
})
self.Channel = IntEnum(
"Channel",
{
"WATERPUMP": self._config["WaterPump"],
"VALVE1": self._config["Valve1"],
"VALVE2": self._config["Valve2"],
"VALVE3": self._config["Valve3"],
},
)

except Exception as error:
print(f"Process {self._pid} - " + repr(error))
success = False

return success

def step(
self,
) -> bool:
Expand All @@ -124,7 +131,7 @@ def step(
except:
success = False
return success

def _gpio_setup(self, **kwargs) -> None:
"""
This method setup as outputs the GPIOs from the json config file.
Expand All @@ -135,7 +142,7 @@ def _gpio_setup(self, **kwargs) -> None:
"""
for key in kwargs:
GPIO.setup(kwargs[key], GPIO.OUT)

def handle_relay(self, channel, value):
"""
Method to handle the relay. It only takes effect if the GPIO HW value has changed.
Expand All @@ -151,7 +158,7 @@ def handle_relay(self, channel, value):
if GPIO.input(channel) != value:
GPIO.output(channel, value)
self._log(f"{channel.name} set to {value}")

def start_waterPump(self):
"""
Set to 1 GPIO waterpump
Expand All @@ -165,7 +172,7 @@ def stop_waterPump(self):
"""
GPIO.output(self.Channel.WATERPUMP, 0)
self._log(f"{self.Channel.WATERPUMP.name} set to 0")

def start_valve1(self):
"""
Set to 1 GPIO valve1
Expand All @@ -179,7 +186,7 @@ def stop_valve1(self):
"""
GPIO.output(self.Channel.VALVE1, 0)
self._log(f"{self.Channel.VALVE1.name} set to 0")

def start_valve2(self):
"""
Set to 1 GPIO valve2
Expand All @@ -193,7 +200,7 @@ def stop_valve2(self):
"""
GPIO.output(self.Channel.VALVE2, 0)
self._log(f"{self.Channel.VALVE2.name} set to 0")

def start_valve3(self):
"""
Set to 1 GPIO valve3
Expand All @@ -207,12 +214,10 @@ def stop_valve3(self):
"""
GPIO.output(self.Channel.VALVE3, 0)
self._log(f"{self.Channel.VALVE3.name} set to 0")

def _log(self, msg):
"""
Logging function that queues message for telegram
#TODO: will implement a python logger
"""
self.telegram_queue.put(f"{__name__.split('.')[-1]}: {msg}")


68 changes: 38 additions & 30 deletions draco/interfaces/scheduler_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ def __init__(
config: Mapping[str, Any] = {},
memory_proxy: tuple = (),
telegram_queue: Queue = None,
name: str = "scheduler"
name: str = "scheduler",
) -> None:
"""
Telegram interface constructor.
Telegram interface constructor.
Parameters
----------
config : Mapping[str, Any]
Class configuration map.
memory_proxy: tuple
system_status_proxy
system_status_lock
telegram_queue : Queue
telegram queue to send logging to main user
name: str
name in json file
Parameters
----------
config : Mapping[str, Any]
Class configuration map.
memory_proxy: tuple
system_status_proxy
system_status_lock
telegram_queue : Queue
telegram queue to send logging to main user
name: str
name in json file
"""
config_draco = config.copy()
if name in config:
Expand Down Expand Up @@ -57,19 +57,19 @@ def init(
print(f"Process {self._pid} - " + repr(error))
success = False
return success

def step(self) -> None:
"""
This methods will check status and stop / run schedulers
"""
print(schedule.get_jobs())
info = self._check_status()
#Only setup the scheduler if value change
# Only setup the scheduler if value change
if self.initial_holidays_state != info["holidays"]:
self.initial_holidays_state = info["holidays"]
self.setup_scheduler(info)
schedule.run_pending()

def setup_scheduler(self, info) -> None:
"""
Function that is called in step, it setup the schedulers or remove them
Expand All @@ -78,13 +78,19 @@ def setup_scheduler(self, info) -> None:
self._log(f"Setting the holidays schedulers:")
self._log(f"- Alive logging")
self._log(f"- Summer watering")
schedule.every().day.at('22:00').do(self._alive_logging).tag('all', 'holidays', 'watchdog')
schedule.every().day.at('09:00').do(self._alive_logging).tag('all', 'holidays', 'watchdog')
schedule.every().day.at('20:00').do(self._summer_watering).tag('all', 'holidays', 'watchdog')
schedule.every().day.at("22:00").do(self._alive_logging).tag(
"all", "holidays", "watchdog"
)
schedule.every().day.at("09:00").do(self._alive_logging).tag(
"all", "holidays", "watchdog"
)
schedule.every().day.at("20:00").do(self._summer_watering).tag(
"all", "holidays", "watchdog"
)
else:
self._log(f"Clearing the holidays schedulers")
schedule.clear('holidays')
schedule.clear("holidays")

def _check_status(self):
"""
This method check the system status proxy
Expand All @@ -93,22 +99,24 @@ def _check_status(self):
info = self.system_status_proxy._getvalue()
self.system_status_lock.release()
return info

def _alive_logging(self):
self._log(f"Ey, I am alive.")
#TODO send a webcam photo through telegram
# TODO send a webcam photo through telegram

def _summer_watering(self):
"""
Job that is triggered for watering during the summer
"""
self._log(f"Summer watering scheduler")
self._command_waterPump(value=1)
self._command_valve(valve_number=2, value=1)
#15 minutes of watering TODO: put inside configuration
schedule.every().day.at('20:15').do(self._command_waterPump, value=0)
schedule.every().day.at('20:25').do(self._command_valve, valve_number=2, value=0)

# 15 minutes of watering TODO: put inside configuration
schedule.every().day.at("20:15").do(self._command_waterPump, value=0)
schedule.every().day.at("20:25").do(
self._command_valve, valve_number=2, value=0
)

def _command_waterPump(self, value):
"""
This method request the value of the pump to 'value'
Expand All @@ -119,7 +127,7 @@ def _command_waterPump(self, value):
self._log(f"Request Pump Status to {value}")
if value == 0:
return schedule.CancelJob

def _command_valve(self, valve_number, value):
"""
This method request the value of the valves 1, 2, 3 to 'value'
Expand All @@ -130,7 +138,7 @@ def _command_valve(self, valve_number, value):
self._log(f"Request Valve {valve_number} Status to {value}")
if value == 0:
return schedule.CancelJob

def _log(self, msg):
"""
Logging function that queues message for telegram
Expand Down
Loading

0 comments on commit 75199fe

Please sign in to comment.