func (s *WyzeSense) getMac() error {
	var err error
	log.Debug("Start GetMac...")
	p, err := s.doSimpleCommand(getMac())
	if err != nil {
		return err
	}
	if p == nil {
		log.Debug("GetMac timed out")
	}
	log.Debugf("GetMac returned: %s", (p.payload))
	return nil
}
getMac sends the getmac cmd
package gosense
import (
	"context"
	"encoding/binary"
	"encoding/hex"
	"os"
	"time"
	log "github.com/sirupsen/logrus"
)
type WyzeSense struct {
	Name string
	fd       *os.File
	handlers map[cmdType]func(*WyzeSense, packet, context.CancelFunc) error
	alarmch  chan (Alarm)
	sensorch chan (SenseSensor)
	ctx              context.Context
	currentCmdCancel context.CancelFunc
	currentResponse  *packet
}
func NewWyzeSense(devicename string,
	alarmch chan (Alarm),
	sensorch chan (SenseSensor)) (*WyzeSense, error) {
	log.Infof("NewWyzeSense: trying to open device: [%s]", devicename)
	s := &WyzeSense{
		handlers: make(map[cmdType]func(*WyzeSense, packet, context.CancelFunc) error),
		ctx:      context.Background(),
		alarmch:  alarmch,
		sensorch: sensorch,
	}
	fs, err := os.OpenFile(devicename, os.O_RDWR, 0777)
	if err != nil {
		log.Errorf("Failed opening device: {%s}", err)
		return s, err
	}
	s.fd = fs
	s.handlers[notifySyncTime] = onSyncTime
	s.handlers[notifySensorAlarm] = onSensorAlarm
	s.handlers[notifyEventLog] = onEventLog
	go s.readerLoop()
	return s, nil
}
func (s *WyzeSense) Start() error {
	err := s.inquiry()
	if err != nil {
		log.Debugf("Inquiry failed: %s", err)
		return err
	}
	err = s.getMac()
	if err != nil {
		log.Debugf("GetMac failed: %s", err)
		return err
	}
	ver, err := s.getVersion()
	if err != nil {
		log.Debugf("GetVersion failed: %s", err)
		return err
	}
	log.Debugf("GetVersion: ver: [%s]", ver)
	sensors, err := s.GetSensorList()
	if err != nil {
		log.Debugf("GetSensorList failed: %s", err)
		return err
	}
	log.Debugf("GetSensorList: sensors: [%v]", sensors)
	err = s.finishAuth()
	if err != nil {
		log.Debugf("FinishAuth failed: %s", err)
		return err
	}
	log.Debugf("FinishAuth: success!")
	return nil
}
func (s *WyzeSense) Close() {
	if s.fd != nil {
		s.fd.Close()
	}
}
func findMagic(buf []byte) int {
	next := false
	for i, n := range buf {
		if 0x55 == n {
			next = true
			continue
		}
		if next && 0xaa == n {
			return i - 1
		}
		next = false
	}
	return -1
}
func (s *WyzeSense) readerLoop() {
	var err error
	buf := make([]byte, 0x4)
	buf = nil
	for {
		i := findMagic(buf)
		if i < 0 {
			buf, err = s.readRawHid()
			if err != nil {
				continue
			}
			continue
		}
		buf = buf[i:]
		l := len(buf)
		log.Debugf("Trying to parse: %d bytes: [ %s ]",
			l, hex.EncodeToString(buf))
		p, err := parsePacket(buf)
		if err != nil {
			log.Error("Error parsing buffer as packet")
			buf = buf[l:]
			continue
		}
		if cmdType(p.cmd>>8) == asyncCommand && p.cmd != asyncAck {
			log.Debugf("    ==> Sending ACK packet for cmd %04x", p.cmd)
			s.sendPacket(AsyncAck(p.cmd))
		}
		buf = buf[p.lenght():]
		if handler, ok := s.handlers[p.cmd]; ok {
			err = handler(s, p, s.currentCmdCancel)
		}
	}
}
func (s *WyzeSense) readRawHid() ([]byte, error) {
	buf := make([]byte, 0x80)
	_, err := s.fd.Read(buf)
	if err != nil {
		log.Errorf("Failed reading from device: ", err)
		return nil, err
	}
	l := buf[0]
	buf = buf[1 : l+1]
	log.Debugf("readRawHid: %d bytes: [ %s ]",
		l, hex.EncodeToString(buf))
	return buf, nil
}
func (s *WyzeSense) sendPacket(p packet) error {
	log.Debugf("====> sending: [%s]", p.toString())
	return p.send(s.fd)
}
func (s *WyzeSense) doCommand(cmd packet,
	handler func(*WyzeSense, packet, context.CancelFunc) error) (*packet, error) {
	var err error
	s.handlers[cmd.cmd+1] = handler
	ctxTimeout, cancelFunc := context.WithTimeout(s.ctx, 5*time.Second)
	s.currentCmdCancel = cancelFunc
	err = cmd.send(s.fd)
	if err != nil {
		log.Errorf("Failed sending to device: %s", err.Error())
		return nil, err
	}
	select {
	case <-ctxTimeout.Done():
		break
	}
	cancelFunc()
	delete(s.handlers, cmd.cmd+1)
	return s.currentResponse, err
}
func (s *WyzeSense) doSimpleCommand(cmd packet) (*packet, error) {
	var err error
	p, err := s.doCommand(cmd, func(s *WyzeSense, cmd packet, cancelFun context.CancelFunc) error {
		s.currentResponse = &cmd
		cancelFun()
		return nil
	})
	return p, err
}
func (s *WyzeSense) inquiry() error {
	var err error
	log.Debug("Start Inquiry...")
	p, err := s.doSimpleCommand(inquiry())
	if err != nil {
		return err
	}
	if p == nil {
		log.Debug("Inquiry timed out")
	}
	ret := p.payload[0]
	log.Debugf("Inquiry returned: %d", ret)
	return nil
}