IPC Integration
Sunsetr provides a Unix socket-based IPC (Inter-Process Communication) system for real-time state monitoring and external integrations. The easiest way to interact with IPC is through the status command.
IPC Socket Location
The IPC socket is created at:
$XDG_RUNTIME_DIR/sunsetr-events.sock
Typically this resolves to:
/run/user/1000/sunsetr-events.sock
Event Types
The IPC socket broadcasts three types of events:
1. StateApplied:
Sent when temperature/gamma values are applied to the display.
JSON format:
{
"active_preset": "default",
"period": "sunset",
"state": "transitioning",
"progress": 0.4637135,
"current_temp": 5016,
"current_gamma": 95.36286,
"target_temp": 3300,
"target_gamma": 90.0,
"next_period": "2025-11-11T17:49:25.000679991-06:00"
}
2. PeriodChanged:
Sent when transitioning between periods (Day ↔ Sunset ↔ Night ↔ Sunrise).
Available periods:
day- Stable day periodsunset- Transitioning from day to nightnight- Stable night periodsunrise- Transitioning from night to daystatic- Static mode (no transitions)
3. PresetChanged:
Sent when switching presets.
Includes:
- New preset name
- Target temperature and gamma values
- Target Period
Status Bar Integration
Waybar Example:
Add to ~/.config/waybar/config:
{
"custom/sunsetr": {
"exec": "sunsetr status --json --follow | jq --unbuffered --compact-output 'if .event_type == \"preset_changed\" then {text: \"\\(.target_temp)K\", alt: .target_period, tooltip: \"Preset: \\(.to_preset // \"default\")\\nTarget: \\(.target_temp)K @ \\(.target_gamma)%\"} elif .event_type == \"state_applied\" then {text: \"\\(.current_temp)K\", alt: .period, tooltip: \"Period: \\(.period)\\nTemp: \\(.current_temp)K @ \\(.current_gamma)%\"} else empty end'",
"return-type": "json",
"format": "{icon} {text}",
"format-icons": {
"day": "",
"night": "",
"sunset": "",
"sunrise": "",
"static": ""
},
"on-click": "sunsetr preset day"
}
}
Note: This requires that you have a day preset set in your presets directory.
Custom IPC Clients
You can write custom clients that connect to the IPC socket directly.
Python Example
import socket
import json
def monitor_sunsetr():
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect("/run/user/1000/sunsetr-events.sock")
buffer = ""
try:
while True:
data = sock.recv(4096).decode('utf-8')
buffer += data
while '\n' in buffer:
line, buffer = buffer.split('\n', 1)
if line.strip():
event = json.loads(line)
event_type = event.get('event_type', 'unknown')
if event_type == 'state_applied':
period = event.get('period', 'unknown')
temp = event.get('current_temp', 0)
gamma = event.get('current_gamma', 0)
print(f"Period: {period}")
print(f"Temp: {temp}K")
print(f"Gamma: {gamma}%")
elif event_type == 'preset_changed':
preset = event.get('to_preset') or 'default'
target_period = event.get('target_period', 'unknown')
target_temp = event.get('target_temp', 0)
target_gamma = event.get('target_gamma', 0)
print(f"Preset changed to: {preset}")
print(f"Period: {target_period}")
print(f"Target: {target_temp}K @ {target_gamma}%")
elif event_type == 'period_changed':
to_period = event.get('to_period', event.get('period', 'unknown'))
from_period = event.get('from_period', 'unknown')
print(f"Period: {from_period} → {to_period}")
else:
# Unknown event type, print full event for debugging
print(f"Unknown event: {json.dumps(event, indent=2)}")
print("---")
except KeyboardInterrupt:
print("\nExiting...")
finally:
sock.close()
if __name__ == "__main__":
monitor_sunsetr()
Bash Example with socat
# Stream IPC events (all events, raw JSON)
socat UNIX-CONNECT:/run/user/1000/sunsetr-events.sock -
# Parse state_applied events with jq
socat UNIX-CONNECT:/run/user/1000/sunsetr-events.sock - | \
while read -r line; do
echo "$line" | jq -r 'select(.event_type == "state_applied") | "Period: \(.period) | Temp: \(.current_temp)K"'
done