propresenter-php/doc/api/communication-devices.md
Thorsten Bus 9e3e719806 feat(library): add readers + writers for all ProPresenter global libraries and theme bundles
Add full IO support for every global ProPresenter library file plus
theme folders, and extend the existing Labels/Macros readers with
exporters and editable accessors so every supported document is now a
round-trippable, mutable object.

New library readers/writers (each: FileReader, FileWriter, Library
wrapper, element wrapper where applicable, CLI tool, tests, doc/api/*.md):

- Groups          (ProGroupsDocument)        + GroupDefinition
- ClearGroups     (ClearGroupsDocument)      + ClearGroupDefinition
- CCLI            (CCLIDocument)
- Messages        (MessageDocument)          + Message
- Timers          (TimersDocument + Clock)   + Timer
- Stage           (Stage.Document)           + StageLayout
- Workspace       (ProPresenterWorkspace)    + Screen
- Props           (PropDocument)             + Prop
- TestPatterns    (TestPatternDocument)
- Calendar        (new CalendarDocument)     + CalendarEvent
- KeyMappings     (new KeyMappingsDocument)  + KeyMapping
- CommunicationDevices (JSON file)           + CommunicationDevice
- Theme bundles   (Template.Document folder + Assets/) + ThemeBundle/Slide/Asset

Extensions to existing modules:

- LabelsFileWriter; Label and LabelLibrary gain setters, addLabel,
  removeLabel, setColor / setColorHex helpers
- MacrosFileWriter; Macro/MacroCollection/MacroLibrary gain UUID, name,
  color, image_type, image_data, trigger_on_startup setters plus
  add/remove for macros and collections

Two new minimal proto schemas were defined for documents that lacked
upstream definitions:

- proto/calendar.proto   - CalendarDocument with Event entries, raw
  bytes for the action/macro sub-messages so the schema can evolve
- proto/keyMappings.proto - KeyMappingsDocument with ApplicationInfo
  and a forward-looking Mapping message (sample only carries the info)

The Theme file turned out to be a regular Rv\Data\Template\Document, so
no new proto was required for theme content; ThemeBundle layers folder
+ Assets/ handling on top in the same spirit as PresentationBundle.

GroupDefinition is intentionally distinct from the existing Group class
(which wraps song-level CueGroup) to avoid breaking song APIs.

Verified with the full PHPUnit suite: 370 tests, 9200 assertions, all
green; LSP diagnostics clean across src/. The unmodified reference
samples for Labels, Groups, ClearGroups, TestPatterns, Calendar and
KeyMappings round-trip byte-for-byte; the others round-trip with the
same byte length (PHP protobuf is not canonically deterministic but
re-write-after-write stabilises).

doc/INDEX.md, doc/keywords.md and AGENTS.md updated so every new module
is discoverable from the top level.
2026-05-03 21:40:09 +02:00

2.6 KiB

CommunicationDevices Library API

PHP module for reading and writing the global ProPresenter CommunicationDevices file. Unlike most config files in this project, this file is JSON, not protobuf.

Quick Reference

use ProPresenter\Parser\CommunicationDevice;
use ProPresenter\Parser\CommunicationDevicesFileReader;
use ProPresenter\Parser\CommunicationDevicesFileWriter;

$library = CommunicationDevicesFileReader::read('/path/to/CommunicationDevices');
$library->addDevice((new CommunicationDevice())->setId('device-1')->setName('Router'));
CommunicationDevicesFileWriter::write($library, '/path/to/CommunicationDevices');

File Layout

CommunicationDevices is a JSON array. The reference sample is [], so the wrapper preserves arbitrary object fields while exposing forward-looking common fields: id, name, type, and address.


Reading

$library = CommunicationDevicesFileReader::read('/Users/me/.../CommunicationDevices');

Throws InvalidArgumentException for missing files and RuntimeException for unreadable files or invalid JSON.


CommunicationDevicesLibrary

CommunicationDevicesLibrary::fromJson($json); // CommunicationDevicesLibrary
$library->toJson();                           // string
$library->getDocument();                      // raw decoded array
$library->getDevices();                       // CommunicationDevice[]
$library->addDevice($device);                 // CommunicationDevice
$library->removeDevice($id);                  // bool
$library->count();                            // int

CommunicationDevice

$device->getId();
$device->setId($id);
$device->getName();
$device->setName($name);
$device->getType();
$device->setType($type);
$device->getAddress();
$device->setAddress($address);
$device->toArray(); // full decoded JSON object

CLI Tool

php bin/parse-communication-devices.php /path/to/CommunicationDevices

Empty files print a useful (none configured) summary.


Key Files

File Purpose
src/CommunicationDevicesLibrary.php JSON-array wrapper
src/CommunicationDevice.php Single JSON device value object
src/CommunicationDevicesFileReader.php Reads and validates JSON
src/CommunicationDevicesFileWriter.php Writes compact JSON
bin/parse-communication-devices.php CLI summary tool

Scope Notes

Because only an empty sample is available, unknown JSON fields are preserved in each device's backing array. The writer uses compact JSON with unescaped slashes / Unicode for stable semantic round trips.