diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java new file mode 100644 index 0000000..5980048 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java @@ -0,0 +1,85 @@ +package com.casic.br.ktd.model; + +import java.util.List; + +public class AlarmRuleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String deviceId; + private int high; + private String ts; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public int getHigh() { + return high; + } + + public void setHigh(int high) { + this.high = high; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java new file mode 100644 index 0000000..5980048 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java @@ -0,0 +1,85 @@ +package com.casic.br.ktd.model; + +import java.util.List; + +public class AlarmRuleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String deviceId; + private int high; + private String ts; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public int getHigh() { + return high; + } + + public void setHigh(int high) { + this.high = high; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt index e375c35..ced6d54 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt @@ -64,7 +64,35 @@ * 获取巡检任务列表 */ @POST("/system/busPatrolCar/listPage") - suspend fun getVehiclesByPage( + suspend fun getVehicles( + @Header("token") token: String, + @QueryMap limit: Map, + @QueryMap offset: Map, + ): String + + /** + * 新增巡检过程点详情 + */ + @POST("/system/busPatrolTrack/add") + suspend fun uploadPointDetail( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 新增报警规则,主要是阈值 + */ + @POST("/system/alarmRule/add") + suspend fun addAlarmRule( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 获取巡检任务列表 + */ + @POST("/system/alarmRule/listPage") + suspend fun getAlarmRules( @Header("token") token: String, @QueryMap limit: Map, @QueryMap offset: Map, diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java new file mode 100644 index 0000000..5980048 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java @@ -0,0 +1,85 @@ +package com.casic.br.ktd.model; + +import java.util.List; + +public class AlarmRuleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String deviceId; + private int high; + private String ts; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public int getHigh() { + return high; + } + + public void setHigh(int high) { + this.high = high; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt index e375c35..ced6d54 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt @@ -64,7 +64,35 @@ * 获取巡检任务列表 */ @POST("/system/busPatrolCar/listPage") - suspend fun getVehiclesByPage( + suspend fun getVehicles( + @Header("token") token: String, + @QueryMap limit: Map, + @QueryMap offset: Map, + ): String + + /** + * 新增巡检过程点详情 + */ + @POST("/system/busPatrolTrack/add") + suspend fun uploadPointDetail( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 新增报警规则,主要是阈值 + */ + @POST("/system/alarmRule/add") + suspend fun addAlarmRule( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 获取巡检任务列表 + */ + @POST("/system/alarmRule/listPage") + suspend fun getAlarmRules( @Header("token") token: String, @QueryMap limit: Map, @QueryMap offset: Map, diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt index 2cc5a36..82e55ae 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt @@ -113,12 +113,70 @@ /** * 获取巡检车列表 */ - suspend fun getVehiclesByPage(offset: Int): String { + suspend fun getVehicles(): String { val limitMap = HashMap() limitMap["limit"] = LocaleConstant.PAGE_LIMIT val offsetMap = HashMap() - offsetMap["offset"] = offset - return api.getVehiclesByPage(AuthenticationHelper.token, limitMap, offsetMap) + offsetMap["offset"] = 1 + return api.getVehicles(AuthenticationHelper.token, limitMap, offsetMap) + } + + /** + * 新增巡检过程点详情 + */ + suspend fun uploadPointDetail( + isAlarm: String, + lagitude: String, + gas: String, + pitch: String, + position: String, + speed: String, + deviceStatus: String, + direction: String, + longitude: String, + ts: String + ): String { + val param = JsonObject() + param.addProperty("isAlarm", isAlarm) + param.addProperty("lagitude", lagitude) + param.addProperty("gas", gas) + param.addProperty("pitch", pitch) + param.addProperty("position", position) + param.addProperty("speed", speed) + param.addProperty("deviceStatus", deviceStatus) + param.addProperty("direction", direction) + param.addProperty("longitude", longitude) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.uploadPointDetail(AuthenticationHelper.token, requestBody) + } + + /** + * 新增报警规则,主要是阈值 + */ + suspend fun addAlarmRule(high: String, deviceId: String, ts: String): String { + val param = JsonObject() + param.addProperty("high", high) + param.addProperty("deviceId", deviceId) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addAlarmRule(AuthenticationHelper.token, requestBody) + } + + /** + * 获取巡检车列表 + */ + suspend fun getAlarmRules(): String { + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = 1 + return api.getAlarmRules(AuthenticationHelper.token, limitMap, offsetMap) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java new file mode 100644 index 0000000..5980048 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java @@ -0,0 +1,85 @@ +package com.casic.br.ktd.model; + +import java.util.List; + +public class AlarmRuleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String deviceId; + private int high; + private String ts; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public int getHigh() { + return high; + } + + public void setHigh(int high) { + this.high = high; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt index e375c35..ced6d54 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt @@ -64,7 +64,35 @@ * 获取巡检任务列表 */ @POST("/system/busPatrolCar/listPage") - suspend fun getVehiclesByPage( + suspend fun getVehicles( + @Header("token") token: String, + @QueryMap limit: Map, + @QueryMap offset: Map, + ): String + + /** + * 新增巡检过程点详情 + */ + @POST("/system/busPatrolTrack/add") + suspend fun uploadPointDetail( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 新增报警规则,主要是阈值 + */ + @POST("/system/alarmRule/add") + suspend fun addAlarmRule( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 获取巡检任务列表 + */ + @POST("/system/alarmRule/listPage") + suspend fun getAlarmRules( @Header("token") token: String, @QueryMap limit: Map, @QueryMap offset: Map, diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt index 2cc5a36..82e55ae 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt @@ -113,12 +113,70 @@ /** * 获取巡检车列表 */ - suspend fun getVehiclesByPage(offset: Int): String { + suspend fun getVehicles(): String { val limitMap = HashMap() limitMap["limit"] = LocaleConstant.PAGE_LIMIT val offsetMap = HashMap() - offsetMap["offset"] = offset - return api.getVehiclesByPage(AuthenticationHelper.token, limitMap, offsetMap) + offsetMap["offset"] = 1 + return api.getVehicles(AuthenticationHelper.token, limitMap, offsetMap) + } + + /** + * 新增巡检过程点详情 + */ + suspend fun uploadPointDetail( + isAlarm: String, + lagitude: String, + gas: String, + pitch: String, + position: String, + speed: String, + deviceStatus: String, + direction: String, + longitude: String, + ts: String + ): String { + val param = JsonObject() + param.addProperty("isAlarm", isAlarm) + param.addProperty("lagitude", lagitude) + param.addProperty("gas", gas) + param.addProperty("pitch", pitch) + param.addProperty("position", position) + param.addProperty("speed", speed) + param.addProperty("deviceStatus", deviceStatus) + param.addProperty("direction", direction) + param.addProperty("longitude", longitude) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.uploadPointDetail(AuthenticationHelper.token, requestBody) + } + + /** + * 新增报警规则,主要是阈值 + */ + suspend fun addAlarmRule(high: String, deviceId: String, ts: String): String { + val param = JsonObject() + param.addProperty("high", high) + param.addProperty("deviceId", deviceId) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addAlarmRule(AuthenticationHelper.token, requestBody) + } + + /** + * 获取巡检车列表 + */ + suspend fun getAlarmRules(): String { + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = 1 + return api.getAlarmRules(AuthenticationHelper.token, limitMap, offsetMap) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt index 8028354..1d37485 100644 --- a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt @@ -31,7 +31,7 @@ * ============================================================================================= * */ //数据接收频率 - const val DATA_TIMER_PERIOD = 1000L + const val DATA_TIMER_PERIOD = 2000L /** * ============================================================================================= @@ -44,6 +44,8 @@ const val SERVER_BASE_URL = "http://111.198.10.15:11646" const val CAR_NUMBER = "carNumber" const val CAR_ID = "carId" + const val ALARM_RULE = "alarmRule" + const val YT_DEVICE_ID = "deviceId" //海康摄像头参数 const val HK_NET_IP = "192.168.1.64" diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java new file mode 100644 index 0000000..5980048 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java @@ -0,0 +1,85 @@ +package com.casic.br.ktd.model; + +import java.util.List; + +public class AlarmRuleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String deviceId; + private int high; + private String ts; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public int getHigh() { + return high; + } + + public void setHigh(int high) { + this.high = high; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt index e375c35..ced6d54 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt @@ -64,7 +64,35 @@ * 获取巡检任务列表 */ @POST("/system/busPatrolCar/listPage") - suspend fun getVehiclesByPage( + suspend fun getVehicles( + @Header("token") token: String, + @QueryMap limit: Map, + @QueryMap offset: Map, + ): String + + /** + * 新增巡检过程点详情 + */ + @POST("/system/busPatrolTrack/add") + suspend fun uploadPointDetail( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 新增报警规则,主要是阈值 + */ + @POST("/system/alarmRule/add") + suspend fun addAlarmRule( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 获取巡检任务列表 + */ + @POST("/system/alarmRule/listPage") + suspend fun getAlarmRules( @Header("token") token: String, @QueryMap limit: Map, @QueryMap offset: Map, diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt index 2cc5a36..82e55ae 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt @@ -113,12 +113,70 @@ /** * 获取巡检车列表 */ - suspend fun getVehiclesByPage(offset: Int): String { + suspend fun getVehicles(): String { val limitMap = HashMap() limitMap["limit"] = LocaleConstant.PAGE_LIMIT val offsetMap = HashMap() - offsetMap["offset"] = offset - return api.getVehiclesByPage(AuthenticationHelper.token, limitMap, offsetMap) + offsetMap["offset"] = 1 + return api.getVehicles(AuthenticationHelper.token, limitMap, offsetMap) + } + + /** + * 新增巡检过程点详情 + */ + suspend fun uploadPointDetail( + isAlarm: String, + lagitude: String, + gas: String, + pitch: String, + position: String, + speed: String, + deviceStatus: String, + direction: String, + longitude: String, + ts: String + ): String { + val param = JsonObject() + param.addProperty("isAlarm", isAlarm) + param.addProperty("lagitude", lagitude) + param.addProperty("gas", gas) + param.addProperty("pitch", pitch) + param.addProperty("position", position) + param.addProperty("speed", speed) + param.addProperty("deviceStatus", deviceStatus) + param.addProperty("direction", direction) + param.addProperty("longitude", longitude) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.uploadPointDetail(AuthenticationHelper.token, requestBody) + } + + /** + * 新增报警规则,主要是阈值 + */ + suspend fun addAlarmRule(high: String, deviceId: String, ts: String): String { + val param = JsonObject() + param.addProperty("high", high) + param.addProperty("deviceId", deviceId) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addAlarmRule(AuthenticationHelper.token, requestBody) + } + + /** + * 获取巡检车列表 + */ + suspend fun getAlarmRules(): String { + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = 1 + return api.getAlarmRules(AuthenticationHelper.token, limitMap, offsetMap) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt index 8028354..1d37485 100644 --- a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt @@ -31,7 +31,7 @@ * ============================================================================================= * */ //数据接收频率 - const val DATA_TIMER_PERIOD = 1000L + const val DATA_TIMER_PERIOD = 2000L /** * ============================================================================================= @@ -44,6 +44,8 @@ const val SERVER_BASE_URL = "http://111.198.10.15:11646" const val CAR_NUMBER = "carNumber" const val CAR_ID = "carId" + const val ALARM_RULE = "alarmRule" + const val YT_DEVICE_ID = "deviceId" //海康摄像头参数 const val HK_NET_IP = "192.168.1.64" diff --git a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt index bfe09d8..aad5658 100644 --- a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt +++ b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt @@ -35,6 +35,7 @@ import com.casic.br.ktd.utils.LoadingDialogHub import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.utils.LocationHelper +import com.casic.br.ktd.vm.PointViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.LineChartMarkerView @@ -114,10 +115,18 @@ private lateinit var aMap: AMap private lateinit var uiSettings: UiSettings private lateinit var taskViewModel: TaskViewModel + private lateinit var pointViewModel: PointViewModel private lateinit var taskParam: TaskParam private var carId = "" private var taskTitle = "" private var beginDate = "" + private var dataModel: SensorDataModel? = null + + //1:报警,0:正常 + private var isAlarm = "0" + + //甲烷浓度阈值 + private var gasAlarmRule = 1000 /** * 协程配置云台设备,缓解新进页面较卡的问题 @@ -152,9 +161,11 @@ PageNavigationManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] + pointViewModel = ViewModelProvider(this)[PointViewModel::class.java] taskTitle = intent.getStringExtra(Constant.INTENT_PARAM).toString() carId = SaveKeyValues.getValue(LocaleConstant.CAR_ID, "") as String + gasAlarmRule = SaveKeyValues.getValue(LocaleConstant.ALARM_RULE, 1000) as Int /** * 配置云台设备 @@ -231,8 +242,26 @@ //发送位置信息给UDP服务端 udpClient.send("${aMapLocation.longitude}, ${aMapLocation.latitude}") + //上传经纬度以及甲烷浓度 + val deviceStatus = if (dataModel?.methaneState == "正常") { + "1" + } else { + "0" + } + pointViewModel.uploadPointDetail( + isAlarm, + aMapLocation.latitude.toString(), + dataModel?.methane.toString(), + dataModel?.vertical.toString(), + "", + aMapLocation.speed.toString(), + deviceStatus, + dataModel?.horizontal.toString(), + aMapLocation.longitude.toString(), + System.currentTimeMillis().timestampToCompleteDate() + ) + //速度 转为 km/h - Log.d(kTag, "onLocationGet => 速度:${aMapLocation.speed}") speed = decimalFormat.format(aMapLocation.speed * 3.6).toFloat() carSpeedView.text = String.format("${speed}Km/h") @@ -747,60 +776,71 @@ return } val deviceJson = intent.getStringExtra(Constant.BROADCAST_INTENT_DATA_KEY) - val dataModel = gson.fromJson( + dataModel = gson.fromJson( deviceJson, object : TypeToken() {}.type ) - sensorStateView.text = dataModel.methaneState - if (dataModel.methaneState == "正常") { - sensorStateView.setTextColor(Color.GREEN) - } else { - sensorStateView.setTextColor(Color.RED) + + if (dataModel != null) { + sensorStateView.text = dataModel!!.methaneState + if (dataModel!!.methaneState == "正常") { + sensorStateView.setTextColor(Color.GREEN) + } else { + sensorStateView.setTextColor(Color.RED) + } + val degree = resources.getString(R.string.degree) + horizontalDegreeView.text = String.format("${dataModel!!.horizontal}$degree") + verticalDegreeView.text = String.format("${dataModel!!.vertical}$degree") + gasConcentrationView.text = String.format("${dataModel!!.methane}ppm·m") + + //TODO 报警图片、视频 + if (dataModel!!.methane >= gasAlarmRule) { + isAlarm = "1" + //抓取报警时候的图片并上传 + + //抓取报警时候的视频并上传 + } + + /***折线图**************************************************************************/ + if (!initSuccess) { + methaneLineChart.init() + //添加自定义Marker + val markerView = LineChartMarkerView(context) + markerView.chartView = methaneLineChart + markerView.setXAxisDate(xAxisLabels) + methaneLineChart.marker = markerView + + initSuccess = true + } + + val chartPointModel = ChartPointModel("", 0) + chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() + chartPointModel.dataValue = dataModel!!.methane + chartBeans.add(chartPointModel) + xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) + + //浓度线 + strengthEntries.add( + Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") + ) + + //设置数据 + val dataSet = LineDataSet(strengthEntries, "") + dataSet.setDrawCircles(false) + //线条颜色 + dataSet.color = Color.RED + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + + //解决折线点太多导致卡顿问题 + if (lineData.entryCount > 100) { + lineData.removeDataSet(0) + lineData.notifyDataChanged() + } + methaneLineChart.data = lineData + methaneLineChart.invalidate() } - val degree = resources.getString(R.string.degree) - horizontalDegreeView.text = String.format("${dataModel.horizontal}$degree") - verticalDegreeView.text = String.format("${dataModel.vertical}$degree") - gasConcentrationView.text = String.format("${dataModel.methane}ppm·m") - - /***折线图**************************************************************************/ - if (!initSuccess) { - methaneLineChart.init() - //添加自定义Marker - val markerView = LineChartMarkerView(context) - markerView.chartView = methaneLineChart - markerView.setXAxisDate(xAxisLabels) - methaneLineChart.marker = markerView - - initSuccess = true - } - - val chartPointModel = ChartPointModel("", 0) - chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() - chartPointModel.dataValue = dataModel.methane - chartBeans.add(chartPointModel) - xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) - - //浓度线 - strengthEntries.add( - Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") - ) - - //设置数据 - val dataSet = LineDataSet(strengthEntries, "") - dataSet.setDrawCircles(false) - //线条颜色 - dataSet.color = Color.RED - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER - lineDataSets.add(dataSet) - val lineData = LineData(lineDataSets) - lineData.setDrawValues(false) - - //解决折线点太多导致卡顿问题 - if (lineData.entryCount > 100) { - lineData.removeDataSet(0) - lineData.notifyDataChanged() - } - methaneLineChart.data = lineData - methaneLineChart.invalidate() } }, LocaleConstant.ACTION_UPDATE_DATA) } diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java new file mode 100644 index 0000000..5980048 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java @@ -0,0 +1,85 @@ +package com.casic.br.ktd.model; + +import java.util.List; + +public class AlarmRuleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String deviceId; + private int high; + private String ts; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public int getHigh() { + return high; + } + + public void setHigh(int high) { + this.high = high; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt index e375c35..ced6d54 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt @@ -64,7 +64,35 @@ * 获取巡检任务列表 */ @POST("/system/busPatrolCar/listPage") - suspend fun getVehiclesByPage( + suspend fun getVehicles( + @Header("token") token: String, + @QueryMap limit: Map, + @QueryMap offset: Map, + ): String + + /** + * 新增巡检过程点详情 + */ + @POST("/system/busPatrolTrack/add") + suspend fun uploadPointDetail( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 新增报警规则,主要是阈值 + */ + @POST("/system/alarmRule/add") + suspend fun addAlarmRule( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 获取巡检任务列表 + */ + @POST("/system/alarmRule/listPage") + suspend fun getAlarmRules( @Header("token") token: String, @QueryMap limit: Map, @QueryMap offset: Map, diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt index 2cc5a36..82e55ae 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt @@ -113,12 +113,70 @@ /** * 获取巡检车列表 */ - suspend fun getVehiclesByPage(offset: Int): String { + suspend fun getVehicles(): String { val limitMap = HashMap() limitMap["limit"] = LocaleConstant.PAGE_LIMIT val offsetMap = HashMap() - offsetMap["offset"] = offset - return api.getVehiclesByPage(AuthenticationHelper.token, limitMap, offsetMap) + offsetMap["offset"] = 1 + return api.getVehicles(AuthenticationHelper.token, limitMap, offsetMap) + } + + /** + * 新增巡检过程点详情 + */ + suspend fun uploadPointDetail( + isAlarm: String, + lagitude: String, + gas: String, + pitch: String, + position: String, + speed: String, + deviceStatus: String, + direction: String, + longitude: String, + ts: String + ): String { + val param = JsonObject() + param.addProperty("isAlarm", isAlarm) + param.addProperty("lagitude", lagitude) + param.addProperty("gas", gas) + param.addProperty("pitch", pitch) + param.addProperty("position", position) + param.addProperty("speed", speed) + param.addProperty("deviceStatus", deviceStatus) + param.addProperty("direction", direction) + param.addProperty("longitude", longitude) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.uploadPointDetail(AuthenticationHelper.token, requestBody) + } + + /** + * 新增报警规则,主要是阈值 + */ + suspend fun addAlarmRule(high: String, deviceId: String, ts: String): String { + val param = JsonObject() + param.addProperty("high", high) + param.addProperty("deviceId", deviceId) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addAlarmRule(AuthenticationHelper.token, requestBody) + } + + /** + * 获取巡检车列表 + */ + suspend fun getAlarmRules(): String { + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = 1 + return api.getAlarmRules(AuthenticationHelper.token, limitMap, offsetMap) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt index 8028354..1d37485 100644 --- a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt @@ -31,7 +31,7 @@ * ============================================================================================= * */ //数据接收频率 - const val DATA_TIMER_PERIOD = 1000L + const val DATA_TIMER_PERIOD = 2000L /** * ============================================================================================= @@ -44,6 +44,8 @@ const val SERVER_BASE_URL = "http://111.198.10.15:11646" const val CAR_NUMBER = "carNumber" const val CAR_ID = "carId" + const val ALARM_RULE = "alarmRule" + const val YT_DEVICE_ID = "deviceId" //海康摄像头参数 const val HK_NET_IP = "192.168.1.64" diff --git a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt index bfe09d8..aad5658 100644 --- a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt +++ b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt @@ -35,6 +35,7 @@ import com.casic.br.ktd.utils.LoadingDialogHub import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.utils.LocationHelper +import com.casic.br.ktd.vm.PointViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.LineChartMarkerView @@ -114,10 +115,18 @@ private lateinit var aMap: AMap private lateinit var uiSettings: UiSettings private lateinit var taskViewModel: TaskViewModel + private lateinit var pointViewModel: PointViewModel private lateinit var taskParam: TaskParam private var carId = "" private var taskTitle = "" private var beginDate = "" + private var dataModel: SensorDataModel? = null + + //1:报警,0:正常 + private var isAlarm = "0" + + //甲烷浓度阈值 + private var gasAlarmRule = 1000 /** * 协程配置云台设备,缓解新进页面较卡的问题 @@ -152,9 +161,11 @@ PageNavigationManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] + pointViewModel = ViewModelProvider(this)[PointViewModel::class.java] taskTitle = intent.getStringExtra(Constant.INTENT_PARAM).toString() carId = SaveKeyValues.getValue(LocaleConstant.CAR_ID, "") as String + gasAlarmRule = SaveKeyValues.getValue(LocaleConstant.ALARM_RULE, 1000) as Int /** * 配置云台设备 @@ -231,8 +242,26 @@ //发送位置信息给UDP服务端 udpClient.send("${aMapLocation.longitude}, ${aMapLocation.latitude}") + //上传经纬度以及甲烷浓度 + val deviceStatus = if (dataModel?.methaneState == "正常") { + "1" + } else { + "0" + } + pointViewModel.uploadPointDetail( + isAlarm, + aMapLocation.latitude.toString(), + dataModel?.methane.toString(), + dataModel?.vertical.toString(), + "", + aMapLocation.speed.toString(), + deviceStatus, + dataModel?.horizontal.toString(), + aMapLocation.longitude.toString(), + System.currentTimeMillis().timestampToCompleteDate() + ) + //速度 转为 km/h - Log.d(kTag, "onLocationGet => 速度:${aMapLocation.speed}") speed = decimalFormat.format(aMapLocation.speed * 3.6).toFloat() carSpeedView.text = String.format("${speed}Km/h") @@ -747,60 +776,71 @@ return } val deviceJson = intent.getStringExtra(Constant.BROADCAST_INTENT_DATA_KEY) - val dataModel = gson.fromJson( + dataModel = gson.fromJson( deviceJson, object : TypeToken() {}.type ) - sensorStateView.text = dataModel.methaneState - if (dataModel.methaneState == "正常") { - sensorStateView.setTextColor(Color.GREEN) - } else { - sensorStateView.setTextColor(Color.RED) + + if (dataModel != null) { + sensorStateView.text = dataModel!!.methaneState + if (dataModel!!.methaneState == "正常") { + sensorStateView.setTextColor(Color.GREEN) + } else { + sensorStateView.setTextColor(Color.RED) + } + val degree = resources.getString(R.string.degree) + horizontalDegreeView.text = String.format("${dataModel!!.horizontal}$degree") + verticalDegreeView.text = String.format("${dataModel!!.vertical}$degree") + gasConcentrationView.text = String.format("${dataModel!!.methane}ppm·m") + + //TODO 报警图片、视频 + if (dataModel!!.methane >= gasAlarmRule) { + isAlarm = "1" + //抓取报警时候的图片并上传 + + //抓取报警时候的视频并上传 + } + + /***折线图**************************************************************************/ + if (!initSuccess) { + methaneLineChart.init() + //添加自定义Marker + val markerView = LineChartMarkerView(context) + markerView.chartView = methaneLineChart + markerView.setXAxisDate(xAxisLabels) + methaneLineChart.marker = markerView + + initSuccess = true + } + + val chartPointModel = ChartPointModel("", 0) + chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() + chartPointModel.dataValue = dataModel!!.methane + chartBeans.add(chartPointModel) + xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) + + //浓度线 + strengthEntries.add( + Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") + ) + + //设置数据 + val dataSet = LineDataSet(strengthEntries, "") + dataSet.setDrawCircles(false) + //线条颜色 + dataSet.color = Color.RED + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + + //解决折线点太多导致卡顿问题 + if (lineData.entryCount > 100) { + lineData.removeDataSet(0) + lineData.notifyDataChanged() + } + methaneLineChart.data = lineData + methaneLineChart.invalidate() } - val degree = resources.getString(R.string.degree) - horizontalDegreeView.text = String.format("${dataModel.horizontal}$degree") - verticalDegreeView.text = String.format("${dataModel.vertical}$degree") - gasConcentrationView.text = String.format("${dataModel.methane}ppm·m") - - /***折线图**************************************************************************/ - if (!initSuccess) { - methaneLineChart.init() - //添加自定义Marker - val markerView = LineChartMarkerView(context) - markerView.chartView = methaneLineChart - markerView.setXAxisDate(xAxisLabels) - methaneLineChart.marker = markerView - - initSuccess = true - } - - val chartPointModel = ChartPointModel("", 0) - chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() - chartPointModel.dataValue = dataModel.methane - chartBeans.add(chartPointModel) - xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) - - //浓度线 - strengthEntries.add( - Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") - ) - - //设置数据 - val dataSet = LineDataSet(strengthEntries, "") - dataSet.setDrawCircles(false) - //线条颜色 - dataSet.color = Color.RED - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER - lineDataSets.add(dataSet) - val lineData = LineData(lineDataSets) - lineData.setDrawValues(false) - - //解决折线点太多导致卡顿问题 - if (lineData.entryCount > 100) { - lineData.removeDataSet(0) - lineData.notifyDataChanged() - } - methaneLineChart.data = lineData - methaneLineChart.invalidate() } }, LocaleConstant.ACTION_UPDATE_DATA) } diff --git a/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt b/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt index a8ce2cb..74ceb87 100644 --- a/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt @@ -19,6 +19,7 @@ import com.casic.br.ktd.fragment.MinePageFragment import com.casic.br.ktd.fragment.TaskPageFragment import com.casic.br.ktd.utils.LocaleConstant +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.VehicleViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity @@ -36,6 +37,7 @@ private val slideAdapter by lazy { SlideAdapter(this) } private var clickTime: Long = 0 private lateinit var vehicleViewModel: VehicleViewModel + private lateinit var alarmViewModel: AlarmViewModel init { slideUnSelectedItems.add(SlideItem(R.mipmap.home_unselected, "首页")) @@ -66,7 +68,7 @@ switchPage(fragmentPages[0]) vehicleViewModel = ViewModelProvider(this)[VehicleViewModel::class.java] - vehicleViewModel.getVehiclesByPage(1) + vehicleViewModel.getVehicles() vehicleViewModel.vehicleList.observe(this) { if (it.code == 200) { if (it.data.rows.isNotEmpty()) { @@ -78,6 +80,22 @@ } } } + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] + alarmViewModel.getAlarmRules() + alarmViewModel.alarmRuleList.observe(this) { + if (it.code == 200) { + if (it.data.rows.isNotEmpty()) { + //TODO 报警规则需要取最新的 + + val model = it.data.rows[0] + SaveKeyValues.putValue(LocaleConstant.ALARM_RULE, model.high) + SaveKeyValues.putValue(LocaleConstant.YT_DEVICE_ID, model.deviceId) + } else { + Log.d(kTag, "initData => 无可用报警规则") + } + } + } } override fun initEvent() { diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java new file mode 100644 index 0000000..5980048 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java @@ -0,0 +1,85 @@ +package com.casic.br.ktd.model; + +import java.util.List; + +public class AlarmRuleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String deviceId; + private int high; + private String ts; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public int getHigh() { + return high; + } + + public void setHigh(int high) { + this.high = high; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt index e375c35..ced6d54 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt @@ -64,7 +64,35 @@ * 获取巡检任务列表 */ @POST("/system/busPatrolCar/listPage") - suspend fun getVehiclesByPage( + suspend fun getVehicles( + @Header("token") token: String, + @QueryMap limit: Map, + @QueryMap offset: Map, + ): String + + /** + * 新增巡检过程点详情 + */ + @POST("/system/busPatrolTrack/add") + suspend fun uploadPointDetail( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 新增报警规则,主要是阈值 + */ + @POST("/system/alarmRule/add") + suspend fun addAlarmRule( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 获取巡检任务列表 + */ + @POST("/system/alarmRule/listPage") + suspend fun getAlarmRules( @Header("token") token: String, @QueryMap limit: Map, @QueryMap offset: Map, diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt index 2cc5a36..82e55ae 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt @@ -113,12 +113,70 @@ /** * 获取巡检车列表 */ - suspend fun getVehiclesByPage(offset: Int): String { + suspend fun getVehicles(): String { val limitMap = HashMap() limitMap["limit"] = LocaleConstant.PAGE_LIMIT val offsetMap = HashMap() - offsetMap["offset"] = offset - return api.getVehiclesByPage(AuthenticationHelper.token, limitMap, offsetMap) + offsetMap["offset"] = 1 + return api.getVehicles(AuthenticationHelper.token, limitMap, offsetMap) + } + + /** + * 新增巡检过程点详情 + */ + suspend fun uploadPointDetail( + isAlarm: String, + lagitude: String, + gas: String, + pitch: String, + position: String, + speed: String, + deviceStatus: String, + direction: String, + longitude: String, + ts: String + ): String { + val param = JsonObject() + param.addProperty("isAlarm", isAlarm) + param.addProperty("lagitude", lagitude) + param.addProperty("gas", gas) + param.addProperty("pitch", pitch) + param.addProperty("position", position) + param.addProperty("speed", speed) + param.addProperty("deviceStatus", deviceStatus) + param.addProperty("direction", direction) + param.addProperty("longitude", longitude) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.uploadPointDetail(AuthenticationHelper.token, requestBody) + } + + /** + * 新增报警规则,主要是阈值 + */ + suspend fun addAlarmRule(high: String, deviceId: String, ts: String): String { + val param = JsonObject() + param.addProperty("high", high) + param.addProperty("deviceId", deviceId) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addAlarmRule(AuthenticationHelper.token, requestBody) + } + + /** + * 获取巡检车列表 + */ + suspend fun getAlarmRules(): String { + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = 1 + return api.getAlarmRules(AuthenticationHelper.token, limitMap, offsetMap) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt index 8028354..1d37485 100644 --- a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt @@ -31,7 +31,7 @@ * ============================================================================================= * */ //数据接收频率 - const val DATA_TIMER_PERIOD = 1000L + const val DATA_TIMER_PERIOD = 2000L /** * ============================================================================================= @@ -44,6 +44,8 @@ const val SERVER_BASE_URL = "http://111.198.10.15:11646" const val CAR_NUMBER = "carNumber" const val CAR_ID = "carId" + const val ALARM_RULE = "alarmRule" + const val YT_DEVICE_ID = "deviceId" //海康摄像头参数 const val HK_NET_IP = "192.168.1.64" diff --git a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt index bfe09d8..aad5658 100644 --- a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt +++ b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt @@ -35,6 +35,7 @@ import com.casic.br.ktd.utils.LoadingDialogHub import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.utils.LocationHelper +import com.casic.br.ktd.vm.PointViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.LineChartMarkerView @@ -114,10 +115,18 @@ private lateinit var aMap: AMap private lateinit var uiSettings: UiSettings private lateinit var taskViewModel: TaskViewModel + private lateinit var pointViewModel: PointViewModel private lateinit var taskParam: TaskParam private var carId = "" private var taskTitle = "" private var beginDate = "" + private var dataModel: SensorDataModel? = null + + //1:报警,0:正常 + private var isAlarm = "0" + + //甲烷浓度阈值 + private var gasAlarmRule = 1000 /** * 协程配置云台设备,缓解新进页面较卡的问题 @@ -152,9 +161,11 @@ PageNavigationManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] + pointViewModel = ViewModelProvider(this)[PointViewModel::class.java] taskTitle = intent.getStringExtra(Constant.INTENT_PARAM).toString() carId = SaveKeyValues.getValue(LocaleConstant.CAR_ID, "") as String + gasAlarmRule = SaveKeyValues.getValue(LocaleConstant.ALARM_RULE, 1000) as Int /** * 配置云台设备 @@ -231,8 +242,26 @@ //发送位置信息给UDP服务端 udpClient.send("${aMapLocation.longitude}, ${aMapLocation.latitude}") + //上传经纬度以及甲烷浓度 + val deviceStatus = if (dataModel?.methaneState == "正常") { + "1" + } else { + "0" + } + pointViewModel.uploadPointDetail( + isAlarm, + aMapLocation.latitude.toString(), + dataModel?.methane.toString(), + dataModel?.vertical.toString(), + "", + aMapLocation.speed.toString(), + deviceStatus, + dataModel?.horizontal.toString(), + aMapLocation.longitude.toString(), + System.currentTimeMillis().timestampToCompleteDate() + ) + //速度 转为 km/h - Log.d(kTag, "onLocationGet => 速度:${aMapLocation.speed}") speed = decimalFormat.format(aMapLocation.speed * 3.6).toFloat() carSpeedView.text = String.format("${speed}Km/h") @@ -747,60 +776,71 @@ return } val deviceJson = intent.getStringExtra(Constant.BROADCAST_INTENT_DATA_KEY) - val dataModel = gson.fromJson( + dataModel = gson.fromJson( deviceJson, object : TypeToken() {}.type ) - sensorStateView.text = dataModel.methaneState - if (dataModel.methaneState == "正常") { - sensorStateView.setTextColor(Color.GREEN) - } else { - sensorStateView.setTextColor(Color.RED) + + if (dataModel != null) { + sensorStateView.text = dataModel!!.methaneState + if (dataModel!!.methaneState == "正常") { + sensorStateView.setTextColor(Color.GREEN) + } else { + sensorStateView.setTextColor(Color.RED) + } + val degree = resources.getString(R.string.degree) + horizontalDegreeView.text = String.format("${dataModel!!.horizontal}$degree") + verticalDegreeView.text = String.format("${dataModel!!.vertical}$degree") + gasConcentrationView.text = String.format("${dataModel!!.methane}ppm·m") + + //TODO 报警图片、视频 + if (dataModel!!.methane >= gasAlarmRule) { + isAlarm = "1" + //抓取报警时候的图片并上传 + + //抓取报警时候的视频并上传 + } + + /***折线图**************************************************************************/ + if (!initSuccess) { + methaneLineChart.init() + //添加自定义Marker + val markerView = LineChartMarkerView(context) + markerView.chartView = methaneLineChart + markerView.setXAxisDate(xAxisLabels) + methaneLineChart.marker = markerView + + initSuccess = true + } + + val chartPointModel = ChartPointModel("", 0) + chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() + chartPointModel.dataValue = dataModel!!.methane + chartBeans.add(chartPointModel) + xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) + + //浓度线 + strengthEntries.add( + Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") + ) + + //设置数据 + val dataSet = LineDataSet(strengthEntries, "") + dataSet.setDrawCircles(false) + //线条颜色 + dataSet.color = Color.RED + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + + //解决折线点太多导致卡顿问题 + if (lineData.entryCount > 100) { + lineData.removeDataSet(0) + lineData.notifyDataChanged() + } + methaneLineChart.data = lineData + methaneLineChart.invalidate() } - val degree = resources.getString(R.string.degree) - horizontalDegreeView.text = String.format("${dataModel.horizontal}$degree") - verticalDegreeView.text = String.format("${dataModel.vertical}$degree") - gasConcentrationView.text = String.format("${dataModel.methane}ppm·m") - - /***折线图**************************************************************************/ - if (!initSuccess) { - methaneLineChart.init() - //添加自定义Marker - val markerView = LineChartMarkerView(context) - markerView.chartView = methaneLineChart - markerView.setXAxisDate(xAxisLabels) - methaneLineChart.marker = markerView - - initSuccess = true - } - - val chartPointModel = ChartPointModel("", 0) - chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() - chartPointModel.dataValue = dataModel.methane - chartBeans.add(chartPointModel) - xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) - - //浓度线 - strengthEntries.add( - Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") - ) - - //设置数据 - val dataSet = LineDataSet(strengthEntries, "") - dataSet.setDrawCircles(false) - //线条颜色 - dataSet.color = Color.RED - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER - lineDataSets.add(dataSet) - val lineData = LineData(lineDataSets) - lineData.setDrawValues(false) - - //解决折线点太多导致卡顿问题 - if (lineData.entryCount > 100) { - lineData.removeDataSet(0) - lineData.notifyDataChanged() - } - methaneLineChart.data = lineData - methaneLineChart.invalidate() } }, LocaleConstant.ACTION_UPDATE_DATA) } diff --git a/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt b/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt index a8ce2cb..74ceb87 100644 --- a/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt @@ -19,6 +19,7 @@ import com.casic.br.ktd.fragment.MinePageFragment import com.casic.br.ktd.fragment.TaskPageFragment import com.casic.br.ktd.utils.LocaleConstant +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.VehicleViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity @@ -36,6 +37,7 @@ private val slideAdapter by lazy { SlideAdapter(this) } private var clickTime: Long = 0 private lateinit var vehicleViewModel: VehicleViewModel + private lateinit var alarmViewModel: AlarmViewModel init { slideUnSelectedItems.add(SlideItem(R.mipmap.home_unselected, "首页")) @@ -66,7 +68,7 @@ switchPage(fragmentPages[0]) vehicleViewModel = ViewModelProvider(this)[VehicleViewModel::class.java] - vehicleViewModel.getVehiclesByPage(1) + vehicleViewModel.getVehicles() vehicleViewModel.vehicleList.observe(this) { if (it.code == 200) { if (it.data.rows.isNotEmpty()) { @@ -78,6 +80,22 @@ } } } + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] + alarmViewModel.getAlarmRules() + alarmViewModel.alarmRuleList.observe(this) { + if (it.code == 200) { + if (it.data.rows.isNotEmpty()) { + //TODO 报警规则需要取最新的 + + val model = it.data.rows[0] + SaveKeyValues.putValue(LocaleConstant.ALARM_RULE, model.high) + SaveKeyValues.putValue(LocaleConstant.YT_DEVICE_ID, model.deviceId) + } else { + Log.d(kTag, "initData => 无可用报警规则") + } + } + } } override fun initEvent() { diff --git a/app/src/main/java/com/casic/br/ktd/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/ktd/vm/AlarmViewModel.kt new file mode 100644 index 0000000..3b8117a --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/vm/AlarmViewModel.kt @@ -0,0 +1,50 @@ +package com.casic.br.ktd.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.br.ktd.base.BaseApplication +import com.casic.br.ktd.extensions.separateResponseCode +import com.casic.br.ktd.extensions.toErrorMessage +import com.casic.br.ktd.model.AlarmRuleListModel +import com.casic.br.ktd.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 报警相关 VM + * */ +class AlarmViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val alarmRuleList = MutableLiveData() + + fun addAlarmRule(high: String, deviceId: String, ts: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addAlarmRule(high, deviceId, ts) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun getAlarmRules() = launch({ + val response = RetrofitServiceManager.getAlarmRules() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + alarmRuleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } + }, { + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java new file mode 100644 index 0000000..5980048 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java @@ -0,0 +1,85 @@ +package com.casic.br.ktd.model; + +import java.util.List; + +public class AlarmRuleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String deviceId; + private int high; + private String ts; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public int getHigh() { + return high; + } + + public void setHigh(int high) { + this.high = high; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt index e375c35..ced6d54 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt @@ -64,7 +64,35 @@ * 获取巡检任务列表 */ @POST("/system/busPatrolCar/listPage") - suspend fun getVehiclesByPage( + suspend fun getVehicles( + @Header("token") token: String, + @QueryMap limit: Map, + @QueryMap offset: Map, + ): String + + /** + * 新增巡检过程点详情 + */ + @POST("/system/busPatrolTrack/add") + suspend fun uploadPointDetail( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 新增报警规则,主要是阈值 + */ + @POST("/system/alarmRule/add") + suspend fun addAlarmRule( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 获取巡检任务列表 + */ + @POST("/system/alarmRule/listPage") + suspend fun getAlarmRules( @Header("token") token: String, @QueryMap limit: Map, @QueryMap offset: Map, diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt index 2cc5a36..82e55ae 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt @@ -113,12 +113,70 @@ /** * 获取巡检车列表 */ - suspend fun getVehiclesByPage(offset: Int): String { + suspend fun getVehicles(): String { val limitMap = HashMap() limitMap["limit"] = LocaleConstant.PAGE_LIMIT val offsetMap = HashMap() - offsetMap["offset"] = offset - return api.getVehiclesByPage(AuthenticationHelper.token, limitMap, offsetMap) + offsetMap["offset"] = 1 + return api.getVehicles(AuthenticationHelper.token, limitMap, offsetMap) + } + + /** + * 新增巡检过程点详情 + */ + suspend fun uploadPointDetail( + isAlarm: String, + lagitude: String, + gas: String, + pitch: String, + position: String, + speed: String, + deviceStatus: String, + direction: String, + longitude: String, + ts: String + ): String { + val param = JsonObject() + param.addProperty("isAlarm", isAlarm) + param.addProperty("lagitude", lagitude) + param.addProperty("gas", gas) + param.addProperty("pitch", pitch) + param.addProperty("position", position) + param.addProperty("speed", speed) + param.addProperty("deviceStatus", deviceStatus) + param.addProperty("direction", direction) + param.addProperty("longitude", longitude) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.uploadPointDetail(AuthenticationHelper.token, requestBody) + } + + /** + * 新增报警规则,主要是阈值 + */ + suspend fun addAlarmRule(high: String, deviceId: String, ts: String): String { + val param = JsonObject() + param.addProperty("high", high) + param.addProperty("deviceId", deviceId) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addAlarmRule(AuthenticationHelper.token, requestBody) + } + + /** + * 获取巡检车列表 + */ + suspend fun getAlarmRules(): String { + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = 1 + return api.getAlarmRules(AuthenticationHelper.token, limitMap, offsetMap) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt index 8028354..1d37485 100644 --- a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt @@ -31,7 +31,7 @@ * ============================================================================================= * */ //数据接收频率 - const val DATA_TIMER_PERIOD = 1000L + const val DATA_TIMER_PERIOD = 2000L /** * ============================================================================================= @@ -44,6 +44,8 @@ const val SERVER_BASE_URL = "http://111.198.10.15:11646" const val CAR_NUMBER = "carNumber" const val CAR_ID = "carId" + const val ALARM_RULE = "alarmRule" + const val YT_DEVICE_ID = "deviceId" //海康摄像头参数 const val HK_NET_IP = "192.168.1.64" diff --git a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt index bfe09d8..aad5658 100644 --- a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt +++ b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt @@ -35,6 +35,7 @@ import com.casic.br.ktd.utils.LoadingDialogHub import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.utils.LocationHelper +import com.casic.br.ktd.vm.PointViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.LineChartMarkerView @@ -114,10 +115,18 @@ private lateinit var aMap: AMap private lateinit var uiSettings: UiSettings private lateinit var taskViewModel: TaskViewModel + private lateinit var pointViewModel: PointViewModel private lateinit var taskParam: TaskParam private var carId = "" private var taskTitle = "" private var beginDate = "" + private var dataModel: SensorDataModel? = null + + //1:报警,0:正常 + private var isAlarm = "0" + + //甲烷浓度阈值 + private var gasAlarmRule = 1000 /** * 协程配置云台设备,缓解新进页面较卡的问题 @@ -152,9 +161,11 @@ PageNavigationManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] + pointViewModel = ViewModelProvider(this)[PointViewModel::class.java] taskTitle = intent.getStringExtra(Constant.INTENT_PARAM).toString() carId = SaveKeyValues.getValue(LocaleConstant.CAR_ID, "") as String + gasAlarmRule = SaveKeyValues.getValue(LocaleConstant.ALARM_RULE, 1000) as Int /** * 配置云台设备 @@ -231,8 +242,26 @@ //发送位置信息给UDP服务端 udpClient.send("${aMapLocation.longitude}, ${aMapLocation.latitude}") + //上传经纬度以及甲烷浓度 + val deviceStatus = if (dataModel?.methaneState == "正常") { + "1" + } else { + "0" + } + pointViewModel.uploadPointDetail( + isAlarm, + aMapLocation.latitude.toString(), + dataModel?.methane.toString(), + dataModel?.vertical.toString(), + "", + aMapLocation.speed.toString(), + deviceStatus, + dataModel?.horizontal.toString(), + aMapLocation.longitude.toString(), + System.currentTimeMillis().timestampToCompleteDate() + ) + //速度 转为 km/h - Log.d(kTag, "onLocationGet => 速度:${aMapLocation.speed}") speed = decimalFormat.format(aMapLocation.speed * 3.6).toFloat() carSpeedView.text = String.format("${speed}Km/h") @@ -747,60 +776,71 @@ return } val deviceJson = intent.getStringExtra(Constant.BROADCAST_INTENT_DATA_KEY) - val dataModel = gson.fromJson( + dataModel = gson.fromJson( deviceJson, object : TypeToken() {}.type ) - sensorStateView.text = dataModel.methaneState - if (dataModel.methaneState == "正常") { - sensorStateView.setTextColor(Color.GREEN) - } else { - sensorStateView.setTextColor(Color.RED) + + if (dataModel != null) { + sensorStateView.text = dataModel!!.methaneState + if (dataModel!!.methaneState == "正常") { + sensorStateView.setTextColor(Color.GREEN) + } else { + sensorStateView.setTextColor(Color.RED) + } + val degree = resources.getString(R.string.degree) + horizontalDegreeView.text = String.format("${dataModel!!.horizontal}$degree") + verticalDegreeView.text = String.format("${dataModel!!.vertical}$degree") + gasConcentrationView.text = String.format("${dataModel!!.methane}ppm·m") + + //TODO 报警图片、视频 + if (dataModel!!.methane >= gasAlarmRule) { + isAlarm = "1" + //抓取报警时候的图片并上传 + + //抓取报警时候的视频并上传 + } + + /***折线图**************************************************************************/ + if (!initSuccess) { + methaneLineChart.init() + //添加自定义Marker + val markerView = LineChartMarkerView(context) + markerView.chartView = methaneLineChart + markerView.setXAxisDate(xAxisLabels) + methaneLineChart.marker = markerView + + initSuccess = true + } + + val chartPointModel = ChartPointModel("", 0) + chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() + chartPointModel.dataValue = dataModel!!.methane + chartBeans.add(chartPointModel) + xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) + + //浓度线 + strengthEntries.add( + Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") + ) + + //设置数据 + val dataSet = LineDataSet(strengthEntries, "") + dataSet.setDrawCircles(false) + //线条颜色 + dataSet.color = Color.RED + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + + //解决折线点太多导致卡顿问题 + if (lineData.entryCount > 100) { + lineData.removeDataSet(0) + lineData.notifyDataChanged() + } + methaneLineChart.data = lineData + methaneLineChart.invalidate() } - val degree = resources.getString(R.string.degree) - horizontalDegreeView.text = String.format("${dataModel.horizontal}$degree") - verticalDegreeView.text = String.format("${dataModel.vertical}$degree") - gasConcentrationView.text = String.format("${dataModel.methane}ppm·m") - - /***折线图**************************************************************************/ - if (!initSuccess) { - methaneLineChart.init() - //添加自定义Marker - val markerView = LineChartMarkerView(context) - markerView.chartView = methaneLineChart - markerView.setXAxisDate(xAxisLabels) - methaneLineChart.marker = markerView - - initSuccess = true - } - - val chartPointModel = ChartPointModel("", 0) - chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() - chartPointModel.dataValue = dataModel.methane - chartBeans.add(chartPointModel) - xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) - - //浓度线 - strengthEntries.add( - Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") - ) - - //设置数据 - val dataSet = LineDataSet(strengthEntries, "") - dataSet.setDrawCircles(false) - //线条颜色 - dataSet.color = Color.RED - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER - lineDataSets.add(dataSet) - val lineData = LineData(lineDataSets) - lineData.setDrawValues(false) - - //解决折线点太多导致卡顿问题 - if (lineData.entryCount > 100) { - lineData.removeDataSet(0) - lineData.notifyDataChanged() - } - methaneLineChart.data = lineData - methaneLineChart.invalidate() } }, LocaleConstant.ACTION_UPDATE_DATA) } diff --git a/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt b/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt index a8ce2cb..74ceb87 100644 --- a/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt @@ -19,6 +19,7 @@ import com.casic.br.ktd.fragment.MinePageFragment import com.casic.br.ktd.fragment.TaskPageFragment import com.casic.br.ktd.utils.LocaleConstant +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.VehicleViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity @@ -36,6 +37,7 @@ private val slideAdapter by lazy { SlideAdapter(this) } private var clickTime: Long = 0 private lateinit var vehicleViewModel: VehicleViewModel + private lateinit var alarmViewModel: AlarmViewModel init { slideUnSelectedItems.add(SlideItem(R.mipmap.home_unselected, "首页")) @@ -66,7 +68,7 @@ switchPage(fragmentPages[0]) vehicleViewModel = ViewModelProvider(this)[VehicleViewModel::class.java] - vehicleViewModel.getVehiclesByPage(1) + vehicleViewModel.getVehicles() vehicleViewModel.vehicleList.observe(this) { if (it.code == 200) { if (it.data.rows.isNotEmpty()) { @@ -78,6 +80,22 @@ } } } + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] + alarmViewModel.getAlarmRules() + alarmViewModel.alarmRuleList.observe(this) { + if (it.code == 200) { + if (it.data.rows.isNotEmpty()) { + //TODO 报警规则需要取最新的 + + val model = it.data.rows[0] + SaveKeyValues.putValue(LocaleConstant.ALARM_RULE, model.high) + SaveKeyValues.putValue(LocaleConstant.YT_DEVICE_ID, model.deviceId) + } else { + Log.d(kTag, "initData => 无可用报警规则") + } + } + } } override fun initEvent() { diff --git a/app/src/main/java/com/casic/br/ktd/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/ktd/vm/AlarmViewModel.kt new file mode 100644 index 0000000..3b8117a --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/vm/AlarmViewModel.kt @@ -0,0 +1,50 @@ +package com.casic.br.ktd.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.br.ktd.base.BaseApplication +import com.casic.br.ktd.extensions.separateResponseCode +import com.casic.br.ktd.extensions.toErrorMessage +import com.casic.br.ktd.model.AlarmRuleListModel +import com.casic.br.ktd.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 报警相关 VM + * */ +class AlarmViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val alarmRuleList = MutableLiveData() + + fun addAlarmRule(high: String, deviceId: String, ts: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addAlarmRule(high, deviceId, ts) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun getAlarmRules() = launch({ + val response = RetrofitServiceManager.getAlarmRules() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + alarmRuleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } + }, { + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/vm/PointViewModel.kt b/app/src/main/java/com/casic/br/ktd/vm/PointViewModel.kt new file mode 100644 index 0000000..d81e7d6 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/vm/PointViewModel.kt @@ -0,0 +1,39 @@ +package com.casic.br.ktd.vm + +import com.casic.br.ktd.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.vm.BaseViewModel + +/** + * 巡检过程点 VM + * */ +class PointViewModel : BaseViewModel() { + + fun uploadPointDetail( + isAlarm: String, + lagitude: String, + gas: String, + pitch: String, + position: String, + speed: String, + deviceStatus: String, + direction: String, + longitude: String, + ts: String + ) = launch({ + RetrofitServiceManager.uploadPointDetail( + isAlarm, + lagitude, + gas, + pitch, + position, + speed, + deviceStatus, + direction, + longitude, + ts + ) + }, { + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt index 4fe2b98..e1b54d6 100644 --- a/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt +++ b/app/src/main/java/com/casic/br/ktd/fragment/TaskPageFragment.kt @@ -9,15 +9,22 @@ import com.casic.br.ktd.R import com.casic.br.ktd.adapter.TaskAdapter import com.casic.br.ktd.base.KotlinBaseFragment +import com.casic.br.ktd.holder.SwipeViewHolder import com.casic.br.ktd.model.TaskListModel +import com.casic.br.ktd.utils.LoadingDialogHub +import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.view.InspectionActivity +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.AlertInputDialog import com.casic.br.ktd.widgets.DateRangeActionSheet import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.extensions.timestampToCompleteDate +import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.utils.WeakReferenceHandler +import com.pengxh.kt.lite.vm.LoadState import com.qmuiteam.qmui.recyclerView.QMUIRVItemSwipeAction import com.qmuiteam.qmui.recyclerView.QMUISwipeAction import kotlinx.android.synthetic.main.fragment_task.view.* @@ -27,6 +34,7 @@ private val kTag = "TaskPageFragment" private lateinit var weakReferenceHandler: WeakReferenceHandler private lateinit var taskViewModel: TaskViewModel + private lateinit var alarmViewModel: AlarmViewModel private lateinit var taskAdapter: TaskAdapter private var dataBeans: MutableList = ArrayList() private var selectedItems: MutableList = ArrayList() @@ -35,6 +43,7 @@ private var isLoadMore = false private var startTime = "" private var endTime = "" + private var deviceId = "" override fun initView(savedInstanceState: Bundle?) { weakReferenceHandler = WeakReferenceHandler(this) @@ -64,12 +73,15 @@ } } getTasksByPage() + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] } override fun onResume() { super.onResume() //fragment切换时候重置侧滑按钮 swipeAction.clear() + deviceId = SaveKeyValues.getValue(LocaleConstant.YT_DEVICE_ID, "") as String } override fun handleMessage(msg: Message): Boolean { @@ -100,7 +112,11 @@ override fun getSwipeDirection( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { - return QMUIRVItemSwipeAction.SWIPE_LEFT + if (viewHolder is SwipeViewHolder) { + return QMUIRVItemSwipeAction.SWIPE_LEFT + } + //taskAdapter有两种布局,普通布局(标题)不需要侧滑 + return QMUIRVItemSwipeAction.SWIPE_NONE } override fun onClickAction( @@ -210,7 +226,9 @@ .setOnDialogButtonClickListener(object : AlertInputDialog.OnDialogButtonClickListener { override fun onConfirmClick(value: String) { - + alarmViewModel.addAlarmRule( + value, deviceId, System.currentTimeMillis().timestampToCompleteDate() + ) } override fun onCancelClick() {} @@ -244,7 +262,19 @@ override fun initLayoutRes(): Int = R.layout.fragment_task override fun observeRequestState() { - + alarmViewModel.loadState.observe(this) { + when (it) { + LoadState.Loading -> LoadingDialogHub.show(requireActivity(), "报警规则新增中,请稍后...") + LoadState.Success -> { + LoadingDialogHub.dismiss() + "报警规则新增成功".show(requireActivity()) + } + else -> { + LoadingDialogHub.dismiss() + "报警规则新增失败,请重试".show(requireActivity()) + } + } + } } override fun setupTopBarLayout() { diff --git a/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java new file mode 100644 index 0000000..5980048 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/model/AlarmRuleListModel.java @@ -0,0 +1,85 @@ +package com.casic.br.ktd.model; + +import java.util.List; + +public class AlarmRuleListModel { + + private int code; + private DataModel data; + private String message; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataModel getData() { + return data; + } + + public void setData(DataModel data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public static class DataModel { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsModel { + private String deviceId; + private int high; + private String ts; + + public String getDeviceId() { + return deviceId; + } + + public void setDeviceId(String deviceId) { + this.deviceId = deviceId; + } + + public int getHigh() { + return high; + } + + public void setHigh(int high) { + this.high = high; + } + + public String getTs() { + return ts; + } + + public void setTs(String ts) { + this.ts = ts; + } + } + } +} diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt index e375c35..ced6d54 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitService.kt @@ -64,7 +64,35 @@ * 获取巡检任务列表 */ @POST("/system/busPatrolCar/listPage") - suspend fun getVehiclesByPage( + suspend fun getVehicles( + @Header("token") token: String, + @QueryMap limit: Map, + @QueryMap offset: Map, + ): String + + /** + * 新增巡检过程点详情 + */ + @POST("/system/busPatrolTrack/add") + suspend fun uploadPointDetail( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 新增报警规则,主要是阈值 + */ + @POST("/system/alarmRule/add") + suspend fun addAlarmRule( + @Header("token") token: String, + @Body requestBody: RequestBody + ): String + + /** + * 获取巡检任务列表 + */ + @POST("/system/alarmRule/listPage") + suspend fun getAlarmRules( @Header("token") token: String, @QueryMap limit: Map, @QueryMap offset: Map, diff --git a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt index 2cc5a36..82e55ae 100644 --- a/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/br/ktd/retrofit/RetrofitServiceManager.kt @@ -113,12 +113,70 @@ /** * 获取巡检车列表 */ - suspend fun getVehiclesByPage(offset: Int): String { + suspend fun getVehicles(): String { val limitMap = HashMap() limitMap["limit"] = LocaleConstant.PAGE_LIMIT val offsetMap = HashMap() - offsetMap["offset"] = offset - return api.getVehiclesByPage(AuthenticationHelper.token, limitMap, offsetMap) + offsetMap["offset"] = 1 + return api.getVehicles(AuthenticationHelper.token, limitMap, offsetMap) + } + + /** + * 新增巡检过程点详情 + */ + suspend fun uploadPointDetail( + isAlarm: String, + lagitude: String, + gas: String, + pitch: String, + position: String, + speed: String, + deviceStatus: String, + direction: String, + longitude: String, + ts: String + ): String { + val param = JsonObject() + param.addProperty("isAlarm", isAlarm) + param.addProperty("lagitude", lagitude) + param.addProperty("gas", gas) + param.addProperty("pitch", pitch) + param.addProperty("position", position) + param.addProperty("speed", speed) + param.addProperty("deviceStatus", deviceStatus) + param.addProperty("direction", direction) + param.addProperty("longitude", longitude) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.uploadPointDetail(AuthenticationHelper.token, requestBody) + } + + /** + * 新增报警规则,主要是阈值 + */ + suspend fun addAlarmRule(high: String, deviceId: String, ts: String): String { + val param = JsonObject() + param.addProperty("high", high) + param.addProperty("deviceId", deviceId) + param.addProperty("ts", ts) + val requestBody = param.toString().toRequestBody( + "application/json;charset=UTF-8".toMediaType() + ) + return api.addAlarmRule(AuthenticationHelper.token, requestBody) + } + + /** + * 获取巡检车列表 + */ + suspend fun getAlarmRules(): String { + val limitMap = HashMap() + limitMap["limit"] = LocaleConstant.PAGE_LIMIT + + val offsetMap = HashMap() + offsetMap["offset"] = 1 + return api.getAlarmRules(AuthenticationHelper.token, limitMap, offsetMap) } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt index 8028354..1d37485 100644 --- a/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/ktd/utils/LocaleConstant.kt @@ -31,7 +31,7 @@ * ============================================================================================= * */ //数据接收频率 - const val DATA_TIMER_PERIOD = 1000L + const val DATA_TIMER_PERIOD = 2000L /** * ============================================================================================= @@ -44,6 +44,8 @@ const val SERVER_BASE_URL = "http://111.198.10.15:11646" const val CAR_NUMBER = "carNumber" const val CAR_ID = "carId" + const val ALARM_RULE = "alarmRule" + const val YT_DEVICE_ID = "deviceId" //海康摄像头参数 const val HK_NET_IP = "192.168.1.64" diff --git a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt index bfe09d8..aad5658 100644 --- a/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt +++ b/app/src/main/java/com/casic/br/ktd/view/InspectionActivity.kt @@ -35,6 +35,7 @@ import com.casic.br.ktd.utils.LoadingDialogHub import com.casic.br.ktd.utils.LocaleConstant import com.casic.br.ktd.utils.LocationHelper +import com.casic.br.ktd.vm.PointViewModel import com.casic.br.ktd.vm.TaskViewModel import com.casic.br.ktd.widgets.AlertControlDialog import com.casic.br.ktd.widgets.LineChartMarkerView @@ -114,10 +115,18 @@ private lateinit var aMap: AMap private lateinit var uiSettings: UiSettings private lateinit var taskViewModel: TaskViewModel + private lateinit var pointViewModel: PointViewModel private lateinit var taskParam: TaskParam private var carId = "" private var taskTitle = "" private var beginDate = "" + private var dataModel: SensorDataModel? = null + + //1:报警,0:正常 + private var isAlarm = "0" + + //甲烷浓度阈值 + private var gasAlarmRule = 1000 /** * 协程配置云台设备,缓解新进页面较卡的问题 @@ -152,9 +161,11 @@ PageNavigationManager.addActivity(this) weakReferenceHandler = WeakReferenceHandler(this) taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java] + pointViewModel = ViewModelProvider(this)[PointViewModel::class.java] taskTitle = intent.getStringExtra(Constant.INTENT_PARAM).toString() carId = SaveKeyValues.getValue(LocaleConstant.CAR_ID, "") as String + gasAlarmRule = SaveKeyValues.getValue(LocaleConstant.ALARM_RULE, 1000) as Int /** * 配置云台设备 @@ -231,8 +242,26 @@ //发送位置信息给UDP服务端 udpClient.send("${aMapLocation.longitude}, ${aMapLocation.latitude}") + //上传经纬度以及甲烷浓度 + val deviceStatus = if (dataModel?.methaneState == "正常") { + "1" + } else { + "0" + } + pointViewModel.uploadPointDetail( + isAlarm, + aMapLocation.latitude.toString(), + dataModel?.methane.toString(), + dataModel?.vertical.toString(), + "", + aMapLocation.speed.toString(), + deviceStatus, + dataModel?.horizontal.toString(), + aMapLocation.longitude.toString(), + System.currentTimeMillis().timestampToCompleteDate() + ) + //速度 转为 km/h - Log.d(kTag, "onLocationGet => 速度:${aMapLocation.speed}") speed = decimalFormat.format(aMapLocation.speed * 3.6).toFloat() carSpeedView.text = String.format("${speed}Km/h") @@ -747,60 +776,71 @@ return } val deviceJson = intent.getStringExtra(Constant.BROADCAST_INTENT_DATA_KEY) - val dataModel = gson.fromJson( + dataModel = gson.fromJson( deviceJson, object : TypeToken() {}.type ) - sensorStateView.text = dataModel.methaneState - if (dataModel.methaneState == "正常") { - sensorStateView.setTextColor(Color.GREEN) - } else { - sensorStateView.setTextColor(Color.RED) + + if (dataModel != null) { + sensorStateView.text = dataModel!!.methaneState + if (dataModel!!.methaneState == "正常") { + sensorStateView.setTextColor(Color.GREEN) + } else { + sensorStateView.setTextColor(Color.RED) + } + val degree = resources.getString(R.string.degree) + horizontalDegreeView.text = String.format("${dataModel!!.horizontal}$degree") + verticalDegreeView.text = String.format("${dataModel!!.vertical}$degree") + gasConcentrationView.text = String.format("${dataModel!!.methane}ppm·m") + + //TODO 报警图片、视频 + if (dataModel!!.methane >= gasAlarmRule) { + isAlarm = "1" + //抓取报警时候的图片并上传 + + //抓取报警时候的视频并上传 + } + + /***折线图**************************************************************************/ + if (!initSuccess) { + methaneLineChart.init() + //添加自定义Marker + val markerView = LineChartMarkerView(context) + markerView.chartView = methaneLineChart + markerView.setXAxisDate(xAxisLabels) + methaneLineChart.marker = markerView + + initSuccess = true + } + + val chartPointModel = ChartPointModel("", 0) + chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() + chartPointModel.dataValue = dataModel!!.methane + chartBeans.add(chartPointModel) + xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) + + //浓度线 + strengthEntries.add( + Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") + ) + + //设置数据 + val dataSet = LineDataSet(strengthEntries, "") + dataSet.setDrawCircles(false) + //线条颜色 + dataSet.color = Color.RED + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + + //解决折线点太多导致卡顿问题 + if (lineData.entryCount > 100) { + lineData.removeDataSet(0) + lineData.notifyDataChanged() + } + methaneLineChart.data = lineData + methaneLineChart.invalidate() } - val degree = resources.getString(R.string.degree) - horizontalDegreeView.text = String.format("${dataModel.horizontal}$degree") - verticalDegreeView.text = String.format("${dataModel.vertical}$degree") - gasConcentrationView.text = String.format("${dataModel.methane}ppm·m") - - /***折线图**************************************************************************/ - if (!initSuccess) { - methaneLineChart.init() - //添加自定义Marker - val markerView = LineChartMarkerView(context) - markerView.chartView = methaneLineChart - markerView.setXAxisDate(xAxisLabels) - methaneLineChart.marker = markerView - - initSuccess = true - } - - val chartPointModel = ChartPointModel("", 0) - chartPointModel.dataTime = System.currentTimeMillis().timestampToCompleteDate() - chartPointModel.dataValue = dataModel.methane - chartBeans.add(chartPointModel) - xAxisLabels.add(chartBeans.last().dataTime.dateToTime()) - - //浓度线 - strengthEntries.add( - Entry(i++.toFloat(), chartBeans.last().dataValue.toFloat(), "浓度") - ) - - //设置数据 - val dataSet = LineDataSet(strengthEntries, "") - dataSet.setDrawCircles(false) - //线条颜色 - dataSet.color = Color.RED - dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER - lineDataSets.add(dataSet) - val lineData = LineData(lineDataSets) - lineData.setDrawValues(false) - - //解决折线点太多导致卡顿问题 - if (lineData.entryCount > 100) { - lineData.removeDataSet(0) - lineData.notifyDataChanged() - } - methaneLineChart.data = lineData - methaneLineChart.invalidate() } }, LocaleConstant.ACTION_UPDATE_DATA) } diff --git a/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt b/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt index a8ce2cb..74ceb87 100644 --- a/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt +++ b/app/src/main/java/com/casic/br/ktd/view/MainActivity.kt @@ -19,6 +19,7 @@ import com.casic.br.ktd.fragment.MinePageFragment import com.casic.br.ktd.fragment.TaskPageFragment import com.casic.br.ktd.utils.LocaleConstant +import com.casic.br.ktd.vm.AlarmViewModel import com.casic.br.ktd.vm.VehicleViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity @@ -36,6 +37,7 @@ private val slideAdapter by lazy { SlideAdapter(this) } private var clickTime: Long = 0 private lateinit var vehicleViewModel: VehicleViewModel + private lateinit var alarmViewModel: AlarmViewModel init { slideUnSelectedItems.add(SlideItem(R.mipmap.home_unselected, "首页")) @@ -66,7 +68,7 @@ switchPage(fragmentPages[0]) vehicleViewModel = ViewModelProvider(this)[VehicleViewModel::class.java] - vehicleViewModel.getVehiclesByPage(1) + vehicleViewModel.getVehicles() vehicleViewModel.vehicleList.observe(this) { if (it.code == 200) { if (it.data.rows.isNotEmpty()) { @@ -78,6 +80,22 @@ } } } + + alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java] + alarmViewModel.getAlarmRules() + alarmViewModel.alarmRuleList.observe(this) { + if (it.code == 200) { + if (it.data.rows.isNotEmpty()) { + //TODO 报警规则需要取最新的 + + val model = it.data.rows[0] + SaveKeyValues.putValue(LocaleConstant.ALARM_RULE, model.high) + SaveKeyValues.putValue(LocaleConstant.YT_DEVICE_ID, model.deviceId) + } else { + Log.d(kTag, "initData => 无可用报警规则") + } + } + } } override fun initEvent() { diff --git a/app/src/main/java/com/casic/br/ktd/vm/AlarmViewModel.kt b/app/src/main/java/com/casic/br/ktd/vm/AlarmViewModel.kt new file mode 100644 index 0000000..3b8117a --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/vm/AlarmViewModel.kt @@ -0,0 +1,50 @@ +package com.casic.br.ktd.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.br.ktd.base.BaseApplication +import com.casic.br.ktd.extensions.separateResponseCode +import com.casic.br.ktd.extensions.toErrorMessage +import com.casic.br.ktd.model.AlarmRuleListModel +import com.casic.br.ktd.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +/** + * 报警相关 VM + * */ +class AlarmViewModel : BaseViewModel() { + + private val gson by lazy { Gson() } + val alarmRuleList = MutableLiveData() + + fun addAlarmRule(high: String, deviceId: String, ts: String) = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.addAlarmRule(high, deviceId, ts) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.get()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) + + fun getAlarmRules() = launch({ + val response = RetrofitServiceManager.getAlarmRules() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + alarmRuleList.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } + }, { + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/vm/PointViewModel.kt b/app/src/main/java/com/casic/br/ktd/vm/PointViewModel.kt new file mode 100644 index 0000000..d81e7d6 --- /dev/null +++ b/app/src/main/java/com/casic/br/ktd/vm/PointViewModel.kt @@ -0,0 +1,39 @@ +package com.casic.br.ktd.vm + +import com.casic.br.ktd.retrofit.RetrofitServiceManager +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.vm.BaseViewModel + +/** + * 巡检过程点 VM + * */ +class PointViewModel : BaseViewModel() { + + fun uploadPointDetail( + isAlarm: String, + lagitude: String, + gas: String, + pitch: String, + position: String, + speed: String, + deviceStatus: String, + direction: String, + longitude: String, + ts: String + ) = launch({ + RetrofitServiceManager.uploadPointDetail( + isAlarm, + lagitude, + gas, + pitch, + position, + speed, + deviceStatus, + direction, + longitude, + ts + ) + }, { + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/ktd/vm/VehicleViewModel.kt b/app/src/main/java/com/casic/br/ktd/vm/VehicleViewModel.kt index 0fabb74..686b024 100644 --- a/app/src/main/java/com/casic/br/ktd/vm/VehicleViewModel.kt +++ b/app/src/main/java/com/casic/br/ktd/vm/VehicleViewModel.kt @@ -16,12 +16,12 @@ * Vehicle(巡检车)相关 VM * */ class VehicleViewModel : BaseViewModel() { - private val gson by lazy { Gson() } + private val gson by lazy { Gson() } val vehicleList = MutableLiveData() - fun getVehiclesByPage(offset: Int) = launch({ - val response = RetrofitServiceManager.getVehiclesByPage(offset) + fun getVehicles() = launch({ + val response = RetrofitServiceManager.getVehicles() val responseCode = response.separateResponseCode() if (responseCode == 200) { vehicleList.value = gson.fromJson(