使用Siri和树莓派DIY智能家居

需求

解决每天的开关灯操作,可以通过

实现控制卧室灯开关

设计

  1. 给家里的普通灯换一个无线开关(86型,315MHz 单火线无线遥控开关),淘宝上很多,使用固定编码
  2. 使用树莓派搭建HomeKit API网关
  3. 通过树莓派驱动315MHz无线模块,发射开关信号
  4. iPhone上安装Homekit APP:MyTouchHome,让手机可以发出控制指令

实现

实现过程中发现买的OPPLE的调光调色LED灯的遥控器没有采用315M/433M,无法使用现有模块去实现。

遥控拆了,从电路板上“剥皮”,使用漆包线跳线出来(忘拍图了)

之前有尝试nodejs去做(使用homebridge),现在对golang更感兴趣,改用golang实现。

最终测试OK,实现开灯关灯,调光调色以后再折腾

测试成功

代码

package main

import (
	"os"
	"os/signal"
	"time"

	"github.com/brutella/hc"
	"github.com/brutella/hc/accessory"
	"github.com/brutella/log"
	"github.com/davecheney/gpio"
)

func main() {
	log.Verbose = true
	log.Info = true

	// GPIO
	pinOn, err := gpio.OpenPin(20, gpio.ModeOutput)
	if err != nil {
		log.Fatalf("error opening pinOn! %s\n", err)
	}
	pinOff, err := gpio.OpenPin(21, gpio.ModeOutput)
	if err != nil {
		log.Fatalf("error opening pinOff! %s\n", err)
	}
	pinState, err := gpio.OpenPin(16, gpio.ModeInput)
	if err != nil {
		log.Fatalf("error opening pinState! %s\n", err)
	}

	// turn the led off on exit
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	go func() {
		for _ = range c {
			log.Printf("\nClearing and unexporting the pin.\n")
			pinOn.Clear()
			// pinOn.Close()
			pinOff.Clear()
			// pinOff.Close()
			os.Exit(0)
		}
	}()

	// HomeControl
	info := accessory.Info{
		Name:         "JerryLamp",
		Manufacturer: "Jerry",
	}

	acc := accessory.NewLightbulb(info)

	acc.Lightbulb.On.OnValueRemoteUpdate(func(on bool) {
		if on == true {
			// 发送开关信号到遥控器
			pinOn.Set()
			time.AfterFunc(600*time.Millisecond, func() {
				pinOn.Clear()
			})
			log.Println("Turn Light On")
		} else {
			pinOff.Set()
			time.AfterFunc(600*time.Millisecond, func() {
				pinOff.Clear()
			})
			log.Println("Turn Light Off")
		}
	})

	// 状态检测
	var timer *time.Timer
	timer = time.AfterFunc(1*time.Second, func() {
		acc.Lightbulb.On.SetValue(!pinState.Get())
		timer.Reset(1 * time.Second)
	})

	t, err := hc.NewIPTransport(hc.Config{Pin: "00102003"}, acc.Accessory)
	if err != nil {
		log.Fatal(err)
	}

	hc.OnTermination(func() {
		t.Stop()
	})

	t.Start()
}