danmandle / bond

Some research I've done into the Bond fan controller API. More to come.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UPDATE: BOND now has offical documentation for the local API for v2: http://docs-local.appbond.com

BOND, an unofficial API documentation

The BOND lets you connect your existing ceiling fans to your smart devices. Activate, control fan speeds, and turn on lights – all from your phone, tablet, Amazon Echo, or Google Home.

And now through their API

This is a collection of what I've dug up so far on using Charles. Obligatory Use at your own risk.

API Docs generated by Postman: https://documenter.getpostman.com/view/1026/RWaDVqwy

How to work with the Postman collection

  1. Download Postman
  2. Import the collection
  3. Edit collection, update the email and password variable

To send any commands to the BOND, you must get a token from login, BOND hub id from bonds, and fan/device id from cloud_device (List Fans and Capabilities).

You can store the JWT key and reuse it for future API calls. If/when it expires, you can login again to get a new key.

Requests

Login

This will include some important details:

user.token

This is your JWT token for your user. This will be used on the request to return your Bond hubs

key

This is your token for the Osprey API server

Bond Hubs

Returns a list of BOND hubs associated with your account

Note: You must pass the cookie you get from the login request. Session ID expires in two weeks

List Fans and Capabilities

This is the first call to the Osprey server. I think that appbond.com is for user accounts and what Bond hubs are attached to which accounts whereas osprey.appbond.com is where you interact with the hubs directly.

The bondId variable will auto-populate your first Bond hub

Sample Response

New ids generated for privacy

[{
    "bond_id": "BDXXXXX",
    "device_type": 1,
    "id": "d44edf01-b0e0-4eb5-a413-bb7a6fbc4ab1",
    "name": "Parlor Fan",
    "panel": [
        {
            "control": "button",
            "directive": "TurnOff",
            "feedback": "state.power==0",
            "icon": "power_off",
            "name": "Power Off"
        },
        {
            "argument": 1,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==1)",
            "icon": "speed_1",
            "name": "Speed 1"
        },
        {
            "argument": 2,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==2)",
            "icon": "speed_2",
            "name": "Speed 2"
        },
        {
            "argument": 3,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==3)",
            "icon": "speed_3",
            "name": "Speed 3"
        },
        {
            "argument": 4,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==4)",
            "icon": "speed_4",
            "name": "Speed 4"
        },
        {
            "argument": 5,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==5)",
            "icon": "speed_5",
            "name": "Speed 5"
        },
        {
            "argument": 6,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==6)",
            "icon": "speed_6",
            "name": "Speed 6"
        },
        {
            "argument": 1,
            "control": "button",
            "directive": "SetDirection",
            "feedback": "(state.direction==1)",
            "icon": "reverse",
            "name": "Forward"
        },
        {
            "argument": -1,
            "control": "button",
            "directive": "SetDirection",
            "feedback": "(state.direction==-1)",
            "icon": "reverse",
            "name": "Reverse"
        },
        {
            "control": "button",
            "directive": "TurnLightOn",
            "feedback": "",
            "icon": "light",
            "name": "Light"
        },
        {
            "control": "momentary_button",
            "directive_push": "IncreaseBrightness",
            "directive_release": "StopDimming",
            "feedback": "",
            "icon": "dimmer_increase",
            "name": "Dimmer Up"
        },
        {
            "control": "momentary_button",
            "directive_push": "DecreaseBrightness",
            "directive_release": "StopDimming",
            "feedback": "",
            "icon": "dimmer_decrease",
            "name": "Dimmer Down"
        }
    ],
    "remote_id": "RCF98",
    "remote_info": {
        "device_type": 1,
        "fccid": "CHQ7225T",
        "frequency": 433900,
        "icid": "",
        "manufacturer": "Rhine",
        "max_speed": 6,
        "model": "UC7225T",
        "model_alternate": "",
        "photo_url": "https://s3.aws.com/bond-media/RCF98.jpg",
        "zerogap_thresh_ms": 8000
    },
    "state": {
        "addr": "1110000110011110",
        "bps": 2998,
        "brightness": 100,
        "dimmer_decrease": false,
        "dimmer_increase": false,
        "direction": -1,
        "freq": 433930,
        "light": 1,
        "light_bottom": 0,
        "light_top": 0,
        "power": 1,
        "speed": 6,
        "subremote": "light",
        "zero_gap": 31
    }
},
{
    "bond_id": "BD25842",
    "device_type": 1,
    "id": "a7b80289-5083-4180-b5a1-71aa55692b7a",
    "name": "Living Room Fan",
    "panel": [
        {
            "control": "button",
            "directive": "TurnOff",
            "feedback": "state.power==0",
            "icon": "power_off",
            "name": "Power Off"
        },
        {
            "argument": 1,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==1)",
            "icon": "speed_1",
            "name": "Speed 1"
        },
        {
            "argument": 2,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==2)",
            "icon": "speed_2",
            "name": "Speed 2"
        },
        {
            "argument": 3,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==3)",
            "icon": "speed_3",
            "name": "Speed 3"
        },
        {
            "argument": 4,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==4)",
            "icon": "speed_4",
            "name": "Speed 4"
        },
        {
            "argument": 5,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==5)",
            "icon": "speed_5",
            "name": "Speed 5"
        },
        {
            "argument": 6,
            "control": "button",
            "directive": "SetSpeed",
            "feedback": "(state.power==1) and (state.speed==6)",
            "icon": "speed_6",
            "name": "Speed 6"
        },
        {
            "argument": 1,
            "control": "button",
            "directive": "SetDirection",
            "feedback": "(state.direction==1)",
            "icon": "reverse",
            "name": "Forward"
        },
        {
            "argument": -1,
            "control": "button",
            "directive": "SetDirection",
            "feedback": "(state.direction==-1)",
            "icon": "reverse",
            "name": "Reverse"
        },
        {
            "control": "button",
            "directive": "TurnLightOn",
            "feedback": "",
            "icon": "light",
            "name": "Light"
        },
        {
            "control": "momentary_button",
            "directive_push": "IncreaseBrightness",
            "directive_release": "StopDimming",
            "feedback": "",
            "icon": "dimmer_increase",
            "name": "Dimmer Up"
        },
        {
            "control": "momentary_button",
            "directive_push": "DecreaseBrightness",
            "directive_release": "StopDimming",
            "feedback": "",
            "icon": "dimmer_decrease",
            "name": "Dimmer Down"
        }
    ],
    "remote_id": "RCF98",
    "remote_info": {
        "device_type": 1,
        "fccid": "CHQ7225T",
        "frequency": 433900,
        "icid": "",
        "manufacturer": "Rhine",
        "max_speed": 6,
        "model": "UC7225T",
        "model_alternate": "",
        "photo_url": "https://s3.aws.com/bond-media/RCF98.jpg",
        "zerogap_thresh_ms": 8000
    },
    "state": {
        "addr": "0000000000000000",
        "bps": 3004,
        "brightness": 100,
        "dimmer_decrease": false,
        "dimmer_increase": false,
        "direction": 1,
        "freq": 433930,
        "light": 1,
        "light_bottom": 0,
        "light_top": 0,
        "power": 1,
        "speed": 3,
        "subremote": "fan",
        "zero_gap": 29
    }
}]

Toggle Fan Light, Set Fan Speed, Direction Up/Down, Increase/Decrease Brightness

Pretty self-explanatory.

Note about increase/decrease brightness

In the app when you tap to increase or decrease light brightness it POSTs to IncreaseBrightness then immediately POSTs a StopDimming.

What's next?

BOND MQTT Relay Docker container

I use Home Assistant and the fastest way to get Bond integrated with my setup is via MQTT. I'm planning on writing a node.js app that will live in an easy to deploy Docker container.

Home Assistant Platform

Once I figure out how to create a platform (and how to write in Python) I'll work on creating a platform for easy integration.

About

Some research I've done into the Bond fan controller API. More to come.