package flow import ( "database/sql" "encoding/binary" "log" "os" "sync" "time" serial "github.com/tarm/serial" "gopkg.in/ini.v1" ) // GetOperatorDB 获取 operator 日志 func GetOperatorDB() *sql.DB { db, err := sql.Open("sqlite3", "./log.db") if err != nil { panic(err) } _, err = db.Exec("create table if not EXISTS operator ( ts INT, rootflow varchar(255), flowpath text, writelog char(8), readlog char(14))") if err != nil { panic(err) } return db } // OperatorFlag 操作位 type OperatorFlag uint16 const ( UltrasonicPower OperatorFlag = 0b1000000000000000 // UltrasonicPower bit15 超声波电源开关 1开,0关 // CYZ-A-X CirculatingIrrigation OperatorFlag = 0b0100000000000000 // CirculatingIrrigation bit14 循环灌洗水泵 1开,0关 UFRecoil OperatorFlag = 0b0010000000000000 // bit13 UF 超滤膜反冲进水阀 1开,0关 UFPositive OperatorFlag = 0b0001000000000000 // bit12 UF 超滤膜正冲进水阀 1开,0关 // YM-01-X-03 UFTreatedWater OperatorFlag = 0b0000100000000000 // bit11 UF 超滤膜净水出水阀 1开,0关 UFRawWater OperatorFlag = 0b0000010000000000 // bit10 UF超滤膜原水进水阀 1开,0关 // CirculatingTankWashWater YM-01-X-01 CirculatingTankWashWater OperatorFlag = 0b0000001000000000 // bit9 循环罐洗进水电动球阀 1开,0关 UFPositiveFlushingWaterOutlet OperatorFlag = 0b0000000100000000 // bit8 UF超滤膜正冲浓水出口电磁阀 1开,0关 // CleaningTankExhaust YV-02-02-1-X-06 CleaningTankExhaust OperatorFlag = 0b0000000010000000 // bit7 清洗罐排气电磁阀 1开,0关 DPFCompactCylinderControlB OperatorFlag = 0b0000000001000000 // bit6 DPF压紧气缸控制电磁阀B 1开,0关 DPFCompactCylinderControlA OperatorFlag = 0b0000000000100000 // bit5 DPF压紧气缸控制电磁阀A 1开,0关 // YV-02-05-1-X-04 CleaningTankDrainingWater OperatorFlag = 0b0000000000010000 // bit4 清洗罐放水阀控制电磁阀 1开,0关 GasExplosion OperatorFlag = 0b0000000000001000 // bit3 气爆阀控制电磁阀 1开,0关 // YV-02-02-1-X-02 CleaningTankInflation OperatorFlag = 0b0000000000000100 // bit2 清洗罐充气电磁阀 1开,0关 CleaningTankSealB OperatorFlag = 0b0000000000000010 // bit1 清洗罐密封圈充气电磁阀B 1开,0关 CleaningTankSealA OperatorFlag = 0b0000000000000001 // bit0 清洗罐密封圈充气电磁阀A 1开,0关 ) // OperatorOption 操作位设置 func OperatorOption(flag OperatorFlag) []byte { var buf []byte = make([]byte, 8, 8) buf[0] = byte(0xaa) buf[1] = byte(0x55) binary.BigEndian.PutUint16(buf[2:], uint16(flag)) check := byte(0) for _, b := range buf { check += b } buf[7] = check return buf } // Operator 日志系统 type Operator struct { port *serial.Port portReaderLock *sync.Mutex portWriterLock *sync.Mutex oplog *sql.DB } var operator *Operator func init() { op := &Operator{} op.portReaderLock = &sync.Mutex{} op.portWriterLock = &sync.Mutex{} op.oplog = GetOperatorDB() var portid string var baud int var rtimeout time.Duration var cfg *ini.File cfg, err := ini.Load("my_test.cfg") if err != nil { log.Println(err) log.Println("加载配置my.cfg失败, 将使用默认值") f, err := os.OpenFile("./my_test.cfg", os.O_CREATE|os.O_WRONLY, 0666) if err != nil { panic(err) } f.WriteString("[config]\nportid = COM1\nbaud = 9600\nreadtimeout = 5") cfg, err = ini.Load("my_test.cfg") if err != nil { panic(err) } } section := cfg.Section("config") portid = section.Key("portid").MustString("COM1") baud = section.Key("baud").MustInt(9600) rtimeout = time.Second * time.Duration(section.Key("readtimeout").MustInt64(5)) port, err := serial.OpenPort(&serial.Config{Name: portid, Baud: baud, ReadTimeout: rtimeout}) if err != nil { panic(err) } op.port = port }