func updateBulb(bulb *lifx.Bulb) { on := true if bulb.GetPower() == 0 { on = false } state := bulb.GetState() name := bulb.GetLabel() if light, found := lights[name]; found == true && state.Visible == false { log.Printf("Remove light", light) removeLight(light, name) return } light_bulb := lightForBulb(bulb).bulb light_bulb.SetOn(on) brightness := float64(state.Brightness) / float64(math.MaxUint16) * 100 saturation := float64(state.Saturation) / float64(math.MaxUint16) * 100 hue := float64(state.Hue) / float64(math.MaxUint16) * 360 light_bulb.SetBrightness(int(brightness)) light_bulb.SetSaturation(saturation) light_bulb.SetHue(hue) log.Println("LIFX is now", on) log.Println("Brightness", brightness) log.Println("Saturation", saturation) log.Println("Hue", hue) }
func lightForBulb(bulb *lifx.Bulb) *lifxLight { label := bulb.GetLabel() light, found := lights[label] if found == true { fmt.Println("Found") return light } fmt.Println("Create new switch for blub") info := model.Info{ Name: label, Manufacturer: "LIFX", } light_bulb := accessory.NewLightBulb(info) light_bulb.OnIdentify(func() { timeout := 1 * time.Second toggleBulb(bulb) time.Sleep(timeout) toggleBulb(bulb) time.Sleep(timeout) toggleBulb(bulb) time.Sleep(timeout) toggleBulb(bulb) }) light_bulb.OnStateChanged(func(on bool) { if on == true { client.LightOn(bulb) log.Println("Switch is on") } else { client.LightOff(bulb) log.Println("Switch is off") } }) updateColors := func(client *lifx.Client, bulb *lifx.Bulb) { // TODO define max variables in Gohap // HAP: [0...360] // LIFX: [0...MAX_UINT16] hue := light_bulb.GetHue() // HAP: [0...100] // LIFX: [0...MAX_UINT16] saturation := light_bulb.GetSaturation() // HAP: [0...100] // LIFX: [0...MAX_UINT16] brightness := light_bulb.GetBrightness() // [2500..9000] kelvin := HSBKKelvinDefault lifx_brightness := math.MaxUint16 * float64(brightness) / 100 lifx_saturation := math.MaxUint16 * float64(saturation) / 100 lifx_hue := math.MaxUint16 * float64(hue) / 360 log.Println("Brightness", lifx_brightness) log.Println("Hue", lifx_saturation) log.Println("Saturation", lifx_hue) client.LightColour(bulb, uint16(lifx_hue), uint16(lifx_saturation), uint16(lifx_brightness), uint16(kelvin), 0x0500) } light_bulb.OnBrightnessChanged(func(value int) { log.Println("Brightness", value) updateColors(client, bulb) }) light_bulb.OnSaturationChanged(func(value float64) { log.Println("Saturation", value) updateColors(client, bulb) }) light_bulb.OnHueChanged(func(value float64) { log.Println("Hue", value) updateColors(client, bulb) }) transport, err := hap.NewIPTransport(pin, light_bulb.Accessory) if err != nil { log.Fatal(err) } go func() { transport.Start() }() light = &lifxLight{transport, light_bulb, light_bulb.Accessory} lights[label] = light return light }
func (d *LifxDriver) newLight(bulb *lifx.Bulb) (*devices.LightDevice, error) { //TODO cut this down! name := bulb.GetLabel() d.log.Infof("Making light with ID: %s Label: %s", bulb.GetLifxAddress(), name) light, err := devices.CreateLightDevice(d, &model.Device{ NaturalID: bulb.GetLifxAddress(), NaturalIDType: "lifx", Name: &name, Signatures: &map[string]string{ "ninja:manufacturer": "Lifx", "ninja:productName": "Lifx Bulb", "ninja:productType": "Light", "ninja:thingType": "light", }, }, d.conn) if err != nil { d.log.FatalError(err, "Could not create light device") } light.ApplyOnOff = func(state bool) error { var err error if state { err = d.client.LightOn(bulb) } else { err = d.client.LightOff(bulb) } if err != nil { return fmt.Errorf("Failed to set on-off state: %s", err) } return nil } light.ApplyLightState = func(state *devices.LightDeviceState) error { jsonState, _ := json.Marshal(state) d.log.Infof("Sending light state to lifx bulb: %s", jsonState) if state.OnOff != nil { err := light.ApplyOnOff(*state.OnOff) if err != nil { return err } } if state.Color != nil || state.Brightness != nil || state.Transition != nil { // pull out the origin state bulbState := bulb.GetState() if state.Brightness == nil { brightness := float64(bulbState.Brightness) / math.MaxUint16 state.Brightness = &brightness } if state.Color == nil { // save the brightness brightness := state.Brightness state = convertState(&bulbState) state.Brightness = brightness } if state.Transition == nil { state.Transition = &defaultTransition } /*if state.Color == nil { return fmt.Errorf("Color value missing from batch set") } if state.Brightness == nil { return fmt.Errorf("Brightness value missing from batch set") }*/ switch state.Color.Mode { case "hue": return d.client.LightColour( bulb, uint16(*state.Color.Hue*math.MaxUint16), uint16(*state.Color.Saturation*math.MaxUint16), uint16(*state.Brightness*math.MaxUint16), 0, uint32(*state.Transition), ) case "xy": //TODO: Lifx does not support XY color return fmt.Errorf("XY color mode is not yet supported in the Lifx driver") case "temperature": d.client.LightColour( bulb, 0, 0, uint16(*state.Brightness*math.MaxUint16), uint16(*state.Color.Temperature), uint32(*state.Transition), ) default: return fmt.Errorf("Unknown color mode %s", state.Color.Mode) } } return nil } bulb.SetStateHandler(buildStateHandler(d, bulb, light)) if err := light.EnableOnOffChannel(); err != nil { d.log.FatalError(err, "Could not enable lifx on-off channel") } if err := light.EnableBrightnessChannel(); err != nil { d.log.FatalError(err, "Could not enable lifx brightness channel") } if err := light.EnableColorChannel("temperature", "hue"); err != nil { d.log.FatalError(err, "Could not enable lifx color channel") } if err := light.EnableTransitionChannel(); err != nil { d.log.FatalError(err, "Could not enable lifx transition channel") } // extra channels for sensors illuminance := channels.NewIlluminanceChannel() if err := d.conn.ExportChannel(light, illuminance, "illuminance"); err != nil { d.log.FatalError(err, "Could not enable lifx illuminance channel") } d.log.Debugf("register illuminance channel for %s", bulb.GetLifxAddress()) d.devices[bulb.GetLifxAddress()] = &lifxDevice{illuminance} return light, nil }