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 7345a5e3668..f72aaef828f 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,13 +15,11 @@ import io.homeassistant.companion.android.R 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.capitalize import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import kotlinx.coroutines.withTimeoutOrNull import java.net.URL -import java.util.Locale import java.util.concurrent.TimeUnit import io.homeassistant.companion.android.common.R as commonR @@ -36,15 +34,6 @@ object CameraControl : HaControl { area: AreaRegistryResponse?, baseUrl: String? ): Control.StatefulBuilder { - control.setStatusText( - when (entity.state) { - "idle" -> context.getString(commonR.string.state_idle) - "recording" -> context.getString(commonR.string.state_recording) - "streaming" -> context.getString(commonR.string.state_streaming) - else -> entity.state.capitalize(Locale.getDefault()) - } - ) - val image = if (baseUrl != null && (entity.attributes["entity_picture"] as? String)?.isNotBlank() == true) { getThumbnail(baseUrl + entity.attributes["entity_picture"] as String) } else { 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 564d99e528d..a62e4f40b37 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 @@ -39,19 +39,6 @@ object ClimateControl : HaControl { area: AreaRegistryResponse?, baseUrl: String? ): Control.StatefulBuilder { - control.setStatusText( - when (entity.state) { - "auto" -> context.getString(commonR.string.state_auto) - "cool" -> context.getString(commonR.string.state_cool) - "dry" -> context.getString(commonR.string.state_dry) - "fan_only" -> context.getString(commonR.string.state_fan_only) - "heat" -> context.getString(commonR.string.state_heat) - "heat_cool" -> context.getString(commonR.string.state_heat_cool) - "off" -> context.getString(commonR.string.state_off) - "unavailable" -> context.getString(commonR.string.state_unavailable) - else -> entity.state - } - ) val minValue = (entity.attributes["min_temp"] as? Number)?.toFloat() ?: 0f val maxValue = (entity.attributes["max_temp"] as? Number)?.toFloat() ?: 100f var currentValue = (entity.attributes["temperature"] as? Number)?.toFloat() ?: ( 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 e405151834a..52ea1289bb2 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 @@ -15,6 +15,7 @@ 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.getCoverPosition +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.R as commonR @@ -28,22 +29,12 @@ object CoverControl : HaControl { area: AreaRegistryResponse?, baseUrl: String? ): Control.StatefulBuilder { - control.setStatusText( - when (entity.state) { - "closed" -> context.getString(commonR.string.state_closed) - "closing" -> context.getString(commonR.string.state_closing) - "open" -> context.getString(commonR.string.state_open) - "opening" -> context.getString(commonR.string.state_opening) - "unavailable" -> context.getString(commonR.string.state_unavailable) - else -> entity.state - } - ) val position = entity.getCoverPosition() control.setControlTemplate( if ((entity.attributes["supported_features"] as Int) and SUPPORT_SET_POSITION == SUPPORT_SET_POSITION) { ToggleRangeTemplate( entity.entityId, - entity.state in listOf("open", "opening"), + entity.isActive(), "", RangeTemplate( entity.entityId, @@ -58,7 +49,7 @@ object CoverControl : HaControl { ToggleTemplate( entity.entityId, ControlButton( - entity.state in listOf("open", "opening"), + entity.isActive(), "Description" ) ) 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 f1953ce6158..a4873828c5d 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 @@ -12,6 +12,7 @@ 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.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 @@ -30,7 +31,7 @@ object DefaultSwitchControl : HaControl { ToggleTemplate( entity.entityId, ControlButton( - entity.state == "on", + entity.isActive(), "Description" ) ) 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 89c673541d5..a7821a972eb 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 @@ -15,6 +15,7 @@ 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.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 import io.homeassistant.companion.android.common.R as commonR @@ -33,7 +34,7 @@ object FanControl : HaControl { control.setControlTemplate( ToggleRangeTemplate( entity.entityId, - entity.state == "on", + entity.isActive(), "", RangeTemplate( entity.entityId, @@ -50,7 +51,7 @@ object FanControl : HaControl { ToggleTemplate( entity.entityId, ControlButton( - entity.state == "on", + entity.isActive(), "" ) ) 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 3dc188656ba..eee7394a999 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 @@ -16,6 +16,7 @@ import io.homeassistant.companion.android.common.R 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 @@ -46,14 +47,7 @@ interface HaControl { (info.area?.name ?: getDomainString(context, entity)) ) control.setStatus(Control.STATUS_OK) - control.setStatusText( - when (entity.state) { - "off" -> context.getString(R.string.state_off) - "on" -> context.getString(R.string.state_on) - "unavailable" -> context.getString(R.string.state_unavailable) - else -> context.getString(R.string.state_unknown) - } - ) + control.setStatusText(entity.friendlyState(context)) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { control.setAuthRequired(info.authRequired) } 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 7e1777804e1..9202a5416e6 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 @@ -15,6 +15,7 @@ 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.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 import io.homeassistant.companion.android.common.R as commonR @@ -33,7 +34,7 @@ object LightControl : HaControl { if (entity.supportsLightBrightness()) { ToggleRangeTemplate( entity.entityId, - entity.state == "on", + entity.isActive(), "", RangeTemplate( entity.entityId, @@ -48,7 +49,7 @@ object LightControl : HaControl { ToggleTemplate( entity.entityId, ControlButton( - entity.state == "on", + entity.isActive(), "Description" ) ) 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 d295cede69a..c33058ad124 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 @@ -11,6 +11,7 @@ import android.service.controls.templates.ToggleTemplate 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.isActive import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse import io.homeassistant.companion.android.common.R as commonR @@ -23,22 +24,11 @@ object LockControl : HaControl { area: AreaRegistryResponse?, baseUrl: String? ): Control.StatefulBuilder { - control.setStatusText( - when (entity.state) { - "jammed" -> context.getString(commonR.string.state_jammed) - "locked" -> context.getString(commonR.string.state_locked) - "locking" -> context.getString(commonR.string.state_locking) - "unlocked" -> context.getString(commonR.string.state_unlocked) - "unlocking" -> context.getString(commonR.string.state_unlocking) - "unavailable" -> context.getString(commonR.string.state_unavailable) - else -> context.getString(commonR.string.state_unknown) - } - ) control.setControlTemplate( ToggleTemplate( entity.entityId, ControlButton( - entity.state == "locked", + entity.isActive(), "Description" ) ) 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 6dcc583880a..582bb2a5373 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 @@ -11,6 +11,7 @@ import android.service.controls.templates.ToggleTemplate 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.isActive import io.homeassistant.companion.android.common.data.websocket.impl.entities.AreaRegistryResponse import io.homeassistant.companion.android.common.R as commonR @@ -27,29 +28,11 @@ object VacuumControl : HaControl { baseUrl: String? ): Control.StatefulBuilder { entitySupportedFeatures = entity.attributes["supported_features"] as Int - if (entitySupportedFeatures and SUPPORT_TURN_ON != SUPPORT_TURN_ON) { - control.setStatusText( - when (entity.state) { - "cleaning" -> context.getString(commonR.string.state_cleaning) - "docked" -> context.getString(commonR.string.state_docked) - "error" -> context.getString(commonR.string.state_error) - "idle" -> context.getString(commonR.string.state_idle) - "paused" -> context.getString(commonR.string.state_paused) - "returning" -> context.getString(commonR.string.state_returning) - "unavailable" -> context.getString(commonR.string.state_unavailable) - else -> context.getString(commonR.string.state_unknown) - } - ) - } control.setControlTemplate( ToggleTemplate( entity.entityId, ControlButton( - if (entitySupportedFeatures and SUPPORT_TURN_ON == SUPPORT_TURN_ON) { - entity.state == "on" - } else { - entity.state == "cleaning" - }, + entity.isActive(), "Description" ) ) diff --git a/app/src/main/java/io/homeassistant/companion/android/qs/TileExtensions.kt b/app/src/main/java/io/homeassistant/companion/android/qs/TileExtensions.kt index b04377a04fe..658585e1c77 100755 --- a/app/src/main/java/io/homeassistant/companion/android/qs/TileExtensions.kt +++ b/app/src/main/java/io/homeassistant/companion/android/qs/TileExtensions.kt @@ -24,6 +24,7 @@ import dagger.hilt.components.SingletonComponent import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.EntityExt import io.homeassistant.companion.android.common.data.integration.getIcon +import io.homeassistant.companion.android.common.data.integration.isActive import io.homeassistant.companion.android.common.data.integration.onEntityPressedWithoutState import io.homeassistant.companion.android.common.data.servers.ServerManager import io.homeassistant.companion.android.database.qs.TileDao @@ -111,7 +112,7 @@ abstract class TileExtensions : TileService() { ) { serverManager.integrationRepository(tileData.serverId).getEntityUpdates(listOf(tileData.entityId))?.collect { tile.state = - if (it.state in validActiveStates) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE + if (it.isActive()) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE getTileIcon(tileData.iconName, it, applicationContext)?.let { icon -> tile.icon = Icon.createWithBitmap(icon) } @@ -161,8 +162,8 @@ abstract class TileExtensions : TileService() { } if (tileData.entityId.split('.')[0] in toggleDomainsWithLock) { tile.state = when { - state?.state in validActiveStates -> Tile.STATE_ACTIVE - state?.state != null && state.state !in validActiveStates -> Tile.STATE_INACTIVE + state?.isActive() == true -> Tile.STATE_ACTIVE + state?.state != null && !state.isActive() -> Tile.STATE_INACTIVE else -> Tile.STATE_UNAVAILABLE } } else { @@ -332,7 +333,6 @@ abstract class TileExtensions : TileService() { companion object { private const val TAG = "TileExtensions" private val toggleDomainsWithLock = EntityExt.DOMAINS_TOGGLE - private val validActiveStates = listOf("on", "open", "locked") } private fun handleInject() { diff --git a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/Entity.kt b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/Entity.kt index 6a40382fad9..1b0f4507dbd 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/Entity.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/Entity.kt @@ -213,7 +213,7 @@ fun Entity.getFanSteps(): Int? { ((attributes as Map<*, *>)["percentage_step"] as? Double)?.toDouble() ?: 1.0 ) - 1 } catch (e: Exception) { - Log.e(EntityExt.TAG, "Unable to get getFanSteps") + Log.e(EntityExt.TAG, "Unable to get getFanSteps", e) null } } @@ -227,7 +227,7 @@ fun Entity.supportsLightBrightness(): Boolean { val supportedColorModes = (attributes as Map<*, *>)["supported_color_modes"] as? List val supportsBrightness = - if (supportedColorModes == null) false else (supportedColorModes - EntityExt.LIGHT_MODE_NO_BRIGHTNESS_SUPPORT).isNotEmpty() + if (supportedColorModes == null) false else (supportedColorModes - EntityExt.LIGHT_MODE_NO_BRIGHTNESS_SUPPORT.toSet()).isNotEmpty() val supportedFeatures = attributes["supported_features"] as Int supportsBrightness || (supportedFeatures and EntityExt.LIGHT_SUPPORT_BRIGHTNESS_DEPR == EntityExt.LIGHT_SUPPORT_BRIGHTNESS_DEPR) } catch (e: Exception) { @@ -298,7 +298,7 @@ fun Entity.getLightColor(): Int? { } } -fun Entity.getIcon(context: Context): IIcon? { +fun Entity.getIcon(context: Context): IIcon { val attributes = this.attributes as Map val icon = attributes["icon"] as? String return if (icon?.startsWith("mdi") == true) { @@ -383,6 +383,7 @@ fun Entity.getIcon(context: Context): IIcon? { "input_number" -> CommunityMaterial.Icon3.cmd_ray_vertex "input_select" -> CommunityMaterial.Icon2.cmd_format_list_bulleted "input_text" -> CommunityMaterial.Icon2.cmd_form_textbox + "lawn_mower" -> CommunityMaterial.Icon3.cmd_robot_mower "light" -> CommunityMaterial.Icon2.cmd_lightbulb "lock" -> when (compareState) { "unlocked" -> CommunityMaterial.Icon2.cmd_lock_open @@ -699,30 +700,69 @@ val Entity.friendlyName: String get() = (attributes as? Map<*, *>)?.get("friendly_name")?.toString() ?: entityId fun Entity.friendlyState(context: Context, options: EntityRegistryOptions? = null, appendUnitOfMeasurement: Boolean = false): String { + // https://github.com/mikey0000/frontend/blob/c14d801380f04ac63c4cf9ac2479e3b39ef4db32/src/common/entity/get_states.ts#L5 var friendlyState = when (state) { + "above_horizon" -> context.getString(commonR.string.state_above_horizon) + "active" -> context.getString(commonR.string.state_active) "armed_away" -> context.getString(commonR.string.state_armed_away) "armed_custom_bypass" -> context.getString(commonR.string.state_armed_custom_bypass) "armed_home" -> context.getString(commonR.string.state_armed_home) "armed_night" -> context.getString(commonR.string.state_armed_night) "armed_vacation" -> context.getString(commonR.string.state_armed_vacation) "arming" -> context.getString(commonR.string.state_arming) + "auto" -> context.getString(commonR.string.state_auto) + "below_horizon" -> context.getString(commonR.string.state_below_horizon) + "buffering" -> context.getString(commonR.string.state_buffering) + "cleaning" -> context.getString(commonR.string.state_cleaning) + "clear-night" -> context.getString(commonR.string.state_clear_night) + "cloudy" -> context.getString(commonR.string.state_cloudy) "closed" -> context.getString(commonR.string.state_closed) "closing" -> context.getString(commonR.string.state_closing) + "cool" -> context.getString(commonR.string.state_cool) "disarmed" -> context.getString(commonR.string.state_disarmed) "disarming" -> context.getString(commonR.string.state_disarming) + "docked" -> context.getString(commonR.string.state_docked) + "dry" -> context.getString(commonR.string.state_dry) + "error" -> context.getString(commonR.string.state_error) + "exceptional" -> context.getString(commonR.string.state_exceptional) + "fan_only" -> context.getString(commonR.string.state_fan_only) + "fog" -> context.getString(commonR.string.state_fog) + "hail" -> context.getString(commonR.string.state_hail) + "heat" -> context.getString(commonR.string.state_heat) + "heat_cool" -> context.getString(commonR.string.state_heat_cool) + "home" -> context.getString(commonR.string.state_home) + "idle" -> context.getString(commonR.string.state_idle) "jammed" -> context.getString(commonR.string.state_jammed) + "lightning-raining" -> context.getString(commonR.string.state_lightning_raining) + "lightning" -> context.getString(commonR.string.state_lightning) "locked" -> context.getString(commonR.string.state_locked) "locking" -> context.getString(commonR.string.state_locking) + "mowing" -> context.getString(commonR.string.state_mowing) + "not_home" -> context.getString(commonR.string.state_not_home) "off" -> context.getString(commonR.string.state_off) "on" -> context.getString(commonR.string.state_on) "open" -> context.getString(commonR.string.state_open) "opening" -> context.getString(commonR.string.state_opening) + "partlycloudy" -> context.getString(commonR.string.state_partlycloudy) + "paused" -> context.getString(commonR.string.state_paused) "pending" -> context.getString(commonR.string.state_pending) + "playing" -> context.getString(commonR.string.state_playing) + "problem" -> context.getString(commonR.string.state_problem) + "pouring" -> context.getString(commonR.string.state_pouring) + "rainy" -> context.getString(commonR.string.state_rainy) + "recording" -> context.getString(commonR.string.state_recording) + "returning" -> context.getString(commonR.string.state_returning) + "snowy-rainy" -> context.getString(commonR.string.state_snowy_rainy) + "snowy" -> context.getString(commonR.string.state_snowy) + "standby" -> context.getString(commonR.string.state_standby) + "streaming" -> context.getString(commonR.string.state_streaming) + "sunny" -> context.getString(commonR.string.state_sunny) "triggered" -> context.getString(commonR.string.state_triggered) "unavailable" -> context.getString(commonR.string.state_unavailable) "unlocked" -> context.getString(commonR.string.state_unlocked) "unlocking" -> context.getString(commonR.string.state_unlocking) "unknown" -> context.getString(commonR.string.state_unknown) + "windy", "windy-variant" -> context.getString(commonR.string.state_windy) else -> state } if (friendlyState == state && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 2e1b7fbec52..9c1a9dc55d7 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -1147,4 +1147,28 @@ Arming Disarming Pending + Mowing + Above horizon + Active + Below horizon + Buffering + Cloudy + Exceptional + Clear, night + Fog + Hail + Home + Lightning, raining + Lightning + Not home + Partly cloudy + Playing + Problem + Pouring + Rainy + Snowy, rainy + Snowy + Standby + Sunny + Windy diff --git a/wear/src/main/java/io/homeassistant/companion/android/home/views/EntityUi.kt b/wear/src/main/java/io/homeassistant/companion/android/home/views/EntityUi.kt index f965d04fba9..9a76022385e 100644 --- a/wear/src/main/java/io/homeassistant/companion/android/home/views/EntityUi.kt +++ b/wear/src/main/java/io/homeassistant/companion/android/home/views/EntityUi.kt @@ -26,6 +26,7 @@ import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.EntityExt import io.homeassistant.companion.android.common.data.integration.domain import io.homeassistant.companion.android.common.data.integration.getIcon +import io.homeassistant.companion.android.common.data.integration.isActive import io.homeassistant.companion.android.theme.wearColorPalette import io.homeassistant.companion.android.util.WearToggleChip import io.homeassistant.companion.android.util.onEntityClickedFeedback @@ -47,7 +48,7 @@ fun EntityUi( val friendlyName = attributes["friendly_name"].toString() if (entity.domain in EntityExt.DOMAINS_TOGGLE) { - val isChecked = entity.state in listOf("on", "locked", "open", "opening") + val isChecked = entity.isActive() ToggleChip( checked = isChecked, onCheckedChange = {