func main() { // Install HAP devices x10Accessories := X10Devices() particleAccessories := ParticleDevices() accessories := append(x10Accessories, particleAccessories...) bridge := accessory.NewLightBulb(model.Info{ Name: "Bridge", Manufacturer: "Evan", }) t, err := hap.NewIPTransport("10000000", bridge.Accessory, accessories...) if err != nil { log.Fatal(err) } t.Start() // Setup REST API m := martini.Classic() m.Get("/", func() string { return "Hello world!" }) m.RunOnAddr(":5591") }
func main() { switchInfo := model.Info{ Name: "Lamp", } sw := accessory.NewSwitch(switchInfo) config := hap.Config{Pin: "12344321", Port: "12345", StoragePath: "./db"} t, err := hap.NewIPTransport(config, sw.Accessory) if err != nil { log.Fatal(err) } // Log to console when client (e.g. iOS app) changes the value of the on characteristic sw.OnStateChanged(func(on bool) { if on == true { log.Println("[INFO] Client changed switch to on") } else { log.Println("[INFO] Client changed switch to off") } }) // Periodically toggle the switch's on characteristic go func() { for { on := !sw.IsOn() if on == true { log.Println("[INFO] Switch on") } else { log.Println("[INFO] Switch off") } sw.SetOn(on) time.Sleep(5 * time.Second) } }() hap.OnTermination(func() { t.Stop() }) t.Start() }
func NewHomeKitService(thermostat *Thermostat) *HomeKitService { thermostatInfo := model.Info{ Name: "Thermostat", } hkThermostat := accessory.NewThermostat(thermostatInfo, temp, 17, 25, 0.5) hkThermostat.SetTargetMode(model.HeatCoolModeHeat) hkThermostat.OnTargetTempChange(func(temp float64) { log.Println("[INFO] HomeKit requested thermostat to change to", temp) thermostat.targetTemp = temp }) hkThermostat.OnTargetModeChange(func(mode model.HeatCoolModeType) { log.Println("[INFO] HomeKit requested thermostat to change to", mode) switch mode { case model.HeatCoolModeHeat: log.Println("[INFO] HomeKit setting thermostat to default on temp of", defaultOnTemp) thermostat.targetTemp = defaultOnTemp case model.HeatCoolModeOff: log.Println("[INFO] HomeKit setting thermostat to default off temp of", defaultOffTemp) thermostat.targetTemp = defaultOffTemp case model.HeatCoolModeAuto, model.HeatCoolModeCool: hkThermostat.SetTargetMode(model.HeatCoolModeHeat) } }) transport, err := hap.NewIPTransport("24282428", hkThermostat.Accessory) if err != nil { log.Fatal(err) } t := HomeKitService{ thermostat: thermostat, done: make(chan bool), hkThermostat: hkThermostat, transport: transport, } return &t }
func setupHomeKit() { aInfo := accessory.Info{ Name: "Hive Bridge", Manufacturer: "British Gas PLC", } a := accessory.New(aInfo, accessory.TypeBridge) tInfo := accessory.Info{ Name: "Heating", Manufacturer: "British Gas PLC", } t := accessory.NewThermostat(tInfo, 20.0, hive.MinTemp, hive.MaxTemp, 0.5) t.Thermostat.TargetTemperature.OnValueRemoteUpdate(targetTempChangeRequest) thermostat = t bInfo := accessory.Info{ Name: "Heating Boost", Manufacturer: "British Gas PLC", } b := accessory.NewSwitch(bInfo) b.Switch.On.OnValueRemoteUpdate(heatingBoostStateChangeRequest) heatingBoostSwitch = b sInfo := accessory.Info{ Name: "Hot Water", Manufacturer: "British Gas PLC", } h := accessory.NewSwitch(sInfo) h.Switch.On.OnValueRemoteUpdate(hotWaterStateChangeRequest) hotWaterSwitch = h config := hap.Config{ Pin: pin, } var err error transport, err = hap.NewIPTransport(config, a, t.Accessory, b.Accessory, h.Accessory) if err != nil { log.Fatal(err) } }
func main() { info := model.Info{ Name: "Personal Light Bulb", Manufacturer: "Matthias", } light := accessory.NewLightBulb(info) light.OnStateChanged(func(on bool) { if on == true { turnLightOn() } else { turnLightOff() } }) t, err := hap.NewIPTransport("32191123", light.Accessory) if err != nil { log.Fatal(err) } t.Start() }
func main() { info := model.Info{ Name: "My Door Sensor", SerialNumber: "XXX-YYY-ZZZ", Manufacturer: "Me", Model: "1", Firmware: "1.0", } doorSensor := accessory.NewContactSensor(info) t, err := hap.NewIPTransport(hap.Config{Pin: "32191123"}, doorSensor.Accessory) if err != nil { log.Fatal(err) } // Periodically toggle the contact sensor's state characteristic go func() { for { var state model.ContactSensorStateType if doorSensor.State() == model.ContactDetected { state = model.ContactNotDetected } else { state = model.ContactDetected } doorSensor.SetState(state) time.Sleep(5 * time.Second) } }() hap.OnTermination(func() { t.Stop() }) t.Start() }
func GetHKLight(light common.Light) *HKLight { hkLight, found := lights[light.ID()] if found { return hkLight } label, _ := light.GetLabel() log.Printf("[INFO] Creating New HKLight for %s", label) info := model.Info{ Name: label, Manufacturer: "LIFX", } lightBulb := accessory.NewLightBulb(info) power, _ := light.GetPower() lightBulb.SetOn(power) color, _ := light.GetColor() hue, saturation, brightness := ConvertLIFXColor(color) lightBulb.SetBrightness(int(brightness)) lightBulb.SetSaturation(saturation) lightBulb.SetHue(hue) transport, err := hap.NewIPTransport(pin, lightBulb.Accessory) if err != nil { log.Fatal(err) } go func() { transport.Start() }() hkLight = &HKLight{lightBulb.Accessory, nil, transport, lightBulb} lights[light.ID()] = hkLight lightBulb.OnIdentify(func() { timeout := 1 * time.Second for i := 0; i < 4; i++ { ToggleLight(light) time.Sleep(timeout) } }) lightBulb.OnStateChanged(func(power bool) { log.Printf("[INFO] Changed State for %s", label) light.SetPower(power) }) updateColor := func(light common.Light) { // HAP: [0...360] // LIFX: [0...MAX_UINT16] hue := lightBulb.GetHue() // HAP: [0...100] // LIFX: [0...MAX_UINT16] saturation := lightBulb.GetSaturation() // HAP: [0...100] // LIFX: [0...MAX_UINT16] brightness := lightBulb.GetBrightness() // [HSBKKelvinMin..HSBKKelvinMax] kelvin := HSBKKelvinDefault lifxHue := math.MaxUint16 * float64(hue) / float64(characteristic.MaxHue) lifxSaturation := math.MaxUint16 * float64(saturation) / float64(characteristic.MaxSaturation) lifxBrightness := math.MaxUint16 * float64(brightness) / float64(characteristic.MaxBrightness) color := common.Color{ uint16(lifxHue), uint16(lifxSaturation), uint16(lifxBrightness), kelvin, } light.SetColor(color, 500*time.Millisecond) } lightBulb.OnHueChanged(func(value float64) { log.Printf("[INFO] Changed Hue for %s to %d", label, value) updateColor(light) }) lightBulb.OnSaturationChanged(func(value float64) { log.Printf("[INFO] Changed Saturation for %s to %d", label, value) updateColor(light) }) lightBulb.OnBrightnessChanged(func(value int) { log.Printf("[INFO] Changed Brightness for %s to %d", label, value) updateColor(light) }) return hkLight }
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 handleNewLight(light common.Light) (err error) { id := light.ID() _, exists := lights[id] if exists { log.Debugf("A light with the ID '%s' has already been added", id) return nil } subscription, err := light.NewSubscription() if err != nil { log.WithField(`error`, err).Error(`Subscribing to light events`) return err } label, _ := light.GetLabel() log.Infof("Adding light [%s]", label) info := model.Info{ Name: label, Manufacturer: "LIFX", } haLight := accessory.NewLightBulb(info) lights[id] = lightMeta{ light: light, subscription: subscription, haLight: haLight, } // Get the initial state of the light and communicate it via HomeKit updateHaPowerState(light, haLight) updateHaColors(light, haLight) events := subscription.Events() go func() { for { select { case event := <-events: switch event := event.(type) { case common.EventUpdateColor: log.Infof("Light: %s, Event: Update Color", id) updateHaColors(light, haLight) case common.EventUpdateLabel: // TODO: Find out how to update the name of a homekit device log.Infof("Light: %s, Event: Update Label", id) case common.EventUpdatePower: log.Infof("Light: %s, Event: Update Power", id) updateHaPowerState(light, haLight) default: log.Debugf("Unhandled event on light: %+v", event) continue } } } }() haLight.OnIdentify(func() { timeout := 1 * time.Second for i := 0; i < 4; i++ { toggleLight(light) time.Sleep(timeout) } }) haLight.OnStateChanged(func(on bool) { go func() { light.SetPower(on) }() }) haLight.OnBrightnessChanged(func(value int) { go func() { updateLightColors(light, haLight) }() }) haLight.OnSaturationChanged(func(value float64) { go func() { updateLightColors(light, haLight) }() }) haLight.OnHueChanged(func(value float64) { go func() { updateLightColors(light, haLight) }() }) transport, err := hap.NewIPTransport(pin, haLight.Accessory) if err != nil { log.Fatal(err) } go func() { transport.Start() }() return nil }
// This app can connect to the UVR1611 data bus and provide the sensor values to HomeKit clients // // Optimizations: To improve the performance on a Raspberry Pi B+, the interrupt handler of the // gpio pin is removed every time after successfully decoding a packet. This allows other goroutines // (e.g. HAP server) to do their job more quickly. func main() { var ( pin = flag.String("pin", "", "Accessory pin required for pairing") mode = flag.String("conn", "mock", "Connection type; mock, gpio, replay") file = flag.String("file", "", "Log file from which to replay packets") port = flag.String("port", "P8_07", "GPIO port; default P8_07") timeout = flag.Int("timeout", 120, "Timeout in seconds until accessories are not reachable") ) flag.Parse() sensors = map[string]*hkuvr1611.Sensor{} info := InfoForAccessoryName("UVR1611") uvrAccessory = accessory.New(info, accessory.TypeBridge) timer_duration := time.Duration(*timeout) * time.Second timer = time.AfterFunc(timer_duration, func() { log.Println("[INFO] Not Reachable") if transport != nil { sensors = map[string]*hkuvr1611.Sensor{} transport.Stop() transport = nil } }) var conn Connection callback := func(packet uvr1611.Packet) { sensors := HandlePacket(packet) if transport == nil { config := hap.Config{Pin: *pin} if t, err := hap.NewIPTransport(config, uvrAccessory, sensors...); err != nil { log.Fatal(err) } else { go func() { t.Start() }() transport = t } } timer.Reset(timer_duration) } switch *mode { case "mock": conn = mock.NewConnection(callback) case "replay": conn = mock.NewReplayConnection(*file, callback) case "gpio": conn = gpio.NewConnection(*port, callback) default: log.Fatal("Incorrect -conn flag") } hap.OnTermination(func() { if transport != nil { transport.Stop() } conn.Close() timer.Stop() os.Exit(1) }) select {} }