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 7badd42f3ed..35d1e3d7de2 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 @@ -122,7 +122,7 @@ object ClimateControl : HaControl { } return when (action) { is FloatAction -> { - integrationRepository.callService( + integrationRepository.callAction( entityStr.split(".")[0], "set_temperature", hashMapOf( @@ -133,7 +133,7 @@ object ClimateControl : HaControl { true } is ModeAction -> { - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], "set_hvac_mode", hashMapOf( @@ -154,7 +154,7 @@ object ClimateControl : HaControl { val supportedModes = this.climateStates[action.templateId]!!.supportedModes val currentMode = this.climateStates[action.templateId]!!.currentMode val nextMode = (supportedModes.indexOf(currentMode) + 1) % supportedModes.count() - integrationRepository.callService( + integrationRepository.callAction( entityStr.split(".")[0], "set_hvac_mode", hashMapOf( 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 e15906033fb..0338d2ab27d 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 @@ -78,7 +78,7 @@ object CoverControl : HaControl { ): Boolean { return when (action) { is BooleanAction -> { - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], if ((action as? BooleanAction)?.newState == true) "open_cover" else "close_cover", hashMapOf( @@ -89,7 +89,7 @@ object CoverControl : HaControl { } is FloatAction -> { val convertPosition = action.newValue - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], "set_cover_position", hashMapOf( 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 d81a16bf232..85d86c6c336 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 @@ -50,7 +50,7 @@ object DefaultButtonControl : HaControl { integrationRepository: IntegrationRepository, action: ControlAction ): Boolean { - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], when (action.templateId.split(".")[0]) { "button", "input_button" -> "press" 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 c3d263b5058..2bdc1b62992 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 @@ -44,7 +44,7 @@ object DefaultSliderControl : HaControl { integrationRepository: IntegrationRepository, action: ControlAction ): Boolean { - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], "set_value", hashMapOf( 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 381c1b60e04..37ed4db4245 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 @@ -55,7 +55,7 @@ object DefaultSwitchControl : HaControl { integrationRepository: IntegrationRepository, action: ControlAction ): Boolean { - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], if ((action as? BooleanAction)?.newState == true) "turn_on" else "turn_off", hashMapOf("entity_id" to action.templateId) 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 81ea93d70c0..c41461c528d 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 @@ -70,7 +70,7 @@ object FanControl : HaControl { ): Boolean { when (action) { is BooleanAction -> { - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], if (action.newState) "turn_on" else "turn_off", hashMapOf("entity_id" to action.templateId) @@ -78,7 +78,7 @@ object FanControl : HaControl { } is FloatAction -> { val convertPercentage = action.newValue - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], "set_percentage", hashMapOf( 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 7162fd45a00..b7153453dab 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 @@ -68,7 +68,7 @@ object LightControl : HaControl { ): Boolean { return when (action) { is BooleanAction -> { - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], if (action.newState) "turn_on" else "turn_off", hashMapOf( @@ -79,7 +79,7 @@ object LightControl : HaControl { } is FloatAction -> { val convertBrightness = action.newValue.div(100).times(255) - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], "turn_on", hashMapOf( 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 b1319eeed71..35bb1a83ac4 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 @@ -44,7 +44,7 @@ object LockControl : HaControl { integrationRepository: IntegrationRepository, action: ControlAction ): Boolean { - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], if ((action as? BooleanAction)?.newState == true) "lock" else "unlock", hashMapOf("entity_id" to action.templateId) 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 bf29c9a456f..e524d4e9161 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 @@ -48,7 +48,7 @@ object VacuumControl : HaControl { integrationRepository: IntegrationRepository, action: ControlAction ): Boolean { - integrationRepository.callService( + integrationRepository.callAction( action.templateId.split(".")[0], if (entitySupportedFeatures and SUPPORT_TURN_ON == SUPPORT_TURN_ON) { if ((action as? BooleanAction)?.newState == true) "turn_on" else "turn_off" 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 9e273d90b87..3206dca3368 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 @@ -291,7 +291,7 @@ abstract class TileExtensions : TileService() { withContext(Dispatchers.Main) { Toast.makeText( applicationContext, - commonR.string.service_call_failure, + commonR.string.action_failure, Toast.LENGTH_SHORT ) .show() diff --git a/app/src/main/java/io/homeassistant/companion/android/widgets/button/ButtonWidget.kt b/app/src/main/java/io/homeassistant/companion/android/widgets/button/ButtonWidget.kt index 0a76289d802..64d4b9a76a0 100644 --- a/app/src/main/java/io/homeassistant/companion/android/widgets/button/ButtonWidget.kt +++ b/app/src/main/java/io/homeassistant/companion/android/widgets/button/ButtonWidget.kt @@ -57,8 +57,8 @@ class ButtonWidget : AppWidgetProvider() { internal const val EXTRA_SERVER_ID = "EXTRA_SERVER_ID" internal const val EXTRA_DOMAIN = "EXTRA_DOMAIN" - internal const val EXTRA_SERVICE = "EXTRA_SERVICE" - internal const val EXTRA_SERVICE_DATA = "EXTRA_SERVICE_DATA" + internal const val EXTRA_ACTION = "EXTRA_SERVICE" + internal const val EXTRA_ACTION_DATA = "EXTRA_SERVICE_DATA" internal const val EXTRA_LABEL = "EXTRA_LABEL" internal const val EXTRA_ICON_NAME = "EXTRA_ICON_NAME" internal const val EXTRA_BACKGROUND_TYPE = "EXTRA_BACKGROUND_TYPE" @@ -148,15 +148,15 @@ class ButtonWidget : AppWidgetProvider() { super.onReceive(context, intent) when (action) { - CALL_SERVICE_AUTH -> authThenCallConfiguredService(context, appWidgetId) - CALL_SERVICE -> callConfiguredService(context, appWidgetId) - RECEIVE_DATA -> saveServiceCallConfiguration(context, intent.extras, appWidgetId) + CALL_SERVICE_AUTH -> authThenCallConfiguredAction(context, appWidgetId) + CALL_SERVICE -> callConfiguredAction(context, appWidgetId) + RECEIVE_DATA -> saveActionCallConfiguration(context, intent.extras, appWidgetId) Intent.ACTION_SCREEN_ON -> updateAllWidgets(context) } } - private fun authThenCallConfiguredService(context: Context, appWidgetId: Int) { - Log.d(TAG, "Calling authentication, then configured service") + private fun authThenCallConfiguredAction(context: Context, appWidgetId: Int) { + Log.d(TAG, "Calling authentication, then configured action") val intent = Intent(context, WidgetAuthenticationActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_NEW_DOCUMENT @@ -260,8 +260,8 @@ class ButtonWidget : AppWidgetProvider() { views.setViewVisibility(R.id.widgetLabelLayout, labelVisibility) } - private fun callConfiguredService(context: Context, appWidgetId: Int) { - Log.d(TAG, "Calling widget service") + private fun callConfiguredAction(context: Context, appWidgetId: Int) { + Log.d(TAG, "Calling widget action") // Set up progress bar as immediate feedback to show the click has been received // Success or failure feedback will come from the mainScope coroutine @@ -279,53 +279,53 @@ class ButtonWidget : AppWidgetProvider() { var feedbackColor = R.drawable.widget_button_background_red var feedbackIcon = R.drawable.ic_clear_black - // Load the service call data from Shared Preferences + // Load the action call data from Shared Preferences val domain = widget?.domain - val service = widget?.service - val serviceDataJson = widget?.serviceData + val action = widget?.service + val actionDataJson = widget?.serviceData Log.d( TAG, - "Service Call Data loaded:" + System.lineSeparator() + + "Action Call Data loaded:" + System.lineSeparator() + "domain: " + domain + System.lineSeparator() + - "service: " + service + System.lineSeparator() + - "service_data: " + serviceDataJson + "action: " + action + System.lineSeparator() + + "action_data: " + actionDataJson ) - if (domain == null || service == null || serviceDataJson == null) { - Log.w(TAG, "Service Call Data incomplete. Aborting service call") + if (domain == null || action == null || actionDataJson == null) { + Log.w(TAG, "Action Call Data incomplete. Aborting action call") } else { - // If everything loaded correctly, package the service data and attempt the call + // If everything loaded correctly, package the action data and attempt the call try { // Convert JSON to HashMap - val serviceDataMap: HashMap = - jacksonObjectMapper().readValue(serviceDataJson) + val actionDataMap: HashMap = + jacksonObjectMapper().readValue(actionDataJson) - if (serviceDataMap["entity_id"] != null) { + if (actionDataMap["entity_id"] != null) { val entityIdWithoutBrackets = Pattern.compile("\\[(.*?)\\]") - .matcher(serviceDataMap["entity_id"].toString()) + .matcher(actionDataMap["entity_id"].toString()) if (entityIdWithoutBrackets.find()) { val value = entityIdWithoutBrackets.group(1) if (value != null) { if (value == "all" || value.split(",").contains("all") ) { - serviceDataMap["entity_id"] = "all" + actionDataMap["entity_id"] = "all" } } } } - Log.d(TAG, "Sending service call to Home Assistant") - serverManager.integrationRepository(widget.serverId).callService(domain, service, serviceDataMap) - Log.d(TAG, "Service call sent successfully") + Log.d(TAG, "Sending action call to Home Assistant") + serverManager.integrationRepository(widget.serverId).callAction(domain, action, actionDataMap) + Log.d(TAG, "Action call sent successfully") - // If service call does not throw an exception, send positive feedback + // If action call does not throw an exception, send positive feedback feedbackColor = R.drawable.widget_button_background_green feedbackIcon = R.drawable.ic_check_black_24dp } catch (e: Exception) { - Log.e(TAG, "Could not send service call.", e) - Toast.makeText(context, commonR.string.service_call_failure, Toast.LENGTH_LONG).show() + Log.e(TAG, "Could not send action call.", e) + Toast.makeText(context, commonR.string.action_failure, Toast.LENGTH_LONG).show() } } @@ -353,13 +353,13 @@ class ButtonWidget : AppWidgetProvider() { } } - private fun saveServiceCallConfiguration(context: Context, extras: Bundle?, appWidgetId: Int) { + private fun saveActionCallConfiguration(context: Context, extras: Bundle?, appWidgetId: Int) { if (extras == null) return val serverId = if (extras.containsKey(EXTRA_SERVER_ID)) extras.getInt(EXTRA_SERVER_ID) else null val domain: String? = extras.getString(EXTRA_DOMAIN) - val service: String? = extras.getString(EXTRA_SERVICE) - val serviceData: String? = extras.getString(EXTRA_SERVICE_DATA) + val action: String? = extras.getString(EXTRA_ACTION) + val actionData: String? = extras.getString(EXTRA_ACTION_DATA) val label: String? = extras.getString(EXTRA_LABEL) val requireAuthentication: Boolean = extras.getBoolean(EXTRA_REQUIRE_AUTHENTICATION) val icon: String = extras.getString(EXTRA_ICON_NAME) ?: "mdi:flash" @@ -367,23 +367,23 @@ class ButtonWidget : AppWidgetProvider() { ?: WidgetBackgroundType.DAYNIGHT val textColor: String? = extras.getString(EXTRA_TEXT_COLOR) - if (serverId == null || domain == null || service == null || serviceData == null) { - Log.e(TAG, "Did not receive complete service call data") + if (serverId == null || domain == null || action == null || actionData == null) { + Log.e(TAG, "Did not receive complete action call data") return } mainScope.launch { Log.d( TAG, - "Saving service call config data:" + System.lineSeparator() + + "Saving action call config data:" + System.lineSeparator() + "domain: " + domain + System.lineSeparator() + - "service: " + service + System.lineSeparator() + - "service_data: " + serviceData + System.lineSeparator() + + "action: " + action + System.lineSeparator() + + "action_data: " + actionData + System.lineSeparator() + "require_authentication: " + requireAuthentication + System.lineSeparator() + "label: " + label ) - val widget = ButtonWidgetEntity(appWidgetId, serverId, icon, domain, service, serviceData, label, backgroundType, textColor, requireAuthentication) + val widget = ButtonWidgetEntity(appWidgetId, serverId, icon, domain, action, actionData, label, backgroundType, textColor, requireAuthentication) buttonWidgetDao.add(widget) // It is the responsibility of the configuration activity to update the app widget diff --git a/app/src/main/java/io/homeassistant/companion/android/widgets/button/ButtonWidgetConfigureActivity.kt b/app/src/main/java/io/homeassistant/companion/android/widgets/button/ButtonWidgetConfigureActivity.kt index ed9213453e0..f3a6bff9202 100644 --- a/app/src/main/java/io/homeassistant/companion/android/widgets/button/ButtonWidgetConfigureActivity.kt +++ b/app/src/main/java/io/homeassistant/companion/android/widgets/button/ButtonWidgetConfigureActivity.kt @@ -35,8 +35,8 @@ import com.mikepenz.iconics.typeface.IIcon import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import dagger.hilt.android.AndroidEntryPoint import io.homeassistant.companion.android.common.R as commonR +import io.homeassistant.companion.android.common.data.integration.Action import io.homeassistant.companion.android.common.data.integration.Entity -import io.homeassistant.companion.android.common.data.integration.Service import io.homeassistant.companion.android.database.widget.ButtonWidgetDao import io.homeassistant.companion.android.database.widget.WidgetBackgroundType import io.homeassistant.companion.android.databinding.WidgetButtonConfigureBinding @@ -46,7 +46,7 @@ import io.homeassistant.companion.android.util.icondialog.IconDialogFragment import io.homeassistant.companion.android.util.icondialog.getIconByMdiName import io.homeassistant.companion.android.util.icondialog.mdiName import io.homeassistant.companion.android.widgets.BaseWidgetConfigureActivity -import io.homeassistant.companion.android.widgets.common.ServiceFieldBinder +import io.homeassistant.companion.android.widgets.common.ActionFieldBinder import io.homeassistant.companion.android.widgets.common.SingleItemArrayAdapter import io.homeassistant.companion.android.widgets.common.WidgetDynamicFieldAdapter import javax.inject.Inject @@ -63,9 +63,9 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { lateinit var buttonWidgetDao: ButtonWidgetDao override val dao get() = buttonWidgetDao - private var services = mutableMapOf>() + private var actions = mutableMapOf>() private var entities = mutableMapOf>>() - private var dynamicFields = ArrayList() + private var dynamicFields = ArrayList() private lateinit var dynamicFieldAdapter: WidgetDynamicFieldAdapter private lateinit var binding: WidgetButtonConfigureBinding @@ -78,7 +78,7 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { private var requestLauncherSetup = false - private var serviceAdapter: SingleItemArrayAdapter? = null + private var actionAdapter: SingleItemArrayAdapter? = null private val onAddFieldListener = View.OnClickListener { val context = this@ButtonWidgetConfigureActivity @@ -98,7 +98,7 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { val position = dynamicFields.size dynamicFields.add( position, - ServiceFieldBinder( + ActionFieldBinder( binding.widgetTextConfigService.text.toString(), fieldKeyInput.text.toString() ) @@ -115,14 +115,14 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { } } - private val serviceTextWatcher: TextWatcher = ( + private val actionTextWatcher: TextWatcher = ( object : TextWatcher { @SuppressLint("NotifyDataSetChanged") override fun afterTextChanged(p0: Editable?) { - val serviceText: String = p0.toString() + val actionText: String = p0.toString() - if (services[selectedServerId].orEmpty().keys.contains(serviceText)) { - Log.d(TAG, "Valid domain and service--processing dynamic fields") + if (actions[selectedServerId].orEmpty().keys.contains(actionText)) { + Log.d(TAG, "Valid domain and action--processing dynamic fields") // Make sure there are not already any dynamic fields created // This can happen if selecting the drop-down twice or pasting @@ -130,19 +130,19 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { // We only call this if servicesAvailable was fetched and is not null, // so we can safely assume that it is not null here - val serviceData = services[selectedServerId]!![serviceText]!!.serviceData - val target = serviceData.target - val fields = serviceData.fields + val actionData = actions[selectedServerId]!![actionText]!!.actionData + val target = actionData.target + val fields = actionData.fields val fieldKeys = fields.keys - Log.d(TAG, "Fields applicable to this service: $fields") + Log.d(TAG, "Fields applicable to this action: $fields") - val existingServiceData = mutableMapOf() + val existingActionData = mutableMapOf() val addedFields = mutableListOf() buttonWidgetDao.get(appWidgetId)?.let { buttonWidget -> if ( buttonWidget.serverId != selectedServerId || - "${buttonWidget.domain}.${buttonWidget.service}" != serviceText + "${buttonWidget.domain}.${buttonWidget.service}" != actionText ) { return@let } @@ -150,13 +150,13 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { val dbMap: HashMap = jacksonObjectMapper().readValue(buttonWidget.serviceData) for (item in dbMap) { val value = item.value.toString().replace("[", "").replace("]", "") + if (item.key == "entity_id") ", " else "" - existingServiceData[item.key] = value.ifEmpty { null } + existingActionData[item.key] = value.ifEmpty { null } addedFields.add(item.key) } } if (target != false) { - dynamicFields.add(0, ServiceFieldBinder(serviceText, "entity_id", existingServiceData["entity_id"])) + dynamicFields.add(0, ActionFieldBinder(actionText, "entity_id", existingActionData["entity_id"])) } fieldKeys.sorted().forEach { fieldKey -> @@ -166,14 +166,14 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { // IDs get priority and go at the top, since the other fields // are usually optional but the ID is required if (fieldKey.contains("_id")) { - dynamicFields.add(0, ServiceFieldBinder(serviceText, fieldKey, existingServiceData[fieldKey])) + dynamicFields.add(0, ActionFieldBinder(actionText, fieldKey, existingActionData[fieldKey])) } else { - dynamicFields.add(ServiceFieldBinder(serviceText, fieldKey, existingServiceData[fieldKey])) + dynamicFields.add(ActionFieldBinder(actionText, fieldKey, existingActionData[fieldKey])) } } addedFields.minus("entity_id").minus(fieldKeys).forEach { extraFieldKey -> Log.d(TAG, "Creating a text input box for extra $extraFieldKey") - dynamicFields.add(ServiceFieldBinder(serviceText, extraFieldKey, existingServiceData[extraFieldKey])) + dynamicFields.add(ActionFieldBinder(actionText, extraFieldKey, existingActionData[extraFieldKey])) } dynamicFieldAdapter.notifyDataSetChanged() @@ -190,8 +190,8 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { } ) - private fun getServiceString(service: Service): String { - return "${service.domain}.${service.service}" + private fun getActionString(action: Action): String { + return "${action.domain}.${action.action}" } public override fun onCreate(savedInstanceState: Bundle?) { @@ -236,8 +236,8 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { binding.backgroundType.adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_item, backgroundTypeValues) if (buttonWidget != null) { - val serviceText = "${buttonWidget.domain}.${buttonWidget.service}" - binding.widgetTextConfigService.setText(serviceText) + val actionText = "${buttonWidget.domain}.${buttonWidget.service}" + binding.widgetTextConfigService.setText(actionText) binding.label.setText(buttonWidget.label) binding.backgroundType.setSelection( @@ -265,24 +265,24 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { setupServerSelect(buttonWidget?.serverId) - serviceAdapter = SingleItemArrayAdapter(this) { - if (it != null) getServiceString(it) else "" + actionAdapter = SingleItemArrayAdapter(this) { + if (it != null) getActionString(it) else "" } - binding.widgetTextConfigService.setAdapter(serviceAdapter) + binding.widgetTextConfigService.setAdapter(actionAdapter) binding.widgetTextConfigService.onFocusChangeListener = dropDownOnFocus serverManager.defaultServers.forEach { server -> lifecycleScope.launch { try { - services[server.id] = HashMap() + actions[server.id] = HashMap() serverManager.integrationRepository(server.id).getServices()?.forEach { - services[server.id]!![getServiceString(it)] = it + actions[server.id]!![getActionString(it)] = it } - if (server.id == selectedServerId) setAdapterServices(server.id) + if (server.id == selectedServerId) setAdapterActions(server.id) } catch (e: Exception) { - // Custom components can cause services to not load + // Custom components can cause actions to not load // Display error text - Log.e(TAG, "Unable to load services from Home Assistant", e) + Log.e(TAG, "Unable to load actions from Home Assistant", e) if (server.id == selectedServerId) binding.widgetConfigServiceError.visibility = View.VISIBLE } } @@ -292,7 +292,7 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { serverManager.integrationRepository(server.id).getEntities()?.forEach { entities[server.id]!![it.entityId] = it } - if (server.id == selectedServerId) setAdapterServices(server.id) + if (server.id == selectedServerId) setAdapterActions(server.id) } catch (e: Exception) { // If entities fail to load, it's okay to pass // an empty map to the dynamicFieldAdapter @@ -300,7 +300,7 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { } } - binding.widgetTextConfigService.addTextChangedListener(serviceTextWatcher) + binding.widgetTextConfigService.addTextChangedListener(actionTextWatcher) binding.backgroundType.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { @@ -315,12 +315,12 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { binding.addFieldButton.setOnClickListener(onAddFieldListener) binding.addButton.setOnClickListener { if (requestLauncherSetup) { - val widgetConfigService = binding.widgetTextConfigService.text.toString() + val widgetConfigAction = binding.widgetTextConfigService.text.toString() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && selectedServerId != null && ( - widgetConfigService in services[selectedServerId].orEmpty().keys || - widgetConfigService.split(".", limit = 2).size == 2 + widgetConfigAction in actions[selectedServerId].orEmpty().keys || + widgetConfigAction.split(".", limit = 2).size == 2 ) ) { getSystemService()?.requestPinAppWidget( @@ -379,27 +379,27 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { override fun onServerSelected(serverId: Int) { binding.widgetTextConfigService.setText("") - setAdapterServices(serverId) + setAdapterActions(serverId) } @SuppressLint("NotifyDataSetChanged") - private fun setAdapterServices(serverId: Int) { - Log.d(TAG, "Services found: $services") - serviceAdapter?.clearAll() - if (services[serverId] != null) { - serviceAdapter?.addAll(services[serverId]?.values.orEmpty().toMutableList()) - serviceAdapter?.sort() + private fun setAdapterActions(serverId: Int) { + Log.d(TAG, "Actions found: $actions") + actionAdapter?.clearAll() + if (actions[serverId] != null) { + actionAdapter?.addAll(actions[serverId]?.values.orEmpty().toMutableList()) + actionAdapter?.sort() } dynamicFieldAdapter.replaceValues( - services[serverId].orEmpty() as HashMap, + actions[serverId].orEmpty() as HashMap, entities[serverId].orEmpty() as HashMap> ) - serviceTextWatcher.afterTextChanged(binding.widgetTextConfigService.text) + actionTextWatcher.afterTextChanged(binding.widgetTextConfigService.text) - // Update service adapter + // Update action adapter runOnUiThread { - serviceAdapter?.filter?.filter(binding.widgetTextConfigService.text) + actionAdapter?.filter?.filter(binding.widgetTextConfigService.text) } } @@ -419,7 +419,7 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { try { val context = this@ButtonWidgetConfigureActivity - // Set up a broadcast intent and pass the service call data as extras + // Set up a broadcast intent and pass the action data as extras val intent = Intent() intent.action = ButtonWidget.RECEIVE_DATA intent.component = ComponentName(context, ButtonWidget::class.java) @@ -431,18 +431,18 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { selectedServerId!! ) - // Analyze and send service and domain - val serviceText = binding.widgetTextConfigService.text.toString() - val services = services[selectedServerId].orEmpty() - val domain = services[serviceText]?.domain ?: serviceText.split(".", limit = 2)[0] - val service = services[serviceText]?.service ?: serviceText.split(".", limit = 2)[1] + // Analyze and send action and domain + val actionText = binding.widgetTextConfigService.text.toString() + val actions = actions[selectedServerId].orEmpty() + val domain = actions[actionText]?.domain ?: actionText.split(".", limit = 2)[0] + val action = actions[actionText]?.action ?: actionText.split(".", limit = 2)[1] intent.putExtra( ButtonWidget.EXTRA_DOMAIN, domain ) intent.putExtra( - ButtonWidget.EXTRA_SERVICE, - service + ButtonWidget.EXTRA_ACTION, + action ) // Fetch and send label and icon @@ -455,8 +455,8 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { binding.widgetConfigIconSelector.tag as String ) - // Analyze and send service data - val serviceDataMap = HashMap() + // Analyze and send action data + val actionDataMap = HashMap() dynamicFields.forEach { var value = it.value if (value != null) { @@ -465,13 +465,13 @@ class ButtonWidgetConfigureActivity : BaseWidgetConfigureActivity() { val trailingRegex = "[, ]+$".toRegex() value = value.replace(trailingRegex, "") } - serviceDataMap[it.field] = value + actionDataMap[it.field] = value } } intent.putExtra( - ButtonWidget.EXTRA_SERVICE_DATA, - jacksonObjectMapper().writeValueAsString(serviceDataMap) + ButtonWidget.EXTRA_ACTION_DATA, + jacksonObjectMapper().writeValueAsString(actionDataMap) ) intent.putExtra( diff --git a/app/src/main/java/io/homeassistant/companion/android/widgets/common/ServiceFieldBinder.kt b/app/src/main/java/io/homeassistant/companion/android/widgets/common/ActionFieldBinder.kt similarity index 66% rename from app/src/main/java/io/homeassistant/companion/android/widgets/common/ServiceFieldBinder.kt rename to app/src/main/java/io/homeassistant/companion/android/widgets/common/ActionFieldBinder.kt index 563d40f6250..d695659adb4 100644 --- a/app/src/main/java/io/homeassistant/companion/android/widgets/common/ServiceFieldBinder.kt +++ b/app/src/main/java/io/homeassistant/companion/android/widgets/common/ActionFieldBinder.kt @@ -1,7 +1,7 @@ package io.homeassistant.companion.android.widgets.common -data class ServiceFieldBinder( - val service: String, +data class ActionFieldBinder( + val action: String, val field: String, var value: Any? = null ) diff --git a/app/src/main/java/io/homeassistant/companion/android/widgets/common/WidgetDynamicFieldAdapter.kt b/app/src/main/java/io/homeassistant/companion/android/widgets/common/WidgetDynamicFieldAdapter.kt index f65f096454b..e23c357d618 100644 --- a/app/src/main/java/io/homeassistant/companion/android/widgets/common/WidgetDynamicFieldAdapter.kt +++ b/app/src/main/java/io/homeassistant/companion/android/widgets/common/WidgetDynamicFieldAdapter.kt @@ -8,17 +8,17 @@ import android.widget.AutoCompleteTextView import android.widget.MultiAutoCompleteTextView.CommaTokenizer import androidx.core.widget.doAfterTextChanged import androidx.recyclerview.widget.RecyclerView +import io.homeassistant.companion.android.common.data.integration.Action import io.homeassistant.companion.android.common.data.integration.Entity -import io.homeassistant.companion.android.common.data.integration.Service import io.homeassistant.companion.android.common.util.capitalize import io.homeassistant.companion.android.databinding.WidgetButtonConfigureDynamicFieldBinding import java.util.Locale import kotlin.Exception class WidgetDynamicFieldAdapter( - private var services: HashMap, + private var actions: HashMap, private var entities: HashMap>, - private val serviceFieldList: ArrayList + private val actionFieldList: ArrayList ) : RecyclerView.Adapter() { companion object { @@ -36,7 +36,7 @@ class WidgetDynamicFieldAdapter( } override fun getItemCount(): Int { - return serviceFieldList.size + return actionFieldList.size } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { @@ -52,8 +52,8 @@ class WidgetDynamicFieldAdapter( val autoCompleteTextView = binding.dynamicAutocompleteTextview val context = holder.itemView.context - val serviceText: String = serviceFieldList[position].service - val fieldKey = serviceFieldList[position].field + val actionText: String = actionFieldList[position].action + val fieldKey = actionFieldList[position].field // Set label for the text view // Reformat text to "Capital Words" instead of "capital_words" @@ -67,11 +67,11 @@ class WidgetDynamicFieldAdapter( } // If the field has an example, use it as a hint - if (services[serviceText]?.serviceData?.fields?.get(fieldKey)?.example != null) { + if (actions[actionText]?.actionData?.fields?.get(fieldKey)?.example != null) { try { // Fetch example text var exampleText = - services[serviceText]?.serviceData?.fields?.get(fieldKey)?.example.toString() + actions[actionText]?.actionData?.fields?.get(fieldKey)?.example.toString() // Strip of brackets if the example is a list // Lists can be entered as comma-separated strings @@ -99,7 +99,7 @@ class WidgetDynamicFieldAdapter( // Only populate with entities for the domain // or for homeassistant domain, which should be able // to manipulate entities in any domain - val domain = services[serviceText]?.domain + val domain = actions[actionText]?.domain // Add all as an available entity // all is a special keyword, so it won't be listed in any @@ -121,12 +121,12 @@ class WidgetDynamicFieldAdapter( autoCompleteTextView.setAdapter(adapter) autoCompleteTextView.setTokenizer(CommaTokenizer()) autoCompleteTextView.onFocusChangeListener = dropDownOnFocus - } else if (services[serviceText]?.serviceData?.fields?.get(fieldKey)?.values != null) { + } else if (actions[actionText]?.actionData?.fields?.get(fieldKey)?.values != null) { // If a non-"entity_id" field has specific values, // populate the autocomplete with valid values val fieldAdapter = SingleItemArrayAdapter(context) { it!! } fieldAdapter.addAll( - services[serviceText]!!.serviceData.fields.getValue(fieldKey).values!!.sorted().toMutableList() + actions[actionText]!!.actionData.fields.getValue(fieldKey).values!!.sorted().toMutableList() ) autoCompleteTextView.setAdapter(fieldAdapter) autoCompleteTextView.setTokenizer(CommaTokenizer()) @@ -140,11 +140,11 @@ class WidgetDynamicFieldAdapter( // Populate textview with stored text for that field // Currently value can by Any? but will currently only be storing String? // This may have to be changed later if multi-select gets implemented - if (serviceFieldList[position].value != null) { + if (actionFieldList[position].value != null) { try { - autoCompleteTextView.setText(serviceFieldList[position].value as String) + autoCompleteTextView.setText(actionFieldList[position].value as String) } catch (e: Exception) { - Log.d(TAG, "Unable to get service field list", e) + Log.d(TAG, "Unable to get action field list", e) // Set text to empty string to prevent a recycled, incorrect value autoCompleteTextView.setText("") } @@ -155,21 +155,21 @@ class WidgetDynamicFieldAdapter( // Have the text view store its text for later recall autoCompleteTextView.doAfterTextChanged { // Only attempt to store data if we are in bounds - if (serviceFieldList.size >= holder.bindingAdapterPosition && + if (actionFieldList.size >= holder.bindingAdapterPosition && holder.bindingAdapterPosition != RecyclerView.NO_POSITION ) { // Don't store data that's empty (or just whitespace) if (it.isNullOrBlank()) { - serviceFieldList[holder.bindingAdapterPosition].value = null + actionFieldList[holder.bindingAdapterPosition].value = null } else { - serviceFieldList[holder.bindingAdapterPosition].value = it.toString().toJsonType() + actionFieldList[holder.bindingAdapterPosition].value = it.toString().toJsonType() } } } } - fun replaceValues(services: HashMap, entities: HashMap>) { - this.services = services + fun replaceValues(actions: HashMap, entities: HashMap>) { + this.actions = actions this.entities = entities } diff --git a/app/src/main/java/io/homeassistant/companion/android/widgets/entity/EntityWidget.kt b/app/src/main/java/io/homeassistant/companion/android/widgets/entity/EntityWidget.kt index 09190b01a19..f027af2c9d4 100644 --- a/app/src/main/java/io/homeassistant/companion/android/widgets/entity/EntityWidget.kt +++ b/app/src/main/java/io/homeassistant/companion/android/widgets/entity/EntityWidget.kt @@ -278,7 +278,7 @@ class EntityWidget : BaseWidgetProvider() { } if (!success) { - Toast.makeText(context, commonR.string.service_call_failure, Toast.LENGTH_LONG).show() + Toast.makeText(context, commonR.string.action_failure, Toast.LENGTH_LONG).show() val views = getWidgetRemoteViews(context, appWidgetId) appWidgetManager.updateAppWidget(appWidgetId, views) diff --git a/app/src/main/java/io/homeassistant/companion/android/widgets/mediaplayer/MediaPlayerControlsWidget.kt b/app/src/main/java/io/homeassistant/companion/android/widgets/mediaplayer/MediaPlayerControlsWidget.kt index ef35639c5cb..e7cbdd95bca 100644 --- a/app/src/main/java/io/homeassistant/companion/android/widgets/mediaplayer/MediaPlayerControlsWidget.kt +++ b/app/src/main/java/io/homeassistant/companion/android/widgets/mediaplayer/MediaPlayerControlsWidget.kt @@ -453,13 +453,13 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { super.onScreenOn(context) } UPDATE_MEDIA_IMAGE -> updateView(context, appWidgetId) - CALL_PREV_TRACK -> callPreviousTrackService(context, appWidgetId) - CALL_REWIND -> callRewindService(context, appWidgetId) - CALL_PLAYPAUSE -> callPlayPauseService(context, appWidgetId) - CALL_FASTFORWARD -> callFastForwardService(context, appWidgetId) - CALL_NEXT_TRACK -> callNextTrackService(context, appWidgetId) - CALL_VOLUME_DOWN -> callVolumeDownService(context, appWidgetId) - CALL_VOLUME_UP -> callVolumeUpService(context, appWidgetId) + CALL_PREV_TRACK -> callPreviousTrackAction(context, appWidgetId) + CALL_REWIND -> callRewindAction(context, appWidgetId) + CALL_PLAYPAUSE -> callPlayPauseAction(context, appWidgetId) + CALL_FASTFORWARD -> callFastForwardAction(context, appWidgetId) + CALL_NEXT_TRACK -> callNextTrackAction(context, appWidgetId) + CALL_VOLUME_DOWN -> callVolumeDownAction(context, appWidgetId) + CALL_VOLUME_UP -> callVolumeUpAction(context, appWidgetId) } } @@ -484,7 +484,7 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { widgetScope?.launch { Log.d( TAG, - "Saving service call config data:" + System.lineSeparator() + + "Saving action call config data:" + System.lineSeparator() + "entity id: " + entitySelection + System.lineSeparator() ) mediaPlayCtrlWidgetDao.add( @@ -514,7 +514,7 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { } } - private fun callPreviousTrackService(context: Context, appWidgetId: Int) { + private fun callPreviousTrackAction(context: Context, appWidgetId: Int) { widgetScope?.launch { Log.d(TAG, "Retrieving media player entity for app widget $appWidgetId") val entity: MediaPlayerControlsWidgetEntity? = mediaPlayCtrlWidgetDao.get(appWidgetId) @@ -526,21 +526,21 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { Log.d( TAG, - "Calling previous track service:" + System.lineSeparator() + + "Calling previous track action:" + System.lineSeparator() + "entity id: " + entity.entityId + System.lineSeparator() ) val domain = "media_player" - val service = "media_previous_track" + val action = "media_previous_track" val entityId: String = getEntity(context, entity.serverId, entity.entityId.split(","), null)?.entityId.toString() - val serviceDataMap: HashMap = hashMapOf("entity_id" to entityId) + val actionDataMap: HashMap = hashMapOf("entity_id" to entityId) - serverManager.integrationRepository().callService(domain, service, serviceDataMap) + serverManager.integrationRepository().callAction(domain, action, actionDataMap) } } - private fun callRewindService(context: Context, appWidgetId: Int) { + private fun callRewindAction(context: Context, appWidgetId: Int) { widgetScope?.launch { Log.d(TAG, "Retrieving media player entity for app widget $appWidgetId") val entity: MediaPlayerControlsWidgetEntity? = mediaPlayCtrlWidgetDao.get(appWidgetId) @@ -552,7 +552,7 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { Log.d( TAG, - "Calling rewind service:" + System.lineSeparator() + + "Calling rewind action:" + System.lineSeparator() + "entity id: " + entity.entityId + System.lineSeparator() ) @@ -578,23 +578,23 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { } val domain = "media_player" - val service = "media_seek" + val action = "media_seek" val entityId: String = getEntity(context, entity.serverId, entity.entityId.split(","), null)?.entityId.toString() - val serviceDataMap: HashMap = hashMapOf( + val actionDataMap: HashMap = hashMapOf( "entity_id" to entityId, "seek_position" to currentTime - 10 ) try { - serverManager.integrationRepository(entity.serverId).callService(domain, service, serviceDataMap) + serverManager.integrationRepository(entity.serverId).callAction(domain, action, actionDataMap) } catch (e: Exception) { - Log.e(TAG, "Exception calling rewind service", e) + Log.e(TAG, "Exception calling rewind action", e) } } } - private fun callPlayPauseService(context: Context, appWidgetId: Int) { + private fun callPlayPauseAction(context: Context, appWidgetId: Int) { widgetScope?.launch { Log.d(TAG, "Retrieving media player entity for app widget $appWidgetId") val entity: MediaPlayerControlsWidgetEntity? = mediaPlayCtrlWidgetDao.get(appWidgetId) @@ -606,25 +606,25 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { Log.d( TAG, - "Calling play/pause service:" + System.lineSeparator() + + "Calling play/pause action:" + System.lineSeparator() + "entity id: " + entity.entityId + System.lineSeparator() ) val domain = "media_player" - val service = "media_play_pause" + val action = "media_play_pause" val entityId: String = getEntity(context, entity.serverId, entity.entityId.split(","), null)?.entityId.toString() - val serviceDataMap: HashMap = hashMapOf("entity_id" to entityId) + val actionDataMap: HashMap = hashMapOf("entity_id" to entityId) try { - serverManager.integrationRepository(entity.serverId).callService(domain, service, serviceDataMap) + serverManager.integrationRepository(entity.serverId).callAction(domain, action, actionDataMap) } catch (e: Exception) { - Log.e(TAG, "Exception calling play pause service", e) + Log.e(TAG, "Exception calling play pause action", e) } } } - private fun callFastForwardService(context: Context, appWidgetId: Int) { + private fun callFastForwardAction(context: Context, appWidgetId: Int) { widgetScope?.launch { Log.d(TAG, "Retrieving media player entity for app widget $appWidgetId") val entity: MediaPlayerControlsWidgetEntity? = mediaPlayCtrlWidgetDao.get(appWidgetId) @@ -636,7 +636,7 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { Log.d( TAG, - "Calling fast forward service:" + System.lineSeparator() + + "Calling fast forward action:" + System.lineSeparator() + "entity id: " + entity.entityId + System.lineSeparator() ) @@ -662,23 +662,23 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { } val domain = "media_player" - val service = "media_seek" + val action = "media_seek" val entityId: String = getEntity(context, entity.serverId, entity.entityId.split(","), null)?.entityId.toString() - val serviceDataMap: HashMap = hashMapOf( + val actionDataMap: HashMap = hashMapOf( "entity_id" to entityId, "seek_position" to currentTime + 10 ) try { - serverManager.integrationRepository(entity.serverId).callService(domain, service, serviceDataMap) + serverManager.integrationRepository(entity.serverId).callAction(domain, action, actionDataMap) } catch (e: Exception) { - Log.e(TAG, "Exception calling fast forward service", e) + Log.e(TAG, "Exception calling fast forward action", e) } } } - private fun callNextTrackService(context: Context, appWidgetId: Int) { + private fun callNextTrackAction(context: Context, appWidgetId: Int) { widgetScope?.launch { Log.d(TAG, "Retrieving media player entity for app widget $appWidgetId") val entity: MediaPlayerControlsWidgetEntity? = mediaPlayCtrlWidgetDao.get(appWidgetId) @@ -690,25 +690,25 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { Log.d( TAG, - "Calling next track service:" + System.lineSeparator() + + "Calling next track action:" + System.lineSeparator() + "entity id: " + entity.entityId + System.lineSeparator() ) val domain = "media_player" - val service = "media_next_track" + val action = "media_next_track" val entityId: String = getEntity(context, entity.serverId, entity.entityId.split(","), null)?.entityId.toString() - val serviceDataMap: HashMap = hashMapOf("entity_id" to entityId) + val actionDataMap: HashMap = hashMapOf("entity_id" to entityId) try { - serverManager.integrationRepository(entity.serverId).callService(domain, service, serviceDataMap) + serverManager.integrationRepository(entity.serverId).callAction(domain, action, actionDataMap) } catch (e: Exception) { - Log.e(TAG, "Exception calling next track service", e) + Log.e(TAG, "Exception calling next track action", e) } } } - private fun callVolumeDownService(context: Context, appWidgetId: Int) { + private fun callVolumeDownAction(context: Context, appWidgetId: Int) { widgetScope?.launch { Log.d(TAG, "Retrieving media player entity for app widget $appWidgetId") val entity: MediaPlayerControlsWidgetEntity? = mediaPlayCtrlWidgetDao.get(appWidgetId) @@ -720,25 +720,25 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { Log.d( TAG, - "Calling volume down service:" + System.lineSeparator() + + "Calling volume down action:" + System.lineSeparator() + "entity id: " + entity.entityId + System.lineSeparator() ) val domain = "media_player" - val service = "volume_down" + val action = "volume_down" val entityId: String = getEntity(context, entity.serverId, entity.entityId.split(","), null)?.entityId.toString() - val serviceDataMap: HashMap = hashMapOf("entity_id" to entityId) + val actionDataMap: HashMap = hashMapOf("entity_id" to entityId) try { - serverManager.integrationRepository(entity.serverId).callService(domain, service, serviceDataMap) + serverManager.integrationRepository(entity.serverId).callAction(domain, action, actionDataMap) } catch (e: Exception) { - Log.e(TAG, "Exception calling volume down service", e) + Log.e(TAG, "Exception calling volume down action", e) } } } - private fun callVolumeUpService(context: Context, appWidgetId: Int) { + private fun callVolumeUpAction(context: Context, appWidgetId: Int) { widgetScope?.launch { Log.d(TAG, "Retrieving media player entity for app widget $appWidgetId") val entity: MediaPlayerControlsWidgetEntity? = mediaPlayCtrlWidgetDao.get(appWidgetId) @@ -750,20 +750,20 @@ class MediaPlayerControlsWidget : BaseWidgetProvider() { Log.d( TAG, - "Calling volume up service:" + System.lineSeparator() + + "Calling volume up action:" + System.lineSeparator() + "entity id: " + entity.entityId + System.lineSeparator() ) val domain = "media_player" - val service = "volume_up" + val action = "volume_up" val entityId: String = getEntity(context, entity.serverId, entity.entityId.split(","), null)?.entityId.toString() - val serviceDataMap: HashMap = hashMapOf("entity_id" to entityId) + val actionDataMap: HashMap = hashMapOf("entity_id" to entityId) try { - serverManager.integrationRepository(entity.serverId).callService(domain, service, serviceDataMap) + serverManager.integrationRepository(entity.serverId).callAction(domain, action, actionDataMap) } catch (e: Exception) { - Log.e(TAG, "Exception calling volume up service", e) + Log.e(TAG, "Exception calling volume up action", e) } } } diff --git a/app/src/main/res/layout/widget_button_configure.xml b/app/src/main/res/layout/widget_button_configure.xml index 267ea4bf494..8c374e59976 100644 --- a/app/src/main/res/layout/widget_button_configure.xml +++ b/app/src/main/res/layout/widget_button_configure.xml @@ -16,7 +16,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="20dp" - android:text="@string/configure_service_call" /> + android:text="@string/configure_action" /> + android:text="@string/label_action" /> + android:text="@string/add_action_data_field" /> + val fields: Map ) diff --git a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/ServiceFields.kt b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/ActionFields.kt similarity index 91% rename from common/src/main/java/io/homeassistant/companion/android/common/data/integration/ServiceFields.kt rename to common/src/main/java/io/homeassistant/companion/android/common/data/integration/ActionFields.kt index e0d480e22d5..8408bba7f55 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/ServiceFields.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/ActionFields.kt @@ -3,7 +3,7 @@ package io.homeassistant.companion.android.common.data.integration import com.fasterxml.jackson.annotation.JsonIgnoreProperties @JsonIgnoreProperties(ignoreUnknown = true) -data class ServiceFields( +data class ActionFields( val name: String?, val description: String?, val example: Any?, 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 1aae6c2726f..52139260b61 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 @@ -642,7 +642,7 @@ private fun sensorIcon(state: String?, entity: Entity>): IIcon suspend fun Entity.onPressed( integrationRepository: IntegrationRepository ) { - val service = when (domain) { + val action = when (domain) { "lock" -> { if (state == "unlocked") "lock" else "unlock" } @@ -660,10 +660,10 @@ suspend fun Entity.onPressed( else -> "toggle" } - integrationRepository.callService( + integrationRepository.callAction( domain = this.domain, - service = service, - serviceData = hashMapOf("entity_id" to entityId) + action = action, + actionData = hashMapOf("entity_id" to entityId) ) } @@ -677,7 +677,7 @@ suspend fun onEntityPressedWithoutState( integrationRepository: IntegrationRepository ) { val domain = entityId.split(".")[0] - val service = when (domain) { + val action = when (domain) { "lock" -> { val lockEntity = try { integrationRepository.getEntity(entityId) @@ -690,10 +690,10 @@ suspend fun onEntityPressedWithoutState( in EntityExt.DOMAINS_TOGGLE -> "toggle" else -> "turn_on" } - integrationRepository.callService( + integrationRepository.callAction( domain = domain, - service = service, - serviceData = hashMapOf("entity_id" to entityId) + action = action, + actionData = hashMapOf("entity_id" to entityId) ) } diff --git a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/IntegrationRepository.kt b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/IntegrationRepository.kt index 07c8c458d06..9ce25f7174f 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/IntegrationRepository.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/IntegrationRepository.kt @@ -35,14 +35,14 @@ interface IntegrationRepository { suspend fun isHomeAssistantVersionAtLeast(year: Int, month: Int, release: Int): Boolean suspend fun getConfig(): GetConfigResponse - suspend fun getServices(): List? + suspend fun getServices(): List? suspend fun getEntities(): List>? suspend fun getEntity(entityId: String): Entity>? suspend fun getEntityUpdates(): Flow>? suspend fun getEntityUpdates(entityIds: List): Flow>? - suspend fun callService(domain: String, service: String, serviceData: HashMap) + suspend fun callAction(domain: String, action: String, actionData: HashMap) suspend fun scanTag(data: HashMap) diff --git a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt index 71559450d03..83f9c73e38d 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/IntegrationRepositoryImpl.kt @@ -6,14 +6,15 @@ import dagger.assisted.AssistedInject import io.homeassistant.companion.android.common.BuildConfig import io.homeassistant.companion.android.common.data.HomeAssistantVersion import io.homeassistant.companion.android.common.data.LocalStorage +import io.homeassistant.companion.android.common.data.integration.Action import io.homeassistant.companion.android.common.data.integration.DeviceRegistration import io.homeassistant.companion.android.common.data.integration.Entity import io.homeassistant.companion.android.common.data.integration.IntegrationException import io.homeassistant.companion.android.common.data.integration.IntegrationRepository import io.homeassistant.companion.android.common.data.integration.SensorRegistration -import io.homeassistant.companion.android.common.data.integration.Service import io.homeassistant.companion.android.common.data.integration.UpdateLocation import io.homeassistant.companion.android.common.data.integration.ZoneAttributes +import io.homeassistant.companion.android.common.data.integration.impl.entities.ActionRequest import io.homeassistant.companion.android.common.data.integration.impl.entities.EntityResponse import io.homeassistant.companion.android.common.data.integration.impl.entities.FireEventRequest import io.homeassistant.companion.android.common.data.integration.impl.entities.IntegrationRequest @@ -22,7 +23,6 @@ import io.homeassistant.companion.android.common.data.integration.impl.entities. import io.homeassistant.companion.android.common.data.integration.impl.entities.RegisterDeviceRequest import io.homeassistant.companion.android.common.data.integration.impl.entities.SensorRegistrationRequest import io.homeassistant.companion.android.common.data.integration.impl.entities.SensorUpdateRequest -import io.homeassistant.companion.android.common.data.integration.impl.entities.ServiceCallRequest import io.homeassistant.companion.android.common.data.integration.impl.entities.Template import io.homeassistant.companion.android.common.data.integration.impl.entities.UpdateLocationRequest import io.homeassistant.companion.android.common.data.servers.ServerManager @@ -268,18 +268,18 @@ class IntegrationRepositoryImpl @AssistedInject constructor( } } - override suspend fun callService( + override suspend fun callAction( domain: String, - service: String, - serviceData: HashMap + action: String, + actionData: HashMap ) { var wasSuccess = false - val serviceCallRequest = - ServiceCallRequest( + val actionRequest = + ActionRequest( domain, - service, - serviceData + action, + actionData ) var causeException: Exception? = null @@ -290,7 +290,7 @@ class IntegrationRepositoryImpl @AssistedInject constructor( it.toHttpUrlOrNull()!!, IntegrationRequest( "call_service", - serviceCallRequest + actionRequest ) ).isSuccessful } catch (e: Exception) { @@ -554,12 +554,12 @@ class IntegrationRepositoryImpl @AssistedInject constructor( ) } - override suspend fun getServices(): List? { + override suspend fun getServices(): List? { val response = webSocketRepository.getServices() return response?.flatMap { it.services.map { service -> - Service(it.domain, service.key, service.value) + Action(it.domain, service.key, service.value) } }?.toList() } diff --git a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/entities/ServiceCallRequest.kt b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/entities/ActionRequest.kt similarity index 84% rename from common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/entities/ServiceCallRequest.kt rename to common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/entities/ActionRequest.kt index b6344562579..d4f869bf42a 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/entities/ServiceCallRequest.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/data/integration/impl/entities/ActionRequest.kt @@ -1,6 +1,6 @@ package io.homeassistant.companion.android.common.data.integration.impl.entities -data class ServiceCallRequest( +data class ActionRequest( val domain: String, val service: String, val serviceData: HashMap diff --git a/common/src/main/java/io/homeassistant/companion/android/common/data/websocket/impl/WebSocketRepositoryImpl.kt b/common/src/main/java/io/homeassistant/companion/android/common/data/websocket/impl/WebSocketRepositoryImpl.kt index d0ff4e3e62c..db3f39071a1 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/data/websocket/impl/WebSocketRepositoryImpl.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/data/websocket/impl/WebSocketRepositoryImpl.kt @@ -15,7 +15,7 @@ import io.homeassistant.companion.android.common.data.HomeAssistantApis.Companio import io.homeassistant.companion.android.common.data.HomeAssistantApis.Companion.USER_AGENT_STRING import io.homeassistant.companion.android.common.data.HomeAssistantVersion import io.homeassistant.companion.android.common.data.authentication.AuthorizationException -import io.homeassistant.companion.android.common.data.integration.ServiceData +import io.homeassistant.companion.android.common.data.integration.ActionData import io.homeassistant.companion.android.common.data.integration.impl.entities.EntityResponse import io.homeassistant.companion.android.common.data.servers.ServerManager import io.homeassistant.companion.android.common.data.websocket.WebSocketRepository @@ -222,7 +222,7 @@ class WebSocketRepositoryImpl @AssistedInject constructor( ) ) - val response: Map>? = mapResponse(socketResponse) + val response: Map>? = mapResponse(socketResponse) return response?.map { DomainResponse(it.key, it.value) } diff --git a/common/src/main/java/io/homeassistant/companion/android/common/data/websocket/impl/entities/DomainResponse.kt b/common/src/main/java/io/homeassistant/companion/android/common/data/websocket/impl/entities/DomainResponse.kt index ff4ebb82cdf..51a6c13de77 100644 --- a/common/src/main/java/io/homeassistant/companion/android/common/data/websocket/impl/entities/DomainResponse.kt +++ b/common/src/main/java/io/homeassistant/companion/android/common/data/websocket/impl/entities/DomainResponse.kt @@ -1,8 +1,8 @@ package io.homeassistant.companion.android.common.data.websocket.impl.entities -import io.homeassistant.companion.android.common.data.integration.ServiceData +import io.homeassistant.companion.android.common.data.integration.ActionData data class DomainResponse( val domain: String, - val services: Map + val services: Map ) diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 84c792c090e..52f4cc111bd 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -13,7 +13,7 @@ Unable to send activity intent, please check command format Add device Add favorite - Add field + Add field Add shortcut Disable all %1$d sensors Add @@ -123,7 +123,7 @@ Unable to send broadcast intent, please check the command format Buttons Next - Call any service + Perform an action Calendar Camera Camera tile @@ -150,7 +150,7 @@ Entity state Preview Configuration - Configure service call + Configure action Widget label Are you sure? This cannot be undone Confirm deleting all notifications @@ -329,7 +329,7 @@ Entity ID(s): Icon: Label: - Service: + Action: Label Device language default @@ -489,7 +489,7 @@ If you want to enable notifications in the future, you can change this in Settings. Get alerted from notifications Send commands to your device - Enable notifications to create a notify service for your device + Enable notifications to create a notify action for your device Open with headset button Use Assist with the assistant/voice command button on supported headphones and earbuds Other settings @@ -759,7 +759,7 @@ Are you sure you want to delete this server from the app? Deleting server… Server name - Unable to send service call + Unable to send action Session timeout (in seconds) Set favorites Set favorites on Wear OS device @@ -985,10 +985,10 @@ Light/dark theme Dynamic color Transparent - Service button + Action button Picture widget Image - A custom component is preventing service data from loading. + A custom component is preventing action data from loading. Unable to create widget. Unable to fetch data for configured entity. Home Assistant widget @@ -1020,9 +1020,9 @@ Toggle Unable to render the template Label - Entity ID - Domain - Service + Entity ID + Domain + Action 30 Widget text size: 12 diff --git a/wear/src/main/java/io/homeassistant/companion/android/home/HomePresenterImpl.kt b/wear/src/main/java/io/homeassistant/companion/android/home/HomePresenterImpl.kt index 8c55b664c56..cbce398bbba 100644 --- a/wear/src/main/java/io/homeassistant/companion/android/home/HomePresenterImpl.kt +++ b/wear/src/main/java/io/homeassistant/companion/android/home/HomePresenterImpl.kt @@ -99,7 +99,7 @@ class HomePresenterImpl @Inject constructor( else -> "turn_on" } try { - serverManager.integrationRepository().callService( + serverManager.integrationRepository().callAction( domain, serviceName, hashMapOf("entity_id" to entityId) @@ -111,7 +111,7 @@ class HomePresenterImpl @Inject constructor( override suspend fun onFanSpeedChanged(entityId: String, speed: Float) { try { - serverManager.integrationRepository().callService( + serverManager.integrationRepository().callAction( entityId.split(".")[0], "set_percentage", hashMapOf( @@ -126,7 +126,7 @@ class HomePresenterImpl @Inject constructor( override suspend fun onBrightnessChanged(entityId: String, brightness: Float) { try { - serverManager.integrationRepository().callService( + serverManager.integrationRepository().callAction( entityId.split(".")[0], "turn_on", hashMapOf( @@ -142,7 +142,7 @@ class HomePresenterImpl @Inject constructor( override suspend fun onColorTempChanged(entityId: String, colorTemp: Float, isKelvin: Boolean) { try { val colorTempKey = if (isKelvin) "color_temp_kelvin" else "color_temp" - serverManager.integrationRepository().callService( + serverManager.integrationRepository().callAction( entityId.split(".")[0], "turn_on", hashMapOf(