-
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathOnAir.py
More file actions
152 lines (129 loc) · 5.28 KB
/
Copy pathOnAir.py
File metadata and controls
152 lines (129 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# ===============================================================================
# OnAir.py - On-Air Sign Controller for LED Displays
# ===============================================================================
# Author: William McEvoy (@datagod)
#
# DESCRIPTION:
# This script controls an "On-Air" LED display sign via HTTP requests to a
# LEDcommander server. It supports two modes:
# 1. Command-line interface (CLI) for manual on/off control with optional
# duration (currently commented out).
# 2. GPIO button integration for toggling the sign on/off using a physical
# button connected to a Raspberry Pi.
#
# The script assumes LEDcommander is running with a Flask server on port 5055.
# It sends JSON commands to trigger the "showonair" or "showonair_off" actions.
#
# REQUIREMENTS:
# - requests: For HTTP communication.
# - RPi.GPIO: For Raspberry Pi GPIO handling (button mode).
# - argparse: For CLI parsing (if uncommented).
#
# USAGE:
# - Button Mode: Run the script on a Raspberry Pi with a button connected to GPIO 5.
# Press the button to toggle the On-Air sign (default duration: 30 minutes).
# - CLI Mode: Uncomment the CLI section and run with arguments:
# python OnAir.py --on --minutes=30 # Turn on for 30 minutes
# python OnAir.py --off # Turn off
#
# CONFIGURATION:
# - BUTTON_GPIO: GPIO pin for the button (default: 5).
# - SERVER_URL: URL of the LEDcommander Flask server (default: http://ledpi1:5055/command).
#
# NOTES:
# - Ensure LEDcommander is accessible and running before use.
# - Debounce time is set to 300ms to prevent rapid toggles.
# - Error handling includes connection issues and general exceptions.
#
# ===============================================================================
import requests
import time
import argparse
# No need for multiprocessing here; assume LEDcommander is running separately with Flask on port 5055
'''
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Control OnAir display")
parser.add_argument('--on', action='store_true', help="Turn OnAir on")
parser.add_argument('--off', action='store_true', help="Turn OnAir off")
parser.add_argument('--minutes', type=int, default=30, help="Minutes to remain on air (default: 30)")
args = parser.parse_args()
if not (args.on or args.off):
print("Error: Must specify --on or --off")
parser.print_help()
exit(1)
url = "http://ledpie:5055/command" # Adjust host/port if running remotely
try:
if args.on:
duration = args.minutes * 60 # Convert minutes to seconds
data = {"Action": "showonair", "duration": duration}
response = requests.post(url, json=data)
print(f"[OnAir] Response: {response.json() if response.ok else response.text}")
elif args.off:
data = {"Action": "showonair_off"}
response = requests.post(url, json=data)
print(f"[OnAir] Response: {response.json() if response.ok else response.text}")
except requests.exceptions.ConnectionError:
print("[OnAir] Error: Could not connect to LEDcommander Flask server. Ensure it's running.")
except Exception as e:
print(f"[OnAir] Error: {e}")
'''
import RPi.GPIO as GPIO
import time
import requests
import threading
BUTTON_GPIO = 5
SERVER_URL = "http://ledpi1:5055/command" # Replace <remote_ip> with the actual IP of the computer running LEDcommander
ON_AIR_MINUTES = 30
ON_AIR_SECONDS = ON_AIR_MINUTES * 60
on_air = False
expiry_timer = None
def clear_on_air_state():
global on_air
on_air = False
print(f"[OnAir] {ON_AIR_MINUTES}-minute timer expired; local state reset to off")
def schedule_expiry_timer():
global expiry_timer
if expiry_timer:
expiry_timer.cancel()
expiry_timer = threading.Timer(ON_AIR_SECONDS, clear_on_air_state)
expiry_timer.daemon = True
expiry_timer.start()
def button_callback(channel):
global on_air
if GPIO.input(BUTTON_GPIO) == GPIO.LOW:
print("Button was pressed!")
try:
if on_air:
data = {"Action": "showonair_off"}
response = requests.post(SERVER_URL, json=data, timeout=5)
print(f"[Off] Response: {response.json() if response.ok else response.text}")
on_air = False
if expiry_timer:
expiry_timer.cancel()
else:
data = {"Action": "showonair", "duration": ON_AIR_SECONDS}
response = requests.post(SERVER_URL, json=data, timeout=5)
print(f"[On] Response: {response.json() if response.ok else response.text}")
on_air = True
schedule_expiry_timer()
except requests.exceptions.ConnectionError:
print("Error: Could not connect to LEDcommander server. Ensure it's running.")
except Exception as e:
print(f"Error: {e}")
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_GPIO, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Detect FALLING edge (press: HIGH -> LOW)
GPIO.add_event_detect(
BUTTON_GPIO,
GPIO.FALLING,
callback=button_callback,
bouncetime=300
)
print("Waiting for button presses... (Ctrl+C to exit)")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("Exiting...")
finally:
GPIO.cleanup()