Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "[Android] Implement using generic IM(invoke,read,write,subscribe) APIs (#25956)" #26704

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.ChipIdLookup
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.AddressUpdateFragmentBinding
import com.google.chip.chiptool.util.DeviceIdUtil

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipClusters
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.ClusterIDMapping
import chip.devicecontroller.InvokeCallback
import chip.devicecontroller.OpenCommissioningCallback
import chip.devicecontroller.model.InvokeElement
import chip.tlv.AnonymousTag
import chip.tlv.TlvWriter
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
import com.google.chip.chiptool.R
Expand Down Expand Up @@ -133,31 +129,22 @@ class MultiAdminClientFragment : Fragment() {

private suspend fun sendRevokeCommandClick() {
val timedInvokeTimeout = 10000
// TODO : Need to be implement poj-to-tlv
val tlvWriter = TlvWriter()
tlvWriter.startStructure(AnonymousTag)
tlvWriter.endStructure()
val invokeElement = InvokeElement.newInstance(0
, ClusterIDMapping.AdministratorCommissioning.ID
, ClusterIDMapping.AdministratorCommissioning.Command.RevokeCommissioning.id
, tlvWriter.getEncoded(), null)

deviceController.invoke(object: InvokeCallback {
override fun onError(ex: Exception?) {
showMessage("Revoke Commissioning failure $ex")
Log.e(TAG, "Revoke Commissioning failure", ex)
}

override fun onResponse(invokeElement: InvokeElement?, successCode: Long) {
Log.e(TAG, "onResponse : $invokeElement, Code : $successCode")
getAdministratorCommissioningClusterForDevice().revokeCommissioning(object : ChipClusters.DefaultClusterCallback {
override fun onSuccess() {
showMessage("Revoke Commissioning success")
}

}, getConnectedDevicePointer(), invokeElement, timedInvokeTimeout, 0)
override fun onError(ex: Exception) {
showMessage("Revoke Commissioning failure $ex")
Log.e(TAG, "Revoke Commissioning failure", ex)
}
}, timedInvokeTimeout)
}

private suspend fun getConnectedDevicePointer(): Long {
return ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId)
private suspend fun getAdministratorCommissioningClusterForDevice(): ChipClusters.AdministratorCommissioningCluster {
return ChipClusters.AdministratorCommissioningCluster(
ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId), 0
)
}

private fun showMessage(msg: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,19 @@ import android.widget.SeekBar
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipClusters
import chip.devicecontroller.ChipClusters.OnOffCluster
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.InvokeCallback
import chip.devicecontroller.ReportCallback
import chip.devicecontroller.ResubscriptionAttemptCallback
import chip.devicecontroller.SubscriptionEstablishedCallback
import chip.devicecontroller.model.ChipAttributePath
import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.InvokeElement
import chip.devicecontroller.model.NodeState
import chip.tlv.TlvWriter
import com.google.chip.chiptool.ChipClient
import com.google.chip.chiptool.GenericChipDeviceListener
import com.google.chip.chiptool.R
import com.google.chip.chiptool.databinding.OnOffClientFragmentBinding
import com.google.chip.chiptool.util.TlvParseUtil
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch

import chip.devicecontroller.ClusterIDMapping.*
import chip.tlv.AnonymousTag
import chip.tlv.ContextSpecificTag

class OnOffClientFragment : Fragment() {
private val deviceController: ChipDeviceController
get() = ChipClient.getDeviceController(requireContext())
Expand All @@ -61,9 +49,9 @@ class OnOffClientFragment : Fragment() {
addressUpdateFragment =
childFragmentManager.findFragmentById(R.id.addressUpdateFragment) as AddressUpdateFragment

binding.onBtn.setOnClickListener { scope.launch { sendOnOffClusterCommand(OnOff.Command.On) } }
binding.offBtn.setOnClickListener { scope.launch { sendOnOffClusterCommand(OnOff.Command.Off) } }
binding.toggleBtn.setOnClickListener { scope.launch { sendOnOffClusterCommand(OnOff.Command.Toggle) } }
binding.onBtn.setOnClickListener { scope.launch { sendOnCommandClick() } }
binding.offBtn.setOnClickListener { scope.launch { sendOffCommandClick() } }
binding.toggleBtn.setOnClickListener { scope.launch { sendToggleCommandClick() } }
binding.readBtn.setOnClickListener { scope.launch { sendReadOnOffClick() } }
binding.showSubscribeDialogBtn.setOnClickListener { showSubscribeDialog() }

Expand Down Expand Up @@ -94,24 +82,16 @@ class OnOffClientFragment : Fragment() {
}

private suspend fun sendReadOnOffClick() {
val endpointId = addressUpdateFragment.endpointId
val clusterId = OnOff.ID
val attributeId = OnOff.Attribute.OnOff.id

val attributePath = ChipAttributePath.newInstance(endpointId.toLong(), clusterId, attributeId)

ChipClient.getDeviceController(requireContext()).readPath(object: ReportCallback {
override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: java.lang.Exception) {
Log.e(TAG, "Error reading onOff attribute", ex)
getOnOffClusterForDevice().readOnOffAttribute(object : ChipClusters.BooleanAttributeCallback {
override fun onSuccess(on: Boolean) {
Log.v(TAG, "On/Off attribute value: $on")
showMessage("On/Off attribute value: $on")
}

override fun onReport(nodeState: NodeState?) {
val value = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.value ?: "null"
Log.v(TAG, "On/Off attribute value: $value")
showMessage("On/Off attribute value: $value")
override fun onError(ex: Exception) {
Log.e(TAG, "Error reading onOff attribute", ex)
}

}, getConnectedDevicePointer(), listOf(attributePath), null, false, 0 /* imTimeoutMs */)
})
}

private fun showSubscribeDialog() {
Expand All @@ -135,53 +115,31 @@ class OnOffClientFragment : Fragment() {
}
dialog.show()
}

private suspend fun sendSubscribeOnOffClick(minInterval: Int, maxInterval: Int) {
val endpointId = addressUpdateFragment.endpointId
val clusterId = OnOff.ID
val attributeId = OnOff.Attribute.OnOff.id

val attributePath = ChipAttributePath.newInstance(endpointId.toLong(), clusterId, attributeId)

val subscriptionEstablishedCallback =
SubscriptionEstablishedCallback {
subscriptionId ->
Log.i(TAG, "Subscription to device established : ${subscriptionId.toULong()}")
requireActivity().runOnUiThread {
Toast.makeText(requireActivity(), "${getString(R.string.wildcard_subscribe_established_toast_message)} : $subscriptionId", Toast.LENGTH_SHORT).show()
}
}

val resubscriptionAttemptCallback =
ResubscriptionAttemptCallback { terminationCause, nextResubscribeIntervalMsec
-> Log.i(TAG, "ResubscriptionAttempt terminationCause:$terminationCause, nextResubscribeIntervalMsec:$nextResubscribeIntervalMsec") }

deviceController.subscribeToPath(subscriptionEstablishedCallback,
resubscriptionAttemptCallback,
object: ReportCallback {
override fun onError(attributePath: ChipAttributePath?, eventPath: ChipEventPath?, ex: Exception) {
Log.e(TAG, "Error configuring on/off attribute", ex)
}

override fun onReport(nodeState: NodeState?) {
val tlv = nodeState?.getEndpointState(endpointId)?.getClusterState(clusterId)?.getAttributeState(attributeId)?.tlv ?: return
// TODO : Need to be implement poj-to-tlv
val value = TlvParseUtil.decodeBoolean(tlv)
val formatter = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
val time = formatter.format(Calendar.getInstance(Locale.getDefault()).time)
val message = "Subscribed on/off value at $time: ${if (value) "ON" else "OFF"}"

Log.v(TAG, message)
showReportMessage(message)
}
},
getConnectedDevicePointer(),
listOf(attributePath),
null,
minInterval,
maxInterval,
false,
false,
/* imTimeoutMs= */ 0)
val onOffCluster = getOnOffClusterForDevice()

val subscribeCallback = object : ChipClusters.BooleanAttributeCallback {
override fun onSuccess(value: Boolean) {
val formatter = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
val time = formatter.format(Calendar.getInstance(Locale.getDefault()).time)
val message = "Subscribed on/off value at $time: ${if (value) "ON" else "OFF"}"

Log.v(TAG, message)
showReportMessage(message)
}

override fun onSubscriptionEstablished(subscriptionId: Long) {
val message = "Subscription for on/off established with subscriptionId: $subscriptionId"
Log.v(TAG, message)
showMessage(message)
}

override fun onError(ex: Exception) {
Log.e(TAG, "Error configuring on/off attribute", ex)
}
}
onOffCluster.subscribeOnOffAttribute(subscribeCallback, minInterval, maxInterval)
}

inner class ChipControllerCallback : GenericChipDeviceListener() {
Expand All @@ -206,60 +164,69 @@ class OnOffClientFragment : Fragment() {
}

private suspend fun sendLevelCommandClick() {
// TODO : Need to be implement poj-to-tlv
val tlvWriter = TlvWriter()
tlvWriter.startStructure(AnonymousTag)
tlvWriter.put(ContextSpecificTag(0), binding.levelBar.progress.toUInt())
tlvWriter.put(ContextSpecificTag(1), 0u)
tlvWriter.put(ContextSpecificTag(2), 0u)
tlvWriter.put(ContextSpecificTag(3), 0u)
tlvWriter.endStructure()

val invokeElement = InvokeElement.newInstance(addressUpdateFragment.endpointId.toLong()
, LevelControl.ID
, LevelControl.Command.MoveToLevel.id
, tlvWriter.getEncoded(), null)

deviceController.invoke(object: InvokeCallback {
override fun onError(ex: Exception?) {
val cluster = ChipClusters.LevelControlCluster(
ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId),
addressUpdateFragment.endpointId
)
cluster.moveToLevel(object : ChipClusters.DefaultClusterCallback {
override fun onSuccess() {
showMessage("MoveToLevel command success")
}

override fun onError(ex: Exception) {
showMessage("MoveToLevel command failure $ex")
Log.e(TAG, "MoveToLevel command failure", ex)
}

override fun onResponse(invokeElement: InvokeElement?, successCode: Long) {
Log.e(TAG, "onResponse : $invokeElement, Code : $successCode")
showMessage("MoveToLevel command success")
}, binding.levelBar.progress, 0, 0, 0)
}

private suspend fun sendOnCommandClick() {
getOnOffClusterForDevice().on(object : ChipClusters.DefaultClusterCallback {
override fun onSuccess() {
showMessage("ON command success")
}

override fun onError(ex: Exception) {
showMessage("ON command failure $ex")
Log.e(TAG, "ON command failure", ex)
}

}, getConnectedDevicePointer(), invokeElement, 0, 0)
})
}

private suspend fun sendOnOffClusterCommand(commandId: OnOff.Command) {
// TODO : Need to be implement poj-to-tlv
val tlvWriter = TlvWriter()
tlvWriter.startStructure(AnonymousTag)
tlvWriter.endStructure()
val invokeElement = InvokeElement.newInstance(addressUpdateFragment.endpointId.toLong()
, OnOff.ID
, commandId.id
, tlvWriter.getEncoded(), null)

deviceController.invoke(object: InvokeCallback {
override fun onError(ex: Exception?) {
showMessage("${commandId.name} command failure $ex")
Log.e(TAG, "${commandId.name} command failure", ex)
private suspend fun sendOffCommandClick() {
getOnOffClusterForDevice().off(object : ChipClusters.DefaultClusterCallback {
override fun onSuccess() {
showMessage("OFF command success")
}

override fun onError(ex: Exception) {
showMessage("OFF command failure $ex")
Log.e(TAG, "OFF command failure", ex)
}
})
}

override fun onResponse(invokeElement: InvokeElement?, successCode: Long) {
Log.e(TAG, "onResponse : $invokeElement, Code : $successCode")
showMessage("${commandId.name} command success")
private suspend fun sendToggleCommandClick() {
getOnOffClusterForDevice().toggle(object : ChipClusters.DefaultClusterCallback {
override fun onSuccess() {
showMessage("TOGGLE command success")
}

}, getConnectedDevicePointer(), invokeElement, 0, 0)
override fun onError(ex: Exception) {
showMessage("TOGGLE command failure $ex")
Log.e(TAG, "TOGGLE command failure", ex)
}
})
}

private suspend fun getConnectedDevicePointer(): Long {
return ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId)
private suspend fun getOnOffClusterForDevice(): OnOffCluster {
return OnOffCluster(

ChipClient.getConnectedDevicePointer(requireContext(), addressUpdateFragment.deviceId),
addressUpdateFragment.endpointId
)
}

private fun showMessage(msg: String) {
Expand Down
Loading