-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
147 lines (123 loc) · 5.43 KB
/
main.py
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
from openrgb import OpenRGBClient
import requests
import os
import config # Importing the configuration file
import logging
import json
from icalendar import Calendar
import datetime
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
# Function to scrape bin collection data from iCalendar file or website if URL is specified
def scrape_bin_data():
if config.CALENDAR_URL:
# Use calendar URL if specified
response = requests.get(config.CALENDAR_URL)
cal = Calendar.from_ical(response.text)
else:
# Use local calendar file if no URL is specified
with open(os.path.join(os.path.dirname(__file__), config.CALENDAR_FILE_NAME), 'rb') as f:
cal = Calendar.from_ical(f.read())
# Find events relevant to bin collection
bin_events = []
current_time = datetime.datetime.utcnow() # Use UTC time, which is timezone unaware
for event in cal.walk('vevent'):
if 'Recycling' in event.get('summary') or 'Rubbish' in event.get('summary'):
bin_events.append(event)
# Convert current_time to timezone-naive datetime
current_time = current_time.replace(tzinfo=None)
# Filter out events that have already passed
bin_events = [event for event in bin_events if event.decoded('dtstart').replace(tzinfo=None) >= current_time]
# Sort remaining events by date
bin_events.sort(key=lambda x: x.decoded('dtstart'))
# Get the next bin collection event
next_bin_event = bin_events[0] if bin_events else None
# Extract relevant information
if next_bin_event:
# Construct a list of summaries for events on the same day
bin_summaries = [event.get('summary') for event in bin_events if event.decoded('dtstart').date() == next_bin_event.decoded('dtstart').date()]
combined_summary = ", ".join(bin_summaries)
logging.info(f"Next bin collection event: {combined_summary}")
bin_data = {
'summary': combined_summary,
'start_time': next_bin_event.decoded('dtstart'),
'end_time': next_bin_event.decoded('dtend') if 'dtend' in next_bin_event else None
}
return bin_data
else:
return None
def control_pc_lights(bin_data):
# Initialize OpenRGBClient with specified options
client = OpenRGBClient(config.OPENRGB_SERVER_IP, config.OPENRGB_SERVER_PORT, config.OPENRGB_CLIENT_NAME)
# Get all devices
devices = client.devices
for device in devices:
logging.info(f"Device {device.name} found")
# Set profile based on bin data
profile_index = 0 # Default to the first profile in the list
if "Recycling" in bin_data['summary'] and "Rubbish" in bin_data['summary']:
profile_name = config.RECYCLING_RUBBISH_PROFILE_NAME
elif "Recycling" in bin_data['summary']:
profile_name = config.RECYCLING_PROFILE_NAME
elif "Rubbish" in bin_data['summary']:
profile_name = config.RUBBISH_PROFILE_NAME
else:
logging.error("Unknown bin collection event type")
# Find the index of the profile by name
for index, profile in enumerate(client.profiles):
if profile_name in profile.name:
profile_index = index
break
# Load the profile by index
client.load_profile(profile_index)
logging.info(f"Loaded profile: {profile_name}")
# Function to send push notification via Bark
def send_push_notification(bin_data):
# Extracting bin types from the combined summary
bin_types = []
if "Recycling" in bin_data['summary']:
bin_types.append("Recycling")
if "Rubbish" in bin_data['summary']:
bin_types.append("Rubbish")
# Compose the message with the bin types and reminder
if len(bin_types) == 1:
message = f"Next bin collection: {bin_types[0]}. Remember to put the bin out by 7am."
elif len(bin_types) > 1:
message = f"Next bin collections: {bin_types[0]} and {bin_types[1]}. Remember to put the bins out by 7am."
# Send the push notification using Bark API
try:
notification_data = {
"title": "Bins",
"body": message,
"sound": "",
"url": "",
"level": "timeSensitive",
"group": "Bin Collection Reminders",
"automaticallyCopy": "1"
}
response = requests.post(
url=f"https://api.day.app/{config.BARK_API_KEY}",
headers={"Content-Type": "application/json; charset=utf-8"},
data=json.dumps(notification_data)
)
if response.status_code == 200:
logging.info("Push notification sent successfully.")
else:
logging.error(f"Failed to send push notification. Status code: {response.status_code}")
except requests.exceptions.RequestException as e:
logging.error(f"Notification failed to send. Error: {e}")
def main():
# Scrape bin data
bin_data = scrape_bin_data()
if bin_data:
# Control PC lights based on bin data
control_pc_lights(bin_data)
# Check if notification key is provided
if config.BARK_API_KEY:
# Send push notification
send_push_notification(bin_data)
else:
logging.warning("Notification key not provided in config. Skipping push notification.")
else:
logging.warning("No upcoming bin collection events found.")
if __name__ == "__main__":
main()