[3.3.0][Feat]新增状态监控汇总功能

This commit is contained in:
chenfufeng
2023-06-13 22:37:54 +08:00
parent 9f2c713767
commit 204ce4c2ea
29 changed files with 843 additions and 15 deletions

View File

@@ -18,8 +18,11 @@ import com.zhjt.mogo_core_function_devatools.status.entity.IpcStatus
import com.zhjt.mogo_core_function_devatools.status.entity.RTKStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus
import com.zhjt.mogo_core_function_devatools.status.entity.*
//import com.zhjt.mogo_core_function_devatools.status.entity.NetStatus
import com.zhjt.mogo_core_function_devatools.status.model.StatusModel
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
import com.zhjt.mogo_core_function_devatools.status.flow.OverViewImpl
import com.zhjt.mogo_core_function_devatools.status.flow.can.CanImpl
import com.zhjt.mogo_core_function_devatools.status.flow.gps.GpsImpl
import com.zhjt.mogo_core_function_devatools.status.flow.ipc.IpcImpl
@@ -73,6 +76,7 @@ object StatusManager {
is GpsStatus -> GpsImpl(ctx)
is TracingStatus -> TracingImpl(ctx)
is RTKStatus -> RTKImpl(ctx)
is OverViewStatus -> OverViewImpl(ctx)
}
}.also { flows += it }
for (f in flows) {

View File

@@ -1,5 +1,6 @@
package com.zhjt.mogo_core_function_devatools.status.entity
import com.mogo.eagle.core.data.status.StatusSummaryEntity
import com.mogo.eagle.core.function.api.autopilot.*
import com.mogo.eagle.core.function.call.autopilot.*
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing
@@ -228,6 +229,24 @@ class TracingStatus(var state: Tracing = UNKNOWN): Status() {
override fun isException(): Boolean = state.isException()
}
class OverViewStatus(var hasException: Boolean = false): Status() {
override fun isException(): Boolean {
return hasException
}
override fun equals(other: Any?): Boolean {
if (javaClass != other?.javaClass) return false
other as OverViewStatus
if (hasException != other.hasException) return false
return true
}
override fun hashCode(): Int {
return 0
}
}
fun String.toState(msg: String?): Tracing? {
val ss = msg?.split("|")
var extra: Map<String, String>? = null

View File

@@ -0,0 +1,282 @@
package com.zhjt.mogo_core_function_devatools.status.flow
import android.Manifest
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.location.LocationManager
import android.util.Log
import androidx.core.location.LocationManagerCompat
import com.mogo.commons.module.status.IMogoStatusChangedListener
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.module.status.StatusDescriptor
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
import com.mogo.eagle.core.function.api.telematic.IConnectStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsListenerManager
import com.mogo.eagle.core.function.call.telematic.CallerTelematicStatusListenerManager
import com.mogo.eagle.core.utilcode.util.AppStateManager
import com.mogo.eagle.core.utilcode.util.IAppStateListener
import com.mogo.eagle.core.utilcode.util.PermissionUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.zhjt.mogo_core_function_devatools.status.entity.OverViewStatus
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus
import com.zhjt.mogo_core_function_devatools.status.entity.toState
import mogo_msg.MogoReportMsg
import java.util.concurrent.atomic.AtomicBoolean
internal class OverViewImpl(ctx: Context) : IFlow<OverViewStatus>(ctx),
IMoGoDevaToolsListener, IMoGoAutopilotStatusListener,
IConnectStatusListener, IMogoStatusChangedListener {
companion object {
const val TAG = "OverViewImpl"
}
// =====GPS相关=====
private val registered = AtomicBoolean(false)
private var receiver: CheckLocationReceiver? = null
@Volatile
private var isServerException = false
@Volatile
private var isGpsException = false
@Volatile
private var isCloudSocketException = false
@Volatile
private var isTracingException = false
@Volatile
private var isFirst = true
inner class CheckLocationReceiver(private val onClose: ()->Unit, private val onOpen:()-> Unit) : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == LocationManager.MODE_CHANGED_ACTION) {
if (isLocationEnabled()) {
onOpen.invoke()
} else {
onClose.invoke()
}
}
}
}
private val onClose = {
isGpsException = true
send(OverViewStatus(true))
CallerDevaToolsListenerManager.invokeGpsStatus(false)
}
private val onOpen = {
if (!isGrandFineLocation()) {
isGpsException = true
send(OverViewStatus(true))
CallerDevaToolsListenerManager.invokeGpsStatus(false)
} else {
isGpsException = false
checkIfNotException()
CallerDevaToolsListenerManager.invokeGpsStatus(true)
}
}
private fun isGrandFineLocation(): Boolean = try {
PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION)
} catch (t: Throwable) {
t.printStackTrace()
false
}
private val onStateListener = object : IAppStateListener {
override fun onAppStateChanged(isForeground: Boolean) {
if (isForeground) {
val enable = isLocationEnabled()
val grant = isGrandFineLocation()
if (!enable || !grant) {
isGpsException = true
send(OverViewStatus(true))
CallerDevaToolsListenerManager.invokeGpsStatus(false)
} else {
isGpsException = false
checkIfNotException()
CallerDevaToolsListenerManager.invokeGpsStatus(true)
}
}
}
}
override fun onCreate() {
// // 蓝牙魔方状态
// CallerDevaToolsListenerManager.addListener(TAG, this)
// 司机屏Server服务是否开启的状态
CallerTelematicStatusListenerManager.addListener(TAG, this)
// 云socket连接状态
MogoStatusManager.getInstance()
.registerStatusChangedListener(TAG, StatusDescriptor.CLOUD_SOCKET, this)
CallerAutoPilotStatusListenerManager.addListener(TAG, this)
val isGranted = checkIsGpsException()
if (!isGranted) {
PermissionUtils.requestAccessFineLocation(object : PermissionUtils.SimpleCallback {
override fun onGranted() {
Log.d(TAG,"权限: ${Manifest.permission.ACCESS_FINE_LOCATION} 被授予了....")
if (isLocationEnabled()) {
isGpsException = true
send(OverViewStatus(true))
CallerDevaToolsListenerManager.invokeGpsStatus(false)
} else {
isGpsException = false
checkIfNotException()
CallerDevaToolsListenerManager.invokeGpsStatus(true)
}
}
override fun onDenied() {
ToastUtils.showShort("定位权限被拒绝, 可能导致RTK定位不准确请开启~")
isGpsException = true
send(OverViewStatus(true))
CallerDevaToolsListenerManager.invokeGpsStatus(false)
}
})
}
if (registered.compareAndSet(false, true)) {
ctx.registerReceiver(CheckLocationReceiver(onClose, onOpen).also { receiver = it }, IntentFilter().also { it.addAction(LocationManager.MODE_CHANGED_ACTION) })
}
// // 工控机连接状态外层状态栏已显示,先隐藏
// CallerAutoPilotStatusListenerManager.addListener(TAG, this)
}
private fun checkIsGpsException(): Boolean {
val isGranted = isGrandFineLocation()
AppStateManager.registerAppStateListener(onStateListener)
if (isLocationEnabled() && isGranted) {
isGpsException = false
checkIfNotException()
CallerDevaToolsListenerManager.invokeGpsStatus(true)
} else {
isGpsException = true
send(OverViewStatus(true))
CallerDevaToolsListenerManager.invokeGpsStatus(false)
}
return isGranted
}
/**
* App定位是否打开
*/
private fun isLocationEnabled() = LocationManagerCompat.isLocationEnabled(ctx.getSystemService(Context.LOCATION_SERVICE) as LocationManager)
/**
* 魔方状态
*/
override fun mofangStatus(status: Boolean) {
super.mofangStatus(status)
// if (!status) {
// send(OverViewStatus(true))
// }
}
/**
* 司机屏服务是否启动的状态
*/
override fun onServerStatusChanged(isStarted: Boolean) {
super.onServerStatusChanged(isStarted)
if (!isStarted) {
isServerException = true
send(OverViewStatus(true))
} else {
isServerException = false
checkIfNotException()
}
}
/**
* 只监听云Socket状态
*/
override fun onStatusChanged(descriptor: StatusDescriptor?, isTrue: Boolean) {
if (StatusDescriptor.CLOUD_SOCKET == descriptor) {
if (!isTrue) {
isCloudSocketException = true
send(OverViewStatus(true))
} else {
isCloudSocketException = false
checkIfNotException()
}
}
}
/**
* 工控机监控节点
*/
override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) {
super.onAutopilotGuardian(guardianInfo)
val code = guardianInfo?.code
val message = guardianInfo?.msg
val newState = code?.toState(message)
if (newState != null) {
when (newState) {
TracingStatus.Tracing.MAP_DATA_NOT_EXIST, TracingStatus.Tracing.TRACK_NOT_EXIST,
TracingStatus.Tracing.TRACK_LOAD_FAIL, TracingStatus.Tracing.ROUTE_FAILED, TracingStatus.Tracing.UNKNOWN -> {
if (!isTracingException) {
isTracingException = true
send(OverViewStatus(true))
CallerDevaToolsListenerManager.invokeTracingStatus(false)
}
}
TracingStatus.Tracing.MAP_TRA_TYPE, TracingStatus.Tracing.MAP_DATA_EXIST,
TracingStatus.Tracing.TRACK_FINDED, TracingStatus.Tracing.TRACK_LOADED,
TracingStatus.Tracing.ROUTE_LOADED -> {
// 默认是false需要加第一次的判断
if (isFirst || isTracingException) {
isFirst = false
isTracingException = false
// 不加锁,并行时多触发几次可接受
checkIfNotException()
CallerDevaToolsListenerManager.invokeTracingStatus(true)
}
}
}
}
}
private fun checkIfNotException() {
if (!isServerException && !isCloudSocketException && !isTracingException && !isGpsException) {
send(OverViewStatus(false))
}
}
/**
* 工控机连接状态
*/
override fun onAutopilotIpcConnectStatusChanged(status: Int, reason: String?) {
super.onAutopilotIpcConnectStatusChanged(status, reason)
}
override fun onDestroy() {
super.onDestroy()
// CallerDevaToolsListenerManager.removeListener(TAG)
CallerTelematicStatusListenerManager.removeListener(TAG)
MogoStatusManager.getInstance()
.unregisterStatusChangedListener(TAG, StatusDescriptor.CLOUD_SOCKET, this)
CallerAutoPilotStatusListenerManager.removeListener(TAG)
// CallerAutoPilotStatusListenerManager.removeListener(TAG)
try {
if (registered.compareAndSet(true, false) && receiver != null) {
ctx.unregisterReceiver(receiver)
}
} catch (t: Throwable) {
t.printStackTrace()
}
AppStateManager.unRegisterAppStateListener(onStateListener)
}
}

View File

@@ -2,13 +2,8 @@ package com.zhjt.mogo_core_function_devatools.status.model
import androidx.lifecycle.*
import com.mogo.eagle.core.function.call.autopilot.*
import com.zhjt.mogo_core_function_devatools.status.entity.CanStatus
import com.zhjt.mogo_core_function_devatools.status.entity.GpsStatus
import com.zhjt.mogo_core_function_devatools.status.entity.IpcStatus
import com.zhjt.mogo_core_function_devatools.status.entity.*
//import com.zhjt.mogo_core_function_devatools.status.entity.NetStatus
import com.zhjt.mogo_core_function_devatools.status.entity.RTKStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.UNKNOWN
import java.util.concurrent.atomic.*
import kotlin.Pair
@@ -19,11 +14,13 @@ internal class StatusModel : ViewModel() {
const val TAG = "StatusModel"
val DEFAULTS = Pair(null, ArrayList<Status>().also {
it += OverViewStatus()
it += IpcStatus(CallerAutoPilotControlManager.isConnected())
it += CanStatus(false)
it += TracingStatus(UNKNOWN)
// it += TracingStatus(UNKNOWN)
it += RTKStatus("", -1)
it += GpsStatus(enabled = false, isGranted = false)
// it += NetStatus(false)
// it += GpsStatus(enabled = false, isGranted = false)
})
}

View File

@@ -0,0 +1,34 @@
package com.zhjt.mogo_core_function_devatools.status.ui
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.zhjt.mogo_core_function_devatools.R
/**
* 状态汇总View控件
*/
class StatusSummaryView@JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(
context,
attrs,
defStyleAttr
), IMoGoAutopilotStatusListener {
companion object{
private const val TAG = "SummaryStatusView"
}
init {
LayoutInflater.from(context).inflate(R.layout.view_initiative_bad_case, this, true)
initView()
}
private fun initView() {
}
}

View File

@@ -5,6 +5,7 @@ import android.view.*
import android.widget.*
import androidx.core.content.*
import androidx.recyclerview.widget.*
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.mogo.logger.*
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_DEVA
@@ -15,6 +16,7 @@ import com.zhjt.mogo_core_function_devatools.status.entity.*
import com.zhjt.mogo_core_function_devatools.status.entity.IpcStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus.Tracing.*
import com.zhjt.mogo_core_function_devatools.status.ui.StatusSummaryView
import com.zhjt.mogo_core_function_devatools.status.ui.adapter.StatusAdapter.StatusViewHolder
internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): RecyclerView.Adapter<StatusViewHolder>() {
@@ -39,9 +41,12 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
}
fun bind(status: Status) {
// itemView.onClick {
itemView.onClick {
// ToastUtils.showShort(getText(status))
// }
if (status is OverViewStatus) {
CallerHmiManager.showStatusSummaryDialog()
}
}
when(status) {
is IpcStatus -> {
if (status.enabled) {
@@ -99,6 +104,15 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_rtk_unknow)
}
}
is OverViewStatus -> {
if (status.hasException) {
iv.scaleType = ImageView.ScaleType.FIT_CENTER
iv.setImageResource(drawable.icon_red_warning)
} else {
iv.scaleType = ImageView.ScaleType.FIT_CENTER
iv.setImageResource(drawable.icon_grey_warning)
}
}
}
}
@@ -140,6 +154,9 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
UNKNOWN -> "暂无轨迹"
}
}
is OverViewStatus -> {
""
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B