}
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 {
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 {
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 {
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
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)
+ }
}
}
}
-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 {
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 {
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
}
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)
}
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)
+ }
}
}
// 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() {