jl-iot/service/model/dc.go

299 lines
7.3 KiB
Go
Raw Permalink Normal View History

2023-12-08 18:08:15 +08:00
package model
import (
"encoding/hex"
2023-12-08 18:08:15 +08:00
"fmt"
"log/slog"
"strings"
2023-12-08 18:08:15 +08:00
)
type DCEvent int
const (
// 驱动数据更新
DCE_Drive_Update DCEvent = 1
// 采集数据更新
DCE_Collect_Update DCEvent = 2
)
// 驱动采集数据
2023-12-13 11:03:21 +08:00
type QC interface {
2023-12-08 18:08:15 +08:00
// 更新驱动数据,位数组
UpdateQdByBits(start uint32, bits []bool) error
2023-12-08 18:08:15 +08:00
// 更新驱动数据,字节数组
UpdateQdByBytes(start uint32, values []byte) error
2023-12-08 18:08:15 +08:00
// 更新采集数据,位数组
UpdateCjByBits(start uint32, bits []bool) error
2023-12-08 18:08:15 +08:00
// 更新采集数据,字节数组
UpdateCjByBytes(start uint32, values []byte) error
// 设置驱动数据
SetQdBytes(bytes []byte)
2023-12-08 18:08:15 +08:00
// 获取驱动数据,字节数组
GetQdBytes() []byte
// 获取驱动数据,位数组
GetQdBits() []bool
2023-12-08 18:08:15 +08:00
// 获取指定驱动数据,位
GetQdBitOf(start uint32) bool
2023-12-08 18:08:15 +08:00
// 获取指定驱动数据,位数组
GetQdBitsOf(start uint32, quantity uint32) []bool
2023-12-08 18:08:15 +08:00
// 获取指定驱动数据,字节
GetQdByteOf(start uint32) byte
2023-12-08 18:08:15 +08:00
// 获取指定驱动数据,字节数组
GetQdBytesOf(start uint32, quantity uint32) []byte
// 设置采集数据
SetCjBytes(bytes []byte)
2023-12-08 18:08:15 +08:00
// 获取采集数据,字节数组
GetCjBytes() []byte
// 获取采集数据,位数组
GetCjBits() []bool
2023-12-08 18:08:15 +08:00
// 获取指定采集数据,位
GetCjBitOf(start uint32) bool
2023-12-08 18:08:15 +08:00
// 获取指定采集数据,位数组
GetCjBitsOf(start uint32, quantity uint32) []bool
2023-12-08 18:08:15 +08:00
// 获取指定采集数据,字节
GetCjByteOf(start uint32) byte
2023-12-08 18:08:15 +08:00
// 获取指定采集数据,字节数组
GetCjBytesOf(start uint32, quantity uint32) []byte
// // 发布事件
// Emit(event DCEvent)
// // 订阅事件
// On(event DCEvent, callback func(dc QC))
// // 取消订阅
// Off(event DCEvent, callback func(dc QC))
2023-12-08 18:08:15 +08:00
}
2023-12-13 11:03:21 +08:00
type qc struct {
2023-12-08 18:08:15 +08:00
// 驱动数据
qd []byte
qdBits []bool
2023-12-08 18:08:15 +08:00
// 采集数据
cj []byte
cjBits []bool
// // 事件
// subscribes map[DCEvent][]func(dc QC)
2023-12-08 18:08:15 +08:00
}
func (d *qc) SetCjBytes(bytes []byte) {
d.cj = bytes
d.cjBits = DecodeBools(bytes)
2023-12-08 18:08:15 +08:00
}
// GetCjBytes implements DC.
func (d *qc) GetCjBytes() []byte {
return d.cj
}
func (d *qc) GetCjBits() []bool {
return d.cjBits
}
func (d *qc) GetCjBitOf(start uint32) bool {
if start >= uint32(len(d.cjBits)) {
2023-12-08 18:08:15 +08:00
panic(fmt.Errorf("GetCollectBit超出范围"))
}
return d.cjBits[start]
2023-12-08 18:08:15 +08:00
}
func (d *qc) GetCjBitsOf(start uint32, quantity uint32) []bool {
if start+quantity > uint32(len(d.cjBits)) {
2023-12-08 18:08:15 +08:00
panic(fmt.Errorf("GetCollectBits超出范围"))
}
return d.cjBits[start : start+quantity]
2023-12-08 18:08:15 +08:00
}
func (d *qc) GetCjByteOf(start uint32) byte {
if start >= uint32(len(d.cj)) {
2023-12-08 18:08:15 +08:00
panic(fmt.Errorf("GetCollectByte超出范围"))
}
return d.cj[start]
2023-12-08 18:08:15 +08:00
}
func (d *qc) GetCjBytesOf(start uint32, quantity uint32) []byte {
if start+quantity > uint32(len(d.cj)) {
2023-12-08 18:08:15 +08:00
panic(fmt.Errorf("GetCollectBytes超出范围"))
}
return d.cj[start : start+quantity]
}
func (d *qc) SetQdBytes(bytes []byte) {
d.qd = bytes
d.qdBits = DecodeBools(bytes)
2023-12-08 18:08:15 +08:00
}
// GetQdBytes implements DC.
func (d *qc) GetQdBytes() []byte {
return d.qd
2023-12-08 18:08:15 +08:00
}
func (d *qc) GetQdBits() []bool {
return d.qdBits
}
func (d *qc) GetQdBitOf(start uint32) bool {
if start >= uint32(len(d.qdBits)) {
2023-12-08 18:08:15 +08:00
panic(fmt.Errorf("GetDriveBit超出范围"))
}
return d.qdBits[start]
2023-12-08 18:08:15 +08:00
}
func (d *qc) GetQdBitsOf(start uint32, quantity uint32) []bool {
if start+quantity > uint32(len(d.qdBits)) {
2023-12-08 18:08:15 +08:00
panic(fmt.Errorf("GetDriveBits超出范围"))
}
return d.qdBits[start : start+quantity]
2023-12-08 18:08:15 +08:00
}
func (d *qc) GetQdByteOf(start uint32) byte {
if start >= uint32(len(d.qd)) {
2023-12-08 18:08:15 +08:00
panic(fmt.Errorf("GetDriveByte超出范围"))
}
return d.qd[start]
2023-12-08 18:08:15 +08:00
}
func (d *qc) GetQdBytesOf(start uint32, quantity uint32) []byte {
if start+quantity > uint32(len(d.qd)) {
2023-12-08 18:08:15 +08:00
panic(fmt.Errorf("GetDriveBytes超出范围"))
}
return d.qd[start : start+quantity]
2023-12-08 18:08:15 +08:00
}
// UpdateCjByBits implements DC.
func (d *qc) UpdateCjByBits(start uint32, bits []bool) error {
total := len(d.cjBits)
2023-12-08 18:08:15 +08:00
if start >= uint32(total) {
return fmt.Errorf("UpdateCollectByBits参数start超出范围")
}
end := start + uint32(len(bits))
if end > uint32(total) {
return fmt.Errorf("UpdateCollectByBits参数start+len(bits)超出范围")
}
for i := start; i < end; i++ {
d.cjBits[i] = bits[i-start]
2023-12-08 18:08:15 +08:00
}
d.cj = EncodeBytes(d.cjBits)
slog.Debug("UpdateCollectByBits成功", "collect", BytesDebug(d.cj), "collectBits", BitsDebug(d.cjBits))
// d.Emit(DCE_Collect_Update)
2023-12-08 18:08:15 +08:00
return nil
}
// UpdateCjByBytes implements DC.
func (d *qc) UpdateCjByBytes(start uint32, values []byte) error {
total := len(d.cj)
2023-12-08 18:08:15 +08:00
if start >= uint32(total) {
return fmt.Errorf("UpdateCollectByBytes参数start超出范围")
}
end := start + uint32(len(values))
if end > uint32(total) {
return fmt.Errorf("UpdateCollectByBytes参数start+len(values)超出范围")
}
copy(d.cj[start:end], values)
d.cjBits = DecodeBools(d.cj)
slog.Debug("UpdateCollectByBytes成功", "collect", BytesDebug(d.cj), "collectBits", BitsDebug(d.cjBits))
// d.Emit(DCE_Collect_Update)
2023-12-08 18:08:15 +08:00
return nil
}
// UpdateQdByBits implements DC.
func (d *qc) UpdateQdByBits(start uint32, bits []bool) error {
total := len(d.qdBits)
2023-12-08 18:08:15 +08:00
if start >= uint32(total) {
return fmt.Errorf("UpdateDriveByBits参数start超出范围")
}
end := start + uint32(len(bits))
if end > uint32(total) {
return fmt.Errorf("UpdateDriveByBits参数start+len(bits)超出范围")
}
for i := start; i < end; i++ {
d.qdBits[i] = bits[i-start]
2023-12-08 18:08:15 +08:00
}
d.qd = EncodeBytes(d.qdBits)
slog.Debug("UpdateDriveByBits成功", "drive", BytesDebug(d.qd), "driveBits", BitsDebug(d.qdBits))
// d.Emit(DCE_Drive_Update)
2023-12-08 18:08:15 +08:00
return nil
}
// UpdateQdByBytes implements DC.
func (d *qc) UpdateQdByBytes(start uint32, values []byte) error {
total := len(d.qd)
2023-12-08 18:08:15 +08:00
if start >= uint32(total) {
return fmt.Errorf("UpdateDriveByBytes参数start超出范围")
}
end := start + uint32(len(values))
if end > uint32(total) {
return fmt.Errorf("UpdateDriveByBytes参数start+len(values)超出范围")
}
copy(d.qd[start:end], values)
d.qdBits = DecodeBools(d.qd)
slog.Debug("UpdateDriveByBytes成功", "drive", BytesDebug(d.qd), "driveBits", BitsDebug(d.qdBits))
// d.Emit(DCE_Drive_Update)
2023-12-08 18:08:15 +08:00
return nil
}
// // Emit implements DC.
// func (d *qc) Emit(event DCEvent) {
// listeners := d.subscribes[event]
// for _, v := range listeners {
// v(d)
// }
// }
2023-12-08 18:08:15 +08:00
// // On implements DC.
// func (d *qc) On(event DCEvent, callback func(d QC)) {
// d.subscribes[event] = append(d.subscribes[event], callback)
// }
2023-12-08 18:08:15 +08:00
// // Off implements DC.
// func (d *qc) Off(event DCEvent, callback func(d QC)) {
// panic("unimplemented")
// }
2023-12-08 18:08:15 +08:00
func NewDC(qd []byte, cj []byte) QC {
2023-12-13 11:03:21 +08:00
return &qc{
qd: qd,
qdBits: DecodeBools(qd),
cj: cj,
cjBits: DecodeBools(cj),
// subscribes: make(map[DCEvent][]func(d QC)),
2023-12-08 18:08:15 +08:00
}
}
func DecodeBools(bytes []byte) (out []bool) {
2023-12-08 18:08:15 +08:00
len := len(bytes) * 8
var i int
for i = 0; i < len; i++ {
out = append(out, (((bytes[i/8] >> (i % 8)) & 0x01) == 0x01))
}
return out
}
func EncodeBytes(bits []bool) (out []byte) {
2023-12-08 18:08:15 +08:00
len := len(bits)
if len%8 != 0 {
panic("encodeBytes参数bits长度错误")
}
var i int
out = make([]byte, len/8)
for i = 0; i < len; i++ {
if bits[i] {
out[i/8] = out[i/8] | (1 << (i % 8))
}
}
return out
}
func BytesDebug(bytes []byte) string {
return hex.EncodeToString(bytes)
}
func BitsDebug(bits []bool) string {
var sb strings.Builder
for _, v := range bits {
if v {
sb.WriteString("1")
} else {
sb.WriteString("0")
}
}
return sb.String()
}