package main //screen操作相关 import ( "context" "encoding/json" "github.com/sirupsen/logrus" "lc/common/mqtt" "lc/common/protocol" "lc/common/util" "lc/edge/led_screen/clt_client" "strconv" "strings" "time" ) type LedDevice struct { LedInfo playing string //当前播放节目 没有用到 ctx context.Context cancel context.CancelFunc downQueue *util.MlQueue //upQueue *util.MlQueue mapTopicHandle map[string]func(m mqtt.Message) } func (l *LedDevice) GetCltUrl(ctlurl string) string { return l.BaseURL + ctlurl } func NewLedDevice(info LedInfo) *LedDevice { ctx, cancel := context.WithCancel(context.Background()) dev := LedDevice{ info, "", ctx, cancel, util.NewQueue(100), //util.NewQueue(50), make(map[string]func(m mqtt.Message)), } dev.SetTopicHandle() dev.MQTTSubscribe() go dev.Handle() return &dev } func (l *LedDevice) SetTopicHandle() { l.mapTopicHandle[protocol.TP_LED_SET_PGMS] = l.PublishProgram //发布节目 l.mapTopicHandle[protocol.TP_LED_QUERY_PGMS] = l.ListPrograms //查询节目 l.mapTopicHandle[protocol.TP_LED_DELETE] = l.DeleteProgram //删除节目 l.mapTopicHandle[protocol.TP_LED_CLEAN] = l.CleanAll //清除所有节目 l.mapTopicHandle[protocol.TP_LED_QUERY_INFO] = l.QueryInfo //查询屏信息 l.mapTopicHandle[protocol.TP_LED_SWITCH] = l.SwitchProgram //切换节目 l.mapTopicHandle[protocol.TP_LED_SNAPSHOT] = l.SnapShot //快照 l.mapTopicHandle[protocol.TP_LED_QUERY_SCHEDULE] = l.GetSchedule //获取排程 l.mapTopicHandle[protocol.TP_LED_SET_SCHEDULE] = l.SetSchedule //发布排程 l.mapTopicHandle[protocol.TP_LED_QUERY_POWERSTATUS] = l.PowerStatus //电源状态 l.mapTopicHandle[protocol.TP_LED_SET_CMD] = l.ControlPower //控制电源 l.mapTopicHandle[protocol.TP_LED_QUERY_RESOLUTION] = l.Resolution //屏幕参数 l.mapTopicHandle[protocol.TP_LED_QUERY_VOLUME] = l.GetVolume //查询音量 l.mapTopicHandle[protocol.TP_LED_SET_VOLUME] = l.SetVolume //设置音量 l.mapTopicHandle[protocol.TP_LED_QUERY_BRIGHTCOLOR] = l.GetBrightColor //查询亮度和色温 l.mapTopicHandle[protocol.TP_LED_SET_BRIGHTNESS] = l.SetBright //设置亮度和色温 } func (l *LedDevice) MQTTSubscribe() { GetMQTTMgr().Subscribe(GetTopic(l.SN, "down"), mqtt.AtMostOnce, l.HandleMessage, ToCloud) } func (l *LedDevice) HandleMessage(m mqtt.Message) { l.downQueue.Put(m) } func (l *LedDevice) Handle() { //timer := time.NewTicker(1 * time.Minute) timer := time.NewTicker(10 * time.Second) for { select { case <-l.ctx.Done(): logrus.Errorf("设备[%s]的LedDevice.Handle退出,原因:%v", l.LedInfo.SN, l.ctx.Err()) return case <-timer.C: //心跳,检查在线状态, 每隔1分钟执行一次 url := l.GetCltUrl(clt_client.POWERS_TATUS) _, err := clt_client.GetClient().CommonGet(url) if err != nil { l.CheckOnline(l, uint8(1)) logrus.Errorf(" error: %v", err) continue } l.CheckOnline(l, uint8(0)) l.LedData(l) default: if m, ok, _ := l.downQueue.Get(); ok { if mm, ok := m.(mqtt.Message); ok { action := strings.Split(mm.Topic(), "/")[4] if fn, ok := l.mapTopicHandle[action]; ok { fn(mm) } else { logrus.Errorf("LcDevice.Handle:不支持的主题:%s", mm.Topic()) } } } else { time.Sleep(50 * time.Millisecond) } } } } func (o *LedDevice) CheckOnline(dev *LedDevice, online uint8) { var obj protocol.Pack_LedState if str, err := obj.EnCode(dev.SN, appConfig.GID, GetNextUint64(), util.MlNow(), online); err == nil { topic := appConfig.Tenant + "/cltled/" + dev.SN + "/up/" + protocol.TP_LED_STATE + "/" + strconv.Itoa(int(GetNextUint64())) //fmt.Printf("topic = %v str=%v \n", topic, str) GetMQTTMgr().Publish(topic, []byte(str), mqtt.AtMostOnce, ToCloud) } } // LedData 上报信息屏详细信息 func (o *LedDevice) LedData(dev *LedDevice) { var data protocol.CltledData //电源状态 res, _ := clt_client.GetClient().CommonGet(o.GetCltUrl(clt_client.POWERS_TATUS)) json.Unmarshal(res, &data) //音量 res, _ = clt_client.GetClient().CommonGet(o.GetCltUrl(clt_client.GET_VOLUME)) json.Unmarshal(res, &data) //亮度色温 res, _ = clt_client.GetClient().CommonGet(o.GetCltUrl(clt_client.GET_BRIGHTCOLOR)) json.Unmarshal(res, &data) //开关机时间 res, _ = clt_client.GetClient().CommonGet(o.GetCltUrl(clt_client.GET_SCHEDULE)) json.Unmarshal(res, &data) //分辨率 res, _ = clt_client.GetClient().CommonGet(o.GetCltUrl(clt_client.RESOLUTION)) json.Unmarshal(res, &data) //当前节目 res, _ = clt_client.GetClient().CommonGet(o.GetCltUrl(clt_client.LIST_PROGRAMS)) resMap := make(map[string]map[string]interface{}) json.Unmarshal(res, &resMap) payingName, ok := resMap["playing"]["name"] if ok { if s, ok := payingName.(string); ok { data.Playing = s } } var obj protocol.Pack_LedCltledData if str, err := obj.EnCode(dev.SN, appConfig.GID, GetNextUint64(), &data); err == nil { topic := appConfig.Tenant + "/cltled/" + dev.SN + "/up/" + protocol.TP_LED_DATA + "/" + strconv.Itoa(int(GetNextUint64())) GetMQTTMgr().Publish(topic, []byte(str), mqtt.AtMostOnce, ToCloud) } } func GetNextUint64() uint64 { u64, _ := IDGen.NextId() return uint64(u64) } //===============POST===== // PublishProgram 平台发布节目 func (l *LedDevice) PublishProgram(m mqtt.Message) { clt_client.GetClient().PublishProgram(m, l.BaseURL) //获取结果 并 响应云端 l.ListPrograms(m) //发布成功 //if resp.Playing.Name == pro.Name+".vsn" { // l.playing = resp.Playing.Name // logrus.Infof("%s发布成功!耗时:%v", pro.Name, (later - now)) //} else { // logrus.Infof("%s发布失败!耗时:%v", pro.Name, (later - now)) //} } func (l *LedDevice) SetSchedule(m mqtt.Message) { url := l.GetCltUrl(clt_client.SET_SCHEDULE) l.DoCommonPost(url, "func SetSchedule", m) l.GetSchedule(m) } // ControlPower 控制电源 func (l *LedDevice) ControlPower(m mqtt.Message) { url := l.GetCltUrl(clt_client.CONTROL_POWER) l.DoCommonPost(url, "func ControlPower", m) l.PowerStatus(m) } func (l *LedDevice) DoCommonPost(url, funcname string, m mqtt.Message) { err := clt_client.GetClient().CommonPost(m.Payload(), url) if err != nil { logrus.Errorf(funcname+" error: %v", err) } } //==========================GET==================================GET // ListPrograms 查询所有节目以及当前播放的节目 func (l *LedDevice) ListPrograms(m mqtt.Message) { url := l.GetCltUrl(clt_client.LIST_PROGRAMS) l.DoCommonGet(url, "func ListPrograms", m) } // QueryInfo 查询屏通用信息 func (l *LedDevice) QueryInfo(m mqtt.Message) { url := l.GetCltUrl(clt_client.QUERY_INFO) l.DoCommonGet(url, "func QueryInfo", m) } // PowerStatus 获取电源状态 func (l *LedDevice) PowerStatus(m mqtt.Message) { url := l.GetCltUrl(clt_client.POWERS_TATUS) l.DoCommonGet(url, "get power status", m) } // Resolution 查询屏幕参数 func (l *LedDevice) Resolution(m mqtt.Message) { url := l.GetCltUrl(clt_client.RESOLUTION) l.DoCommonGet(url, "func Resolution", m) } // GetSchedule 查询电源排程 func (l *LedDevice) GetSchedule(m mqtt.Message) { url := l.GetCltUrl(clt_client.GET_SCHEDULE) l.DoCommonGet(url, "func GetSchedule", m) } // GetBrightColor GetBrightnessColorTemperature 查询亮度和色温 func (l *LedDevice) GetBrightColor(m mqtt.Message) { url := l.GetCltUrl(clt_client.GET_BRIGHTCOLOR) l.DoCommonGet(url, "func GetBrightnessColorTemperature", m) } // GetVolume 查询音量 func (l *LedDevice) GetVolume(m mqtt.Message) { url := l.GetCltUrl(clt_client.GET_VOLUME) l.DoCommonGet(url, "func GetVolume", m) } // SnapShot 截屏 func (l *LedDevice) SnapShot(m mqtt.Message) { url := l.GetCltUrl(clt_client.SNAPSHOT) shot := clt_client.GetClient().SnapShot(url) GetMQTTMgr().Publish(getUpTopic(m.Topic()), shot, mqtt.AtMostOnce, ToCloud) } func (l *LedDevice) DoCommonGet(url, funcname string, m mqtt.Message) { resp, err := clt_client.GetClient().CommonGet(url) if err != nil { logrus.Errorf(funcname+" error: %v", err) } GetMQTTMgr().Publish(getUpTopic(m.Topic()), resp, mqtt.AtMostOnce, ToCloud) } //================================PUT // SwitchProgram 切换节目 func (l *LedDevice) SwitchProgram(m mqtt.Message) { clt_client.GetClient().SwitchProgram(m, l.BaseURL) l.SnapShot(m) } // SetBright 调节屏幕亮度 func (l *LedDevice) SetBright(m mqtt.Message) { url := l.GetCltUrl(clt_client.SET_BRIGHT) err := clt_client.GetClient().CommonPut(m.Payload(), url) if err != nil { logrus.Errorf("set bright error: %v", err) } l.GetBrightColor(m) } // SetVolume 设置音量 func (l *LedDevice) SetVolume(m mqtt.Message) { url := l.GetCltUrl(clt_client.SET_VOLUME) err := clt_client.GetClient().CommonPut(m.Payload(), url) if err != nil { logrus.Errorf("set volume error: %v", err) } l.GetVolume(m) } //=============DELETE===== // DeleteProgram 删除节目 func (l *LedDevice) DeleteProgram(m mqtt.Message) { clt_client.GetClient().DelPrograms(m, l.BaseURL) //获取结果 并 响应云端 l.ListPrograms(m) } // CleanAll 清除所有节目 func (l *LedDevice) CleanAll(m mqtt.Message) { clt_client.GetClient().CleanAll(l.BaseURL) //获取结果 并 响应云端 l.ListPrograms(m) }