package device import ( "encoding/json" "fmt" mqtt "github.com/eclipse/paho.mqtt.golang" log "github.com/sirupsen/logrus" "github.com/smbrave/goutil" "github.com/spf13/cast" "strings" "sync" "time" ) var ( ZHTypeGetDevStatus = "getDevStatus" ZHTypeSetTime = "setTime" ZHTypeStartTts = "startTts" ZHTypeStopAudio = "stopAudio" ZHTypeNextAudio = "nextAudio" ZHTypePauseAudio = "pauseAudio" ZHTypeSetAudioVol = "setAudioVol" ) type ZhihengVoice struct { sync.Mutex deviceId string client mqtt.Client callback Callback brand string model string } func NewZhihengVoice(deviceId string, client mqtt.Client, callback Callback) *ZhihengVoice { s := &ZhihengVoice{ deviceId: deviceId, client: client, callback: callback, brand: BrandZhiheng, model: "voice", } if callback != nil { if deviceId == "#" { client.Subscribe(fmt.Sprintf("%s/%s/#", s.brand, s.model), 2, s.Callback) } else { client.Subscribe(fmt.Sprintf("%s/%s/%s/#", s.brand, s.model, deviceId), 2, s.Callback) } } return s } func (s *ZhihengVoice) Operate(cmd string) error { return s.Play(cmd) } func (s *ZhihengVoice) KeepAlive() error { if s.deviceId == "#" { return nil } topic := fmt.Sprintf("%s/%s/%s/cmd", s.brand, s.model, s.deviceId) payload := `{"method":"getDevStatus"}` publishACK := s.client.Publish(topic, 2, false, payload) publishACK.WaitTimeout(time.Second) return publishACK.Error() } func (s *ZhihengVoice) Play(tts string) error { if s.deviceId == "#" { return nil } params := make(map[string]interface{}) params["method"] = "startTts" params["content"] = tts topic := fmt.Sprintf("%s/%s/%s/cmd", s.brand, s.model, s.deviceId) publishACK := s.client.Publish(topic, 2, false, goutil.EncodeJSON(params)) publishACK.WaitTimeout(time.Second) return publishACK.Error() } func (s *ZhihengVoice) GetWelcome() error { if s.deviceId == "#" { return nil } params := make(map[string]interface{}) params["method"] = "getWelcome" topic := fmt.Sprintf("%s/%s/%s/cmd", s.brand, s.model, s.deviceId) publishACK := s.client.Publish(topic, 2, false, goutil.EncodeJSON(params)) publishACK.WaitTimeout(time.Second) return publishACK.Error() } func (s *ZhihengVoice) GetSimCheck() error { if s.deviceId == "#" { return nil } params := make(map[string]interface{}) params["method"] = "getSimCheck" topic := fmt.Sprintf("%s/%s/%s/cmd", s.brand, s.model, s.deviceId) publishACK := s.client.Publish(topic, 2, false, goutil.EncodeJSON(params)) publishACK.WaitTimeout(time.Second) return publishACK.Error() } func (s *ZhihengVoice) SetLed(colors []string) error { if s.deviceId == "#" { return nil } params := make(map[string]interface{}) params["method"] = "setLed" params["colors"] = colors topic := fmt.Sprintf("%s/%s/%s/cmd", s.brand, s.model, s.deviceId) publishACK := s.client.Publish(topic, 2, false, goutil.EncodeJSON(params)) publishACK.WaitTimeout(time.Second) return publishACK.Error() } func (s *ZhihengVoice) SetLedMode() error { if s.deviceId == "#" { return nil } params := make(map[string]interface{}) params["method"] = "setLedMode1" params["colors"] = []string{"#FF0000", "#00FF00", "#0000FF", "#000000", "#FFFFFF", "#FFFF00", "#00FFFF", "#FF00FF"} params["hasClockwise"] = false params["speed"] = 5 topic := fmt.Sprintf("%s/%s/%s/cmd", s.brand, s.model, s.deviceId) publishACK := s.client.Publish(topic, 2, false, goutil.EncodeJSON(params)) publishACK.WaitTimeout(time.Second) return publishACK.Error() } func (s *ZhihengVoice) CloseLed() error { return s.SetLed([]string{"#000000", "#000000", "#000000", "#000000", "#000000", "#000000", "#000000", "#000000"}) } func (s *ZhihengVoice) SetAudioVol(vol int) error { if s.deviceId == "#" { return nil } params := make(map[string]interface{}) params["method"] = "setAudioVol" params["vol"] = vol topic := fmt.Sprintf("%s/%s/%s/cmd", s.brand, s.model, s.deviceId) publishACK := s.client.Publish(topic, 2, false, goutil.EncodeJSON(params)) publishACK.WaitTimeout(time.Second) return publishACK.Error() } func (s *ZhihengVoice) Reboot() error { if s.deviceId == "#" { return nil } params := make(map[string]interface{}) params["method"] = "reboot" topic := fmt.Sprintf("%s/%s/%s/cmd", s.brand, s.model, s.deviceId) publishACK := s.client.Publish(topic, 2, false, goutil.EncodeJSON(params)) publishACK.WaitTimeout(time.Second) return publishACK.Error() } func (s *ZhihengVoice) getDeviceId(topic string) string { devId := s.deviceId if devId == "#" { fields := strings.Split(topic, "/") if len(fields) >= 3 { devId = fields[2] } } return devId } func (s *ZhihengVoice) Callback(client mqtt.Client, message mqtt.Message) { s.Lock() defer s.Unlock() topic := message.Topic() payload := message.Payload() // res的才回调,忽略cmd请求 if strings.HasSuffix(topic, "cmd") { return } log.Debugf("[%s][%s] deviceId[%s] topic[%s] payloyad[%s]", s.brand, s.model, s.deviceId, topic, string(payload)) var callMsg Message callMsg.MsgType = FSTypeGetinfo callMsg.MsgTime = time.Now().Unix() callMsg.MsgId = cast.ToString(message.MessageID()) callMsg.DeviceId = s.getDeviceId(topic) callMsg.Topic = topic callMsg.Data = make(map[string]interface{}) json.Unmarshal([]byte(payload), &callMsg.Data) s.callback(&callMsg) }