A few smaller changes
authorjweigele <jweigele@local>
Fri, 6 Jan 2023 01:59:53 +0000 (17:59 -0800)
committerjweigele <jweigele@local>
Fri, 6 Jan 2023 01:59:53 +0000 (17:59 -0800)
 * Bugfix in error message that was causing panics
 * Buffer send messages to speed up the surrounding loops
 * Check closing of delivery channel in the programs where it's reading,
   in case connection is killed
 * All white override, to change colors if you want :)

lights/main.go
reprocess/main.go
wunder/main.go

index 115e6850eb190bda72bfb827c3238b1a3af34792..b0d2a63509b1d1e39b5257295ae9000fa8ff0002 100644 (file)
@@ -51,12 +51,14 @@ type RGBConfigYaml struct {
 }
 
 type Switch struct {
-       State           bool
-       Location        string `yaml:"Location"`
-       FriendlyName    string `yaml:"FriendlyName"`
-       OverrideSeconds int    `yaml:"OverrideSeconds"`
-       ExpiresAt       time.Time
-       parentRelay     *RGBRelay
+       State               bool
+       ColorState          bool
+       Location            string `yaml:"Location"`
+       FriendlyName        string `yaml:"FriendlyName"`
+       OverrideSeconds     int    `yaml:"OverrideSeconds"`
+       StateExpiresAt      time.Time
+       ColorStateExpiresAt time.Time
+       parentRelay         *RGBRelay
 }
 
 // Switch definitions
@@ -64,22 +66,11 @@ func (curSwitch *Switch) getLocation() string {
        return curSwitch.Location
 }
 
-func (curSwitch *Switch) isActive() bool {
-       curTime := time.Now().UTC()
-       // this will default true when initialized
-       // thus, switch will start inactive like we want
-       if curTime.After(curSwitch.ExpiresAt) {
-               logger.V(5).Info("Switch is not active", "switch", curSwitch)
-               return false
-       }
-       logger.V(3).Info("Switch is active!", "switch", curSwitch)
-       return true
-}
-
 func (curSwitch *Switch) setExpired(bubbleUp bool) {
        logger.Info("Override removed for switch", "switch", curSwitch)
        curTime := time.Now().UTC()
-       curSwitch.ExpiresAt = curTime
+       curSwitch.StateExpiresAt = curTime
+       curSwitch.ColorStateExpiresAt = curTime
        // set every other switch (not including us to avoid the loop) at this location to expired
        if curSwitch.parentRelay != nil && bubbleUp {
                curSwitch.parentRelay.setSwitchesExpired(curSwitch)
@@ -98,10 +89,42 @@ func (curSwitch *Switch) getRoutingKey() string {
 func (curSwitch *Switch) setState(state bool) {
        curTime := time.Now().UTC()
        curSwitch.State = state
-       curSwitch.ExpiresAt = curTime.Add(time.Duration(curSwitch.OverrideSeconds) * time.Second)
+       curSwitch.StateExpiresAt = curTime.Add(time.Duration(curSwitch.OverrideSeconds) * time.Second)
        logger.Info("Setting state for switch", "state", state, "switch", curSwitch)
 }
 
+func (curSwitch *Switch) setColor() {
+       curTime := time.Now().UTC()
+       curSwitch.ColorStateExpiresAt = curTime.Add(time.Duration(curSwitch.OverrideSeconds) * time.Second)
+       logger.Info("Setting color state for switch", "switch", curSwitch)
+}
+
+// get on off status, first "is active", second "is on (or off)"
+func (curSwitch *Switch) getOnOff() (bool, bool) {
+       curTime := time.Now().UTC()
+       // this will default true when initialized
+       // thus, switch will start inactive like we want
+       if curTime.After(curSwitch.StateExpiresAt) {
+               logger.V(5).Info("Switch is not active", "switch", curSwitch)
+               return false, curSwitch.State
+       }
+       logger.V(3).Info("Switch is active!", "switch", curSwitch)
+       return true, curSwitch.State
+}
+
+// get color status, first "is active", second "is full white"
+func (curSwitch *Switch) getColor() (bool, bool) {
+       curTime := time.Now().UTC()
+       // this will default true when initialized
+       // thus, switch will start inactive like we want
+       if curTime.After(curSwitch.ColorStateExpiresAt) {
+               logger.V(5).Info("Switch is not active", "switch", curSwitch)
+               return false, curSwitch.ColorState
+       }
+       logger.V(3).Info("Switch is active!", "switch", curSwitch)
+       return true, curSwitch.ColorState
+}
+
 func (curSwitch *Switch) parseState(data map[string]interface{}) {
        logger.V(3).Info("Got parseState on switch", "switch", curSwitch, "data", data)
        switchAction := data["action"]
@@ -111,6 +134,8 @@ func (curSwitch *Switch) parseState(data map[string]interface{}) {
                curSwitch.setState(true)
        case "off_press_release", "off_press":
                curSwitch.setState(false)
+       case "up_press", "up_press_release":
+               curSwitch.setColor()
        case "down_press", "down_press_release":
                curSwitch.setExpired(true)
        default:
@@ -269,6 +294,8 @@ func (relay *RGBRelay) gammaCorrect(inputVal float64) float64 {
        } else {
                inputVal = inputVal / 12.92
        }
+       // clamp to 1.0
+       inputVal = math.Min(1.0, inputVal)
        return inputVal
 }
 
@@ -276,25 +303,6 @@ func (relay *RGBRelay) getRoutingKey() string {
        return "rgb_relay"
 }
 
-func (relay *RGBRelay) isSwitchActive() bool {
-       var retval bool
-       for _, curSwitch := range relay.switches {
-               if curSwitch.isActive() {
-                       retval = true
-               }
-       }
-       return retval
-}
-
-func (relay *RGBRelay) getSwitchOverride() bool {
-       var override bool
-       for _, curSwitch := range relay.switches {
-               if curSwitch.isActive() {
-                       override = curSwitch.State
-               }
-       }
-       return override
-}
 func (relay *RGBRelay) addSwitch(newSwitch *Switch) {
        if slices.Contains(relay.switches, newSwitch) {
                relay.logger.Error(nil, "Tried to add a switch twice", "switch", newSwitch)
@@ -324,6 +332,15 @@ func (relay *RGBRelay) setPWM(red, green, blue float64) {
 
 func (relay *RGBRelay) sendUpdate(red, green, blue float64) {
        relay.logger.V(3).Info("Sending update for relay")
+       // now, override for any switch that's active
+       for _, curSwitch := range relay.switches {
+               isActive, _ := curSwitch.getColor()
+               if isActive {
+                       red, green, blue = 1.0, 1.0, 1.0
+                       break
+               }
+       }
+
        rgbData, routingKey := relay.relayData.getRelayData(red, green, blue)
        sendItem := helper.RabbitSend{Data: rgbData, RoutingKey: routingKey, EmptySource: true}
        relay.sendChannel <- sendItem
@@ -335,9 +352,14 @@ func (relay *RGBRelay) shouldUpdate() bool {
        // get desired state, starting with the should dim value - i.e. was there recent motion
        var desiredState = !relay.shouldDim()
        // now, override for any switch that's active
-       if relay.isSwitchActive() {
-               desiredState = relay.getSwitchOverride()
+       for _, curSwitch := range relay.switches {
+               isActive, isOn := curSwitch.getOnOff()
+               if isActive {
+                       desiredState = isOn
+                       break
+               }
        }
+
        // just for brevity and clarity
        var LastState = relay.LastState
 
@@ -410,8 +432,10 @@ func (relayData ZigRelayData) getRelayData(red, green, blue float64) (map[string
 
                // again, sengled changes
                if relayData.parent.Sengled {
-                       logger.V(4).Info("Boosting saturation", "pre", s, "post", s+0.2)
-                       s += 0.2
+                       post := s + 0.2
+                       post = math.Min(1.0, post)
+                       logger.V(4).Info("Boosting saturation", "pre", s, "post", post)
+                       s = post
                }
                newColor := colorful.Hsv(h, s, v)
                x, y, z := newColor.Xyz()
@@ -667,7 +691,12 @@ func (manager *RGBManager) readLoop() {
        }
 
        //var counter int
-       for delivery := range deliveries {
+       for {
+               delivery, ok := <-deliveries
+               if !ok {
+                       logger.Error(nil, "Consume failed in read loop because channel closed, exiting")
+                       os.Exit(1)
+               }
                logger.V(3).Info("got a delivery", "delivery", delivery)
                item, err := helper.DecodeDelivery(delivery)
                // it's just one delivery so we're going to yell and then continue along unabated
@@ -711,6 +740,8 @@ func sendLoop(channel chan helper.RabbitSend, rabbit helper.RabbitConfig) {
                        logger.Error(err, "Unable to send data to rabbit, exiting!")
                        os.Exit(1)
                }
+               // give zigbee a bit of a delay to catch up?
+               time.Sleep(time.Duration(500) * time.Millisecond)
        }
 }
 
@@ -758,7 +789,8 @@ func main() {
                os.Exit(1)
        }
 
-       channel := make(chan helper.RabbitSend)
+       // buffer 5 messages
+       channel := make(chan helper.RabbitSend, 5)
        go sendLoop(channel, rabbit)
 
        manager := RGBManager{}
index dbbc18ba54cf9fd59c0ea03f78bd5a227448fbb2..4558da6322f6b276d0fd790c627ac1dbce0bfd01 100644 (file)
@@ -261,7 +261,12 @@ func readLoop(channel chan helper.RabbitSend, devices []device, rabbit helper.Ra
                os.Exit(1)
        }
 
-       for delivery := range deliveries {
+       for {
+               delivery, ok := <-deliveries
+               if !ok {
+                       logger.Error(nil, "Unable to consume in readLoop, exiting")
+                       os.Exit(1)
+               }
                item, err := helper.DecodeDelivery(delivery)
                // it's just one delivery so we're going to yell and then continue along unabated
                if err != nil {
index 38a81292820174fa6057498f40bdfff192c65d9f..9e4a139093865b9980a6fad657de6169a97c7cfd 100644 (file)
@@ -92,7 +92,7 @@ func tempLoop(channel chan int, weatherStation string, rabbit helper.RabbitConfi
                const tempLength int = 60
                currentTemp, err := fetchTemp(weatherStation)
                if err != nil {
-                       logger.Error(err, "msg", "Wasn't able to get temp, ignoring")
+                       logger.Error(err, "Wasn't able to get temp, ignoring")
                } else {
                        if currentTemp == 0 {
                                logger.Info("Got 0F for temp, ignoring")
@@ -104,7 +104,7 @@ func tempLoop(channel chan int, weatherStation string, rabbit helper.RabbitConfi
                                }
                                tempAvg := sum(tempList) / float64(len(tempList))
                                if math.Abs(tempAvg-celsius) > 3.0 {
-                                       logger.Info("msg", "temperature outside mean, not printing", "current", celsius, "average", tempAvg)
+                                       logger.Info("temperature outside mean, not printing", "current", celsius, "average", tempAvg)
                                } else {
                                        sendTemp(currentTemp, celsius, rabbit)
                                }