A few tweaks
authorjweigele <jweigele@local>
Thu, 15 Dec 2022 05:02:01 +0000 (21:02 -0800)
committerjweigele <jweigele@local>
Thu, 15 Dec 2022 05:02:01 +0000 (21:02 -0800)
 * Deal with send errors by actually exiting, which should cause pod
    restart to reconnect (or backoff, or whatever)
 * A bit more logging when you can't cast a map on DIY action decodes
 * Wait to refresh off states on lights, preventing IMMEDIATE turn-off
    when you first start the program, or have the pod moved elsewhere.
    Normal off->on and all other actions are unaffected.

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

index 3f0e95f7f6f1c710ff30ae28ee090bcb5c252ad7..953f5d063ce79751d99caa57c339fbb0118a8c28 100644 (file)
@@ -162,16 +162,18 @@ func (relayData RelayData) getRelayData(red, green, blue float64) (map[string]in
 }
 
 type RGBRelay struct {
-       UpdateStaleness int    `yaml:"UpdateStaleness"`
-       DimmingTimeout  int    `yaml:"DimmingTimeout"`
-       Location        string `yaml:"Location"`
-       LastUpdate      time.Time
-       LastMotion      time.Time
-       LastState       bool
-       logger          logr.Logger
-       sendChannel     chan helper.RabbitSend
-       switches        []*Switch `yaml:"Switches"`
-       relayData       IRelayData
+       UpdateStaleness   int    `yaml:"UpdateStaleness"`
+       DimmingTimeout    int    `yaml:"DimmingTimeout"`
+       Location          string `yaml:"Location"`
+       LastUpdate        time.Time
+       LastMotion        time.Time
+       LastState         bool
+       logger            logr.Logger
+       sendChannel       chan helper.RabbitSend
+       switches          []*Switch `yaml:"Switches"`
+       relayData         IRelayData
+       startupFinishTime time.Time
+       startupComplete   bool
 }
 
 /*func NewRGBRelay(Location string, DimmingTimeout int, sendChannel chan helper.RabbitSend) *RGBRelay {
@@ -184,6 +186,8 @@ type RGBRelay struct {
 func (relay *RGBRelay) Init(sendChannel chan helper.RabbitSend) {
        relay.logger = logger.WithValues("relay", relay)
        relay.sendChannel = sendChannel
+       // keep checking until we exceed this value, then we're ready to change some states
+       relay.startupFinishTime = time.Now().UTC().Add(time.Duration(300) * time.Second)
        relay.relayData = RelayData{parent: relay}
        // initialize defaults, if they weren't set previously
        if relay.DimmingTimeout == 0 {
@@ -206,6 +210,22 @@ func (relay *RGBRelay) shouldOverride() bool {
        return false
 }
 
+func (relay *RGBRelay) isStartupComplete() bool {
+       // short circuit the time checking if we already passed it
+       if relay.startupComplete {
+               return true
+       }
+       // otherwise, if we just passed the startupFinishTime,
+       // set the flag for later and return true
+       if time.Now().UTC().After(relay.startupFinishTime) {
+               relay.startupComplete = true
+               return true
+       }
+
+       // we're still starting up, just return false
+       return false
+}
+
 // getMetricValue is used to set prometheus lights on/off state
 func (relay *RGBRelay) getMetricValue() float64 {
        if relay.LastState {
@@ -343,8 +363,11 @@ func (relay *RGBRelay) shouldUpdate() bool {
                relay.setLastUpdate()
                retval = true
        } else if LastState == false && desiredState == false {
-               // last state off, desired off (aka already off)
-               if relay.LastUpdateTooOld() {
+               // last state off, desired off (aka already off), last conditional checks to see if we just booted up or not
+               if !relay.isStartupComplete() {
+                       relay.logger.V(2).Info("Waiting for startup to complete before refreshing lights off")
+                       retval = false
+               } else if relay.LastUpdateTooOld() {
                        relay.logger.V(2).Info("Last update too old, refreshing (off)")
                        relay.setLastUpdate()
                        retval = true
@@ -683,7 +706,11 @@ func sendLoop(channel chan helper.RabbitSend, rabbit helper.RabbitConfig) {
        for sendItem := range channel {
                //helper.SendData(sendItem, rabbit, true)
                logger.V(3).Info("Sending item", "item", sendItem)
-               helper.SendData(sendItem, rabbit, false)
+               err := helper.SendData(sendItem, rabbit, false)
+               if err != nil {
+                       logger.Error(err, "Unable to send data to rabbit, exiting!")
+                       os.Exit(1)
+               }
        }
 }
 
index 077031cab3364daaee420ae2c00a17e9a6cb6494..dbbc18ba54cf9fd59c0ea03f78bd5a227448fbb2 100644 (file)
@@ -161,7 +161,7 @@ func handleTemp(obj map[string]interface{}) {
 
 }
 
-func handleDIY(obj map[string]interface{}, sendChannel chan helper.RabbitSend) {
+func (dev *diydevice) handleDIY(obj map[string]interface{}, sendChannel chan helper.RabbitSend) {
        logger.V(1).Info("DIY data received", "obj", obj)
        _, isAction := obj["action"]
        if isAction {
@@ -205,7 +205,7 @@ func handleDIY(obj map[string]interface{}, sendChannel chan helper.RabbitSend) {
                                logger.Info("Sense type not detected, ignoring")
                        }
                } else {
-                       logger.Error(nil, "Unable to cast action key to map ignoring this delivery", "action", obj["action"])
+                       logger.Error(nil, "Unable to cast action key to map ignoring this delivery", "obj", obj, "device", dev)
                }
 
        } else {
@@ -225,14 +225,14 @@ func (dev *powerdevice) shouldUpdate(now time.Time) bool {
        return false
 }
 
-func handlePower(obj map[string]interface{}, sendChannel chan helper.RabbitSend, triggerDevice *powerdevice) {
+func (dev *powerdevice) handlePower(obj map[string]interface{}, sendChannel chan helper.RabbitSend) {
        now := time.Now().UTC()
        logger.V(1).Info("Power data received", "obj", obj)
-       if triggerDevice.shouldUpdate(now) {
-               triggerDevice.add(now, obj["power"].(float64))
-               powerGauge.With(prometheus.Labels{"ePDUOutletStatusIndex": triggerDevice.friendlyName, "ePDUOutletStatusOutletName": triggerDevice.powerName}).Set(triggerDevice.avgPower())
+       if dev.shouldUpdate(now) {
+               dev.add(now, obj["power"].(float64))
+               powerGauge.With(prometheus.Labels{"ePDUOutletStatusIndex": dev.friendlyName, "ePDUOutletStatusOutletName": dev.powerName}).Set(dev.avgPower())
                // here, we have unique objects, but we're forced to be more permissive for temperature so might as well do the same here
-               tempHash := labelValHash{labelValues: []string{triggerDevice.friendlyName, triggerDevice.powerName}}
+               tempHash := labelValHash{labelValues: []string{dev.friendlyName, dev.powerName}}
                powerExpire[tempHash.getHash()] = now
 
        }
@@ -280,11 +280,11 @@ func readLoop(channel chan helper.RabbitSend, devices []device, rabbit helper.Ra
                                switch t := device.(type) {
                                case *diydevice:
                                        logger.V(2).Info("DIY device, sending to handle", "device", device)
-                                       handleDIY(item, channel)
+                                       device.(*diydevice).handleDIY(item, channel)
                                case *powerdevice:
                                        logger.V(2).Info("Power device, sending to handle", "device", device)
                                        // it's explicitly a powerdevice, so cast it before sending
-                                       handlePower(item, channel, device.(*powerdevice))
+                                       device.(*powerdevice).handlePower(item, channel)
                                default:
                                        logger.Info("Found a device we can't classify", "device", device, "type", t)
                                }
@@ -329,7 +329,11 @@ func powerLoop(sendChannel chan helper.RabbitSend, devices []device) {
 func sendLoop(channel chan helper.RabbitSend, rabbit helper.RabbitConfig) {
        for sendItem := range channel {
                //helper.SendData(sendItem, rabbit, true)
-               helper.SendData(sendItem, rabbit, false)
+               err := helper.SendData(sendItem, rabbit, false)
+               if err != nil {
+                       logger.Error(err, "Unable to send data to rabbit, exiting!")
+                       os.Exit(1)
+               }
        }
 }
 
index 53150c41ed8a9bada1f637e0be40c3a126624965..38a81292820174fa6057498f40bdfff192c65d9f 100644 (file)
@@ -123,7 +123,11 @@ func sendTemp(tempValueF float64, tempValueC float64, rabbit helper.RabbitConfig
        // just a constant now
        sendObj["location"] = "Outside (Wunderground)"
        rabbitData := helper.RabbitSend{Data: sendObj, IncludeDate: true}
-       helper.SendData(rabbitData, rabbit, true)
+       err := helper.SendData(rabbitData, rabbit, true)
+       if err != nil {
+               logger.Error(err, "Unable to send data, exiting!")
+               os.Exit(1)
+       }
 }
 
 func main() {