Skip to content

prefabapp/prefab

Repository files navigation

Prefab

Prefab is an application that provides a simple HTTP interface to HomeKit data. As of this writing the native HomeKit APIs are only available on iOS based systems. The goal of this app is to provide HomeKit access to macOS. The Prefab application provides access to data provided by HomeKit while the prefab CLI tool provides a simple client to request HomeKit data and provide shell access.

This repository includes:

  • Prefab.app: A standalone macOS application with HTTP server
  • prefab CLI: Command-line tool for accessing HomeKit data
  • PrefabServer Swift Package: Embed the HTTP server in your own macOS apps
  • C++ Client Library: Access Prefab's API from C++ applications

Requirements

  • Xcode: Version 15.0 or later
  • macOS: 14.2 or later (for macOS target)
  • iOS: 17.2 or later (for iOS target)
  • HomeKit Setup: Physical HomeKit accessories or HomeKit simulator
  • Apple Developer Account: Required for HomeKit entitlements and code signing

Dependencies

This project uses Swift Package Manager through Xcode with the following dependencies:

C++ Client Dependencies

The C++ client library has its own dependencies:

  • libcurl: HTTP client library
  • nlohmann/json: JSON parsing (automatically downloaded)
  • Avahi (Linux, optional): For mDNS service discovery

Setup and Installation

1. Clone the Repository

git clone https://github.com/kellyp/prefab.git
cd prefab

2. Open in Xcode

open prefab.xcodeproj

3. Resolve Dependencies

Dependencies are automatically resolved by Xcode when you first open the project. If you need to manually resolve them:

  1. In Xcode, go to FilePackagesResolve Package Versions
  2. Wait for Xcode to download and resolve all Swift packages

4. Configure Code Signing

  1. Select the prefab project in the navigator
  2. Select the Prefab target
  3. Go to Signing & Capabilities
  4. Select your development team
  5. Ensure the HomeKit capability is enabled

Building

Build from Xcode

  1. Select your target device or simulator
  2. Press ⌘+B to build, or ⌘+R to build and run

Build from Command Line

# Build all targets
xcodebuild -project prefab.xcodeproj -scheme Prefab build

# Build for specific destination
xcodebuild -project prefab.xcodeproj -scheme Prefab -destination 'platform=macOS' build

Build Products

The build creates two main products:

  • Prefab.app: The main SwiftUI application with HTTP server
  • prefab: The command-line tool (embedded in the app bundle)

Swift Package (PrefabServer)

This repository includes a Swift Package that allows other macOS apps to embed the Prefab HTTP server functionality:

  • Location: Package.swift and Sources/PrefabServer/ directory
  • Purpose: Embed HomeKit HTTP server in your own macOS applications
  • Target: macOS 14.2+ applications
  • Features: Full HTTP server, HomeKit integration, mDNS/Bonjour advertising, REST API endpoints

Adding PrefabServer to Your Project

Option 1: Local Package (Development)

If you have the Prefab repository locally:

  1. In Xcode, select your project
  2. Go to FileAdd Package Dependencies...
  3. Click Add Local...
  4. Navigate to the Prefab repository directory
  5. Select the directory and click Add Package

Option 2: Git Repository

If the package is hosted in a Git repository:

  1. In Xcode, select your project
  2. Go to FileAdd Package Dependencies...
  3. Enter the repository URL: https://github.com/kellyp/prefab.git
  4. Select the version or branch you want to use
  5. Click Add Package

Using PrefabServer in Your App

  1. Import the package in your Swift files:

    import PrefabServer
  2. Configure your app target:

    • Enable HomeKit capability in Signing & Capabilities
    • Add NSHomeKitUsageDescription to your Info.plist:
      <key>NSHomeKitUsageDescription</key>
      <string>This app needs access to HomeKit to control your smart home devices.</string>
  3. Create and start the server:

    import PrefabServer
    
    class AppDelegate: NSObject, NSApplicationDelegate {
        var server: PrefabServer?
        
        func applicationDidFinishLaunching(_ notification: Notification) {
            // Create server instance
            server = PrefabServer()
            
            // Start the HTTP server
            server?.start()
            
            // Server is now running on http://localhost:8080
            // It will automatically advertise via mDNS/Bonjour
        }
        
        func applicationWillTerminate(_ notification: Notification) {
            // Stop the server when app terminates
            server?.stop()
        }
    }
  4. Access HomeKit data:

    // Access the HomeBase singleton
    let homeBase = server?.homeBase
    
    // Monitor homes
    homeBase?.$homes
        .sink { homes in
            print("Found \(homes.count) homes")
        }

Server Configuration

The server runs with the following defaults:

  • Port: 8080
  • Host: 0.0.0.0 (listens on all interfaces)
  • mDNS Service: _prefab._tcp.
  • Service Name: "Prefab HomeKit Bridge"

API Endpoints

Once started, the server provides the same REST API endpoints as the standalone Prefab app:

  • GET /homes - List all homes
  • GET /homes/:home - Get specific home
  • GET /rooms/:home - List rooms in a home
  • GET /rooms/:home/:room - Get specific room
  • GET /accessories/:home/:room - List accessories in a room
  • GET /accessories/:home/:room/:accessory - Get accessory details
  • PUT /accessories/:home/:room/:accessory - Update accessory
  • GET /scenes/:home - List scenes in a home
  • GET /scenes/:home/:scene - Get scene details
  • POST /scenes/:home/:scene/execute - Execute a scene
  • GET /groups/:home - List accessory groups
  • GET /groups/:home/:group - Get group details
  • PUT /groups/:home/:group - Update group

Requirements for Consumers

Apps using PrefabServer must:

  • Target macOS 14.2 or later
  • Have a valid Apple Developer account (paid membership required)
  • Enable HomeKit capability in Xcode
  • Include NSHomeKitUsageDescription in Info.plist
  • Be properly code-signed (required for HomeKit APIs)

See the API Usage section for examples of interacting with the HTTP endpoints.

C++ Client Library

This repository also includes a C++ client library for accessing Prefab's HomeKit API from other systems, particularly Raspberry Pi and Linux devices:

  • Location: cpp-client/ directory
  • Purpose: Access HomeKit data from C++ applications
  • Target: Raspberry Pi, Linux, and other embedded systems
  • Features: HTTP client, automatic service discovery, type-safe API

See cpp-client/README.md for detailed C++ client documentation.

Testing

Run Tests in Xcode

  1. Press ⌘+U to run all tests
  2. Or use ProductTest from the menu

Run Tests from Command Line

# Run all tests
xcodebuild test -project prefab.xcodeproj -scheme Prefab -destination 'platform=macOS'

# Run specific test plan
xcodebuild test -project prefab.xcodeproj -testPlan Prefab -destination 'platform=macOS'

Test Targets

  • prefabTests: Unit tests for core functionality
  • prefabUITests: UI automation tests

Running

1. Run the Main Application

From Xcode:

  • Select the Prefab scheme
  • Press ⌘+R to run

From Command Line:

# Option 1: Build to a specific directory (most predictable)
xcodebuild -project prefab.xcodeproj -scheme Prefab -destination 'platform=macOS' \
  -derivedDataPath ./build build
open ./build/Build/Products/Debug-maccatalyst/Prefab.app

# Option 2: Use default derived data path
xcodebuild -project prefab.xcodeproj -scheme Prefab -destination 'platform=macOS' build
open ~/Library/Developer/Xcode/DerivedData/prefab-*/Build/Products/Debug-iphoneos/Prefab.app

# Option 3: Build and run in one command with custom path
xcodebuild -project prefab.xcodeproj -scheme Prefab -destination 'platform=macOS' \
  -derivedDataPath ./build build && \
open ./build/Build/Products/Debug-maccatalyst/Prefab.app

The application will:

  1. Start the HTTP server on http://localhost:8080 (accessible at 0.0.0.0:8080)
  2. Advertise the service via mDNS/Bonjour as "Prefab HomeKit Server" (_prefab._tcp.)
  3. Display a SwiftUI interface showing your HomeKit homes
  4. Begin serving HomeKit data via REST API

Service Discovery

The server automatically advertises itself using mDNS (Bonjour) with:

  • Service Type: _prefab._tcp.
  • Service Name: "Prefab HomeKit Server"
  • Port: 8080
  • TXT Record: Contains version info and API details

You can discover the service using:

# Using dns-sd command-line tool
dns-sd -B _prefab._tcp.

# Or browse all services
dns-sd -B _tcp.

2. Use the CLI Tool

The CLI tool is embedded within the app bundle. To use it:

# Navigate to the app bundle
cd build/Build/Products/Debug/

# Or if running from Xcode's DerivedData
./prefab --help

Available CLI commands:

# Get all homes
./prefab homes

# Get specific home details
./prefab home --id [HOME_ID]

# Get rooms in a home
./prefab rooms --home-id [HOME_ID]

# Get accessories
./prefab accessories --home-id [HOME_ID]

# Update accessory
./prefab update-accessory --id [ACCESSORY_ID] --value [VALUE]

3. API Usage

Once the app is running, you can interact with the HTTP API locally or from other devices on your network:

# Local access
curl http://localhost:8080/homes

# Network access (replace with actual IP)
curl http://192.168.1.100:8080/homes

# Get specific home
curl http://localhost:8080/homes/[HOME_ID]

# Get rooms in a home
curl http://localhost:8080/homes/[HOME_ID]/rooms

# Get accessories in a home
curl http://localhost:8080/homes/[HOME_ID]/accessories

mDNS/Bonjour Discovery: Other devices can discover the service automatically and connect using the advertised hostname and port.

4. C++ Client Usage

The C++ client library allows other systems (like Raspberry Pi) to access the Prefab API:

# Build the C++ client
cd cpp-client
mkdir build && cd build
cmake ..
make

# Run examples
./examples/simple_client
./examples/discovery_example
./examples/accessory_control "My Home" "Living Room" "Smart Light"

For detailed C++ usage, see cpp-client/README.md.

Development Workflow

First-Time Setup

  1. Ensure you have HomeKit accessories set up on your iOS device, or use the HomeKit simulator
  2. Build and run the app on your Mac
  3. Grant HomeKit permissions when prompted
  4. Verify the API is responding at http://localhost:8080/homes

Making Changes

  1. Edit Swift files in Xcode
  2. The HTTP server will restart automatically when you rebuild
  3. Use the CLI tool or curl to test API changes
  4. Run tests to ensure nothing is broken

Debugging

  • Console Logs: Check Console.app for detailed logging output
  • Network Debugging: Use tools like curl or Postman to test API endpoints
  • HomeKit Debugging: Use the Home app on iOS to verify HomeKit state

Common Issues

HomeKit Permission Denied

If you get 403 Forbidden responses:

  1. Check that HomeKit permission is granted in System Preferences
  2. Verify the HomeKit entitlement is properly configured
  3. Ensure you're signed with a valid developer certificate

Build Failures

If dependencies fail to resolve:

  1. Clean build folder (⌘+Shift+K)
  2. Reset package caches: FilePackagesReset Package Caches
  3. Manually resolve packages: FilePackagesResolve Package Versions

Server Won't Start

If the HTTP server fails to start:

  1. Check that port 8080 is not in use by another process
  2. Review console logs for specific error messages
  3. Ensure proper code signing for network access

License

This project is licensed under the Apache License 2.0. See the LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass
  6. Submit a pull request

About

Simple HomeKit interface thats allow http access and provides a simple CLI

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published