// NewIPTransport creates a transport to provide accessories over IP. // // The IP transports stores the crypto keys inside a database, which // is by default inside a folder at the current working directory. // The folder is named exactly as the accessory name. // // The transports can contain more than one accessory. If this is the // case, the first accessory acts as the HomeKit bridge. // // *Important:* Changing the name of the accessory, or letting multiple // transports store the data inside the same database lead to // unexpected behavior – don't do that. // // The transport is secured with an 8-digit pin, which must be entered // by an iOS client to successfully pair with the accessory. If the // provided transport config does not specify any pin, 00102003 is used. func NewIPTransport(config Config, a *accessory.Accessory, as ...*accessory.Accessory) (Transport, error) { // Find transport name which is visible in mDNS name := a.Info.Name.GetValue() if len(name) == 0 { log.Info.Panic("Invalid empty name for first accessory") } cfg := defaultConfig(name) cfg.merge(config) storage, err := util.NewFileStorage(cfg.StoragePath) if err != nil { return nil, err } database := db.NewDatabaseWithStorage(storage) hap_pin, err := NewPin(cfg.Pin) if err != nil { return nil, err } cfg.load(storage) device, err := hap.NewSecuredDevice(cfg.id, hap_pin, database) t := &ipTransport{ storage: storage, database: database, device: device, config: cfg, container: accessory.NewContainer(), mutex: &sync.Mutex{}, context: hap.NewContextForSecuredDevice(device), emitter: event.NewEmitter(), } t.addAccessory(a) for _, a := range as { t.addAccessory(a) } // Users can only pair discoverable accessories if t.isPaired() { cfg.discoverable = false } cfg.categoryId = int(t.container.AccessoryType()) cfg.updateConfigHash(t.container.ContentHash()) cfg.save(storage) // Listen for events to update mDNS txt records t.emitter.AddListener(t) return t, err }
func TestPutCharacteristic(t *testing.T) { info := accessory.Info{ Name: "My Switch", SerialNumber: "001", Manufacturer: "Google", Model: "Bridge", } a := accessory.NewSwitch(info) a.Switch.On.SetValue(false) m := accessory.NewContainer() m.AddAccessory(a.Accessory) // find on characteristic with type TypeOn var cid int64 for _, s := range a.Accessory.Services { for _, c := range s.Characteristics { if c.Type == characteristic.TypeOn { cid = c.ID } } } if cid == 0 { t.Fatal("characteristic not found") } char := data.Characteristic{AccessoryID: 1, CharacteristicID: cid, Value: true} var slice []data.Characteristic slice = append(slice, char) chars := data.Characteristics{Characteristics: slice} b, err := json.Marshal(chars) if err != nil { t.Fatal(err) } var buffer bytes.Buffer buffer.Write(b) controller := NewCharacteristicController(m) err = controller.HandleUpdateCharacteristics(&buffer, characteristic.TestConn) if err != nil { t.Fatal(err) } if is, want := a.Switch.On.GetValue(), true; is != want { t.Fatalf("is=%v want=%v", is, want) } }
func TestCharacteristicNotification(t *testing.T) { a := accessory.New(info, accessory.TypeOther) c := accessory.NewContainer() c.AddAccessory(a) buffer, err := Body(a, a.Info.Name.Characteristic) if err != nil { t.Fatal(err) } bytes, err := ioutil.ReadAll(buffer) if err != nil { t.Fatal(err) } if is, want := string(bytes), `{"characteristics":[{"aid":1,"iid":5,"value":"My Bridge"}]}`; is != want { t.Fatalf("is=%v want=%v", is, want) } }
func TestGetCharacteristic(t *testing.T) { info := accessory.Info{ Name: "My Bridge", SerialNumber: "001", Manufacturer: "Google", Model: "Bridge", } a := accessory.New(info, accessory.TypeBridge) m := accessory.NewContainer() m.AddAccessory(a) aid := a.GetID() cid := a.Info.Name.GetID() values := idsString(aid, cid) controller := NewCharacteristicController(m) res, err := controller.HandleGetCharacteristics(values) if err != nil { t.Fatal(err) } b, err := ioutil.ReadAll(res) if err != nil { t.Fatal(err) } var chars data.Characteristics err = json.Unmarshal(b, &chars) if err != nil { t.Fatal(err) } if is, want := len(chars.Characteristics), 1; is != want { t.Fatalf("is=%v want=%v", is, want) } if x := chars.Characteristics[0].Value; x != "My Bridge" { t.Fatal(x) } }