MCPcopy Index your code
hub / github.com/brutella/hap

github.com/brutella/hap @v0.0.35

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.0.35 ↗ · + Follow
950 symbols 2,677 edges 323 files 152 documented · 16% updated 20mo ago★ 41913 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

hap

GoDoc Widget Travis Widget

hap (previously hc) is a lightweight library to develop HomeKit accessories in Go. It abstracts the HomeKit Accessory Protocol (HAP) and makes it easy to work with services and characteristics.

hap handles the underlying communication between HomeKit accessories and clients. You can focus on implementing the business logic for your accessory, without having to worry about the protocol.

Here are some projects which use hap.

What is HomeKit?

HomeKit is a set of protocols and libraries from Apple. It is used by Apple's platforms to communicate with smart home appliances. A non-commercial version of the documentation is now available on the HomeKit developer website.

HomeKit is fully integrated into iOS since iOS 8. Developers can use HomeKit.framework to communicate with accessories using high-level APIs.

Home+.app

I've developed the Home+ app to control HomeKit accessories from iPhone, iPad, and Apple Watch. If you want to support hap, please purchase Home from the App Store. That would be awesome. ❤️

Migrate from hc

This library is a rewrite of hc. If you want to migrate from hc, consider the following changes.

  • Instead of hc.NewIPTransport(...) you now call hap.NewServer(...) to create a server.
  • You can create your own persistent storage by implementing the Store interface.
  • Setting the value of a characteristic can now fail. Fixes hc#163
  • You can define custom http handlers. Fixes hc#212
server.ServeMux().HandleFunc("/ping", func(res http.ResponseWriter, req *http.Request) {
    res.Write([]byte("pong"))
})
  • You can define your own public and private key (just in case) by setting the Key field of the server. Otherwise those keys are generate and stored on disk for you.
server.Key = hap.KeyPair{
    Public:  []byte{...},
    Private: []byte{...},
}

Features

  • Supports Go modules (requires Go 1.13)
  • Full implementation of the HAP in Go
  • Supports all HomeKit services and characteristics
  • Built-in service announcement via DNS-SD using dnssd
  • Runs on linux and macOS
  • Documentation: http://godoc.org/github.com/brutella/hap

Usage

In a following example a simple on/off switch is created. It can be paired with HomeKit using the Apple Home app – use the pin code 00102003.

package main

import (
    "github.com/brutella/hap"
    "github.com/brutella/hap/accessory"

    "context"
    "log"
    "os"
    "os/signal"
    "syscall"
)

func main() {
    // Create the switch accessory.
    a := accessory.NewSwitch(accessory.Info{
        Name: "Lamp",
    })

    // Store the data in the "./db" directory.
    fs := hap.NewFsStore("./db")

    // Create the hap server.
    server, err := hap.NewServer(fs, a.A)
    if err != nil {
        // stop if an error happens
        log.Panic(err)
    }

    // Setup a listener for interrupts and SIGTERM signals
    // to stop the server.
    c := make(chan os.Signal)
    signal.Notify(c, os.Interrupt)
    signal.Notify(c, syscall.SIGTERM)

    ctx, cancel := context.WithCancel(context.Background())
    go func() {
        <-c
        // Stop delivering signals.
        signal.Stop(c)
        // Cancel the context to stop the server.
        cancel() 
    }()

    // Run the server.
    server.ListenAndServe(ctx)
}

Events

The library provides callback functions, which let you know when a client updates a characteristic value. The following example shows how to get notified when the On characteristic value changes.

a.Switch.On.OnValueRemoteUpdate(func(on bool) {
    if on == true {
        log.Println("Switch is on")
    } else {
        log.Println("Switch is off")
    }
})

If you want to change the state of a switch programmatically, you call SetValue(...).

a.Switch.On.SetValue(true)

The library takes care of the rest and notifies all connected clients that the state has changed.

Multiple Accessories

When you create a server you can specify multiple accessories like this.

var a1, a2, a3 *accessory.A
s, err := hap.NewServer(fs, a1, a2, a3)

By doing so, the first accessory a1 appears as a bridge in HomeKit. When adding the accessories to HomeKit, iOS only shows the bridge accessory. Once the bridge was added, the other accessories appear automatically.

HomeKit requires that every accessory has a unique id, which must not change between system restarts. hap automatically assigns the ids for you based on the order in which the accessories are added to the server.

The best would be to specify the unique id for every accessory yourself, like this

a1.Id = 1
a2.Id = 2

Accessory Architecture

HomeKit uses a hierarchical architecture to define accessories, services and characeristics. At the root level there is an accessory. Every accessory contains services. And every service contains characteristics.

For example a lightbulb accessory contains a lightbulb service. This service contains the on characteristic.

There are predefined accessories, services and characteristics available in HomeKit. Those types are defined in the packages accessory, service, characteristic.

Contact

Matthias Hochgatterer

Website: https://hochgatterer.me

Github: https://github.com/brutella

Twitter: https://twitter.com/brutella

License

hap is available under the Apache License 2.0 license. See the LICENSE file for more info.

Extension points exported contracts — how you extend this code

Store (Interface)
A Store lets you store key-value pairs. [1 implementers]
store.go
ServeMux (Interface)
A ServeMux lets you attach handlers to http url paths.
server.go
ValueUpdateFunc (FuncType)
ValueUpdateFunc is the value updated function for a characteristic.
characteristic/c.go

Core symbols most depended-on inside this repo

AddC
called by 123
service/s.go
SetValue
called by 99
characteristic/int.go
NewInt
called by 93
characteristic/int.go
New
called by 51
service/s.go
SetMinValue
called by 38
characteristic/int.go
tlv8Error
called by 37
tlv8.go
SetStepValue
called by 36
characteristic/int.go
SetMaxValue
called by 35
characteristic/int.go

Shape

Function 413
Struct 329
Method 201
TypeAlias 4
Interface 2
FuncType 1

Languages

Go100%

Modules by API surface

server.go33 symbols
gen/golang/characteristic.go31 symbols
fs.go25 symbols
characteristic/c.go23 symbols
tlv8/reader.go17 symbols
tlv8/writer.go15 symbols
tlv8/marshal_test.go15 symbols
gen/swift/characteristic.go13 symbols
characteristic/int.go13 symbols
characteristic/float.go13 symbols
characteristic/c_test.go12 symbols
session.go11 symbols

For agents

$ claude mcp add hap \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page