func (a ActivationHandler) query() bool {
	a.queryChannel <- true
	return <-a.queryChannel
}
Query activation state
package main
import (
	"time"
)
type ToggleData struct {
	Mode uint
	Data uint
}
type ActivationHandler struct {
	queryChannel  chan bool
	toggleChannel chan ToggleData
	setChannel    chan bool
}
func startActivation(actChannel chan *ActivationHandler, quit chan bool, reactivationDelay uint) {
	var reactivate time.Time
	var reactivatePending bool
	a := &ActivationHandler{}
	a.queryChannel = make(chan bool)
	a.toggleChannel = make(chan ToggleData)
	a.setChannel = make(chan bool)
	actChannel <- a
	ticker := time.Tick(1 * time.Second)
	var nextToggleTime = time.Now()
forever:
	for {
		select {
		case <-quit:
			break forever
		case <-a.queryChannel:
			a.queryChannel <- grimdActive
		case v := <-a.toggleChannel:
			if v.Mode == 1 && nextToggleTime.After(time.Now()) {
				logger.Warning("Toggle is too close: wait 10 seconds\n")
			} else {
				if v.Mode == 1 {
					grimdActive = !grimdActive
				} else {
					grimdActive = false
				}
				nextToggleTime = time.Now().Add(time.Duration(10) * time.Second)
				if !grimdActive && reactivationDelay > 0 {
					reactivate = time.Now().Add(time.Duration(v.Data) * time.Second)
					reactivatePending = true
				} else {
					reactivatePending = false
				}
				a.queryChannel <- grimdActive
			}
		case v := <-a.setChannel:
			grimdActive = v
			reactivatePending = false
			a.setChannel <- grimdActive
		case <-ticker:
			now := time.Now()
			if reactivatePending && now.After(reactivate) {
				logger.Notice("Reactivating grimd (timer)")
				grimdActive = true
				reactivatePending = false
			}
		}
	}
	logger.Debugf("Activation goroutine exiting")
	quit <- true
}