Fix automation signal chain: forward event data (playlist_id) to action handlers

Event-triggered automations now receive playlist_id from the triggering event
when the action config doesn't have one set. Fixes silent 'No playlist specified'
failures in Discover/Sync chains. Added debug logging to trace event matching.
pull/253/head
Broque Thomas 2 months ago
parent 655e1e251d
commit df390feece

@ -345,17 +345,19 @@ class AutomationEngine:
automation_ids = self._event_automations.get(event_type, [])
if not automation_ids:
logger.info(f"Event '{event_type}' — no automations registered in cache. Cache keys: {list(self._event_automations.keys())}")
return
logger.debug(f"Event '{event_type}' — checking {len(automation_ids)} automation(s)")
logger.info(f"Event '{event_type}' — checking {len(automation_ids)} automation(s), data={data}")
for aid in automation_ids:
try:
auto = self.db.get_automation(aid)
if not auto or not auto.get('enabled'):
logger.debug(f"Event '{event_type}' — automation {aid} disabled or not found, skipping")
continue
config = json.loads(auto.get('trigger_config') or '{}')
if self._evaluate_conditions(config, data):
logger.info(f"Event '{event_type}' matched automation '{auto.get('name')}' (id={aid})")
logger.info(f"Event '{event_type}' MATCHED automation '{auto.get('name')}' (id={aid})")
# Run in separate thread so delays don't block the event loop
threading.Thread(
target=self._run_event_automation,
@ -364,7 +366,7 @@ class AutomationEngine:
name=f'automation-exec-{aid}'
).start()
else:
logger.debug(f"Event '{event_type}' conditions not met for automation {aid}")
logger.info(f"Event '{event_type}' conditions NOT MET for automation '{auto.get('name')}' (id={aid}), config={config}, data={data}")
except Exception as e:
logger.error(f"Event automation {aid} error: {e}")
except Exception as e:
@ -441,6 +443,12 @@ class AutomationEngine:
# Inject automation identity for progress tracking
action_config['_automation_id'] = automation_id
action_config['_automation_name'] = auto.get('name', '')
# Merge event data so action handlers can access trigger context
if event_data:
action_config['_event_data'] = event_data
# Forward playlist_id from event if action config doesn't have one set
if not action_config.get('playlist_id') and event_data.get('playlist_id'):
action_config['playlist_id'] = event_data['playlist_id']
delay_minutes = action_config.get('delay', 0)
_delay_already_inited = False

@ -766,12 +766,14 @@ def _register_automation_handlers():
if old_ids != new_ids:
added_count = len(new_ids - old_ids)
removed_count = len(old_ids - new_ids)
print(f"🔔 [AUTOMATION] Playlist changed: '{pl.get('name', '')}'{added_count} added, {removed_count} removed (old={len(old_ids)}, new={len(new_ids)})")
_update_automation_progress(auto_id,
log_line=f'"{pl.get("name", "")}"{added_count} added, {removed_count} removed', log_type='success')
try:
if automation_engine:
automation_engine.emit('playlist_changed', {
'playlist_name': pl.get('name', ''),
'playlist_id': str(pl.get('id', '')),
'old_count': str(len(old_ids)),
'new_count': str(len(new_ids)),
'added': str(added_count),
@ -780,6 +782,7 @@ def _register_automation_handlers():
except Exception:
pass
else:
print(f"⏭️ [AUTOMATION] No changes: '{pl.get('name', '')}' (tracks={len(old_ids)})")
_update_automation_progress(auto_id,
log_line=f'No changes: "{pl.get("name", "")}"', log_type='skip')
except Exception as e:
@ -27568,8 +27571,10 @@ def _run_playlist_discovery_worker(playlists, automation_id=None):
# (no point triggering downstream sync if nothing changed)
try:
if automation_engine and total_discovered > 0:
_disc_pl_id = str(playlists[0]['id']) if len(playlists) == 1 else ''
automation_engine.emit('discovery_completed', {
'playlist_name': last_playlist_name if len(playlists) == 1 else f'{len(playlists)} playlists',
'playlist_id': _disc_pl_id,
'total_tracks': str(total_tracks),
'discovered_count': str(total_discovered),
'failed_count': str(total_failed),

Loading…
Cancel
Save