Apple TV and HomePod
import { AppleTV, HomePod } from '@corewire/devices';Both classes extend AppleDevice, which holds the connection, the status and the capabilities they share. You never construct an AppleDevice yourself.
AppleTV | HomePod | |
|---|---|---|
| Protocols | AirPlay and Companion Link | AirPlay |
| Pairing | PIN, once; the credentials are yours to store | None (transient) |
| Shared capabilities | remote, nowPlaying, playback, volume, artwork, multiroom, media | the same |
| Own capabilities | apps, accounts, power, system, text, touch | none |
playUrl | Yes | No; stream the audio instead |
| Retry schedule | quick, slow, then rare | quick, then rare |
HomePod covers the HomePod, the HomePod mini and the second generation HomePod. model tells them apart.
The target
A DeviceTarget says where the device is. Only the address is required.
import type { DeviceTarget } from '@corewire/devices';
const target: DeviceTarget = {
address: '192.168.1.20',
port: 7000,
id: 'Living-Room.local'
};| Field | Meaning |
|---|---|
address | The IP address |
port | The AirPlay port; 7000 when omitted |
txt | The AirPlay TXT record, when known. It supplies the model and the MAC (deviceid) that recovery matches on |
id | The mDNS host id. It tags the logs; the address when omitted |
A DiscoveredDevice has a ready target.
Options
Both constructors take DeviceOptions. AppleTV takes AppleTVOptions, which adds credentials and activeUserAccount.
import { AppleTV, Credentials } from '@corewire/devices';
const tv = new AppleTV({address: '192.168.1.20'}, {
credentials: Credentials.parse(await load()),
log: entry => console.log(`[${entry.device}] ${entry.level}: ${entry.message}`),
logLevels: ['error', 'warn', 'info'],
identity: {name: 'Kitchen hub'}
});| Option | Meaning |
|---|---|
credentials | Apple TV only. From a PIN pairing. Without them AirPlay pairs transiently and Companion Link stays off, so the device stays degraded |
activeUserAccount | Apple TV only. An iCloud alternate DSID that Companion Link announces as the active user at startup |
log(entry) | Receives the log entries of this device at logLevels |
logLevels | Default ['error', 'warn']. Any of debug, error, info, net, raw, warn |
timing | The NTP TimingServer announced in every SETUP. Omitted: one server shared by all devices, started at the first connect and closed when the last device disconnects. false: no timing |
resolve(last, signal) | Looks the device up before a retry when the unicast query at the last address found nothing. With this option the device never scans with multicast. The signal aborts after 15 seconds or on disconnect() |
identity | Overrides of the name, model, OS and version this client presents to the device. The name, CoreWire when omitted, is what the Apple TV lists after a PIN pairing |
Properties
| Property | Meaning |
|---|---|
address | The current address; it changes when recovery finds the device elsewhere |
id | The id of the target, or its address |
name | From the TXT record or /info; the id until known |
model, modelName | The DeviceModel and the raw identifier, such as AudioAccessory5,1; empty until known |
status | The current Status, see Connection and recovery |
sessions | The protocol sessions in use now: airplay, mediaRemote, companionLink. Each is undefined while its protocol is down |
sessions is for diagnostics and experiments. It returns the objects from the protocol packages. Calls on them bypass the device layer, and every reconnect replaces them.
Methods
| Method | Meaning |
|---|---|
connect() | Keeps the device connected until disconnect(). Resolves the first time it is connected or degraded |
disconnect() | Stops every retry and closes every session. Emits disconnected at once and resolves once the sessions closed. Idempotent |
supports(capability) | Whether a capability works right now |
AppleTV.pair(target, options?) | Starts a PIN pairing. Static |
Events
A device emits one event, status, with the new Status. The capabilities with state are an EventEmitter of their own: nowPlaying, volume, power, text and multiroom. A status listener that throws does not stop the other listeners. Its error goes to the log.