代码拉取完成,页面将自动刷新
package main
import (
"bytes"
"context"
"errors"
"fmt"
"os/exec"
"strconv"
"time"
log "github.com/sirupsen/logrus"
)
// SerialConfig serial port config
// type SerialConfig struct {
// Dev string `json:"dev,omitempty"`
// Baudrate int `json:"baudrate,omitempty"`
// }
// Duration time.Duration alias
type Duration time.Duration
// BeidouSenderConfig beidou config
type BeidouSenderConfig struct {
// SerialConfig SerialConfig `json:"serial,omitempty"`
ToolPath string `json:"toolPath,omitempty"`
ResponseTimeout Duration `json:"responseTimeout,omitempty"`
Dev string `json:"dev,omitempty"`
Cmd string `json:"cmd,omitempty"`
Addr string `json:"addr,omitempty"`
CommType string `json:"commType,omitempty"`
TransType string `json:"transType,omitempty"`
Interval float64 `json:"interval,omitempty"`
}
// BeidouResult beidou sending result
type BeidouResult struct {
Data string
Success bool
Err error
Response []byte
}
type sendItem struct {
notifyCh chan BeidouResult
data string
}
// BeidouSender sender handle
type BeidouSender struct {
Config BeidouSenderConfig
queueCh chan sendItem
queue []sendItem
}
// UnmarshalJSON implements json unmarshal interface
func (d *Duration) UnmarshalJSON(raw []byte) error {
unqoted, err := strconv.Unquote(string(raw))
if err != nil {
return err
}
xd, err := time.ParseDuration(unqoted)
if err != nil {
return err
}
*d = Duration(xd)
return nil
}
// NewBeidouSender create beidou sender instance
func NewBeidouSender(config BeidouSenderConfig) (*BeidouSender, error) {
sender := &BeidouSender{
Config: config,
queueCh: make(chan sendItem),
queue: []sendItem{},
}
return sender, nil
}
func (bs *BeidouSender) format(data []byte) string {
str := fmt.Sprintf("%X", data)
dev := bs.Config.Dev
cmd := bs.Config.Cmd
addr := bs.Config.Addr
commtype := bs.Config.CommType
transtype := bs.Config.TransType
checksumC := fmt.Sprintf("%s%s,%s,%s,%s,%s", dev, cmd, addr, commtype, transtype, str)
sum := XorCheck([]byte(checksumC))
return fmt.Sprintf("$%s*%02X\r\n", checksumC, sum)
}
// Send put data into sending queue
func (bs *BeidouSender) Send(data []byte, notifyCh chan BeidouResult) error {
s := bs.format(data)
if len(s) <= 0 {
return errors.New("empty data")
}
item := sendItem{
notifyCh: notifyCh,
data: s,
}
bs.queueCh <- item
return nil
}
// func readLine(port *serial.Port, timeout time.Duration) (string, error) {
// go func() {
// var buf [1024]byte
// n, err := port.Read(buf)
// if err == nil {
// }
// }()
// t := time.NewTimer(timeout)
// select {
// case <- t.C:
// {
// return "", errors.New("timeout")
// }
// case <-complete:
// {
// return "", nil
// }
// }
// }
// func (bs *BeidouSender) writeSentence(data string, ch chan BeidouResult) {
// log.WithFields(log.Fields{"data": data}).Info("write data")
// c := &serial.Config{
// Name: bs.Config.SerialConfig.Dev,
// Baud: bs.Config.SerialConfig.Baudrate,
// ReadTimeout: time.Duration(bs.Config.ResponseTimeout),
// }
// s, err := serial.OpenPort(c)
// if err != nil {
// // log.WithFields(log.Fields{"err": err, "COM": c}).Error("error opening device")
// ch <- BeidouResult{
// Data: data,
// Success: false,
// Err: err,
// }
// return
// }
// defer s.Close() // nolint
// nw, err := s.Write([]byte(data))
// if err != nil {
// ch <- BeidouResult{
// Data: data,
// Success: false,
// Err: err,
// }
// return
// }
// if nw != len(data) {
// ch <- BeidouResult{
// Data: data,
// Success: false,
// Err: err,
// }
// return
// }
// var buf [100]byte
// nr, err := s.Read(buf[0:])
// if err != nil {
// ch <- BeidouResult{
// Data: data,
// Success: false,
// Err: err,
// // Response: []byte{},
// }
// return
// }
// if nr == 0 {
// ch <- BeidouResult{
// Data: data,
// Success: false,
// Err: err,
// // Response: buf,
// }
// return
// }
// fmt.Printf("%s\n", string(buf[0:nr]))
// ch <- BeidouResult{
// Data: data,
// Success: true,
// Err: err,
// Response: buf[0:nr],
// }
// }
func (bs *BeidouSender) writeSentence(ctx context.Context, data string, ch chan BeidouResult) {
path := bs.Config.ToolPath
cmd := exec.CommandContext(ctx, path, data)
var stdout bytes.Buffer
cmd.Stdout = &stdout
err := cmd.Run()
ch <- BeidouResult{
Data: data,
Success: true,
Err: err,
Response: stdout.Bytes(),
}
}
func (bs *BeidouSender) sendSentence(ctx context.Context, item sendItem) {
go bs.writeSentence(ctx, item.data, item.notifyCh)
<-ctx.Done()
}
// Start starts the beidou sending daemon
func (bs *BeidouSender) Start() {
timer := time.NewTicker(time.Second * time.Duration(bs.Config.Interval))
var cancel context.CancelFunc
for {
select {
case item := <-bs.queueCh:
{
bs.queue = append(bs.queue, item)
break
}
case t := <-timer.C:
{
log.WithFields(log.Fields{"timer": t.Format(time.RFC3339), "queue": len(bs.queue)}).Info("beidou sending timer tick")
if len(bs.queue) > 0 {
if cancel != nil {
cancel()
}
sendingItem := bs.queue[0]
bs.queue = bs.queue[1:]
var ctx context.Context
ctx, cancel = context.WithDeadline(context.Background(), time.Now().Add(20*time.Second))
go bs.sendSentence(ctx, sendingItem)
}
}
}
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。