fix: 优化接待任务逻辑并修复门控工作流配置刷新

- 减少重置当前任务的动作集合,仅对显式导航/终止命令中断任务
- 修复接待任务中空位置导致任务异常的问题,增加参数校验与默认值处理
- 优化接待任务中位置匹配逻辑,忽略前后空格并修正状态处理流程
- 修复门控工作流执行时配置缺失的问题,添加服务器配置刷新机制
This commit is contained in:
2026-04-21 11:11:15 +08:00
parent 7d28490cec
commit d5ca5966f4
3 changed files with 70 additions and 16 deletions

View File

@@ -99,6 +99,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
private var autoRechargeJob: Job? = null
private var latestYaw: Float? = null
private var receptionAnchorYaw: Float? = null
private var lastWorkflowConfigRefreshAt: Long = 0L
private lateinit var telemetryManager: TelemetryManager
private lateinit var taskController: TaskController
private val robotEventHandler = RobotEventHandler()
@@ -800,10 +801,19 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
private suspend fun executeDoorWorkflow(openDoor: Boolean): String? {
val workflowIdKey = if (openDoor) HttpManager.PREF_KEY_OD_WFID else HttpManager.PREF_KEY_CD_WFID
val workflowApiKey = if (openDoor) HttpManager.PREF_KEY_OD_WF_KEY else HttpManager.PREF_KEY_CD_WF_KEY
val workflowId = prefs.getString(workflowIdKey, "").orEmpty().trim()
val apiKey = prefs.getString(workflowApiKey, "").orEmpty().trim()
var workflowId = prefs.getString(workflowIdKey, "").orEmpty().trim()
var apiKey = prefs.getString(workflowApiKey, "").orEmpty().trim()
if (workflowId.isEmpty() || apiKey.isEmpty()) {
Log.w("MainActivity", "Door workflow config missing: openDoor=$openDoor")
refreshWorkflowConfigsIfNeeded()
workflowId = prefs.getString(workflowIdKey, "").orEmpty().trim()
apiKey = prefs.getString(workflowApiKey, "").orEmpty().trim()
}
if (workflowId.isEmpty() || apiKey.isEmpty()) {
Log.w(
"MainActivity",
"Door workflow config missing after refresh: openDoor=$openDoor, " +
"workflowIdKey=$workflowIdKey, workflowApiKey=$workflowApiKey"
)
return null
}
return HttpManager.workflow_execute(
@@ -814,6 +824,37 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
)
}
private suspend fun refreshWorkflowConfigsIfNeeded() {
val now = System.currentTimeMillis()
if (now - lastWorkflowConfigRefreshAt < 5000L) {
return
}
lastWorkflowConfigRefreshAt = now
val runtimeConfigs = HttpManager.fetchRuntimeConfigs(this@MainActivity) ?: return
val workflowKeys = listOf(
HttpManager.PREF_KEY_OD_WFID,
HttpManager.PREF_KEY_OD_WF_KEY,
HttpManager.PREF_KEY_CD_WFID,
HttpManager.PREF_KEY_CD_WF_KEY
)
val editor = prefs.edit()
var changed = false
for (key in workflowKeys) {
val value = runtimeConfigs[key]?.trim().orEmpty()
if (value.isEmpty()) {
continue
}
if (prefs.getString(key, "").orEmpty() != value) {
editor.putString(key, value)
changed = true
}
}
if (changed) {
editor.apply()
Log.i("MainActivity", "Workflow configs refreshed from server.")
}
}
private fun isActivated(): Boolean {
if (!::prefs.isInitialized) {
return false

View File

@@ -313,7 +313,8 @@ class MqttManager(
private fun handleJsonCommand(obj: JSONObject) {
val action = obj.optString("action", obj.optString("cmd", obj.optString("type", ""))).lowercase()
val actionsResetTask = setOf("recharge", "goto", "notification", "reception", "patrol", "repose", "turn", "tilt", "terminate")
// Only interrupt current task for explicit navigation/termination commands.
val actionsResetTask = setOf("recharge", "goto", "terminate")
if (action in actionsResetTask) {
scope.launch(Dispatchers.Main) {
onSetCurrentTask("")
@@ -424,9 +425,9 @@ class MqttManager(
}
"reception" -> {
speak("接到接待任务", "zh")
val location = obj.optString("location", "前台")
val text = obj.optString("text", "你是我要接待的贵宾吗?")
val destination = obj.optString("destination", "会议室")
val location = obj.optString("location", "前台").trim()
val text = obj.optString("text", "你是我要接待的贵宾吗?").trim()
val destination = obj.optString("destination", "会议室").trim()
scope.launch(Dispatchers.Main) {
onStartReceptionMode(location, text, destination)
}

View File

@@ -120,14 +120,21 @@ class TaskController(
}
fun startReceptionMode(location: String, text: String, destination: String) {
val targetLocation = location.trim()
val promptText = text.trim()
val targetDestination = destination.trim()
if (targetLocation.isEmpty()) {
setCurrentTask("")
return
}
setCurrentTask("reception")
receptionLocation = location
receptionText = text
receptionDestination = destination
receptionLocation = targetLocation
receptionText = promptText.ifEmpty { "你是我要接待的贵宾吗?" }
receptionDestination = targetDestination
isReceptionPromptVisible = false
setReceptionButtonVisible(false)
if (getLastArrivalLocation() != location) {
navController.goTo(location, false)
if (getLastArrivalLocation()?.trim()?.equals(targetLocation, ignoreCase = true) != true) {
navController.goTo(targetLocation, false)
} else {
startTaskWaitTimeout()
}
@@ -177,9 +184,13 @@ class TaskController(
speak("别妨碍我,我正在巡逻呢")
return true
}
if (currentTask == "reception" &&
getLastArrivalLocation()?.equals(receptionLocation, ignoreCase = true) == true
) {
if (currentTask == "reception") {
val isAtReceptionLocation = getLastArrivalLocation()?.trim()
?.equals(receptionLocation, ignoreCase = true) == true
if (!isAtReceptionLocation) {
// Not at reception spot yet, let upper layer continue default behavior.
return false
}
when (state) {
DETECTED -> {
startTaskWaitTimeout()
@@ -194,8 +205,9 @@ class TaskController(
setReceptionButtonVisible(false)
}
}
return true
}
return currentTask == "reception"
return false
}
fun endNonSpecialTask(reason: String) {