Skip to content

Commit

Permalink
Implement multiple write,invoke UI
Browse files Browse the repository at this point in the history
  • Loading branch information
joonhaengHeo committed Feb 28, 2024
1 parent 486ee6d commit fce120a
Show file tree
Hide file tree
Showing 5 changed files with 228 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import chip.devicecontroller.ChipDeviceController
import chip.devicecontroller.ChipIdLookup
import chip.devicecontroller.InvokeCallback
import chip.devicecontroller.ExtendableInvokeCallback
import chip.devicecontroller.ReportCallback
import chip.devicecontroller.ResubscriptionAttemptCallback
import chip.devicecontroller.SubscriptionEstablishedCallback
Expand All @@ -26,6 +26,8 @@ import chip.devicecontroller.model.ChipAttributePath
import chip.devicecontroller.model.ChipEventPath
import chip.devicecontroller.model.ChipPathId
import chip.devicecontroller.model.InvokeElement
import chip.devicecontroller.model.InvokeResponseData
import chip.devicecontroller.model.NoInvokeResponseData
import chip.devicecontroller.model.NodeState
import chip.devicecontroller.model.Status
import com.google.chip.chiptool.ChipClient
Expand Down Expand Up @@ -57,6 +59,8 @@ class WildcardFragment : Fragment() {

private val attributePath = ArrayList<ChipAttributePath>()
private val eventPath = ArrayList<ChipEventPath>()
private val writePath = ArrayList<AttributeWriteRequest>()
private val invokePath = ArrayList<InvokeElement>()
private val subscribeIdList = ArrayList<ULong>()

private val reportCallback =
Expand Down Expand Up @@ -89,29 +93,43 @@ class WildcardFragment : Fragment() {

private val writeAttributeCallback =
object : WriteAttributesCallback {
var viewText = ""

override fun onError(attributePath: ChipAttributePath?, ex: Exception?) {
Log.e(TAG, "Report error for $attributePath: $ex")
viewText += "onError : $attributePath - $ex\n"
}

override fun onResponse(attributePath: ChipAttributePath, status: Status) {
val text = "$attributePath : Write response: $status"
requireActivity().runOnUiThread { binding.outputTv.text = text }
viewText += "$attributePath : Write response: $status\n"
}

override fun onDone() {
Log.i(TAG, "write attribute Done")
requireActivity().runOnUiThread { binding.outputTv.text = viewText }
viewText = ""
}
}

private val invokeCallback =
object : InvokeCallback {
private val extendableInvokeCallback =
object : ExtendableInvokeCallback {
var viewText = ""

override fun onError(e: java.lang.Exception?) {
viewText += "Invoke onError : $e\n"
Log.e(TAG, "Report error", e)
}

override fun onResponse(invokeElement: InvokeElement?, successCode: Long) {
val text = "Invoke Response : $invokeElement, $successCode"
requireActivity().runOnUiThread { binding.outputTv.text = text }
override fun onResponse(invokeResponseData: InvokeResponseData?) {
viewText += "Invoke Response : $invokeResponseData\n"
}

override fun onNoResponse(noInvokeResponseData: NoInvokeResponseData?) {
viewText += "Invoke onNoResponse : $noInvokeResponseData\n"
}

override fun onDone() {
requireActivity().runOnUiThread { binding.outputTv.text = viewText }
viewText = ""
}
}

Expand All @@ -123,22 +141,44 @@ class WildcardFragment : Fragment() {
_binding = WildcardFragmentBinding.inflate(inflater, container, false)
scope = viewLifecycleOwner.lifecycleScope

val writeTypeSpinnerAdapter =
ArrayAdapter(
requireActivity(),
android.R.layout.simple_spinner_dropdown_item,
TLV_MAP.keys.toList()
)
binding.writeValueTypeSp.adapter = writeTypeSpinnerAdapter

binding.selectTypeRadioGroup.setOnCheckedChangeListener { _, i ->
val readBtnOn = (i == R.id.readRadioBtn)
val subscribeBtnOn = (i == R.id.subscribeRadioBtn)
val writeBtnOn = (i == R.id.writeRadioBtn)
val invokeBtnOn = (i == R.id.invokeRadioBtn)

binding.addLayout.visibility = getVisibility(readBtnOn || subscribeBtnOn)
binding.addAttributeBtn.visibility = getVisibility(readBtnOn || subscribeBtnOn)
binding.addEventBtn.visibility = getVisibility(readBtnOn || subscribeBtnOn)
binding.resetBtn.visibility = getVisibility(readBtnOn || subscribeBtnOn)
binding.attributeIdLabel.visibility = getVisibility(readBtnOn || subscribeBtnOn || writeBtnOn)
binding.attributeIdEd.visibility = getVisibility(readBtnOn || subscribeBtnOn || writeBtnOn)
binding.eventIdLabel.visibility = getVisibility(readBtnOn || subscribeBtnOn)
binding.eventIdEd.visibility = getVisibility(readBtnOn || subscribeBtnOn)
binding.addListBtn.visibility = getVisibility(writeBtnOn || invokeBtnOn)
binding.commandIdLabel.visibility = getVisibility(invokeBtnOn)
binding.commandIdEd.visibility = getVisibility(invokeBtnOn)
binding.isUrgentLabel.visibility = getVisibility(subscribeBtnOn)
binding.isUrgentSp.visibility = getVisibility(subscribeBtnOn)
binding.writeValueLabel.visibility = getVisibility(writeBtnOn)
binding.writeValueEd.visibility = getVisibility(writeBtnOn)
binding.writeValueTypeLabel.visibility = getVisibility(writeBtnOn)
binding.writeValueTypeSp.visibility = getVisibility(writeBtnOn)
binding.dataVersionLabel.visibility = getVisibility(writeBtnOn)
binding.dataVersionEd.visibility = getVisibility(writeBtnOn)
binding.invokeValueLabel.visibility = getVisibility(invokeBtnOn)
binding.invokeValueEd.visibility = getVisibility(invokeBtnOn)
binding.shutdownSubscriptionBtn.visibility = getVisibility(subscribeBtnOn)
binding.writeInvokeresetBtn.visibility = getVisibility(writeBtnOn || invokeBtnOn)

resetPath()
}

binding.sendBtn.setOnClickListener {
Expand All @@ -155,8 +195,16 @@ class WildcardFragment : Fragment() {

binding.shutdownSubscriptionBtn.setOnClickListener { showShutdownSubscriptionDialog() }

binding.addAttributeBtn.setOnClickListener { addPathList(ATTRIBUTE) }
binding.addEventBtn.setOnClickListener { addPathList(EVENT) }
binding.addAttributeBtn.setOnClickListener { addPathList(SendType.ATTRIBUTE) }
binding.addEventBtn.setOnClickListener { addPathList(SendType.EVENT) }
binding.addListBtn.setOnClickListener {
Log.d(TAG, "addListBtn : ${binding.writeRadioBtn.isChecked}")
if (binding.writeRadioBtn.isChecked) {
addWriteRequest()
} else {
addInvokeRequest()
}
}
binding.resetBtn.setOnClickListener { resetPath() }

addressUpdateFragment =
Expand All @@ -173,7 +221,7 @@ class WildcardFragment : Fragment() {
}
}

private fun addPathList(type: Int) {
private fun addPathList(type: SendType) {
val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString())
val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString())
val attributeId = getChipPathIdForText(binding.attributeIdEd.text.toString())
Expand All @@ -183,9 +231,9 @@ class WildcardFragment : Fragment() {
(binding.subscribeRadioBtn.isChecked) &&
(binding.isUrgentSp.selectedItem.toString().toBoolean())

if (type == ATTRIBUTE) {
if (type == SendType.ATTRIBUTE) {
attributePath.add(ChipAttributePath.newInstance(endpointId, clusterId, attributeId))
} else if (type == EVENT) {
} else if (type == SendType.EVENT) {
eventPath.add(ChipEventPath.newInstance(endpointId, clusterId, eventId, isUrgent))
}
updateAddListView()
Expand All @@ -194,6 +242,8 @@ class WildcardFragment : Fragment() {
private fun resetPath() {
attributePath.clear()
eventPath.clear()
writePath.clear()
invokePath.clear()
updateAddListView()
}

Expand All @@ -205,6 +255,12 @@ class WildcardFragment : Fragment() {
for (event in eventPath) {
builder.append("event($event)\n")
}
for (write in writePath) {
builder.append("WritePath($write)\n")
}
for (invoke in invokePath) {
builder.append("InvokePath($invoke)\n")
}
binding.sendListView.text = builder.toString()
}

Expand Down Expand Up @@ -312,13 +368,12 @@ class WildcardFragment : Fragment() {
)
}

private suspend fun write(
writeValueType: String,
writeValue: String,
dataVersion: Int?,
timedRequestTimeoutMs: Int,
imTimeoutMs: Int
) {
private fun addWriteRequest() {
Log.d(TAG, "addWriteRequest")
val writeValue = binding.writeValueEd.text.toString()
val writeValueType = binding.writeValueTypeSp.selectedItem.toString()
val dataVersion = binding.dataVersionEd.text.toString()

val endpointId =
if (!addressUpdateFragment.isGroupId()) {
getChipPathIdForText(binding.endpointIdEd.text.toString())
Expand All @@ -329,10 +384,10 @@ class WildcardFragment : Fragment() {
val attributeId = getChipPathIdForText(binding.attributeIdEd.text.toString())

val version =
if (dataVersion == null) {
if (dataVersion.isEmpty()) {
Optional.empty()
} else {
Optional.of(dataVersion)
Optional.of(dataVersion.toInt())
}

lateinit var writeRequest: AttributeWriteRequest
Expand Down Expand Up @@ -364,26 +419,16 @@ class WildcardFragment : Fragment() {
version
)
}
val devicePtr =
try {
addressUpdateFragment.getDevicePointer(requireContext())
} catch (e: IllegalStateException) {
Log.d(TAG, "getDevicePointer exception", e)
return
}
deviceController.write(
writeAttributeCallback,
devicePtr,
listOf(writeRequest),
timedRequestTimeoutMs,
imTimeoutMs
)
writePath.add(writeRequest)
updateAddListView()
}

private suspend fun invoke(invokeJson: String, timedRequestTimeoutMs: Int, imTimeoutMs: Int) {
private fun addInvokeRequest() {
Log.d(TAG, "addInvokeRequest")
val endpointId = getChipPathIdForText(binding.endpointIdEd.text.toString())
val clusterId = getChipPathIdForText(binding.clusterIdEd.text.toString())
val commandId = getChipPathIdForText(binding.commandIdEd.text.toString())
val invokeJson = binding.invokeValueEd.text.toString()

val jsonString = invokeJson.ifEmpty { "{}" }
val invokeElement =
Expand All @@ -398,17 +443,39 @@ class WildcardFragment : Fragment() {
} else {
InvokeElement.newInstance(endpointId, clusterId, commandId, null, jsonString)
}
invokePath.add(invokeElement)
updateAddListView()
}

private suspend fun write(timedRequestTimeoutMs: Int, imTimeoutMs: Int) {
val devicePtr =
try {
addressUpdateFragment.getDevicePointer(requireContext())
} catch (e: IllegalStateException) {
Log.d(TAG, "getDevicePointer exception", e)
return
}
deviceController.invoke(
invokeCallback,
deviceController.write(
writeAttributeCallback,
devicePtr,
invokeElement,
writePath,
timedRequestTimeoutMs,
imTimeoutMs
)
}

private suspend fun invoke(timedRequestTimeoutMs: Int, imTimeoutMs: Int) {
val devicePtr =
try {
addressUpdateFragment.getDevicePointer(requireContext())
} catch (e: IllegalStateException) {
Log.d(TAG, "getDevicePointer exception", e)
return
}
deviceController.extendableInvoke(
extendableInvokeCallback,
devicePtr,
invokePath,
timedRequestTimeoutMs,
imTimeoutMs
)
Expand Down Expand Up @@ -453,31 +520,14 @@ class WildcardFragment : Fragment() {
private fun showWriteDialog() {
binding.outputTv.text = ""
val dialogView = requireActivity().layoutInflater.inflate(R.layout.write_dialog, null)
val writeValueTypeSp = dialogView.findViewById<Spinner>(R.id.writeValueTypeSp)
val spinnerAdapter =
ArrayAdapter(
requireActivity(),
android.R.layout.simple_spinner_dropdown_item,
TLV_MAP.keys.toList()
)
writeValueTypeSp.adapter = spinnerAdapter
val dialog = AlertDialog.Builder(requireContext()).apply { setView(dialogView) }.create()

dialogView.findViewById<Button>(R.id.writeBtn).setOnClickListener {
val writeValue = dialogView.findViewById<EditText>(R.id.writeValueEd).text.toString()
val dataVersion = dialogView.findViewById<EditText>(R.id.dataVersionEd).text.toString()
val timedRequestTimeoutMs =
dialogView.findViewById<EditText>(R.id.timedRequestTimeoutEd).text.toString()
val imTimeout = dialogView.findViewById<EditText>(R.id.imTimeoutEd).text.toString()
scope.launch {
write(
writeValueTypeSp.selectedItem.toString(),
writeValue,
if (dataVersion.isEmpty()) {
null
} else {
dataVersion.toInt()
},
if (timedRequestTimeoutMs.isEmpty()) {
0
} else {
Expand Down Expand Up @@ -547,17 +597,14 @@ class WildcardFragment : Fragment() {
private fun showInvokeDialog() {
binding.outputTv.text = ""
val dialogView = requireActivity().layoutInflater.inflate(R.layout.invoke_dialog, null)
val invokeValueEd = dialogView.findViewById<EditText>(R.id.invokeValueEd)
val dialog = AlertDialog.Builder(requireContext()).apply { setView(dialogView) }.create()

dialogView.findViewById<Button>(R.id.invokeBtn).setOnClickListener {
val invokeValue = invokeValueEd.text.toString()
val timedRequestTimeoutMs =
dialogView.findViewById<EditText>(R.id.timedRequestTimeoutEd).text.toString()
val imTimeout = dialogView.findViewById<EditText>(R.id.imTimeoutEd).text.toString()
scope.launch {
invoke(
invokeValue,
if (timedRequestTimeoutMs.isEmpty()) {
0
} else {
Expand Down Expand Up @@ -684,8 +731,11 @@ class WildcardFragment : Fragment() {

companion object {
private const val TAG = "WildcardFragment"
private const val ATTRIBUTE = 1
private const val EVENT = 2

private enum class SendType {
ATTRIBUTE,
EVENT
}

fun newInstance(): WildcardFragment = WildcardFragment()

Expand Down
Loading

0 comments on commit fce120a

Please sign in to comment.