jl-iot/service/model/dc.go

255 lines
6.7 KiB
Go
Raw Normal View History

2023-12-08 18:08:15 +08:00
package model
import (
"fmt"
"log/slog"
)
type DCEvent int
const (
// 驱动数据更新
DCE_Drive_Update DCEvent = 1
// 采集数据更新
DCE_Collect_Update DCEvent = 2
)
// 驱动采集数据
type DC interface {
// 更新驱动数据,位数组
UpdateDriveByBits(start uint32, bits []bool) error
// 更新驱动数据,字节数组
UpdateDriveByBytes(start uint32, values []byte) error
// 更新采集数据,位数组
UpdateCollectByBits(start uint32, bits []bool) error
// 更新采集数据,字节数组
UpdateCollectByBytes(start uint32, values []byte) error
// 获取驱动数据,字节数组
GetDrive() []byte
// 获取指定驱动数据,位
GetDriveBit(start uint32) bool
// 获取指定驱动数据,位数组
GetDriveBits(start uint32, quantity uint32) []bool
// 获取指定驱动数据,字节
GetDriveByte(start uint32) byte
// 获取指定驱动数据,字节数组
GetDriveBytes(start uint32, quantity uint32) []byte
// 获取采集数据,字节数组
GetCollect() []byte
// 获取指定采集数据,位
GetCollectBit(start uint32) bool
// 获取指定采集数据,位数组
GetCollectBits(start uint32, quantity uint32) []bool
// 获取指定采集数据,字节
GetCollectByte(start uint32) byte
// 获取指定采集数据,字节数组
GetCollectBytes(start uint32, quantity uint32) []byte
// 发布事件
Emit(event DCEvent)
// 订阅事件
On(event DCEvent, callback func(dc DC))
// 取消订阅
Off(event DCEvent, callback func(dc DC))
}
type dc struct {
// 驱动数据
drive []byte
driveBits []bool
// 采集数据
collect []byte
collectBits []bool
// 事件
subscribes map[DCEvent][]func(dc DC)
}
// GetCollect implements DC.
func (d *dc) GetCollect() []byte {
return d.collect
}
func (d *dc) GetCollectBit(start uint32) bool {
if start >= uint32(len(d.collectBits)) {
panic(fmt.Errorf("GetCollectBit超出范围"))
}
return d.collectBits[start]
}
func (d *dc) GetCollectBits(start uint32, quantity uint32) []bool {
if start+quantity > uint32(len(d.collectBits)) {
panic(fmt.Errorf("GetCollectBits超出范围"))
}
return d.collectBits[start : start+quantity]
}
func (d *dc) GetCollectByte(start uint32) byte {
if start >= uint32(len(d.collect)) {
panic(fmt.Errorf("GetCollectByte超出范围"))
}
return d.collect[start]
}
func (d *dc) GetCollectBytes(start uint32, quantity uint32) []byte {
if start+quantity > uint32(len(d.collect)) {
panic(fmt.Errorf("GetCollectBytes超出范围"))
}
return d.collect[start : start+quantity]
}
// GetDrive implements DC.
func (d *dc) GetDrive() []byte {
return d.drive
}
func (d *dc) GetDriveBit(start uint32) bool {
if start >= uint32(len(d.driveBits)) {
panic(fmt.Errorf("GetDriveBit超出范围"))
}
return d.driveBits[start]
}
func (d *dc) GetDriveBits(start uint32, quantity uint32) []bool {
if start+quantity > uint32(len(d.driveBits)) {
panic(fmt.Errorf("GetDriveBits超出范围"))
}
return d.driveBits[start : start+quantity]
}
func (d *dc) GetDriveByte(start uint32) byte {
if start >= uint32(len(d.drive)) {
panic(fmt.Errorf("GetDriveByte超出范围"))
}
return d.drive[start]
}
func (d *dc) GetDriveBytes(start uint32, quantity uint32) []byte {
if start+quantity > uint32(len(d.drive)) {
panic(fmt.Errorf("GetDriveBytes超出范围"))
}
return d.drive[start : start+quantity]
}
// UpdateCollectByBits implements DC.
func (d *dc) UpdateCollectByBits(start uint32, bits []bool) error {
total := len(d.collectBits)
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.collectBits[i] = bits[i-start]
}
d.collect = encodeBytes(d.collectBits)
slog.Debug("UpdateCollectByBits成功", "collect", fmt.Sprintf("%v", d.collect), "collectBits", d.collectBits)
d.Emit(DCE_Collect_Update)
return nil
}
// UpdateCollectByBytes implements DC.
func (d *dc) UpdateCollectByBytes(start uint32, values []byte) error {
total := len(d.collect)
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.collect[start:end], values)
d.collectBits = decodeBools(d.collect)
slog.Debug("UpdateCollectByBytes成功", "collect", fmt.Sprintf("%v", d.collect), "collectBits", d.collectBits)
d.Emit(DCE_Collect_Update)
return nil
}
// UpdateDriveByBits implements DC.
func (d *dc) UpdateDriveByBits(start uint32, bits []bool) error {
total := len(d.driveBits)
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.driveBits[i] = bits[i-start]
}
d.drive = encodeBytes(d.driveBits)
slog.Debug("UpdateDriveByBits成功", "drive", fmt.Sprintf("%v", d.drive), "driveBits", d.driveBits)
d.Emit(DCE_Drive_Update)
return nil
}
// UpdateDriveByBytes implements DC.
func (d *dc) UpdateDriveByBytes(start uint32, values []byte) error {
total := len(d.drive)
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.drive[start:end], values)
d.driveBits = decodeBools(d.drive)
slog.Debug("UpdateDriveByBytes成功", "drive", fmt.Sprintf("%v", d.drive), "driveBits", d.driveBits)
d.Emit(DCE_Drive_Update)
return nil
}
// Emit implements DC.
func (d *dc) Emit(event DCEvent) {
listeners := d.subscribes[event]
for _, v := range listeners {
v(d)
}
}
// On implements DC.
func (d *dc) On(event DCEvent, callback func(d DC)) {
d.subscribes[event] = append(d.subscribes[event], callback)
}
// Off implements DC.
func (d *dc) Off(event DCEvent, callback func(d DC)) {
panic("unimplemented")
}
func NewDC(d []byte, c []byte) DC {
return &dc{
drive: d,
driveBits: decodeBools(d),
collect: c,
collectBits: decodeBools(c),
subscribes: make(map[DCEvent][]func(d DC)),
}
}
func decodeBools(bytes []byte) (out []bool) {
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) {
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
}