Swift API
Initialise the EVOControlLayer
import EvomoMotionAI// Init the ClassificationControlLayerlet controlLayer = ClassificationControlLayer.shared
Setup
LicenseID
// Declare licenseID string once (You will receive the license key from Evomo after agreeing to the license conditions.)ClassificationControlLayer.shared.setLicense(licenseID: "licenseID-String")
Source device
// Define sensor devicecontrolLayer.device = Device(deviceID: "", // Device IDdeviceType: .iPhone, // Device typedevicePosition: .Belly, // Position of the smartphonedeviceOrientation: .buttonRight)
iPhone
Device(deviceID: "", // id for iphone device not relevantdeviceType: .iphone,..)
Movesense
deviceID: Ident string (serial number) of the movesense sensor
Device(deviceID: "175030001022",deviceType: .movesense,..)
Artificial/Simulator
Simulate device sensor by loading a workout file. (helpful to debug or test in simulator)
Note: Wait about 5 seconds for the first movement after starting. The artificial source for simulation only works with belly-based classification models.
Default WorkoutFile is JumpingJack. If you want to select another WorkoutFile -> use the detail property of the device.
If you use the simulator the device is automatically changed to the artificial source.
Device(deviceType: .iPhone,devicePosition: .belly, // !!!deviceOrientation: .buttonRight, // !!!...details: WorkoutFile.squats.rawValue)
Subscriptions
There are three main subscription handler:
- movementHandler - executes on a new classified movement
// Subscribe to the classified movementscontrolLayer.movementHandler = { movement in// Do something with the classified movements in time}
- heartRatehandler - executes on a heart rate value change
// Subscribe to the classified movementscontrolLayer.movementHandler = { movement in// Do something with the classified movements in time}
- deviceEventHandler - execute on new device event
// Handle device eventsClassificationControlLayer.shared.deviceEventHandler = { deviceEvent inlet (device, event) = deviceEventswitch event {case let .dataStraming(state):// Will be triggered on data streaming state change (Bool)// dataStraming = true if sensor data received in the last 0.2 secondscase let .connected(connected):// Will be triggered if the device successfully connect or disconnectcase let .energyPercent(energyPercent):// Implemented for movesense devices (Apple devices dont return a energy level)// The energy level will always emit on after connecting to the device.case let .softwareVersion(version):// not implemented now// Will return the software version of the device after connecting}}// typespublic typealias DeviceEvent = (Device, DeviceStateChange)public enum DeviceStateChange: Equatable {case energyPercent(Double)case dataStraming(Bool)case connected(Bool)case softwareVersion(String)}
Start and stop movement classification
// Start movement classificationClassificationControlLayer.shared.start(lookingForMovementType: nil,isConnected: {// Do something if connected successful}, connectingFailed: { error in// Do something if connecting failed})// Stop movement classification_ = ClassificationControlLayer.shared.stop()
Models
Device
public struct Device {public var deviceID: Stringpublic let deviceType: DeviceTypepublic let devicePosition: DevicePositionpublic let deviceOrientation: DeviceOrientationpublic let deviceForward: Bool = truepublic let heartRate: Bool // if true -> record heartRatepublic var classificationModel: String // customize classification modelpublic var isSimulated: Bool = falsepublic var details: String // set WorkoutFile.rawValue to select a file for simulation mode}
DeviceType
enum DeviceType: String {case iPhone = "iPhone"case movesense = "Movesense"case appleWatch = "Apple Watch"}
DevicePosition
enum DevicePosition: String {case unknown = "Unknown"case leftWrist = "Left Wrist"case rightWrist = "Right Wrist"case leftThigh = "Left Thigh"case rightThigh = "Right Thigh"case belly = "Belly"case neck = "Neck"case leftUpperArm = "Left Upper Arm"case rightUpperArm = "Right Upper Arm"case chest = "Chest"case leftFoot = "Left Foot"case rightFoot = "Right Foot"}
DeviceOrientation
enum DeviceOrientation: String {case unknown = "Unknown"case crownLeft = "CrownLeft"case crownRight = "CrownRight"case buttonUp = "ButtonUp"case buttonDown = "ButtonDown"case buttonRight = "ButtonRight"case buttonLeft = "ButtonLeft"}
WorkoutFile
enum WorkoutFile: String {case jumpingJacks = "20JumpingJacks"case squats = "20SquatsMovingArms"case sixerSets = "6erSets"case running = "running"}
Movement
public struct Movement {public let typeID: Int // This represents the Category ID at the Moment.public var typeLabel: Stringpublic let start: Datepublic var end: Datepublic var durationPositive: Double?public var durationNegative: Double?public var gVelAmplitudePositive: Double?public var gVelAmplitudeNegative: Double?public var amplitude: Double?}
DeviceStateChange
public enum DeviceStateChange: Equatable {case energyPercent(Double)case dataStraming(Bool)case connected(Bool)case softwareVersion(String)}
Error types
public enum DeviceStateChange: Equatable {case energyPercent(Double)case dataStraming(Bool)case connected(Bool)case softwareVersion(String)}