Manager¶
System-level services injected onto PluginAPI: CoreManager for FFmpeg path / inter-plugin RPC / cloud signing, DeviceManager for camera lookup and async discovery, DownloadManager for token-protected downloads, and NotificationManager for publishing notifications into the host.
Note
The reference below is auto-generated from Go doc comments via gomarkdoc. Re-run scripts/gen-api-docs.sh to refresh it.
type CoreManager¶
CoreManager provides system-level operations.
Exposes cross-cutting services like the FFmpeg binary path, server addresses, the cloud server id, inter-plugin lookup, and a stream of core system events. Accessed via api.CoreManager from within a plugin.
type CoreManager struct {
// contains filtered or unexported fields
}
func (*CoreManager) AssistantAccess¶
func (cm *CoreManager) AssistantAccess(ctx context.Context) (*AssistantAccess, error)
AssistantAccess reports whether this plugin may use the assistant model and what the assigned entry can do. Subscribe to OnEvent for "assistantModelChanged" to learn about changes while running.
func (*CoreManager) AssistantAsk¶
func (cm *CoreManager) AssistantAsk(ctx context.Context, request *AssistantAskRequest) (*AssistantAskResult, error)
AssistantAsk asks the assistant model for one completion. The admin decides under Settings, Assistant which plugins may use the model and which entry they get; the key never reaches the plugin.
Example:
answer, err := api.CoreManager.AssistantAsk(ctx, &sdk.AssistantAskRequest{
System: "Answer with one word.",
Prompt: "Is there a person in this picture?",
Images: []sdk.AssistantAskImage{{Data: jpeg, MimeType: "image/jpeg"}},
})
if err == nil && answer.OK {
fmt.Println(answer.Text)
}
func (*CoreManager) ConnectToPlugin¶
func (cm *CoreManager) ConnectToPlugin(pluginName string) (*pluginProxy, error)
ConnectToPlugin connects to a plugin by name and returns a proxy for RPC calls. Returns nil if the plugin is not found. Connections are cached. WithOptions on the proxy changes timeout and retry for its calls.
func (*CoreManager) GetCloudServerID¶
func (cm *CoreManager) GetCloudServerID() (string, error)
GetCloudServerID returns the cloud server identity this server is registered as.
Returns the cloud server_id from the active cloud pairing, or an empty string when the server is not connected to the cloud.
func (*CoreManager) GetFFmpegPath¶
func (cm *CoreManager) GetFFmpegPath() (string, error)
GetFFmpegPath returns the path to the FFmpeg binary.
func (*CoreManager) GetInstanceID¶
func (cm *CoreManager) GetInstanceID() (string, error)
GetInstanceID returns the id of this camera.ui installation.
A copy of the server made from a backup gets a new id, while a move or an undone restore keeps it. A plugin that announces itself on the network under a fixed identity compares it with the id it saw before: a different one means it now runs on a copy and must not reuse that identity.
Servers older than 2.4.0 do not know the call and return an error.
func (*CoreManager) GetPluginsByInterface¶
func (cm *CoreManager) GetPluginsByInterface(interfaceName PluginInterface) ([]PluginInfo, error)
GetPluginsByInterface returns all installed, enabled plugins that implement a specific interface. Plugins the admin disabled are excluded. A returned plugin may still be starting up or may have crashed, so a call into one can fail.
func (*CoreManager) GetRestoreGeneration¶
func (cm *CoreManager) GetRestoreGeneration() (string, error)
GetRestoreGeneration returns the id of the last restore on this server.
It changes every time a backup is restored or a restore is undone and is empty before the first one. A plugin that keeps credentials for an outside service compares it with the id it saw when storing them: a different one means they came back with a backup and may be outdated.
func (*CoreManager) GetServerAddresses¶
func (cm *CoreManager) GetServerAddresses() ([]string, error)
GetServerAddresses returns the server addresses (IP addresses the server is listening on). A plugin running on a worker gets the addresses selected for that worker, empty when none are selected.
func (*CoreManager) InvokeInto¶
func (cm *CoreManager) InvokeInto(ctx context.Context, out any, method string, args ...any) error
InvokeInto calls a host method by name and decodes the result into out.
It is the escape hatch for host methods that have no typed wrapper here, which are the ones camera.ui's own plugins use and nothing else. They carry no compatibility promise: names and shapes may change with any server release. Pass nil for out to ignore the result.
func (*CoreManager) OnEvent¶
func (cm *CoreManager) OnEvent() *Observable[CoreManagerEvent]
OnEvent returns an Observable for core manager events (e.g. cloud account changes).
type CoreManagerEvent¶
CoreManagerEvent is the payload emitted by CoreManager.OnEvent.
The host currently publishes one event type, "cloudAccountChanged". Subscribe via OnEvent to react to it.
type CoreManagerEvent struct {
// Type is the event type identifier (e.g. "cloudAccountChanged").
Type string
// Data is the event-specific payload. Shape depends on the event type.
Data any
}
type CreateDownloadOptions¶
CreateDownloadOptions specifies how to register an existing file as a downloadable artifact.
type CreateDownloadOptions struct {
// FilePath is the absolute path to the file on disk, inside the plugin's
// storage folder (API.StoragePath).
FilePath string `msgpack:"filePath" json:"filePath"`
// Filename is the value used in the Content-Disposition header
// (defaults to the basename of FilePath).
Filename string `msgpack:"filename,omitempty" json:"filename,omitempty"`
// MimeType is the value used in the Content-Type header
// (defaults to "application/octet-stream").
MimeType string `msgpack:"mimeType,omitempty" json:"mimeType,omitempty"`
// TTLMs is the time-to-live in milliseconds (defaults to 10 minutes).
TTLMs int64 `msgpack:"ttlMs,omitempty" json:"ttlMs,omitempty"`
// Cleanup controls when the file on disk is deleted (see DownloadCleanup).
Cleanup DownloadCleanup `msgpack:"cleanup,omitempty" json:"cleanup,omitempty"`
}
type CreateStreamDownloadOptions¶
CreateStreamDownloadOptions specifies how to register a file that is still being written and served progressively.
type CreateStreamDownloadOptions struct {
// FilePath is the absolute path to the file being written, inside the
// plugin's storage folder (API.StoragePath).
FilePath string `msgpack:"filePath" json:"filePath"`
// Filename is the value used in the Content-Disposition header
// (defaults to the basename of FilePath).
Filename string `msgpack:"filename,omitempty" json:"filename,omitempty"`
// MimeType is the value used in the Content-Type header
// (defaults to "application/octet-stream").
MimeType string `msgpack:"mimeType,omitempty" json:"mimeType,omitempty"`
// TTLMs is the time-to-live in milliseconds (defaults to 10 minutes).
TTLMs int64 `msgpack:"ttlMs,omitempty" json:"ttlMs,omitempty"`
// Cleanup controls when the file on disk is deleted (see DownloadCleanup).
Cleanup DownloadCleanup `msgpack:"cleanup,omitempty" json:"cleanup,omitempty"`
// MarkerPath is the path to a marker file whose existence signals
// that writing is still in progress; when removed, the download
// server closes the response. It lies inside the plugin's storage folder.
MarkerPath string `msgpack:"markerPath" json:"markerPath"`
}
type DeviceManager¶
DeviceManager provides camera operations: push discovered cameras and get camera devices.
Use GetCamera to retrieve a camera by ID or name, and PushDiscoveredCameras to surface cameras found during async discovery (e.g. after a cloud login).
Accessed via api.DeviceManager from within a plugin.
type DeviceManager struct {
// contains filtered or unexported fields
}
func (*DeviceManager) GetCamera¶
func (dm *DeviceManager) GetCamera(cameraIDOrName string) (*CameraDevice, error)
GetCamera retrieves a camera by ID or name. Returns nil if no matching camera exists.
func (*DeviceManager) PushDiscoveredCameras¶
func (dm *DeviceManager) PushDiscoveredCameras(cameras []DiscoveredCamera) error
PushDiscoveredCameras pushes discovered cameras to the backend so the user can pick them in the UI without waiting for the next discovery poll. Use it when cameras are discovered asynchronously (e.g. after a cloud login or mDNS event). Only available for CameraController and CameraAndSensorProvider plugins.
type DownloadCleanup¶
DownloadCleanup controls when the file on disk is deleted. The registry entry always expires at TTL; this only controls the file itself.
type DownloadCleanup string
const (
// DownloadCleanupNever keeps the file; the caller manages its lifecycle.
DownloadCleanupNever DownloadCleanup = "never"
// DownloadCleanupOnExpiry deletes the file at TTL. It can be fetched N times
// during the window, the right mode for notification images that fan out to
// multiple devices or recipients.
DownloadCleanupOnExpiry DownloadCleanup = "on-expiry"
// DownloadCleanupOnDownload deletes the file after the first successful
// download or at TTL, whichever comes first. One-shot mode for exports.
DownloadCleanupOnDownload DownloadCleanup = "on-download"
)
type DownloadManager¶
DownloadManager provides token-based file downloads.
Plugins register a file and get back a token URL. No JWT is involved, the token itself is the auth.
Accessed via api.DownloadManager from within a plugin.
Example:
tok, err := api.DownloadManager.CreateDownload(sdk.CreateDownloadOptions{
FilePath: filepath.Join(api.StoragePath, "export.mp4"),
Filename: "recording.mp4",
MimeType: "video/mp4",
TTLMs: 600000,
Cleanup: sdk.DownloadCleanupOnDownload,
})
type DownloadManager struct {
// contains filtered or unexported fields
}
func (*DownloadManager) CreateDownload¶
func (dm *DownloadManager) CreateDownload(options CreateDownloadOptions) (DownloadToken, error)
CreateDownload registers a file for HTTP download and returns a token-based URL.
func (*DownloadManager) CreateStreamDownload¶
func (dm *DownloadManager) CreateStreamDownload(options *CreateStreamDownloadOptions) (DownloadToken, error)
CreateStreamDownload registers a streaming file for progressive HTTP download. The file is tailed during writing; the marker file signals completion.
func (*DownloadManager) DeleteDownload¶
func (dm *DownloadManager) DeleteDownload(token string) error
DeleteDownload removes a download token and optionally deletes the underlying file.
type DownloadToken¶
DownloadToken is returned after registering a download.
type DownloadToken struct {
// Token is the unique download token (also embedded in URL/PublicURL).
Token string `msgpack:"token" json:"token"`
// URL is the in-app, same-origin path: "/api/download/<token>". Use it
// for callers already authenticated against this server (UI, plugins
// going through the proxy).
URL string `msgpack:"url" json:"url"`
// PublicURL is the externally-reachable, session-less URL the server
// publishes for out-of-band fetchers (push-notification image
// attachments, FCM / APNs payloads, share recipients). Shape:
// "<externalUrl>/api/download/<token>", where the token is the auth.
// Empty string when the server has no external URL configured (LAN-only
// deployments); fall back to URL for in-app callers.
PublicURL string `msgpack:"publicUrl" json:"publicUrl"`
// ExpiresAt is the unix timestamp (ms) when the token expires.
ExpiresAt int64 `msgpack:"expiresAt" json:"expiresAt"`
}
type NotificationManager¶
NotificationManager publishes notifications into the host.
Plugins call Publish to ask the host to fan a Notification out to every installed Notifier-plugin and the in-app UI. The host applies user settings (master toggle, per-source toggle, quiet hours) and the publishing plugin's declared capabilities; calls from plugins without CapabilityPublishNotifications are silently dropped.
Accessed via api.NotificationManager from within a plugin.
type NotificationManager struct {
// contains filtered or unexported fields
}
func (*NotificationManager) Publish¶
func (nm *NotificationManager) Publish(n *Notification) error
Publish sends a notification to the host for fan-out to every installed Notifier-plugin and the in-app UI. Fire-and-forget: marshalling/transport errors are returned, but downstream delivery is async and failures there never propagate back here.
The plugin's contract MUST declare CapabilityPublishNotifications; otherwise the host drops the notification.
Example:
api.NotificationManager.Publish(&sdk.Notification{
Title: "Camera offline",
Body: "Front Door stopped recording",
Severity: sdk.SeverityWarn,
DeepLink: "/cameras/front-door",
Data: map[string]string{"cameraId": "front-door"},
})
type PluginCallOptions¶
PluginCallOptions changes how calls through a proxy from ConnectToPlugin wait for an answer.
type PluginCallOptions struct {
// Timeout replaces the default timeout of each attempt; zero keeps it.
Timeout time.Duration
// NoRetry fails a call at once when no process serves the method, instead of retrying for about 3.5 s.
NoRetry bool
}
type SensorConsumer¶
SensorConsumer is an OPTIONAL interface plugins implement to consume other plugins' sensors. The host builds the consumable view from the plugin contract: sensors whose type is listed in `consumes` and that the user exposed. Only bridge plugins implement this.
type SensorConsumer interface {
// ConfigureSensors is called once on startup with every sensor this
// plugin may consume. Each sensor carries type, assigned cameras and
// connected state, so consumers decide rendering purely from that data.
ConfigureSensors(sensors []Sensor) error
// OnSensorAdded is called when a sensor enters this plugin's consumable
// view at runtime: it was created, became exposed, or its type became
// consumable.
OnSensorAdded(sensor Sensor) error
// OnSensorReleased is called when a sensor permanently leaves the
// consumable view: it was deleted or unexposed. Plugin connectivity does
// NOT fire this; watch OnConnectedChanged on the sensor for that.
OnSensorReleased(sensorID string) error
}
type SensorHistoryEntry¶
SensorHistoryEntry is one recorded change of one sensor property.
type SensorHistoryEntry struct {
SensorID string `msgpack:"sensorId" json:"sensorId"`
Property string `msgpack:"property" json:"property"`
Value any `msgpack:"value" json:"value"`
Timestamp int64 `msgpack:"timestamp" json:"timestamp"`
}
type SensorManager¶
SensorManager is the host's view of the sensor registry. Standalone sensors are not registered here: a camera's own sensors go through CameraDevice.AddSensor, and sensors the user picks from an external inventory come in through SensorDiscoveryProvider, bound by the host.
Accessed via api.SensorManager in plugins.
type SensorManager struct {
// contains filtered or unexported fields
}
func (*SensorManager) GetSensorHistory¶
func (m *SensorManager) GetSensorHistory(sensorIDs []string, from, to int64) ([]SensorHistoryEntry, error)
GetSensorHistory returns what a set of sensors did during a window of time.
It returns every recorded change between from and to, and for each property also the value it already had when the window opened, because a door that was open the whole time says as much as one that opened halfway through. Entries come back oldest first.
The history is a short tail, not an archive: it is coalesced to one entry per second and capped per sensor, so a window far in the past may be gone.