An extensive Philips Hue client library for Go with an emphasis on simplicity

Build Status huego Go Report Card codecov Awesome

Huego

An extensive Philips Hue client library for Go with an emphasis on simplicity. It is designed to be clean, unbloated and extensible. With Huego you can interact with any Philips Hue bridge and its resources including Lights, Groups, Scenes, Sensors, Rules, Schedules, Resourcelinks, Capabilities and Configuration .

Installation

Get the package and import it in your code.

go get github.com/amimof/huego

You may use New() if you have already created an user and know the IP address to your bridge.

package main

import (
  "github.com/amimof/huego"
  "fmt"
)

func main() {
  bridge := huego.New("192.168.1.59", "username")
  l, err := bridge.GetLights()
  if err != nil {
    panic(err)
  }
  fmt.Printf("Found %d lights", len(l))
}

Or discover a bridge on your network with Discover() and create a new user with CreateUser(). To successfully create a user, the link button on your bridge must have been pressed before calling CreateUser() in order to authorise the request.

func main() {
  bridge, _ := huego.Discover()
  user, _ := bridge.CreateUser("my awesome hue app") // Link button needs to be pressed
  bridge = bridge.Login(user)
  light, _ := bridge.GetLight(3)
  light.Off()
}

Documentation

See godoc.org/github.com/amimof/huego for the full package documentation.

Contributing

All help in any form is highly appreciated and your are welcome participate in developing Huego together. To contribute submit a Pull Request. If you want to provide feedback, open up a Github Issue or contact me personally.

Owner
Amir Mofasser
😎🔥⚡️💥
Amir Mofasser
Comments
  • Add a new CreateUser function to return CleintKey

    Add a new CreateUser function to return CleintKey

    There were some go format changes, and some test updates. I've also updated CreateUser to not generate a client key, as it doesn't return it, and it's never used.

    Fixes #24

  • Proposal: Please start using Semantic Versioning

    Proposal: Please start using Semantic Versioning

    I found that this project already supports Go modules. But sadly, the tags doesn't follow Semantic Versioning, which means that all tags of this project will be ignored by Go modules and replaced by pseudo-versions, go get acts weirdly when tags are not in that form. It would be great to have the tagged release be named in the format vX.X.X format so that go mod can read it.

    	github.com/amimof/huego v0.0.0-20200504200310-b4a8f71aa2e3
    

    Else the mod file shows something like github.com/amimof/huego v0.0.0-20200504200310-b4a8f71aa2e3 which is not very readable and difficult to upgrade. It’s hard to verify which version is in use. This is not conducive to version control

    So, I propose this project to follow Semantic Versioning in future versions. For example, v1.0.1, v2.0.0, v3.1.0-alpha, v3.1.0-beta.2etc.

  • Add context.Context support in APIs

    Add context.Context support in APIs

    First, thanks for this library: the work is outstanding and I really, really love it! Impressive work!

    I am integrating Huego (and many other libraries) into a library for my home-automation hub. My goal is to provide a technology-agnostic REST web-service.

    A very common pattern for web-services, is to handle properly requests lifetime by honoring the status of the context.Context that is attached to *http.Request instances. Since this context automatically expires when the client underlying connection closes (or any other fatal network condition), this allows for circuit-breaking: for instance, if I use the context.Context from the HTTP request and pass it in an underlying "turn this light on" operation, and the initiating request closes early, it gives a chance to the program to avoid doing unnecessary work by also stopping the "turn this light on" operation sooner.

    It is as simple as doing:

    req = req.WithContext(ctx)
    

    Before issuing a HTTP request.

    The current Huego APIs don't expose a way of passing in a context.Context for each operation. Is that something you'd be interested in? I can probably make a pull-request for it, but I figured I'd discuss it with you first.

    There is a way to do that without breaking the API by "overloading" each operation method with a Ctx suffix. Say:

    // Context creation: can be done in many ways.
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    
    // Example call.
    light.OnCtx(ctx) // Guaranteed to complete when the operation is over or one second passes by, whichever happens first.
    

    Please let me know what you think of this.

  • Make the API context.Context aware

    Make the API context.Context aware

    This closes #8 while keeping backwards compatibility with the existing API.

    I took the liberty of correcting a few spelling errors in the process, but added them to the same commit, hope that's ok.

  • CreateUser

    CreateUser

    Running the example from the readme I get an error:

    func main() {
      bridge, _ := huego.Discover()
      user, _ := bridge.CreateUser("my awesome hue app") // Link button needs to be pressed
      bridge = bridge.Login(user)
      light, _ := bridge.GetLight(3)
      light.Off()
    }
    
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal 0xc0000005 code=0x0 addr=0x8 pc=0x60ab3b]
    
    goroutine 1 [running]:
    github.com/amimof/huego.(*Bridge).getAPIPath(0x0, 0xc042089d60, 0x3, 0x3, 0x40, 0x0, 0x0, 0x62a740)
            C:/Go/bin/src/github.com/amimof/huego/bridge.go:21 +0x4b
    github.com/amimof/huego.(*Bridge).SetLightState(0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
            C:/Go/bin/src/github.com/amimof/huego/bridge.go:487 +0x181
    github.com/amimof/huego.(*Light).Off(0xc0421da0a0, 0x3, 0xc0421da0a0)
            C:/Go/bin/src/github.com/amimof/huego/light.go:59 +0xa7
    main.main()
            C:/Users/Julian/Documents/WaterCan/main/main.go:16 +0x126
    exit status 2
    
  • Adds method that allows to identify a light optically

    Adds method that allows to identify a light optically

    I noticed while experimenting with the library that the function to identify a light is missing. It is very similar to the SetLightState method, but unfortunately the functionality cannot be achieved through it. I think it's mainly because the State always has the "On" property set when serializing to a json object.

  • Feature Request: Utility methods: Convert HEX Color to xy and back

    Feature Request: Utility methods: Convert HEX Color to xy and back

    Hi, on some other SDKs (mainly directly from philips/Signify) there are some utility methods to convert RGB colors into XY. It would be nice, if you can add this to your lib. Some background informations: https://developers.meethue.com/develop/application-design-guidance/color-conversion-formulas-rgb-to-xy-and-back/

  • tags format for Go modules

    tags format for Go modules

    Hello,

    According to https://golang.org/ref/mod the Git tag format should be vX.Y.Z. So the tag for the version 1.2.0 should be v1.2.0 instead of 1.2.0. Currently the versions are not displayed here https://pkg.go.dev/github.com/amimof/huego?tab=versions and all the links to the source code are broken https://pkg.go.dev/github.com/amimof/huego (pkg.go.dev is replacing godoc.org)

  • Use default http client

    Use default http client

    I think it's useful to use the default client here, it allows us to instrument our own client if need be. This is just the simplest way to accomplish this. Ideally I would like to pass this in via a struct type field, but didn't wanna deal with the refactor overhead of that.

  • Won't

    Won't "login"

    I'm able to use the "discover -> create user" when I press the button on the bridge, but I'm not able to get the "new" command to work. Each time I run the line it says "ERROR 1 [/lights]: "unauthorized user"

    But I know I've created that user ( by pushing the button and running the other code ) many times! Help.

    bridge := huego.New("192.168.1.4", "tyler")

  • Add custom http.Client support.

    Add custom http.Client support.

    - What I did Added the ability to use a custom http.Client when interacting with bridges. My particular use-case comes from all of my lighting being segmented off, this allows for me to use my router as a middle-man via an SSH tunnel. However, I feel there are many, many use-cases.

    - How I did it I created a new function similar to New called NewCustom, it is just about the same except for it allows you to pass in your own http.Client. I then refactored all of the unexported http functions (get, put etc) to be methods of Bridge. This allows them to function using http.DefaultClient during normal operations, but with the custom http.Client otherwise.

    - How to verify it I've not only verified that this works for my use-case, but frankly making the testcases work (I didn't realize how httpmock had worked until today) was more work than the modification itself. So I think CI does a pretty good job of verification :)

    - Description for the CHANGELOG

    ## 1.0.3
    * Added ability to use a custom http.Client
    
  • Add Hue v2 support for the upcoming v2.0.0 release

    Add Hue v2 support for the upcoming v2.0.0 release

    Adds support for Hue API V2

    Features

    • Currently V2 work is under the v2/. Folder structure is not final at this point and is sobject to change
    • Introduces the new Client struct which is the type used to interact with the Hue API. Instead of using the Bridge type. The Bridge type is now just a regular struct that represents the bridge resource in the V2 API.
    • Support for both V1 & V2 API. This is possible because we have 1 client per version. ClientV1 and ClientV2 and in the future ClientVX.
    • Huego Clients uses the new CLIPClient which is a general purpose HTTP client. Sort of like a REST client but for Hue briges specifically.
    • The CLIPClient uses Request & Response types to communicate with Hue briges through a Client type.
    • Users may pass in their own http.Client if they want.

    Progress

    • [x] light
    • [x] scene
    • [ ] room
    • [ ] zone
    • [ ] bridge_home
    • [ ] grouped_light
    • [ ] device
    • [ ] bridge
    • [ ] device_power
    • [ ] zigbee_connectivity
    • [ ] zgp_connectivity
    • [ ] motion
    • [ ] temperature
    • [ ] light_level
    • [ ] button
    • [ ] behavior_script
    • [ ] behavior_instance
    • [ ] geofence_client
    • [ ] geolocation
    • [ ] entertainment_configuration
    • [ ] entertainment
    • [ ] homekit
  • Cannot update Scene -- parameter not modifiable

    Cannot update Scene -- parameter not modifiable

    Probably related to #45 -- the recycle parameter is marked as bool without any omit directive. It works for creating the scene but not for updating it.

    Steps to reproduce the issue:

    1. Try to update a scene name
    2. Error: parameter, recycle, is not modifiable

    Describe the results you received: I am implementing a terraform provider, this is the JSON: {"name":"Testing","recycle":false}

    │ Error: ERROR 8 [/scenes/jeU0J-6kXNVvnnL/recycle]: "parameter, recycle, is not modifiable"

    Describe the results you expected:

    Hue Bridge Version

    "apiversion": "1.48.0",
    "swversion": "1948086000",
    

    Can I help?

    I am learning go as I write this provider, if you provide me some pointers I can contribute towards the solution.

    My naive solution would be adding a map to the "update" instead of using the struct so we have fine control over the elements -- but I think the solution from #45 would solve this in a better way.

  • Hue v2 API support?

    Hue v2 API support?

    • [X] This feature/enhancement benefits everyone

    Description

    Hi. Really love this library. I was wondering if you have any plans to support the v2 Hue API. I can’t see anything browsing from my mobile. Thanks for any feedback you can provide.

    Additional information

  • Allow to configure bridge

    Allow to configure bridge

    - What I did Current implementation doesn't allow to configure bridge (e.g. its name). More details are in this comment.

    - How I did it I have change the Config type to use pointers which sets nil value by default and gets filtered out by JSON marshaling.

    - How to verify it

    bridge := huego.New("192.168.x.y", "asdfasdf...")
    
    c := &huego.Config{
        Name: huego.StrPtr("My Bridge"),
    }
    
    _, err := bridge.UpdateConfig(c)
    if err != nil {
        panic(err)
    }
    

    - Description for the CHANGELOG Added the possibility update bridge's configuration (e.g. its name)

  • `omitempty` on boolean attributes prevents changing them to `false`

    `omitempty` on boolean attributes prevents changing them to `false`

    Some boolean attributes are annotated with json:"attributename,omitempty", which means they are omitted from requests when set to the default value for their type, i.e. false. This means that it is impossible to set a boolean attribute to false using a Create* or Update* method.

    AutoDelete in Schedule is one example of an affected attribute. It defaults to true when not provided, and there currently appears to be no way in huego to set it to false.

    Here's a quick program that reproduces this:

    package main
    
    import (
    	"fmt"
    	"encoding/json"
    	"github.com/amimof/huego"
    )
    
    func main() {
    	bridge := huego.New("192.168.0.221", "[redacted]")
    
    	schedule := huego.Schedule{
    		Name: "Test schedule",
    		Command: &huego.Command{
    			Address: "/api/0/lights/4/state",
    			Method: "PUT",
    			Body: map[string]bool{
    				"on": true,
    			},
    		},
    		LocalTime: "PT00:00:03",
    		AutoDelete: false,
    	}
    
    	schedule_json, err := json.Marshal(schedule)
    	if err != nil {
    		fmt.Printf("error: %v\n", err)
    		return
    	}
    
    	fmt.Printf("JSONd schedule looks like this:\n%v\n", string(schedule_json))
    
    	response, err := bridge.CreateSchedule(&schedule)
    	if err != nil {
    		fmt.Printf("error: %v\n", err)
    		return
    	}
    
    	fmt.Printf("response: %v\n", response)
    }
    

    and here's what it outputs on my machine:

    JSONd schedule looks like this:
    {"name":"Test schedule","description":"","command":{"address":"/api/0/lights/4/state","method":"PUT","body":{"on":true}},"localtime":"PT00:00:03"}
    response: &{map[id:2]}
    

    Checking the Bridge API manually confirms that this schedule has autodelete: true, and three seconds later it's gone.

A Go client for Google IoT Core

IoT A simple framework for implementing a Google IoT device. This package makes use of the context package to handle request cancelation, timeouts, an

Sep 26, 2022
handle multiple mqtt server/cluster based on paho client

pakhshi Introduction Consider you have an array of brokers but you want to publish and subscribe on all of them at the same time. Why you may need thi

Nov 9, 2022
Go-ebyte-lora - EBYTE Lora modules interface library for Linux, Raspberry PI

go-ebyte-lora EBYTE Lora modules interface library for Linux, Raspberry PI Super alpha version WARNING: It was tested on Raspberry Pi 4, Serial Read,

May 11, 2022
lirc.go - a library to send and receive via lircd

LIRC Go client for Linux Infrared Remote Control (LIRC) package Usage package main import ( "github.com/chbmuc/lirc" "log" "time" ) func keyPo

Oct 24, 2022
Lua runtime to control Philips Hue lamps 💡

go-hue Control Philips Hue Lamps with Lua About This is just a throw-away tooling to control Hue Lamps with a simple Lua script. hue -interval=2000 sc

Dec 10, 2021
A client software for acme-dns with emphasis on usability and guidance through setup and additional security safeguard mechanisms

acme-dns-client A client software for acme-dns with emphasis on usability and guidance through setup and additional security safeguard mechanisms. It

Dec 2, 2022
An extensive, fast, and accurate command-line image dithering tool.
An extensive, fast, and accurate command-line image dithering tool.

didder is an extensive, fast, and accurate command-line image dithering tool. It is designed to work well for both power users as well as pipeline scripting. It is backed by my dithering library, and is unique in its correctness and variety of dithering algorithms.

Dec 31, 2022
Pigiron is a MIDI routing utility with an extensive OSC interface.

Pigiron README (c) 2021 Steven Jones Pigiron is a fully configurable MIDI routing utility written in Go. It includes a MIDI file player and has a comp

Nov 24, 2022
Prometheus exporter for Hue Sensors

Prometheus exporter for Hue Sensors This program allows you to gather generic metrics on all your Philips Hue sensors with Prometheus. Installation In

Nov 17, 2021
Go-perfguard - A static analyzer with emphasis on performance

perfguard This tool is a work in progress. It's not production-ready yet. perfgu

Dec 28, 2022
Totsugen - Generate emphasis message with golang

totsugen Requirements Go 1.17+ Run $ go run main.go -value {value} # ex: go run

May 21, 2022
Goph - A lightweight Go SSH client focusing on simplicity
Goph - A lightweight Go SSH client focusing on simplicity

Golang SSH Client. Fast and easy golang ssh client module. Goph is a lightweight

Oct 30, 2022
Fluux XMPP is a Go XMPP library, focusing on simplicity, simple automation, and IoT.

Fluux XMPP is a Go XMPP library, focusing on simplicity, simple automation, and IoT. The goal is to make simple to write simple XMPP client

Dec 14, 2022
GO2P is a P2P framework, designed with flexibility and simplicity in mind
GO2P is a P2P framework, designed with flexibility and simplicity in mind

go2p golang p2p framework By v-braun - viktor-braun.de. Description GO2P is a P2P framework, designed with flexibility and simplicity in mind. You can

Jan 5, 2023
A scalable overlay networking tool with a focus on performance, simplicity and security

What is Nebula? Nebula is a scalable overlay networking tool with a focus on performance, simplicity and security. It lets you seamlessly connect comp

Dec 29, 2022
A fast port scanner written in go with a focus on reliability and simplicity. Designed to be used in combination with other tools for attack surface discovery in bug bounties and pentests
A fast port scanner written in go with a focus on reliability and simplicity. Designed to be used in combination with other tools for attack surface discovery in bug bounties and pentests

Naabu is a port scanning tool written in Go that allows you to enumerate valid ports for hosts in a fast and reliable manner. It is a really simple to

Dec 31, 2022
A tiny Nano wallet, focused on ease of use through simplicity

atto is a tiny Nano wallet, which focuses on ease of use through simplicity. Disclaimer: I am no cryptographer and atto has not been audited. I cannot

Nov 14, 2022
🏮Blazing fast URL shortener made with simplicity in mind

klein Blazing fast URL shortener made with simplicity in mind Structures The project is what people would call a "monolith".

Feb 16, 2022
🏮 ― Blazing fast URL shortener made with simplicity in mind

klein Blazing fast URL shortener made with simplicity in mind Run As easy as filling out config/config.yaml and running make. Of course, you need to h

Feb 16, 2022
gosq is a parsing engine for a simplicity-focused, template-based SQL query builder for Go.

gosq is a parsing engine for a simplicity-focused, template-based SQL query builder for Go.

Oct 24, 2022