package lc import ( "fmt" "github.com/sirupsen/logrus" "golang.org/x/text/encoding/simplifiedchinese" "lc-smartX/bx" "net" "strconv" "time" ) type Screener interface { Display() } type Screen struct { Id byte Sn string //B006K12311020021 Name string Type byte FileNum byte Files []string Conn net.Conn IsLive bool StateInfo *bx.StateInfo //状态信息 Params *bx.Params //屏参 } func NewScreen(name string, conn net.Conn) Screen { s := Screen{ Name: name, Conn: conn, IsLive: true, StateInfo: &bx.StateInfo{}, Params: &bx.Params{}, } state := s.State() s.StateInfo.Parse(state.Data) params := s.Param() s.Params.Parse(params.Data) return s } func (s *Screen) Display() { s.Lock(1, "P001") } func (s *Screen) send(data []byte) { if !s.IsLive { fmt.Println("连接已断开!") return } _, err := s.Conn.Write(data) if err != nil { logrus.Error("tcp write error:", err) s.IsLive = false } } // CorrectTime 校正时间 func (s *Screen) CorrectTime() (ok bool) { if !s.IsLive { return false } cmd := bx.NewBxCmdSystemClockCorrect(time.Now()) data := bx.NewBxDataPackCmd(cmd) _, err := s.Conn.Write(data.Pack()) if err != nil { logrus.WithFields(map[string]interface{}{"Id": s.Id, "Name": s.Name}).Errorf("Conn写数据失败:%v", err) return false } return true } type Color byte const ( Default Color = iota Red Green Yellow Blue LightBlue LightPurple White None ) // TextRam // 0x01——静止显示 // 0x02——快速打出 // 0x03——向左移动 // 0x04——向右移动 // 0x05——向上移动 // 0x06——向下移动 func (s *Screen) TextRam(str string, color Color, playMode byte) { if !s.IsLive { return } var areas []bx.BxArea //var id byte //var x, y int16 //var w, h int16 = 64, 16 encoder := simplifiedchinese.GB18030.NewEncoder() bytes, err := encoder.Bytes([]byte("\\C" + strconv.Itoa(int(color)) + str)) if err != nil { logrus.Error("编码转换失败:", err) return } x := 0x8000 w := 0x8040 area := bx.NewBxAreaDynamic(s.StateInfo.DynaAreaNum, playMode, int16(x), 0, int16(w), 16, bytes, false) areas = append(areas, area) // cmd := bx.NewBxCmdSendDynamicArea(areas) pack := bx.NewBxDataPackCmd(cmd) pack.SetDispType(2) //动态显示模式 d := pack.Pack() s.send(d) s.ReadResp() s.StateInfo.DynaAreaNum++ } // DelRamText 删除动态区,不传删除所有 func (s *Screen) DelRamText(numbers ...byte) { if !s.IsLive { return } cmd := bx.NewCmdDelDynamicArea(numbers) pack := bx.NewBxDataPackCmd(cmd) s.send(pack.Pack()) s.ReadResp() if len(numbers) == 0 { s.StateInfo.DynaAreaNum = 0 } else { s.StateInfo.DynaAreaNum-- } } func (s *Screen) TextFlash(msg string, color Color) { if !s.IsLive { return } encoder := simplifiedchinese.GB18030.NewEncoder() var bytes []byte // if color == None { bytes = []byte(msg) } else { bytes, _ = encoder.Bytes([]byte("\\C" + strconv.Itoa(int(color)) + msg)) } x := 0x8000 w := 0x8040 area := bx.NewBxAreaDynamic(0xff, 2, int16(x), 0, int16(w), 16, bytes, false) //if s.FileNum name := fmt.Sprintf("P%03d", s.StateInfo.ProgramNum) fmt.Println("文件名:", name) file := bx.NewBxFile(name, "", []bx.BxArea{area}) cmd := file.NewCmdWriteFile() pack := bx.NewBxDataPackCmd(cmd) data := pack.Pack() fmt.Println("数据长度:", len(data)) fmt.Printf("数据:% 02x\n", data) s.send(data) resp := s.ReadResp() if !resp.IsAck() { logrus.Error("设备拒绝写文件! error:", resp.Error().Description) return } pack1 := bx.NewBxDataPackCmd(cmd) data1 := pack1.Pack() fmt.Println("数据长度:", len(data)) s.send(data1) fmt.Printf("数据1:% 02x\n", data1) resp1 := s.ReadResp() if resp1.NoError() { s.StateInfo.ProgramNum++ } } func (s *Screen) Bitmap(name string, bitmap []byte) { file := bx.NewBitmapFile(name, bitmap) cmd := file.NewCmd() pack := bx.NewBxDataPackCmd(cmd) data := pack.Pack() fmt.Println("数据长度:", len(data)) fmt.Printf("数据:% 02x\n", data) s.send(data) resp := s.ReadResp() if !resp.IsAck() { logrus.Error("设备拒绝写文件! error:", resp.Error().Description) return } pack1 := bx.NewBxDataPackCmd(cmd) data1 := pack1.Pack() fmt.Println("数据长度1:", len(data1)) s.send(data1) fmt.Printf("写图文件数据:% 02x\n", data1) s.ReadResp() } // Lock 锁定状态:0x00——解锁状态,0x01——锁定状态 func (s *Screen) Lock(flag byte, name string) { cmd := bx.NewCmdLock(flag, name) pack := bx.NewBxDataPackCmd(&cmd) s.send(pack.Pack()) } func (s *Screen) QueryFile() { } func (s *Screen) DelFile(delFiles ...string) { cmd := bx.NewCmdDeleteFile(delFiles) pack := bx.NewBxDataPackCmd(cmd) s.send(pack.Pack()) s.ReadResp() if len(delFiles) == 0 { s.StateInfo.ProgramNum = 0 } else { s.StateInfo.ProgramNum-- } } func (s *Screen) DelText(delIds []byte) { cmd := bx.NewBxCmdSendDynamicArea(nil) cmd.SetDelAreaIds(delIds) pack := bx.NewBxDataPackCmd(cmd) s.send(pack.Pack()) } func (s *Screen) TurnOnOff(onOff bool) { if !s.IsLive { return } cmd := bx.NewBxCmdTurnOnOff(onOff) pack := bx.NewBxDataPackCmd(cmd) s.send(pack.Pack()) } // TimingSwitch 定时开关屏 // 13:49 开, 13:55 关,最多设置3组 // // onOffSet := [][2]uint64{ // {1349, 1355}, // } func (s *Screen) TimingSwitch(onOffSet [][2]uint64) { if !s.IsLive { return } cmd := bx.NewCmdTimingSwitch(onOffSet) pack := bx.NewBxDataPackCmd(cmd) s.send(pack.Pack()) } func (s *Screen) CancelTimingSwitch() { if !s.IsLive { return } cmd := bx.NewCmdCancelTimingSwitch() pack := bx.NewBxDataPackCmd(cmd) s.send(pack.Pack()) } func (s *Screen) State() *bx.BxResp { if !s.IsLive { return nil } cmd := bx.NewCmdState() pack := bx.NewBxDataPackCmd(cmd) s.send(pack.Pack()) r := s.ReadResp() return &r } func (s *Screen) Param() *bx.BxResp { if !s.IsLive { return nil } cmd := bx.NewCmdReadParams() pack := bx.NewBxDataPackCmd(cmd) s.send(pack.Pack()) r := s.ReadResp() return &r } func (s *Screen) Info() { s.StateInfo.Print(s.Name) } func (s *Screen) ReadResp() bx.BxResp { var resp = make([]byte, 1024) read, err := s.Conn.Read(resp) if err != nil { logrus.Error("读数据错误:", err) s.IsLive = false return bx.BxResp{} } var bxResp = bx.BxResp{} parse := bxResp.Parse(resp, read) if parse.IsAck() { fmt.Println("response ACK") fmt.Printf("原始响应数据:% 0x\n", resp[:read]) fmt.Println("解析响应数据:", parse) } else if parse.IsInfo() { fmt.Println("state ACK") fmt.Printf("原始响应数据:% 0x\n", resp[:read]) fmt.Println("解析响应数据:", parse) } else { fmt.Println("response") fmt.Printf("原始响应数据:% 0x\n", resp[:read]) fmt.Println("解析响应数据:", parse) } return *parse }