232 lines
5.3 KiB
Go
232 lines
5.3 KiB
Go
package main
|
||
|
||
import (
|
||
"bytes"
|
||
"log"
|
||
"sync"
|
||
"time"
|
||
)
|
||
|
||
// Register 操作注册表
|
||
var Register map[string]func(worker *Worker)
|
||
|
||
// OperatorFlag 训练
|
||
type OperatorFlag uint16
|
||
|
||
const (
|
||
// UltrasonicPower bit15 超声波电源开关 1开,0关
|
||
UltrasonicPower OperatorFlag = 0b1000000000000000
|
||
// CirculatingIrrigation bit14 循环灌洗水泵 1开,0关
|
||
CirculatingIrrigation OperatorFlag = 0b0100000000000000
|
||
UFRecoil OperatorFlag = 0b0010000000000000 // bit13 UF 超滤膜反冲进水阀 1开,0关
|
||
UFPositive OperatorFlag = 0b0001000000000000 // bit12 UF 超滤膜正冲进水阀 1开,0关
|
||
UFTreatedWater OperatorFlag = 0b0000100000000000 // bit11 UF 超滤膜净水出水阀 1开,0关
|
||
UFRawWater OperatorFlag = 0b0000010000000000 // bit10 UF超滤膜原水进水阀 1开,0关
|
||
CirculatingTankWashWater OperatorFlag = 0b0000001000000000 // bit9 循环罐洗进水电动球阀 1开,0关
|
||
UFPositiveFlushingWaterOutlet OperatorFlag = 0b0000000100000000 // bit8 UF超滤膜正冲浓水出口电磁阀 1开,0关
|
||
CleaningTankExhaust OperatorFlag = 0b0000000010000000 // bit7 清洗罐排气电磁阀 1开,0关
|
||
DPFCompactCylinderControlB OperatorFlag = 0b0000000001000000 // bit6 DPF压紧气缸控制电磁阀B 1开,0关
|
||
DPFCompactCylinderControlA OperatorFlag = 0b0000000000100000 // bit5 DPF压紧气缸控制电磁阀A 1开,0关
|
||
CleaningTankDrainingWater OperatorFlag = 0b0000000000010000 // bit4 清洗罐放水阀控制电磁阀 1开,0关
|
||
GasExplosion OperatorFlag = 0b0000000000001000 // bit3 气爆阀控制电磁阀 1开,0关
|
||
CleaningTankInflation OperatorFlag = 0b0000000000000100 // bit2 清洗罐充气电磁阀 1开,0关
|
||
CleaningTankSealB OperatorFlag = 0b0000000000000010 // bit1 清洗罐密封圈充气电磁阀B 1开,0关
|
||
CleaningTankSealA OperatorFlag = 0b0000000000000001 // bit0 清洗罐密封圈充气电磁阀A 1开,0关
|
||
)
|
||
|
||
// init 初始化
|
||
func init() {
|
||
Register["干洗"] = func(worker *Worker) {
|
||
buf := &bytes.Buffer{}
|
||
buf.Write([]byte(0xaa))
|
||
}
|
||
}
|
||
|
||
// Worker 接收命令
|
||
type Worker struct {
|
||
commandLock *sync.Mutex
|
||
command *Command
|
||
|
||
port *SerialPort // 串口相关
|
||
|
||
readlogsLock *sync.Mutex
|
||
readlogs []Log
|
||
|
||
writelogsLock *sync.Mutex
|
||
isOperating bool
|
||
writelogs []Log
|
||
|
||
isStop int
|
||
waitGroup *sync.WaitGroup
|
||
}
|
||
|
||
// Log 日志
|
||
type Log struct {
|
||
Data []byte
|
||
Time time.Time
|
||
}
|
||
|
||
// NewWorker 创建一个工人
|
||
func NewWorker() *Worker {
|
||
w := &Worker{}
|
||
|
||
w.isStop = 0
|
||
w.waitGroup = &sync.WaitGroup{}
|
||
|
||
w.command = CreateCommand()
|
||
w.commandLock = new(sync.Mutex)
|
||
|
||
w.readlogsLock = &sync.Mutex{}
|
||
w.readlogs = make([]Log, 0, 1000)
|
||
|
||
w.writelogsLock = &sync.Mutex{}
|
||
w.writelogs = make([]Log, 0, 1000)
|
||
w.isOperating = false
|
||
|
||
return w
|
||
}
|
||
|
||
func (worker *Worker) write(data []byte) {
|
||
|
||
worker.writelogsLock.Lock()
|
||
worker.isOperating = true
|
||
worker.writelogs = append(worker.writelogs, Log{data, time.Now()})
|
||
if len(worker.writelogs) >= 1000 {
|
||
worker.writelogs = worker.writelogs[500:1000]
|
||
}
|
||
worker.writelogsLock.Unlock()
|
||
|
||
}
|
||
|
||
// read 如果没有读到数据为nil
|
||
func (worker *Worker) read() (result []byte) {
|
||
|
||
worker.readlogsLock.Lock()
|
||
if len(worker.readlogs) > 0 {
|
||
copy(worker.readlogs[len(worker.readlogs)-1].Data, result)
|
||
}
|
||
worker.writelogsLock.Unlock()
|
||
|
||
return result
|
||
}
|
||
|
||
func (worker *Worker) operator(wait *sync.WaitGroup) {
|
||
defer wait.Done()
|
||
|
||
if CurrentOS == "linux" {
|
||
|
||
for {
|
||
|
||
if worker.isStop > 0 {
|
||
break
|
||
}
|
||
|
||
now := time.Now()
|
||
|
||
worker.commandLock.Lock()
|
||
if worker.isOperating {
|
||
|
||
if now.Sub(worker.command.commandTime).Seconds() >= 5 {
|
||
// TODO: 操作
|
||
if operate, ok := Register[worker.command.commands]; ok {
|
||
operate(worker)
|
||
}
|
||
worker.isOperating = false
|
||
}
|
||
|
||
}
|
||
worker.commandLock.Unlock()
|
||
}
|
||
|
||
} else { // Windows
|
||
|
||
}
|
||
|
||
}
|
||
|
||
func (worker *Worker) status(wait *sync.WaitGroup) {
|
||
defer wait.Done()
|
||
|
||
if CurrentOS == "linux" {
|
||
|
||
for {
|
||
|
||
if worker.isStop > 0 {
|
||
break
|
||
}
|
||
|
||
var buf []byte
|
||
n, err := worker.port.linuxRPort.Read(buf)
|
||
if err != nil {
|
||
log.Println(err)
|
||
} else {
|
||
|
||
if n > 0 {
|
||
|
||
worker.readlogsLock.Lock()
|
||
worker.readlogs = append(worker.readlogs, Log{buf, time.Now()})
|
||
if len(worker.readlogs) >= 1000 {
|
||
worker.readlogs = worker.readlogs[500:1000]
|
||
}
|
||
|
||
log.Println("data size ", n)
|
||
log.Panicln("data: ", buf)
|
||
worker.readlogsLock.Unlock()
|
||
}
|
||
}
|
||
|
||
time.Sleep(time.Millisecond * 50)
|
||
}
|
||
|
||
} else { // windows
|
||
|
||
for {
|
||
|
||
if worker.isStop > 0 {
|
||
break
|
||
}
|
||
|
||
var buf []byte
|
||
n, err := worker.port.windowsRWPort.Read(buf)
|
||
if err != nil {
|
||
log.Println(err)
|
||
} else {
|
||
|
||
if n > 0 {
|
||
|
||
log.Println("data size ", n)
|
||
log.Panicln("data: ", buf)
|
||
|
||
worker.readlogsLock.Lock()
|
||
worker.readlogs = append(worker.readlogs, Log{buf, time.Now()})
|
||
if len(worker.readlogs) >= 1000 {
|
||
worker.readlogs = worker.readlogs[500:1000]
|
||
}
|
||
|
||
log.Println("data size ", n)
|
||
log.Panicln("data: ", buf)
|
||
worker.readlogsLock.Unlock()
|
||
|
||
}
|
||
|
||
}
|
||
|
||
time.Sleep(time.Millisecond * 50)
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
// Run 运行
|
||
func (worker *Worker) Run() {
|
||
|
||
sp := NewSerialPort()
|
||
sp.OpenPort()
|
||
worker.port = sp
|
||
|
||
worker.waitGroup.Add(1)
|
||
go worker.status(worker.waitGroup)
|
||
|
||
worker.waitGroup.Wait()
|
||
}
|