diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/CameraControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/CameraControl.kt index 9b1bd598c..6e72d95d0 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/CameraControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/CameraControl.kt @@ -15,7 +15,6 @@ import io.homeassistant.companion.android.R import io.homeassistant.companion.android.common.R as commonR import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse import io.homeassistant.companion.android.common.util.STATE_UNAVAILABLE import java.net.URL import java.util.concurrent.TimeUnit @@ -32,11 +31,10 @@ object CameraControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { - val image = if (baseUrl != null && (entity.attributes["entity_picture"] as? String)?.isNotBlank() == true) { - getThumbnail(baseUrl + entity.attributes["entity_picture"] as String) + val image = if (info.baseUrl != null && (entity.attributes["entity_picture"] as? String)?.isNotBlank() == true) { + getThumbnail(info.baseUrl + entity.attributes["entity_picture"] as String) } else { null } diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/ClimateControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/ClimateControl.kt index 888da90b9..7badd42f3 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/ClimateControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/ClimateControl.kt @@ -4,19 +4,22 @@ import android.content.Context import android.os.Build import android.service.controls.Control import android.service.controls.DeviceTypes +import android.service.controls.actions.BooleanAction import android.service.controls.actions.ControlAction import android.service.controls.actions.FloatAction import android.service.controls.actions.ModeAction import android.service.controls.templates.RangeTemplate import android.service.controls.templates.TemperatureControlTemplate +import android.service.controls.templates.ToggleRangeTemplate import androidx.annotation.RequiresApi import io.homeassistant.companion.android.common.R as commonR import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse @RequiresApi(Build.VERSION_CODES.R) object ClimateControl : HaControl { + private data class ClimateState(val currentMode: String, val supportedModes: ArrayList) + private const val SUPPORT_TARGET_TEMPERATURE = 1 private const val SUPPORT_TARGET_TEMPERATURE_RANGE = 2 private val temperatureControlModes = mapOf( @@ -31,13 +34,13 @@ object ClimateControl : HaControl { "heat_cool" to TemperatureControlTemplate.FLAG_MODE_HEAT_COOL, "off" to TemperatureControlTemplate.FLAG_MODE_OFF ) + private val climateStates = HashMap() override fun provideControlFeatures( context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { val minValue = (entity.attributes["min_temp"] as? Number)?.toFloat() ?: 0f val maxValue = (entity.attributes["max_temp"] as? Number)?.toFloat() ?: 100f @@ -60,7 +63,7 @@ object ClimateControl : HaControl { } val temperatureFormatSize = if (temperatureStepSize < 1f) "1" else "0" val rangeTemplate = RangeTemplate( - entity.entityId, + info.systemId, minValue, maxValue, currentValue, @@ -68,14 +71,24 @@ object ClimateControl : HaControl { "%.${temperatureFormatSize}f $temperatureUnit" ) if (entityShouldBePresentedAsThermostat(entity)) { + val state = ClimateState(entity.state, ArrayList()) + val toggleRangeTemplate = ToggleRangeTemplate( + info.systemId + "_range", + // Set checked to true to always show the temperature indicator, regardless of climate mode + true, + context.getString(commonR.string.widget_tap_action_toggle), + rangeTemplate + ) var modesFlag = 0 (entity.attributes["hvac_modes"] as? List)?.forEach { modesFlag = modesFlag or temperatureControlModeFlags[it]!! + state.supportedModes.add(it) } + this.climateStates[info.systemId] = state control.setControlTemplate( TemperatureControlTemplate( - entity.entityId, - rangeTemplate, + info.systemId, + toggleRangeTemplate, temperatureControlModes[entity.state]!!, temperatureControlModes[entity.state]!!, modesFlag @@ -102,13 +115,18 @@ object ClimateControl : HaControl { integrationRepository: IntegrationRepository, action: ControlAction ): Boolean { + val entityStr: String = if (action.templateId.split(".").size > 2) { + action.templateId.split(".", limit = 2)[1] + } else { + action.templateId + } return when (action) { is FloatAction -> { integrationRepository.callService( - action.templateId.split(".")[0], + entityStr.split(".")[0], "set_temperature", hashMapOf( - "entity_id" to action.templateId, + "entity_id" to entityStr, "temperature" to (action as? FloatAction)?.newValue.toString() ) ) @@ -119,7 +137,7 @@ object ClimateControl : HaControl { action.templateId.split(".")[0], "set_hvac_mode", hashMapOf( - "entity_id" to action.templateId, + "entity_id" to entityStr, "hvac_mode" to ( temperatureControlModes.entries.find { it.value == ((action as? ModeAction)?.newMode ?: -1) @@ -129,6 +147,23 @@ object ClimateControl : HaControl { ) true } + is BooleanAction -> { + if (this.climateStates[action.templateId] == null) { + return false + } + val supportedModes = this.climateStates[action.templateId]!!.supportedModes + val currentMode = this.climateStates[action.templateId]!!.currentMode + val nextMode = (supportedModes.indexOf(currentMode) + 1) % supportedModes.count() + integrationRepository.callService( + entityStr.split(".")[0], + "set_hvac_mode", + hashMapOf( + "entity_id" to entityStr, + "hvac_mode" to supportedModes[nextMode] + ) + ) + true + } else -> { false } diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/CoverControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/CoverControl.kt index 5f9fda56b..e15906033 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/CoverControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/CoverControl.kt @@ -17,7 +17,6 @@ import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository import io.homeassistant.companion.android.common.data.integration.getCoverPosition import io.homeassistant.companion.android.common.data.integration.isActive -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse @RequiresApi(Build.VERSION_CODES.R) object CoverControl : HaControl { @@ -26,8 +25,7 @@ object CoverControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { val position = entity.getCoverPosition() control.setControlTemplate( diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/DefaultButtonControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/DefaultButtonControl.kt index 9c32c34ef..d81a16bf2 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/DefaultButtonControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/DefaultButtonControl.kt @@ -11,7 +11,6 @@ import io.homeassistant.companion.android.common.R as commonR import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository import io.homeassistant.companion.android.common.data.integration.domain -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse import io.homeassistant.companion.android.common.util.capitalize import java.util.Locale @@ -21,8 +20,7 @@ object DefaultButtonControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { control.setStatusText("") control.setControlTemplate( diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/DefaultSliderControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/DefaultSliderControl.kt index 6bf65b960..bf8e04df0 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/DefaultSliderControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/DefaultSliderControl.kt @@ -11,7 +11,6 @@ import androidx.annotation.RequiresApi import io.homeassistant.companion.android.common.R as commonR import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse import kotlinx.coroutines.runBlocking @RequiresApi(Build.VERSION_CODES.R) @@ -20,8 +19,7 @@ object DefaultSliderControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { control.setStatusText("") control.setControlTemplate( diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/DefaultSwitchControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/DefaultSwitchControl.kt index 53925aa38..381c1b60e 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/DefaultSwitchControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/DefaultSwitchControl.kt @@ -14,7 +14,6 @@ import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository import io.homeassistant.companion.android.common.data.integration.domain import io.homeassistant.companion.android.common.data.integration.isActive -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse import io.homeassistant.companion.android.common.util.capitalize import java.util.Locale @@ -24,8 +23,7 @@ object DefaultSwitchControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { control.setControlTemplate( ToggleTemplate( diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/FanControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/FanControl.kt index 385f855c2..81ea93d70 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/FanControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/FanControl.kt @@ -18,7 +18,6 @@ import io.homeassistant.companion.android.common.data.integration.IntegrationRep import io.homeassistant.companion.android.common.data.integration.getFanSpeed import io.homeassistant.companion.android.common.data.integration.isActive import io.homeassistant.companion.android.common.data.integration.supportsFanSetSpeed -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse @RequiresApi(Build.VERSION_CODES.R) object FanControl : HaControl { @@ -26,8 +25,7 @@ object FanControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { if (entity.supportsFanSetSpeed()) { val position = entity.getFanSpeed() diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/HaControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/HaControl.kt index eee7394a9..41e53730f 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/HaControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/HaControl.kt @@ -17,7 +17,6 @@ import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository import io.homeassistant.companion.android.common.data.integration.domain import io.homeassistant.companion.android.common.data.integration.friendlyState -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse import io.homeassistant.companion.android.webview.WebViewActivity @RequiresApi(Build.VERSION_CODES.R) @@ -77,15 +76,14 @@ interface HaControl { } } - return provideControlFeatures(context, control, entity, info.area, info.baseUrl).build() + return provideControlFeatures(context, control, entity, info).build() } fun provideControlFeatures( context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder fun getDeviceType(entity: Entity>): Int diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/HaFailedControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/HaFailedControl.kt index 33b79b814..e833f0264 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/HaFailedControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/HaFailedControl.kt @@ -10,7 +10,6 @@ import androidx.annotation.RequiresApi import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository import io.homeassistant.companion.android.common.data.integration.domain -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse import io.homeassistant.companion.android.common.util.capitalize import java.util.Locale @@ -20,8 +19,7 @@ object HaFailedControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { control.setStatus(if (entity.state == "notfound") Control.STATUS_NOT_FOUND else Control.STATUS_ERROR) control.setStatusText("") diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/LightControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/LightControl.kt index 112fec1a9..7162fd45a 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/LightControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/LightControl.kt @@ -18,7 +18,6 @@ import io.homeassistant.companion.android.common.data.integration.IntegrationRep import io.homeassistant.companion.android.common.data.integration.getLightBrightness import io.homeassistant.companion.android.common.data.integration.isActive import io.homeassistant.companion.android.common.data.integration.supportsLightBrightness -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse @RequiresApi(Build.VERSION_CODES.R) object LightControl : HaControl { @@ -26,8 +25,7 @@ object LightControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { val position = entity.getLightBrightness() control.setControlTemplate( diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/LockControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/LockControl.kt index ceaf6c9f6..b1319eeed 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/LockControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/LockControl.kt @@ -13,7 +13,6 @@ import io.homeassistant.companion.android.common.R as commonR import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository import io.homeassistant.companion.android.common.data.integration.isActive -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse @RequiresApi(Build.VERSION_CODES.R) object LockControl : HaControl { @@ -21,8 +20,7 @@ object LockControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { control.setControlTemplate( ToggleTemplate( diff --git a/app/src/main/java/io/homeassistant/companion/android/controls/VacuumControl.kt b/app/src/main/java/io/homeassistant/companion/android/controls/VacuumControl.kt index e881b22b6..bf29c9a45 100644 --- a/app/src/main/java/io/homeassistant/companion/android/controls/VacuumControl.kt +++ b/app/src/main/java/io/homeassistant/companion/android/controls/VacuumControl.kt @@ -13,7 +13,6 @@ import io.homeassistant.companion.android.common.R as commonR import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationRepository import io.homeassistant.companion.android.common.data.integration.isActive -import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse @RequiresApi(Build.VERSION_CODES.R) object VacuumControl : HaControl { @@ -24,8 +23,7 @@ object VacuumControl : HaControl { context: Context, control: Control.StatefulBuilder, entity: Entity>, - area: AreaRegistryResponse?, - baseUrl: String? + info: HaControlInfo ): Control.StatefulBuilder { entitySupportedFeatures = entity.attributes["supported_features"] as Int control.setControlTemplate(