Skip to content

feat: dynamic scheduling based on astronomical darkness #1

feat: dynamic scheduling based on astronomical darkness

feat: dynamic scheduling based on astronomical darkness #1

name: "Update Sun Schedule"

Check failure on line 1 in .github/workflows/update-sun-schedule.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/update-sun-schedule.yml

Invalid workflow file

(Line: 133, Col: 1): Unexpected value 'Dark hours', (Line: 134, Col: 1): Unexpected value 'Updated'
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.GITHUB_TOKEN }}
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Fetch sun times and update schedule
run: |
python3 << 'EOF'
import json
import requests
from datetime import datetime, time
# Fetch sun times
LAT = 59.95
LNG = 10.466667
url = f"https://api.sunrise-sunset.org/json?lat={LAT}&lng={LNG}&formatted=0"
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 30 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"*/30 {start_hour}-23 * * *"
cron_morning = f"*/30 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"*/30 {start_hour}-{end_hour} * * *"]
# Save schedule info
schedule_info = {
"updated_at": datetime.utcnow().isoformat() + "Z",
"location": {"lat": LAT, "lng": LNG},
"sun_times": results,
"dark_hours": {
"start_hour": start_hour,
"end_hour": end_hour,
"spans_midnight": start_hour >= end_hour
},
"cron_schedules": cron_schedule
}
with open('sun_schedule.json', '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 yaml
# Load schedule info
with open('sun_schedule.json', 'r') as f:
schedule_info = json.load(f)
# Load current workflow
with open('.github/workflows/post.yml', 'r') as f:
workflow = yaml.safe_load(f)
# Update cron schedules
cron_schedules = schedule_info['cron_schedules']
workflow['on']['schedule'] = [{'cron': cron} for cron in cron_schedules]
# Save updated workflow
with open('.github/workflows/post.yml', 'w') as f:
yaml.dump(workflow, f, default_flow_style=False, sort_keys=False)
print(f"✅ Updated post.yml with {len(cron_schedules)} cron schedule(s)")
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"
git add sun_schedule.json .github/workflows/post.yml
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "chore: update sun schedule and workflow timing [automated]
Dark hours: $(jq -r '.dark_hours.start_hour' sun_schedule.json):00 - $(jq -r '.dark_hours.end_hour' sun_schedule.json):00 UTC
Updated: $(jq -r '.updated_at' sun_schedule.json)"
git push
fi