feat: 添加接待返回工作流支持
- 新增 VR 工作流配置键常量,用于存储接待返回工作流的 ID 和 API 密钥 - 在设置页面同步添加 VR 工作流的清除、获取与保存逻辑 - 重构门控工作流执行函数,使其通用化以支持接待返回工作流 - 当接待任务完成并返回基站时,自动触发接待返回工作流执行
This commit is contained in:
@@ -25,6 +25,8 @@ object HttpManager {
|
|||||||
const val PREF_KEY_OD_WF_KEY = "od_wf_key"
|
const val PREF_KEY_OD_WF_KEY = "od_wf_key"
|
||||||
const val PREF_KEY_CD_WFID = "cd_wfid"
|
const val PREF_KEY_CD_WFID = "cd_wfid"
|
||||||
const val PREF_KEY_CD_WF_KEY = "cd_wf_key"
|
const val PREF_KEY_CD_WF_KEY = "cd_wf_key"
|
||||||
|
const val PREF_KEY_VR_WFID = "vr_wfid"
|
||||||
|
const val PREF_KEY_VR_WF_KEY = "vr_wf_key"
|
||||||
|
|
||||||
fun getBaseUrl(context: Context): String {
|
fun getBaseUrl(context: Context): String {
|
||||||
val prefs = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
|
val prefs = context.getSharedPreferences("app_prefs", Context.MODE_PRIVATE)
|
||||||
@@ -98,6 +100,8 @@ object HttpManager {
|
|||||||
.put(PREF_KEY_OD_WF_KEY)
|
.put(PREF_KEY_OD_WF_KEY)
|
||||||
.put(PREF_KEY_CD_WFID)
|
.put(PREF_KEY_CD_WFID)
|
||||||
.put(PREF_KEY_CD_WF_KEY)
|
.put(PREF_KEY_CD_WF_KEY)
|
||||||
|
.put(PREF_KEY_VR_WFID)
|
||||||
|
.put(PREF_KEY_VR_WF_KEY)
|
||||||
.put(PREF_KEY_MQTT_PASSWORD)
|
.put(PREF_KEY_MQTT_PASSWORD)
|
||||||
val response = postJsonArray(context, "/system/config/getConfig", body, token)
|
val response = postJsonArray(context, "/system/config/getConfig", body, token)
|
||||||
if (response == null) {
|
if (response == null) {
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ import kotlinx.coroutines.isActive
|
|||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
import javax.crypto.Mac
|
import javax.crypto.Mac
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
|
||||||
@@ -99,6 +102,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
|
|||||||
private var autoRechargeJob: Job? = null
|
private var autoRechargeJob: Job? = null
|
||||||
private var latestYaw: Float? = null
|
private var latestYaw: Float? = null
|
||||||
private var receptionAnchorYaw: Float? = null
|
private var receptionAnchorYaw: Float? = null
|
||||||
|
private var pendingReceptionReturnWorkflow: Boolean = false
|
||||||
private var lastWorkflowConfigRefreshAt: Long = 0L
|
private var lastWorkflowConfigRefreshAt: Long = 0L
|
||||||
private lateinit var telemetryManager: TelemetryManager
|
private lateinit var telemetryManager: TelemetryManager
|
||||||
private lateinit var taskController: TaskController
|
private lateinit var taskController: TaskController
|
||||||
@@ -232,6 +236,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
|
|||||||
if (destination.isNullOrBlank()) {
|
if (destination.isNullOrBlank()) {
|
||||||
return@setOnClickListener
|
return@setOnClickListener
|
||||||
}
|
}
|
||||||
|
pendingReceptionReturnWorkflow = true
|
||||||
val ttsRequest = TtsRequest.create("接待任务确认,请跟我来", false, language = TtsRequest.Language.ZH_CN)
|
val ttsRequest = TtsRequest.create("接待任务确认,请跟我来", false, language = TtsRequest.Language.ZH_CN)
|
||||||
robot.speak(ttsRequest)
|
robot.speak(ttsRequest)
|
||||||
navCon.goTo(destination, false)
|
navCon.goTo(destination, false)
|
||||||
@@ -404,6 +409,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
|
|||||||
prefs.edit().putString("current_location", location).apply()
|
prefs.edit().putString("current_location", location).apply()
|
||||||
if (robotEventHandler.normalizeLocation(location) == "homebase") {
|
if (robotEventHandler.normalizeLocation(location) == "homebase") {
|
||||||
navCon.tiltAngle(20)
|
navCon.tiltAngle(20)
|
||||||
|
triggerReceptionReturnWorkflowIfNeeded(location)
|
||||||
}
|
}
|
||||||
if (taskController.currentTask == "patrol") {
|
if (taskController.currentTask == "patrol") {
|
||||||
taskController.handlePatrolArrival(location)
|
taskController.handlePatrolArrival(location)
|
||||||
@@ -801,6 +807,16 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
|
|||||||
private suspend fun executeDoorWorkflow(openDoor: Boolean): String? {
|
private suspend fun executeDoorWorkflow(openDoor: Boolean): String? {
|
||||||
val workflowIdKey = if (openDoor) HttpManager.PREF_KEY_OD_WFID else HttpManager.PREF_KEY_CD_WFID
|
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 workflowApiKey = if (openDoor) HttpManager.PREF_KEY_OD_WF_KEY else HttpManager.PREF_KEY_CD_WF_KEY
|
||||||
|
val workflowName = if (openDoor) "open-door" else "close-door"
|
||||||
|
return executeConfiguredWorkflow(workflowIdKey, workflowApiKey, workflowName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun executeConfiguredWorkflow(
|
||||||
|
workflowIdKey: String,
|
||||||
|
workflowApiKey: String,
|
||||||
|
workflowName: String,
|
||||||
|
inputs: Any = emptyMap<String, Any>()
|
||||||
|
): String? {
|
||||||
var workflowId = prefs.getString(workflowIdKey, "").orEmpty().trim()
|
var workflowId = prefs.getString(workflowIdKey, "").orEmpty().trim()
|
||||||
var apiKey = prefs.getString(workflowApiKey, "").orEmpty().trim()
|
var apiKey = prefs.getString(workflowApiKey, "").orEmpty().trim()
|
||||||
if (workflowId.isEmpty() || apiKey.isEmpty()) {
|
if (workflowId.isEmpty() || apiKey.isEmpty()) {
|
||||||
@@ -811,7 +827,7 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
|
|||||||
if (workflowId.isEmpty() || apiKey.isEmpty()) {
|
if (workflowId.isEmpty() || apiKey.isEmpty()) {
|
||||||
Log.w(
|
Log.w(
|
||||||
"MainActivity",
|
"MainActivity",
|
||||||
"Door workflow config missing after refresh: openDoor=$openDoor, " +
|
"Workflow config missing after refresh: workflow=$workflowName, " +
|
||||||
"workflowIdKey=$workflowIdKey, workflowApiKey=$workflowApiKey"
|
"workflowIdKey=$workflowIdKey, workflowApiKey=$workflowApiKey"
|
||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
@@ -820,10 +836,33 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
|
|||||||
context = this@MainActivity,
|
context = this@MainActivity,
|
||||||
apiKey = apiKey,
|
apiKey = apiKey,
|
||||||
workflowId = workflowId,
|
workflowId = workflowId,
|
||||||
inputs = emptyMap<String, Any>()
|
inputs = inputs
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun triggerReceptionReturnWorkflowIfNeeded(location: String) {
|
||||||
|
if (!pendingReceptionReturnWorkflow) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (robotEventHandler.normalizeLocation(location) != "homebase") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pendingReceptionReturnWorkflow = false
|
||||||
|
mainScope.launch {
|
||||||
|
val nowText = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date())
|
||||||
|
val inputs = mapOf("flag" to nowText)
|
||||||
|
val result = executeConfiguredWorkflow(
|
||||||
|
workflowIdKey = HttpManager.PREF_KEY_VR_WFID,
|
||||||
|
workflowApiKey = HttpManager.PREF_KEY_VR_WF_KEY,
|
||||||
|
workflowName = "reception-return-home",
|
||||||
|
inputs = inputs
|
||||||
|
)
|
||||||
|
if (result == null) {
|
||||||
|
showNetworkErrorBanner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun refreshWorkflowConfigsIfNeeded() {
|
private suspend fun refreshWorkflowConfigsIfNeeded() {
|
||||||
val now = System.currentTimeMillis()
|
val now = System.currentTimeMillis()
|
||||||
if (now - lastWorkflowConfigRefreshAt < 5000L) {
|
if (now - lastWorkflowConfigRefreshAt < 5000L) {
|
||||||
@@ -835,7 +874,9 @@ class MainActivity : AppCompatActivity(), OnRobotReadyListener, TtsListener, OnG
|
|||||||
HttpManager.PREF_KEY_OD_WFID,
|
HttpManager.PREF_KEY_OD_WFID,
|
||||||
HttpManager.PREF_KEY_OD_WF_KEY,
|
HttpManager.PREF_KEY_OD_WF_KEY,
|
||||||
HttpManager.PREF_KEY_CD_WFID,
|
HttpManager.PREF_KEY_CD_WFID,
|
||||||
HttpManager.PREF_KEY_CD_WF_KEY
|
HttpManager.PREF_KEY_CD_WF_KEY,
|
||||||
|
HttpManager.PREF_KEY_VR_WFID,
|
||||||
|
HttpManager.PREF_KEY_VR_WF_KEY
|
||||||
)
|
)
|
||||||
val editor = prefs.edit()
|
val editor = prefs.edit()
|
||||||
var changed = false
|
var changed = false
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
.remove(HttpManager.PREF_KEY_OD_WF_KEY)
|
.remove(HttpManager.PREF_KEY_OD_WF_KEY)
|
||||||
.remove(HttpManager.PREF_KEY_CD_WFID)
|
.remove(HttpManager.PREF_KEY_CD_WFID)
|
||||||
.remove(HttpManager.PREF_KEY_CD_WF_KEY)
|
.remove(HttpManager.PREF_KEY_CD_WF_KEY)
|
||||||
|
.remove(HttpManager.PREF_KEY_VR_WFID)
|
||||||
|
.remove(HttpManager.PREF_KEY_VR_WF_KEY)
|
||||||
binding.etActivationCode.setText("")
|
binding.etActivationCode.setText("")
|
||||||
binding.etDeviceName.setText("")
|
binding.etDeviceName.setText("")
|
||||||
updateActivationUi(false)
|
updateActivationUi(false)
|
||||||
@@ -154,8 +156,15 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
val odWfKey = runtimeConfigs?.get(HttpManager.PREF_KEY_OD_WF_KEY).orEmpty()
|
val odWfKey = runtimeConfigs?.get(HttpManager.PREF_KEY_OD_WF_KEY).orEmpty()
|
||||||
val cdWfid = runtimeConfigs?.get(HttpManager.PREF_KEY_CD_WFID).orEmpty()
|
val cdWfid = runtimeConfigs?.get(HttpManager.PREF_KEY_CD_WFID).orEmpty()
|
||||||
val cdWfKey = runtimeConfigs?.get(HttpManager.PREF_KEY_CD_WF_KEY).orEmpty()
|
val cdWfKey = runtimeConfigs?.get(HttpManager.PREF_KEY_CD_WF_KEY).orEmpty()
|
||||||
|
val vrWfid = runtimeConfigs?.get(HttpManager.PREF_KEY_VR_WFID).orEmpty()
|
||||||
|
val vrWfKey = runtimeConfigs?.get(HttpManager.PREF_KEY_VR_WF_KEY).orEmpty()
|
||||||
val mqttReady = mqttUser.isNotBlank() && mqttPass.isNotBlank()
|
val mqttReady = mqttUser.isNotBlank() && mqttPass.isNotBlank()
|
||||||
val workflowReady = odWfid.isNotBlank() && odWfKey.isNotBlank() && cdWfid.isNotBlank() && cdWfKey.isNotBlank()
|
val workflowReady = odWfid.isNotBlank() &&
|
||||||
|
odWfKey.isNotBlank() &&
|
||||||
|
cdWfid.isNotBlank() &&
|
||||||
|
cdWfKey.isNotBlank() &&
|
||||||
|
vrWfid.isNotBlank() &&
|
||||||
|
vrWfKey.isNotBlank()
|
||||||
val configReady = mqttReady && workflowReady
|
val configReady = mqttReady && workflowReady
|
||||||
val editor = prefs.edit()
|
val editor = prefs.edit()
|
||||||
.putString(HttpManager.PREF_KEY_ACTIVATION_CODE, activationCode)
|
.putString(HttpManager.PREF_KEY_ACTIVATION_CODE, activationCode)
|
||||||
@@ -168,6 +177,8 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
.putString(HttpManager.PREF_KEY_OD_WF_KEY, odWfKey)
|
.putString(HttpManager.PREF_KEY_OD_WF_KEY, odWfKey)
|
||||||
.putString(HttpManager.PREF_KEY_CD_WFID, cdWfid)
|
.putString(HttpManager.PREF_KEY_CD_WFID, cdWfid)
|
||||||
.putString(HttpManager.PREF_KEY_CD_WF_KEY, cdWfKey)
|
.putString(HttpManager.PREF_KEY_CD_WF_KEY, cdWfKey)
|
||||||
|
.putString(HttpManager.PREF_KEY_VR_WFID, vrWfid)
|
||||||
|
.putString(HttpManager.PREF_KEY_VR_WF_KEY, vrWfKey)
|
||||||
editor.apply()
|
editor.apply()
|
||||||
updateActivationUi(true)
|
updateActivationUi(true)
|
||||||
if (!configReady) {
|
if (!configReady) {
|
||||||
|
|||||||
Reference in New Issue
Block a user