Skip to content

Update Sun Schedule #265

Update Sun Schedule

Update Sun Schedule #265

name: "Update Sun Schedule"
on:
schedule:
# Run once daily at 02:00 UTC (3 AM Oslo time in winter)
- cron: "0 2 * * *"
workflow_dispatch: # Manual trigger for testing
jobs:
update-schedule:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.PAT_TOKEN }}
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install requests PyYAML
- name: Fetch sun times and update schedule
run: |
python3 << 'EOF'
import json
import requests
from datetime import datetime, time
# Load configuration
with open('config.json', 'r') as f:
config = json.load(f)
# Fetch sun times
LAT = config['location']['latitude']
LNG = config['location']['longitude']
url = config['api']['sunrise_sunset_url'].format(lat=LAT, lng=LNG)
response = requests.get(url, timeout=15)
response.raise_for_status()
data = response.json()
if data.get("status") != "OK":
raise Exception(f"API returned status: {data.get('status')}")
results = data["results"]
# Parse times (ISO format from API when formatted=0)
def parse_time(time_str):
"""Extract hour and minute from ISO datetime string"""
dt = datetime.fromisoformat(time_str.replace('Z', '+00:00'))
return dt.hour, dt.minute
# Get astronomical twilight times (darkest)
twilight_end_h, twilight_end_m = parse_time(results["astronomical_twilight_end"])
twilight_begin_h, twilight_begin_m = parse_time(results["astronomical_twilight_begin"])
# Generate cron schedule for dark hours
# Run every 15 minutes during astronomical darkness
# Cron format: minute hour * * *
# If twilight_end is 17:44:59 (5:44 PM), start at 18:00
# If twilight_begin is 4:18:25 AM, end at 4:00 AM
start_hour = twilight_end_h + 1 if twilight_end_m > 30 else twilight_end_h
end_hour = twilight_begin_h
# Handle case where darkness spans midnight
if start_hour >= end_hour:
# Example: 18:00-23:59 and 00:00-04:00
cron_evening = f"*/15 {start_hour}-23 * * *"
cron_morning = f"*/15 0-{end_hour} * * *" if end_hour > 0 else None
cron_schedule = [cron_evening]
if cron_morning:
cron_schedule.append(cron_morning)
else:
# Continuous dark period (rare in Lommedalen)
cron_schedule = [f"*/15 {start_hour}-{end_hour} * * *"]
# Save schedule info
schedule_info = {
"updated_at": datetime.utcnow().isoformat() + "Z",
"location": config['location'],
"sun_times": results,
"dark_hours": {
"start_hour": start_hour,
"end_hour": end_hour,
"spans_midnight": start_hour >= end_hour
},
"cron_schedules": cron_schedule
}
schedule_file = config['data']['sun_schedule_file']
with open(schedule_file, 'w') as f:
json.dump(schedule_info, f, indent=2)
print(f"✅ Updated sun schedule")
print(f" Astronomical darkness: {start_hour}:00 - {end_hour}:00 UTC")
print(f" Cron schedules: {', '.join(cron_schedule)}")
EOF
- name: Update workflow schedule
run: |
python3 << 'EOF'
import json
import re
# Load config
with open('config.json', 'r') as f:
config = json.load(f)
# Load schedule info
schedule_file = config['data']['sun_schedule_file']
with open(schedule_file, 'r') as f:
schedule_info = json.load(f)
cron_schedules = schedule_info['cron_schedules']
# Read the workflow file
with open('.github/workflows/post.yml', 'r') as f:
content = f.read()
# Find and replace the schedule section using regex
# This preserves comments and formatting
schedule_pattern = r'(on:\s*\n\s+schedule:\s*\n(?:\s+#[^\n]*\n)*)((?:\s+-\s+cron:\s+[^\n]+\n)+)'
# Build new schedule lines
new_schedule_lines = []
for cron in cron_schedules:
new_schedule_lines.append(f' - cron: "{cron}"\n')
new_schedule_section = ''.join(new_schedule_lines)
# Replace the schedule section
def replacer(match):
return match.group(1) + new_schedule_section
updated_content = re.sub(schedule_pattern, replacer, content)
# Write back
with open('.github/workflows/post.yml', 'w') as f:
f.write(updated_content)
print(f"✅ Updated post.yml with {len(cron_schedules)} cron schedule(s)")
print(f" Schedules: {', '.join(cron_schedules)}")
EOF
- name: Commit and push changes
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
# Get schedule file from config
SCHEDULE_FILE=$(jq -r '.data.sun_schedule_file' config.json)
git add "$SCHEDULE_FILE" .github/workflows/post.yml
if git diff --staged --quiet; then
echo "No changes to commit"
else
START_HOUR=$(jq -r '.dark_hours.start_hour' "$SCHEDULE_FILE")
END_HOUR=$(jq -r '.dark_hours.end_hour' "$SCHEDULE_FILE")
UPDATED_AT=$(jq -r '.updated_at' "$SCHEDULE_FILE")
CRON_SCHEDULES=$(jq -r '.cron_schedules | join(", ")' "$SCHEDULE_FILE")
git commit -m "chore: update sun schedule and workflow timing [automated]" \
-m "Dark hours: ${START_HOUR}:00 - ${END_HOUR}:00 UTC" \
-m "Cron: ${CRON_SCHEDULES}" \
-m "Updated: ${UPDATED_AT}"
git push
fi