{"id":21230003,"url":"https://github.com/frklan/caesium","last_synced_at":"2026-05-18T03:34:52.290Z","repository":{"id":178549479,"uuid":"138498328","full_name":"frklan/caesium","owner":"frklan","description":"NodeJS based API to control lightbulbs in Ikea's Trådfri series","archived":false,"fork":false,"pushed_at":"2019-08-18T19:05:59.000Z","size":38,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-20T19:09:29.768Z","etag":null,"topics":["api","ikea","javascript","nodejs","smarthome","tradfri"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/frklan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"code-of-conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-24T16:36:50.000Z","updated_at":"2019-08-18T15:52:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"0375bcc1-3b1e-4df9-b5a0-50ddb08353f5","html_url":"https://github.com/frklan/caesium","commit_stats":null,"previous_names":["frklan/caesium"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/frklan/caesium","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frklan%2Fcaesium","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frklan%2Fcaesium/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frklan%2Fcaesium/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frklan%2Fcaesium/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frklan","download_url":"https://codeload.github.com/frklan/caesium/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frklan%2Fcaesium/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33163771,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-17T22:39:12.733Z","status":"online","status_checked_at":"2026-05-18T02:00:06.436Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","ikea","javascript","nodejs","smarthome","tradfri"],"created_at":"2024-11-20T23:31:10.443Z","updated_at":"2026-05-18T03:34:52.274Z","avatar_url":"https://github.com/frklan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CAESIUM\n\n[![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](https://github.com/frklan/caesium/blob/master/LICENSE)\n\n**N.B. Very much in Alpha mode -- beware of bugs and unexpected behaviour.**\n\nA Rest API to control Ikea Trådfri Lightbulbs. Pretty basic and probably unsecure. Make sure you understand the risks exposing the API to the world.\n\n# Using the API\n\n## Prerequisites\n\nMake sure you have:\n\n* NodeJS\n* Ikea Trådfi Lightbulb\n* Ikea Trådfri Gateway\n* An SSL certificate for your domain (optional)\n\n## Installation\n\n1. Clone the repository ````$ git clone git@github.com:frklan/caesium.git````\n\n2. Install dependencies with ````$ npm install ````\n\n3. Create an .env file in the root of the project containing:\n\n        GW_PASSWORD=\u003cPassword as printed on your Tråfri gateway\u003e\n        JWT_SECRET=\u003cjwt secret\u003e\n        OTP_SECRET=\u003cotp secret\u003e\n\n    *Please refer to below instructions how to generate the JWT\\_SECRET and OTP\\_SECRET*\n\n    Alternatively you can set the corresponding environment variables using your preferred method.\n\n4. Run ```$ npm run start```\n\nAccess the API on port 5000 (or set a port in the .env file: ```PORT=\u003cport number\u003e```)\n\n## JWT_SECRET\n\nThe JWT_SECRET can be generated by any means, it should be a 32 character cryptographically strong random string, store it either in:\n\na. the .env file in the root of the project as\n\n    JWT_SECRET=\u003csecret string\u003e\n\nb. the $JWT_SECRET environment variable, e.g.:\n\n    $ export JWT_SECRET=\u003csecret string\u003e\n\n\n## Generating a JWT token\n\nA JWT token can be manually generated with the following sequence:\n\n1. run ```$  src/util/generateJwtToken```, the output will be similar to:\n\n        src/util/generateJwtToken\n        ID: caesium_api_user\n        TTL: 3600\n        Extra data: \u003cnot set\u003e\n        JWT token: eyJhbGciOiJIUz....WTlOioJg_0zIjKZnB-txLqbT4A\n\n2. Set the header field ```token``` to the JWT token displayed when using the API endpoint, e.g.:\n\n        $ curl https://[YOUR-DOMAIN]:5000/api/v1/bulbs -H \"token: eyJhbGciOiJIUz....WTlOioJg_0zIjKZnB-txLqbT4A\"\n\n**Note** that the JWT token will default expire in 3600 seconds. A longer (or shorter) expiration time can be set with the option --ttl, refer to ```$  src/util/generateJwtToken --help``` for details. There is no way of invalidating JWT tokens unless it expires automatically, hence it is important to treat them as secrets.\n\n## SSL encryption\n\nIf the API is served openly on the internet it is recommended to encrypt all traffic with SSL. It's pretty easy to generate an SSL certificate with letsencrypt and it costs 0€! Yo do, however, need access to a domain or a public webserver. My preferred way of generating the SSL certificate is these easy steps:\n\n1. Get a domain name, e.g. from [namecheap](https://www.namecheap.com/)\n \n2. Install [certbot](https://certbot.eff.org/), \n\t\t\n3. Generate the certificate with ```$certbot certonly --config-dir ./conf --work-dir ./ --logs-dir ./ --preferred-challenges dns -d [YOUR-DOMAIN] --manual``` (replace \\[YOUR-DOMAIN] with your actuall domain)\n\n4. Follow certbot's instruction how to verify your identity and prove that you own \\[YOUR-DOMAIN].\n\n5. Set the following environment variables \n\n   ```shell\n   SSL_CERT_FILE=../conf/live/[YOUR-DOMAIN]/fullchain.pem\n   SSL_KEY_FILE=../conf/live/[YOUR-DOMAIN]/privkey.pem\n   USE_SSL=TRUE\n   ```\n\n6. Run the server as normal and access the the API at https://.....\n\n**Note.** if you'd like to get an official certificate but not expose the API to the internet, you can generate the certificate for a 'non existing' domain, e.g. dev.example.com and then route dev.example.com to a local ip address by changing your hosts file.\n\n**Note.** Do NOT show, transmit or otherwise expose the private key associated with your SSL certificate.\n\n# API endpoints\n\n### POST login\n\n```shell\n$ curl https://[YOUR-DOMAIN]:5000/login -X POST -H \"id: caesium_api_user\" -H \"otp: 349721\"\n```\n\nResponse:\n\n```shell\n{ \n    \"success\":true,\n    \"token\":\"eyJhbGciOiJIUz....WTlOioJg_0zIjKZnB-txLqbT4A\"\n}\n```\n\n### GET api/v1/bulbs\n\nLists current known bulbs and states\n\nExample:\n\n```shell\n$ curl https://[YOUR-DOMAIN]:5000/api/v1/bulbs -X GET -H \"token: eyJhbGciOiJIUz....WTlOioJg_0zIjKZnB-txLqbT4A\"\n```\n\nResponse:\n\n```shell\n{\n    \"gateway\": {\n        \"status\": \"online\",\n        \"name\": \"gw-xxxxxxxxxxxx\",\n        \"host\": \"TRADFRI-Gateway-xxxxxxxxxxxx.local\"\n    },\n    \"lightbulbs\": [\n        {\n            \"name\": \"Table\",\n            \"id\": 65537,\n            \"lastSeen\": 1533745439,\n            \"light\": {\n                \"onOff\": false,\n                \"dimmer\": 22.8,\n                \"color\": \"f1e0b5\",\n                \"colorTemperature\": 0,\n                \"colorX\": 0,\n                \"colorY\": 0,\n                \"transitionTime\": 0.5\n            }\n        },\n        {\n            \"name\": \"Window\",\n            \"id\": 65539,\n            \"lastSeen\": 1533667468,\n            \"light\": {\n                \"onOff\": false,\n                \"dimmer\": 0,\n                \"color\": \"0\",\n                \"colorTemperature\": 0,\n                \"colorX\": 0,\n                \"colorY\": 0,\n                \"transitionTime\": 0.5\n            }\n        },\n`\n```\n\n### GET api/v1/bulb/[bulb id]\n\nReport state on a single bulb\n\nExample:\n\n```shell\n$ curl https://[YOUR-DOMAIN]:5000/api/v1/bulb/65530 -X GET -H \"token: eyJhbGciOiJIUz....WTlOioJg_0zIjKZnB-txLqbT4A\"\n```\n\nResponse:\n\n```shell\n{\n    \"gateway\": {\n        \"status\": \"online\",\n        \"name\": \"gw-xxxxxxxxxxxx\",\n        \"host\": \"TRADFRI-Gateway-xxxxxxxxxxxx.local\"\n    },\n    \"lightbulbs\": [\n        {\n            \"name\": \"Window\",\n            \"id\": 65539,\n            \"lastSeen\": 1533667468,\n            \"light\": {\n                \"onOff\": false,\n                \"dimmer\": 0,\n                \"color\": \"0\",\n                \"colorTemperature\": 0,\n                \"colorX\": 0,\n                \"colorY\": 0,\n                \"transitionTime\": 0.5\n            }\n            }\n        }\n    ]\n}\n```\n\n### POST api/v1/bulb/[bulb id]/toggle\n\nToggles a bulb on or off\n\nExample:\n\n```shell\n$ curl https://[YOUR-DOMAIN]:5000/api/v1/bulb/65530/toggle -X POST -H \"token: eyJhbGciOiJIUz....WTlOioJg_0zIjKZnB-txLqbT4A\"\n```\n\nResponse:\n\n```shell\n{\n    \"gateway\": {\n        \"status\": \"online\",\n        \"name\": \"gw-xxxxxxxxxxxx\",\n        \"host\": \"TRADFRI-Gateway-xxxxxxxxxxxx.local\"\n    },\n    \"status\": \"done\"\n}\n```\n\n### POST api/v1/bulb/[bulb id]/[ON] || [OFF]\n\nSwitches a bulb on or off. \n\nExample:\n\n```shell\n$ curl https://[YOUR-DOMAIN]:5000/api/v1/bulb/65530/ON -X POST -H \"token: eyJhbGciOiJIUz....WTlOioJg_0zIjKZnB-txLqbT4A\"\n```\n\nResponse:\n\n```shell\n{\n    \"gateway\": {\n        \"status\": \"online\",\n        \"name\": \"gw-xxxxxxxxxxxx\",\n        \"host\": \"TRADFRI-Gateway-xxxxxxxxxxxx.local\"\n    },\n    \"status\": \"done\"\n}\n```\n\n# TODO's\n\n- [ ] - [ ] Replace the JWT token with 2FA OTP?\n            Using both JWT and OTP's seems overly complicated, perhaps a single method is enough?\n\n# Contributing\n\nContributions are always welcome!\n\nWhen contributing to this repository, please first discuss the change you wish to make via the issue tracker, email, or any other method with the owner of this repository before making a change.\n\nPlease note that we have a code of conduct, you are required to follow it in all your interactions with the project.\n\n# Versioning\n\nWe use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/frklan/caesium/tags).\n\n# Authors\n\n* **Fredrik Andersson** - *Initial work* - [frklan](https://github.com/frklan)\n\n# License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrklan%2Fcaesium","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrklan%2Fcaesium","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrklan%2Fcaesium/lists"}