tradfri-go

command module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2024 License: MIT Imports: 18 Imported by: 0

README

tradfri-go

CircleCI Go Report Card

Native Go implementation for talking CoAP to a IKEA Trådfri gateway over DTLS 1.2.

Note: The author is not in any way affiliated or related to IKEA, this is purely a hobby project!

Note 2: The application is not really being actively developed and may and have bugs and known issues! Will happily accept PRs though!

This application is just stitching together the excellent work of github.com/dustin and github.com/bocajim into a stand-alone application that can talk to a IKEA Trådfri gateway out-of-the-box without any dependencies on libcoap, openssl or similar libraries.

Inspired by:

Changelog
  • 2024-05-20: Update Go version, fix lint errors and other chores.
  • 2024-05-19: Goreleaser support with Github Actions + chores by dvoros
  • 2023-01-30: Update to Go 1.19 by Beaujr
  • 2020-10-11: v1.0.1 release. Power outlet querying by Yuriy Nasretdinov
  • 2020-05-24: v1.0.0 release. GroupIDs and DeviceIDs are now integers. Some minor refactoring after running golang-cilint
  • 2020-05-24: Corrected property names on models, device listing, timed color change support and HSL color support by rubikscraft
  • 2020-02-11: Blinds support by https://github.com/sthorsen
  • 2020-01-16: Updated logging to use logrus with configurable log level in config.json.
  • 2019-06-19: gRPC support by https://github.com/Age15990
  • 2019-06-08: Configurable HTTP port by https://github.com/Mirdinus
  • 2019-04-02: Configuration redone by https://github.com/Hades32
  • 2019-04-01: Fixed issue with -authenticate
  • 2019-03-10: Initial release
Compatibility

tradfri-go has been tested against the following DTLS-enabled COAP servers:

  • IKEA Trådfri Gateway using PSK after token exchange: OK
  • Californicum COAP server on Scandium DTLS: OK
Building

Uses go modules.

export GO111MODULE=on
go build -o tradfri-go
PSK exchange

The Trådfri gateway has its Pre-shared key (PSK) printed on the bottom sticker. However, that PSK is only used for making an initial exchange where you specify a unique Client_id and the original PSK, and you get a new PSK in return that you use for subsequent interactions with the gateway.

tradfri-go supports this operation out of the box using the following command:

> ./tradfri-go --authenticate --client_id=MyCoolID --psk=TheKeyAtTheBottomOfYourGateway --gateway_ip=<ip to your gateway>

The generated new PSK and settings used are stored in the current directory in the file "config.json", e.g:

> cat config.json
{
  "client_id": "MyCoolID",
  "gateway_address": "192.168.1.19:5684",
  "gateway_ip": "192.168.1.19",
  "pre_shared_key": "the generated psk goes here",
  "psk": "the generated psk goes here",
  "loglevel":"info"
}

tradfri-go will try to read config.json when starting up, and will in that case set the required properties accordingly.

If you don't feel like using config.json, you can either specify the configuration as command-line flags or using the following environment variables:

./tradfri-go --server --client_id MyCoolID122 --psk mynewkey --gateway_ip=192.168.1.19

or

> export CLIENT_ID=MyCoolID1122
> export PRE_SHARED_KEY=mynewkey
> export GATEWAY_IP=192.168.1.19

Configuration is resolved in the following order of precedence:

config.json -> command-line arguments -> environment variables

Determine gateway IP

tradfri-go has no means of finding out the IP of the Gateway. I suggest checking your Router's list of connected devices and try to find an item starting with "GW-".

Running in server mode

Server mode connects to your gateway and then publishes a really simple RESTful interface and a gRPC service for querying your gateway or mutating some state on bulbs etc:

./tradfri-go --server

Now, you can use the simple RESTful API provided by tradfri-go which returns more human-readable responses than the raw CoAP responses:

> curl http://localhost:8080/api/device/65538 | jq .
{
  "deviceMetadata": {
    "id": 65538,
    "name": "Färgglad",
    "vendor": "IKEA of Sweden",
    "type": "TRADFRI bulb E27 CWS opal 600lm"
  },
  "dimmer": 100,
  "xcolor": 30015,
  "ycolor": 26870,
  "rgbcolor": "f1e0b5",
  "power": true
}

Or use one of the declarative endpoints to mutate the state of the bulb:

> curl -X PUT -d '{"rgbcolor":"f1e0b5"}' http://localhost:8080/api/device/65538/rgb
Blinds support

tradfri-go now supports controlling IKEA Blinds by passing a positioning value between 0-100.

Examples (curl and gRPC)

> curl -X PUT -d '{"positioning": 20}' http://localhost:8080/api/device/65552/position
> grpcurl -plaintext -d '{"id": 65552, "value": 20}' localhost:8081 grpc_server.TradfriService/ChangeDevicePositioning

Sets the position to 20% extended.

gRPC support

If you want to use the gRPC service, implement your client like this:

var client pb.TradfriServiceClient
{
	conn, err := grpc.Dial("localhost:8081",
		grpc.WithInsecure(),
	)
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	client = pb.NewTradfriServiceClient(conn)
}

while importing pb "github.com/eriklupander/tradfri-go/grpc_server/golang".

And, as simple as calling every other method in your code, request the server like this:

resp, err := client.ListGroups(context.Background(), &pb.ListGroupsRequest{})

You can also install grpcurl and query the server via the command line:

> grpcurl -plaintext localhost:8081 grpc_server.TradfriService/ListGroups
> grpcurl -plaintext -d '{"id": 65552}' localhost:8081 grpc_server.TradfriService/TurnDeviceOn

Just like the client mode, the application will try to use clientId/PSK from psk.key or using env vars.

Running in client mode

Client mode lets you GET and PUT raw coap payloads to your gateway using the "-get" and "-put" args.

A few examples:

GET my bulb at /15001/65538:

./tradfri-go --get /15001/65538
{"9019":1,"9001":"Färgglad","9002":1550336061,"9020":1551721891,"9003":65538,"9054":0,"5750":2,"3":{"0":"IKEA of Sweden","1":"TRADFRI bulb E27 CWS opal 600lm","2":"","3":"1.3.009","6":1},"3311":[{"5708":65279,"5850":1,"5851":100,"5707":53953,"5709":20316,"5710":8520,"5706":"8f2686","9003":0}]}

PUT that turns off the bulb at /15001/65538:

./tradfri-go --put /15001/65538 --payload '{ "3311": [{ "5850": 0 }] }'

PUT that turns on the bulb at /15001/65538 and sets dimmer to 200:

./tradfri-go --put /15001/65538 --payload '{ "3311": [{ "5850": 1, "5851": 200 }] }'

PUT that sets color of the bulb at /15001/65538 to purple and the dimmer to 100:

./tradfri-go --put /15001/65538 --payload '{ "3311": [{ "5706": "8f2686", "5851": 100 }] }'

The colors possible to set on the bulbs varies. The colors are in the CIE 1931 color space whose x/y values in theory can be set using the 5709 and 5710 codes to values between 0 and 65535. You can't set arbitrary values due to how the CIE 1931 (yes, it's a standard from 1931!) works. Play around with the values, I havn't broken my full-color "TRADFRI bulb E27 CWS opal 600lm" yet...

LICENSE

Uses MIT license, see LICENSE

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL