Skip to content

Feature/plex management#897

Merged
sparkison merged 10 commits intom3ue:devfrom
Serph91P:feature/plex-management
Mar 31, 2026
Merged

Feature/plex management#897
sparkison merged 10 commits intom3ue:devfrom
Serph91P:feature/plex-management

Conversation

@Serph91P
Copy link
Copy Markdown
Contributor

This pull request introduces automated synchronization between Plex DVR channel maps and the application's current channel and group state, ensuring Plex DVR lineups remain up-to-date after relevant changes. The implementation is event-driven, using a new queued job to handle synchronization efficiently and prevent redundant updates. It also adds new fields to the media_server_integrations table to support this feature, and includes comprehensive test coverage for the new sync logic.

Key changes include:

Plex DVR Sync Automation:

  • Introduced a new queued job, SyncPlexDvrJob, which synchronizes Plex DVR channel maps with the current channel and group configuration. The job is debounced (unique for 60 seconds) to prevent redundant executions and logs its trigger source for traceability.
  • Added a new artisan console command, SyncPlexDvr, to manually trigger Plex DVR synchronization for all or specific integrations.

Event-Driven Sync Triggers:

  • Modified channel and group enable/disable actions (including bulk actions) in ChannelResource and GroupResource to dispatch SyncPlexDvrJob after relevant state changes. [1] [2] [3] [4] [5] [6] [7] [8] [9]
  • Updated the SyncListener so that after a successful playlist or EPG sync, SyncPlexDvrJob is dispatched, ensuring Plex DVR is updated whenever the channel lineup or guide data changes. [1] [2]

Database Schema Enhancements:

  • Added new fields to media_server_integrations via migrations to support Plex DVR management: plex_management_enabled, plex_dvr_id, plex_machine_id, and a JSON plex_dvr_tuners field. [1] [2] [3]
  • Updated the model's $casts and $attributes to handle these new fields appropriately. [1] [2]

Testing and Reliability:

  • Added feature tests to ensure SyncPlexDvrJob is dispatched only after successful playlist or EPG synchronizations, and not when those processes fail. [1] [2]

These changes ensure that Plex DVR channel mappings are always in sync with the application's channel and group state, reducing manual intervention and potential mismatches.

@Serph91P Serph91P marked this pull request as ready for review March 29, 2026 21:27
- Add PlexManagementService for managing Plex server via API
  (server info, sessions, DVR/tuner registration, library scanning,
  recordings management)
- Add migration for plex_management_enabled, plex_dvr_id, plex_machine_id
- Add Plex Management tab to Filament resource with DVR registration,
  session monitoring, library scanning, and recording management
- Add feature tests for PlexManagementService
- Fix addDvrDevice to verify HDHR endpoint is reachable before
  registering with Plex (pre-flight GET to /discover.json)
- Send deviceUri as query parameter instead of JSON body
- Add editable HDHR/EPG URL fields so users can set the correct
  network-reachable address (not localhost)
- Make all Plex management notifications persistent so they appear
  in the notification history bell
- Update tests for new pre-verification flow
- Rewrite PlexManagementService with correct multi-step Plex DVR API flow
  (create device → find device → create DVR → attach), mirroring Headendarr
- Add playlist selector (Playlist, Custom, Merged) to DVR registration form
- Fix default HDHR/EPG URLs showing localhost when APP_URL has no scheme
- Add buildHdhrBaseUrl() helper to handle APP_URL with/without scheme
- Update refreshDvrGuide action with playlist selector
- Remove hard dependency on $record->playlist_id for DVR registration
- Rewrite tests with callback-based Http::fake for multi-step DVR flow
- Replace plex_dvr_device_key + plex_dvr_playlist_uuid with JSON
  plex_dvr_tuners column supporting multiple HDHR tuners per DVR
- Fix buildChannelMapPayload to use correct Plex API field names
  (Channel/number/lineupIdentifier instead of LineupChannel/guideNumber/identifier)
- Add Tuner / Remove Tuner UI actions in Filament resource
- syncDvrChannels now iterates all tuners, syncDvrChannelsForTuner handles single tuner
- resolvePlaylistName helper for tuner list display
- Update SyncPlexDvr command query to use plex_dvr_tuners
- All 22 tests updated and passing
- Remove retry(2, 1000) from client() to prevent 404 exceptions
- Replace configureGuide with configureDvrPrefs using /dvrs/{id}/prefs
- Add refreshGuides method using butler/RefreshEPGGuides endpoint
- Add EPG refresh after channel sync completion
- Add debug logging to DVR preference and guide refresh flows
- Update Filament UI with separate EPG refresh action
- Update tests for new methods
- Create SyncPlexDvrJob with ShouldBeUnique (60s debounce window)
- Dispatch on playlist sync completion (SyncListener)
- Dispatch on EPG sync completion (SyncListener)
- Dispatch on channel enable/disable toggle (ChannelResource)
- Dispatch on channel bulk enable/disable (ChannelResource)
- Dispatch on group enable/disable actions (GroupResource)
- Dispatch on group bulk enable/disable actions (GroupResource)
- Remove everyFiveMinutes() cron from routes/console.php
- Keep artisan command app:sync-plex-dvr for manual use
- Add tests for SyncPlexDvrJob and SyncListener dispatch
… endpoint

- configureDvrPrefs now fetches current settings from Plex first, merges
  overrides, and sends all settings back (Plex requires complete payload)
- Removed non-existent /butler/RefreshEPGGuides endpoint from refreshGuides
- EPG refresh is handled by Plex internally via ButlerTaskRefreshEpgGuides pref
- Added fetchCurrentDvrSettings() and defaultDvrSettings() helper methods
- Increased Livewire max_components from 20 to 50 for complex Filament panels
- Updated tests to mock the DVR settings fetch
@Serph91P Serph91P force-pushed the feature/plex-management branch from 8e2c80e to 35b33cf Compare March 30, 2026 15:53
@Serph91P
Copy link
Copy Markdown
Contributor Author

@sparkison this helps a lot for users who use Plex. This will update the DVR inside Plex when you process your playlist or EPG so that Plex knows what's up. Tested this with my own instance of Plex and working good.

@vdrover
Copy link
Copy Markdown

vdrover commented Mar 30, 2026

Are similar additions needed for Emby/jellyfin?

@sparkison
Copy link
Copy Markdown
Member

@sparkison this helps a lot for users who use Plex. This will update the DVR inside Plex when you process your playlist or EPG so that Plex knows what's up. Tested this with my own instance of Plex and working good.

Does this change the Plex setup process?

@Serph91P
Copy link
Copy Markdown
Contributor Author

@sparkison this helps a lot for users who use Plex. This will update the DVR inside Plex when you process your playlist or EPG so that Plex knows what's up. Tested this with my own instance of Plex and working good.

Does this change the Plex setup process?

Nope not at all, the settings appear after you set up Plex. Then you can set up the management of the DVR in the Plex integration settings.

@Serph91P
Copy link
Copy Markdown
Contributor Author

Are similar additions needed for Emby/jellyfin?

I don't understand you question. This is solely for Plex since Emby and Jellyfin can handle changes in the playlist way better than Plex does.

I could look into adding the same for Jellyfin and Emby but I don't really know anything about their API.

@Serph91P
Copy link
Copy Markdown
Contributor Author

@sparkison this helps a lot for users who use Plex. This will update the DVR inside Plex when you process your playlist or EPG so that Plex knows what's up. Tested this with my own instance of Plex and working good.

Does this change the Plex setup process?

I would love to add an observer, so when you disable or enable a channel in the playlist the update also triggers. Right now it only triggers when you process the playlist or epg.

- Add ChannelObserver to dispatch SyncPlexDvrJob when enabled field changes
- Register observer via #[ObservedBy] attribute on Channel model
- Add SyncPlexDvrJob dispatch to VodResource bulk enable/disable actions
- Add ChannelObserverTest with 4 tests covering enable, disable,
  non-enabled field changes, and mass update (query builder) scenarios
- Add compose.services.yaml and dev-setup.sh to .gitignore
# Conflicts:
#	app/Filament/Resources/Channels/ChannelResource.php
#	app/Filament/Resources/Vods/VodResource.php
@Serph91P
Copy link
Copy Markdown
Contributor Author

@sparkison added the channel check so the DVR in Plex updates.

@Serph91P
Copy link
Copy Markdown
Contributor Author

@sparkison this is done and tested from my side. Would be cool if you could merge it.

@sparkison sparkison merged commit 692fb30 into m3ue:dev Mar 31, 2026
4 checks passed
@Serph91P Serph91P deleted the feature/plex-management branch March 31, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants