Ejemplo n.º 1
0
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)
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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
}