summaryrefslogtreecommitdiff
path: root/Example Apps/Example Swift/RemoteControlManager.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Example Apps/Example Swift/RemoteControlManager.swift')
-rw-r--r--Example Apps/Example Swift/RemoteControlManager.swift226
1 files changed, 226 insertions, 0 deletions
diff --git a/Example Apps/Example Swift/RemoteControlManager.swift b/Example Apps/Example Swift/RemoteControlManager.swift
new file mode 100644
index 000000000..fc73434b4
--- /dev/null
+++ b/Example Apps/Example Swift/RemoteControlManager.swift
@@ -0,0 +1,226 @@
+//
+// RemoteControlManager.swift
+// SmartDeviceLink-Example-Swift
+//
+// Created by Beharry, Justin (J.S.) on 7/28/22.
+// Copyright © 2022 smartdevicelink. All rights reserved.
+//
+
+import Foundation
+import SmartDeviceLink
+import SmartDeviceLinkSwift
+
+class RemoteControlManager {
+ private let sdlManager: SDLManager
+ private let homeButtons: [SDLSoftButtonObject]
+ private var remoteControlCapabilities: SDLRemoteControlCapabilities?
+ private var climateModuleId: String?
+ private var hasConsent: Bool?
+ private var climateData: SDLClimateControlData?
+
+ let isEnabled: Bool
+ var climateDataString: String {
+ """
+ AC: \(optionalNumberBoolToString(climateData?.acEnable))
+ AC Max: \(optionalNumberBoolToString(climateData?.acMaxEnable))
+ Auto Mode: \(optionalNumberBoolToString(climateData?.autoModeEnable))
+ Circulate Air: \(optionalNumberBoolToString(climateData?.circulateAirEnable))
+ Climate: \(optionalNumberBoolToString(climateData?.climateEnable))
+ Current Temperature: \(optionalTemperatureToString(climateData?.currentTemperature))
+ Defrost Zone: \(optionalSDLEnumToString(climateData?.defrostZone?.rawValue))
+ Desired Temperature: \(optionalTemperatureToString(climateData?.desiredTemperature))
+ Dual Mode: \(optionalNumberBoolToString(climateData?.dualModeEnable))
+ Fan Speed: \(optionalNumberToString(climateData?.fanSpeed))
+ Heated Mirrors: \(optionalNumberBoolToString(climateData?.heatedMirrorsEnable))
+ Heated Rears Window: \(optionalNumberBoolToString(climateData?.heatedRearWindowEnable))
+ Heated Steering: \(optionalNumberBoolToString(climateData?.heatedSteeringWheelEnable))
+ Heated Windshield: \(optionalNumberBoolToString(climateData?.heatedWindshieldEnable))
+ Ventilation: \(optionalSDLEnumToString(climateData?.ventilationMode?.rawValue))
+ """
+ }
+
+ /// Initialize the RemoteControlManager Object
+ ///
+ /// - Parameters:
+ /// - sdlManager: The SDL Manager.
+ /// - enabled: Permission from the proxy manager to access remote control data
+ /// - homeButton: An array of SDLSoftButtonObjects that remote control manager can reset to.
+ init(sdlManager: SDLManager, enabled: Bool, homeButtons: [SDLSoftButtonObject]) {
+ self.sdlManager = sdlManager
+ self.isEnabled = enabled
+ self.homeButtons = homeButtons
+ }
+
+ func start() {
+ if !self.isEnabled {
+ return SDLLog.w("Missing permissions for Remote Control Manager. Example remote control works only on TCP.")
+ }
+
+ // Retrieve remote control information and store module ids
+ self.sdlManager.systemCapabilityManager.subscribe(capabilityType: .remoteControl) { (capability, subscribed, error) in
+ guard capability?.remoteControlCapability != nil else {
+ return SDLLog.e("SDL errored getting remote control module information: \(String(describing: error))")
+ }
+ self.remoteControlCapabilities = capability?.remoteControlCapability
+
+ let firstClimateModule = self.remoteControlCapabilities?.climateControlCapabilities?.first
+ let moduleId = firstClimateModule?.moduleInfo?.moduleId
+ self.climateModuleId = moduleId
+
+ // Get Consent to control module
+ let getInteriorVehicleDataConsent = SDLGetInteriorVehicleDataConsent(moduleType: .climate, moduleIds: [self.climateModuleId!])
+ self.sdlManager.send(request: getInteriorVehicleDataConsent, responseHandler: { (request, response, error) in
+ guard let response = response as? SDLGetInteriorVehicleDataConsentResponse else {
+ return SDLLog.e("SDL errored getting remote control consent: \(String(describing: error))");
+ }
+ guard let allowed = response.allowed?.first?.boolValue else { return }
+
+ self.hasConsent = allowed
+
+ // initialize climate data and setup subscription
+ if self.hasConsent == true {
+ self.initializeClimateData()
+ self.subscribeClimateControlData()
+ }
+ })
+ }
+ }
+
+ /// Displays Buttons for the user to control the climate
+ func showClimateControl() {
+ // Check that the climate module id has been set and consent has been given
+ guard climateModuleId != nil && hasConsent == true else {
+ return AlertManager.sendAlert(textField1: "The climate module id was not set or consent was not given", sdlManager: self.sdlManager)
+ }
+ self.sdlManager.screenManager.softButtonObjects = climateButtons
+ }
+
+ private func optionalNumberBoolToString(_ number: NSNumber?) -> String {
+ guard let number = number else { return "Unknown" }
+ return number.boolValue ? "On" : "Off"
+ }
+
+ private func optionalNumberToString(_ number: NSNumber?) -> String {
+ guard let number = number else { return "Unknown" }
+ return number.stringValue
+ }
+
+ private func optionalTemperatureToString(_ temperature: SDLTemperature?) -> String {
+ guard let temperature = temperature else { return "Unknown" }
+ return temperature.description
+ }
+
+ private func optionalSDLEnumToString(_ sdlEnum: SDLEnum?) -> String {
+ guard let sdlEnum = sdlEnum else { return "Unknown" }
+ return sdlEnum.rawValue
+ }
+
+ private func initializeClimateData() {
+ // Check that the climate module id has been set and consent has been given
+ guard climateModuleId != nil && hasConsent == true else {
+ return AlertManager.sendAlert(textField1: "The climate module id was not set or consent was not given", sdlManager: self.sdlManager)
+ }
+
+ let getInteriorVehicleData = SDLGetInteriorVehicleData(moduleType: .climate, moduleId: self.climateModuleId!)
+ self.sdlManager.send(request: getInteriorVehicleData) { (req, res, err) in
+ guard let response = res as? SDLGetInteriorVehicleDataResponse else { return }
+ self.climateData = response.moduleData?.climateControlData
+ }
+ }
+
+ private func subscribeClimateControlData() {
+ // Start the subscription to remote control data
+ sdlManager.subscribe(to: .SDLDidReceiveInteriorVehicleData) { (message) in
+ guard let onInteriorVehicleData = message as? SDLOnInteriorVehicleData else { return }
+ self.climateData = onInteriorVehicleData.moduleData.climateControlData
+ }
+
+ // Start the subscription to climate data
+ let getInteriorVehicleData = SDLGetInteriorVehicleData(andSubscribeToModuleType: .climate, moduleId: self.climateModuleId!)
+ sdlManager.send(request: getInteriorVehicleData) { (req, res, err) in
+ guard let response = res as? SDLGetInteriorVehicleDataResponse, response.success.boolValue == true else {
+ return SDLLog.e("SDL errored trying to subscribe to climate data: \(String(describing: err))")
+ }
+ SDLLog.d("Subscribed to climate control data");
+ }
+ }
+
+ private func turnOnAC() {
+ let climateControlData = SDLClimateControlData(dictionary: [
+ "acEnable": true
+ ])
+ let moduleData = SDLModuleData(climateControlData: climateControlData)
+ let setInteriorVehicleData = SDLSetInteriorVehicleData(moduleData: moduleData)
+
+ self.sdlManager.send(request: setInteriorVehicleData) { (request, response, error) in
+ guard response?.success.boolValue == true else {
+ return SDLLog.e("SDL errored trying to turn on climate AC: \(String(describing: error))")
+ }
+ }
+ }
+
+ private func turnOffAC() {
+ let climateControlData = SDLClimateControlData(dictionary: [
+ "acEnable": false
+ ])
+ let moduleData = SDLModuleData(climateControlData: climateControlData)
+ let setInteriorVehicleData = SDLSetInteriorVehicleData(moduleData: moduleData)
+
+ self.sdlManager.send(request: setInteriorVehicleData) { (request, response, error) in
+ guard response?.success.boolValue == true else {
+ return SDLLog.e("SDL errored trying to turn off climate AC: \(String(describing: error))")
+ }
+ }
+ }
+
+ // An array of button objects to control the climate
+ private var climateButtons : [SDLSoftButtonObject] {
+ let acOnButton = SDLSoftButtonObject(name: "AC On", text: "AC On", artwork: nil) { (buttonPress, buttonEvent) in
+ guard buttonPress != nil else { return }
+ self.turnOnAC()
+ }
+
+ let acOffButton = SDLSoftButtonObject(name: "AC Off", text: "AC Off", artwork: nil) { (buttonPress, buttonEvent) in
+ guard buttonPress != nil else { return }
+ self.turnOffAC()
+ }
+
+ let acMaxToggle = SDLSoftButtonObject(name: "AC Max", text: "AC Max", artwork: nil) { (buttonPress, buttonEvent) in
+ guard buttonPress != nil else { return }
+ let remoteButtonPress = SDLButtonPress(buttonName: .acMax, moduleType: .climate, moduleId: self.climateModuleId, buttonPressMode: .short)
+ self.sdlManager.send(request: remoteButtonPress) { (request, response, error) in
+ guard response?.success.boolValue == true else {
+ return SDLLog.e("SDL errored toggling AC Max with remote button press: \(String(describing: error))")
+ }
+ }
+ }
+
+ let temperatureDecreaseButton = SDLSoftButtonObject(name: "Temperature Decrease", text: "Temperature -", artwork: nil) { (buttonPress, buttonEvent) in
+ guard buttonPress != nil else { return }
+ let remoteButtonPress = SDLButtonPress(buttonName: .tempDown, moduleType: .climate, moduleId: self.climateModuleId, buttonPressMode: .short)
+ self.sdlManager.send(request: remoteButtonPress) { (request, response, error) in
+ guard response?.success.boolValue == true else {
+ return SDLLog.e("SDL errored decreasing target climate temperature with remote button: \(String(describing: error))")
+ }
+ }
+ }
+
+ let temperatureIncreaseButton = SDLSoftButtonObject(name: "Temperature Increase", text: "Temperature +", artwork: nil) { (buttonPress, buttonEvent) in
+ guard buttonPress != nil else { return }
+ let remoteButtonPress = SDLButtonPress(buttonName: .tempUp, moduleType: .climate, moduleId: self.climateModuleId, buttonPressMode: .short)
+ self.sdlManager.send(request: remoteButtonPress) { (request, response, error) in
+ guard response?.success.boolValue == true else {
+ return SDLLog.e("SDL errored increasing target climate temperature with remote button:: \(String(describing: error))")
+ }
+ }
+ }
+
+ let backToHomeButton = SDLSoftButtonObject(name: "Home", text: "Back to Home", artwork: nil) { (buttonPress, buttonEvent) in
+ guard buttonPress != nil else { return }
+ self.sdlManager.screenManager.softButtonObjects = self.homeButtons
+ self.sdlManager.screenManager.changeLayout(SDLTemplateConfiguration(predefinedLayout: .nonMedia))
+ }
+
+ return [acOnButton, acOffButton, acMaxToggle, temperatureDecreaseButton, temperatureIncreaseButton, backToHomeButton]
+ }
+}