左晓为主开发手持机充值管理机
zuojincheng
2025-03-21 8521954fa97bdfc54123afb4a72755ece311db06
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package com.dayu.general.bean.card
 
import com.dayu.baselibrary.tools.HexUtil
import com.dayu.general.tool.CardCommon
import java.io.Serializable
 
/**
 * 调试卡
 * 主要用于安装调试用:
 * 1. 第一次刷卡时开启水泵或阀门
 * 2. 第二次刷卡关闭水泵或阀门
 * 3. 刷卡开启后1分钟内没有刷卡关闭,则自动关闭水泵或阀门
 */
class DebugCard : BaseCard(), Serializable {
    companion object {
        const val CARD_TYPE = CardCommon.DEBUG_CARD              // 卡类型:调试卡
        const val AUTO_CLOSE_TIMEOUT = 60_000L  // 自动关闭超时时间(1分钟)
    }
 
    private var pumpOpenTime: Long = 0L  // 水泵开启时间
    private var isPumpOpen: Boolean = false  // 水泵状态
 
    /**
     * 写卡完成后校验是否写卡成功
     */
    fun equalsDebugCard(data: List<ByteArray>?): Boolean {
        if (data == null || data.isEmpty()) {
            return false
        }
        return data[0].contentEquals(getZeroBytes())
    }
 
    /**
     * 通过byte转bean
     */
    fun getBean(data: List<ByteArray>): DebugCard? {
        try {
            val debugCard = DebugCard()
            // 解析第0块
            val zero = data[0]
            
            // 验证卡类型(8位)
            if (HexUtil.byteToHex(zero[8]) != CARD_TYPE) {
                return null
            }
            
            // 验证识别码(9-12位)
            if (zero[9] != IDENTIFY_CODE_A0 ||
                zero[10] != IDENTIFY_CODE_B1 ||
                zero[11] != IDENTIFY_CODE_C2 ||
                zero[12] != IDENTIFY_CODE_89) {
                return null
            }
 
            return debugCard
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        }
    }
 
    /**
     * 生成第0块数据
     */
    inner class Zero : BaseCard() {
        fun toBytes(): ByteArray {
            val data = ByteArray(16)
            try {
                // 设置备用位(0-7位)
                for (i in 0..7) {
                    data[i] = 0x00
                }
                
                // 设置卡类型(8位)
                data[8] = HexUtil.hexToByte(CARD_TYPE)
                
                // 设置识别码(9-12位)
                data[9] = IDENTIFY_CODE_A0
                data[10] = IDENTIFY_CODE_B1
                data[11] = IDENTIFY_CODE_C2
                data[12] = IDENTIFY_CODE_89
                
                // 设置备用位(13-14位)
                data[13] = 0x00
                data[14] = 0x00
                
                // 设置校验和(15位)
                data[15] = getByteSum(data)
            } catch (e: Exception) {
                e.printStackTrace()
            }
            return data
        }
    }
 
    /**
     * 切换水泵状态
     * @return 当前水泵状态
     */
    fun togglePumpState(): Boolean {
        val currentTime = System.currentTimeMillis()
        
        if (!isPumpOpen) {
            // 开启水泵
            isPumpOpen = true
            pumpOpenTime = currentTime
        } else {
            // 关闭水泵
            isPumpOpen = false
            pumpOpenTime = 0L
        }
        
        return isPumpOpen
    }
 
    /**
     * 检查是否需要自动关闭水泵
     * @return true 如果需要自动关闭,false 否则
     */
    fun shouldAutoClose(): Boolean {
        if (!isPumpOpen) return false
        
        val currentTime = System.currentTimeMillis()
        return currentTime - pumpOpenTime >= AUTO_CLOSE_TIMEOUT
    }
 
    /**
     * 自动关闭水泵
     */
    fun autoClosePump() {
        isPumpOpen = false
        pumpOpenTime = 0L
    }
 
    /**
     * 获取水泵状态
     */
    fun isPumpOpen(): Boolean = isPumpOpen
 
    /**
     * 获取水泵开启剩余时间(毫秒)
     * @return 剩余时间,如果水泵关闭则返回0
     */
    fun getRemainingTime(): Long {
        if (!isPumpOpen) return 0L
        
        val currentTime = System.currentTimeMillis()
        val remainingTime = AUTO_CLOSE_TIMEOUT - (currentTime - pumpOpenTime)
        return if (remainingTime > 0) remainingTime else 0L
    }
 
    fun getZeroBytes(): ByteArray = Zero().toBytes()