DeviceManager
Manages one device or service used for data collection.
It configures the device, connects to it, and starts and stops sampling on it. Examples include a hardware device like a smartwatch or fitness band, an onboard service on the smartphone like a location service, or an online service, like a weather service. Each SamplingPackage provides one, and the DeviceController keeps them by device type.
Key points:
- Lifecycle: configure, then connect; disconnect stops sampling first. Subclasses implement the
on...callbacks (onConfigure, onConnect, onDisconnect, onRequestPermissions). - status drives sampling: DeviceStatus.connected resumes all executors, DeviceStatus.disconnecting pauses them (to be resumed), and DeviceStatus.reconnected resumes them again after 15 seconds.
- connect checks hasPermissions first and fails if they are missing.
See ServiceManager, HardwareDeviceManager, BLEDeviceManager and SmartphoneDeviceManager for the main subtypes.
- Implemented types
- Implementers
Constructors
DeviceManager
- String deviceType, {
- TDeviceConfiguration? configuration,
Create a new DeviceManager specifying its deviceType.
Its configuration can be specified on creation here, or specified later in the configure method.
Properties
configuration
The configuration for this device.
deviceType
The type of the device managed by this device manager, e.g. dk.cachet.carp.common.application.devices.Smartphone.
displayName
A human-readable name for this device, or null if unknown.
executors
The task control executors whose tasks run on this device.
Filled by the SmartphoneDeploymentExecutor. Resumed and paused by start, restart and stop.
isConfigured
Has this device manager been configured?
isConnected
Is this device manager connected to the real device?
isConnecting
Is this device manager connecting or already connected to a device?
registration
The latest registration for this device.
Is set using the configure method and contains the latest registered runtime information about the real device, e.g., the BLE address of a Bluetooth device.
shouldConnect
Whether to connect to the real device, based on the last registration.
Uses CamsDeviceRegistration.isConnected if the registration is one. Otherwise true, e.g. if there is no prior registration.
status
The runtime status of this device.
statusEvents
The stream of status events for this device.
supportedDataTypes
The set of data types defining which data can be collected on this device.
typeName
The name of the deviceType without the namespace.
Methods
configure
- TDeviceConfiguration configuration, [
- TRegistration? registration
Configures this device manager with its configuration.
Optionally, a registration can be specified to provide runtime information about the real device, e.g., the BLE address of a Bluetooth device. Calls onConfigure and sets status to DeviceStatus.configured. Does nothing if already configured.
connect
Connects to the device and returns its new DeviceStatus.
Does nothing if already connecting or connected, or if not configured. Sets status to DeviceStatus.disconnected if permissions are missing or onConnect throws.
createRegistration
Creates a registration of this device for the deployment.
This method is used when a device is connected and a registration for this device is needed in the deployment and hence in the deployment service. The registration is typically created from the device information of the real device, e.g., the ID, name, and BLE address of the smartphone or a connected Bluetooth device.
disconnect
Disconnects from the device.
All sampling on this device is stopped first. Returns true if successful or if not connected, false if onDisconnect fails.
hasPermissions
Whether this device manager has the permissions it needs to run.
Note that the result is not cached, since permissions can be revoked in the phone's settings at any time, without the app knowing about it.
isDisconnecting
Called when the device is lost for a while.
E.g. due to a temporary loss of Bluetooth connection. Pauses sampling on this device but marks it to be resumed (via restart) when the device is reconnected, and sets status to DeviceStatus.disconnected. Called automatically when status becomes DeviceStatus.disconnecting.
onConfigure
Callback on configure.
When called, the configuration and the registration is available.
Is to be overridden in sub-classes. Note, however, that it must not be doing a lot of work on startup.
onConnect
Callback on connect. Returns the DeviceStatus of the device.
Can be overridden for device-specific connection handling.
onDisconnect
Callback on disconnect.
This method is called after all sampling on this device has been stopped, and the device manager is trying to disconnect from the real device.
Is to be overridden in sub-classes and implement device-specific disconnection.
onHasPermissions
Callback on hasPermissions.
Can be overridden in sub-classes for device-specific permission handling.
onRequestPermissions
Callback on requestPermissions.
Can be overridden for device-specific permission handling.
requestPermissions
Asks the user for the permissions this device manager needs. Calls onRequestPermissions.
restart
Restarts sampling of the measures using this device.
Resumes, after 15 seconds, only the executors in ExecutorState.PausedButShouldBeResumed, i.e. those paused by a temporary disconnection (isDisconnecting) and not by stop. Called automatically when status becomes DeviceStatus.reconnected.
start
Starts sampling of all measures using this device.
Resumes all executors. Called automatically when status becomes DeviceStatus.connected.
stop
- bool shouldBeResumed = false,
Stops sampling the measures using this device.
Pauses all executors. Used, e.g., when the device is disconnected.
If shouldBeResumed is true, the executors are paused but marked to be resumed later when the device is reconnected. This is useful when the device is temporarily disconnected, e.g., due to a temporary loss of Bluetooth connection, and we want to automatically resume sampling when the device is reconnected.
toString
A string representation of this object.
Some classes have a default textual representation, often paired with a static parse function (like int.parse). These classes will provide the textual representation as their string representation.
Other classes have no meaningful textual representation that a program will care about. Such classes will typically override toString to provide useful information when inspecting the object, mainly for debugging or logging.