Skip to content

Commit

Permalink
Merge pull request hvanderlaan#44 from maltejur/master
Browse files Browse the repository at this point in the history
add tradfri_authenticate.py and update README.md
  • Loading branch information
hvanderlaan authored Apr 7, 2021
2 parents 3318a9d + 061b620 commit 95a6db3
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 37 deletions.
85 changes: 48 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,7 @@
# ikea-smartlights
python framework for controlling the Ikea smart lights (tradfri)

### update
as of gateway version 1.1.15 the usage of securityid is prohibated, you need to register a api user and you will get a pre shared key from the gateway. follow the steps below and all should be well
```bash
coap-client -m post -u "Client_identity" -k "SECURITY_CODE" -e '{"9090":"IDENTITY"}' "coaps://IP_ADDRESS:5684/15011/9063"
# SECURITY_CODE = the security code under the gateway
# IDENTITY = your api user
```
when this is done create a file called tradfri.cfg and add
```ini
[tradfri]
hubip = x.x.x.x
apiuser = username
apikey = pre shared key
```
getting the apple HomeKit code for your gateway. first ensure you have the pre shared key.
```bash
coap-client -m get -u "IDENTITY" -k "PRE SHARED KEY" "coaps://IP_ADDRESS:5684/15011/15012" 2> /dev/null
# Apple HomeKit code looks like: { ... 9083: XXX-XX-XXX, ...}
# XXX-XX-XXX is your HomeKit code
```
## setup

### requirements
at this moment there is no coap libs with dTLS, the ikea smart lights are using dTLS with coap for security. the only option is to build a new libcoap with dTLS included. libcoap requires `cunit, a2x, doxygen and dot` you need to install these requirements first.
Expand All @@ -37,24 +18,16 @@ sudo make install

the framework also requires `tqdm` for showing progressbars, you could strip it from the sourcecode or install the module for python: `pip install pip --upgrade && pip install tqdm`.

### libcoap usage
```bash
# getting tradfri pre shared key
coap-client -m post -u "Client_identity" -k "<key>" -e '{"9090":"IDENTITY"}' "coaps://<hub>:5684/15011/9063"
# getting tradfri information
./coap-client -m get -u "IDENTITY" -k "<psk>" "coaps://<hup>:5684/15001"
# getting tradfri lightbulb status
./coap-client -m get -u "IDENTITY" -k "<psk>" "coaps://<hup>:5684/15001/65537"
### authentication
you will need to authenticate the api before you first use it. to do this, run `python tradfri-authenticate.py` and enter the ip of your hub and the security code (on the back of the hub). the script will automaticaly create a configuration file containing the api key

# turn on tradfri lightbulb
./coap-client -m put -u "IDENTITY" -k "<psk>" -e '{ "3311" : [{ "5850" : 1 }] }' "coaps://<hup>:5684/15001/65537"
# turn off tradfri lightbulb
./coap-client -m put -u "IDENTITY" -k "<psk>" -e '{ "3311" : [{ "5850" : 0 }] }' "coaps://<hup>:5684/15001/65537"
```
## usage

### output
### status
```
python tradfri-status.py
```
```
./tradfri-status.py
[ ] tradfri: requireing all tradfri devices, please wait ...
tradfri lightbulbs: 100%|█████████████████████████████████████████████████████████| 8/8 [00:00<00:00, 10.93 lightbulb/s]
tradfri groups: 100%|█████████████████████████████████████████████████████████████████| 4/4 [00:00<00:00, 10.50 group/s]
Expand All @@ -76,15 +49,53 @@ groupid: 140387, name: woonkamer, state: off
groupid: 186970, name: hal boven, state: off
```

### todo
### turn on a light
```
python tradfri-lights.py -a power -l {LIGHTBULB_ID} -v on
```

### dim the light
```
python tradfri-lights.py -a brightness -l {LIGHTBULB_ID} -v 50
```

### turn off all ligths in room
```
python tradfri-groups.py -a power -g {GROUP_ID} -v off
```

### libcoap usage
```bash
# getting tradfri pre shared key
coap-client -m post -u "Client_identity" -k "<key>" -e '{"9090":"IDENTITY"}' "coaps://<hub>:5684/15011/9063"
# getting tradfri information
./coap-client -m get -u "IDENTITY" -k "<psk>" "coaps://<hup>:5684/15001"
# getting tradfri lightbulb status
./coap-client -m get -u "IDENTITY" -k "<psk>" "coaps://<hup>:5684/15001/65537"

# turn on tradfri lightbulb
./coap-client -m put -u "IDENTITY" -k "<psk>" -e '{ "3311" : [{ "5850" : 1 }] }' "coaps://<hup>:5684/15001/65537"
# turn off tradfri lightbulb
./coap-client -m put -u "IDENTITY" -k "<psk>" -e '{ "3311" : [{ "5850" : 0 }] }' "coaps://<hup>:5684/15001/65537"
```

## HomeKit code
getting the apple HomeKit code for your gateway. first ensure you have the pre shared key.
```bash
coap-client -m get -u "IDENTITY" -k "PRE SHARED KEY" "coaps://IP_ADDRESS:5684/15011/15012" 2> /dev/null
# Apple HomeKit code looks like: { ... 9083: XXX-XX-XXX, ...}
# XXX-XX-XXX is your HomeKit code
```

## todo
- [ ] add support for new color lightbulbs
- [X] add change state (power on/off lightbulb)
- [X] add dimmer value (dimm lightbulb)
- [X] add change state group (power on/off groups)
- [X] add dimmer value group (dimm group)
- [X] add color temperature lightbulb (switch to cold, normal or warm)

### licensing and credits
## licensing and credits
ikea-smartlight is licensed under the GPLv3:
```
This program is free software: you can redistribute it and/or modify
Expand Down
60 changes: 60 additions & 0 deletions tradfri-authenticate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/usr/bin/env python

# file : tradfri-authenticate.py
# purpose : authenticate api user and generate configuration file
#
# author : maltejur
# date : 2020/10/24

"""
tradfri-authenticate.py - authenticate api user and generate configuration file
This module requires libcoap with dTLS compiled, at this moment there is no python coap module
that supports coap with dTLS. see ../bin/README how to compile libcoap with dTLS support
"""

# pylint convention disablement:
# C0103 -> invalid-name
# C0200 -> consider-using-enumerate
# pylint: disable=C0200, C0103

from __future__ import print_function
from __future__ import unicode_literals

import os
import sys
import time
import ConfigParser

from tradfri import tradfriActions

def main():
""" main function """
conf = ConfigParser.ConfigParser()
script_dir = os.path.dirname(os.path.realpath(__file__))
conf.read(script_dir + '/tradfri.cfg')

hubip = raw_input("\nhub ip:\t\t")
securityCode = raw_input("security code: \t")

print("\n[ ] acquiring api key ...", end="")

apiuser, apikey = tradfriActions.tradfri_authenticate(hubip, securityCode)

print("\r[+]\n\nuser:\t{}\napikey:\t{}\n".format(apiuser, apikey))

print("[ ] writing configuration file ...", end="")

conf.add_section('tradfri')
conf.set("tradfri", "hubip", hubip)
conf.set("tradfri", "apiuser", apiuser)
conf.set("tradfri", "apikey", apikey)
conf.write(open(script_dir + '/tradfri.cfg','w'))

print("\r[+]\n")

print("all done!\n")

if __name__ == "__main__":
main()
sys.exit(0)
23 changes: 23 additions & 0 deletions tradfri/tradfriActions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@

import sys
import os
import json
import random
from tradfriStatus import tradfri_get_lightbulb

global coap
Expand Down Expand Up @@ -134,6 +136,27 @@ def tradfri_dim_group(hubip, apiuser, apikey, groupid, value):

return result

def tradfri_authenticate(hubip, securitycode, apiuser = "TRADFRI_PY_API_" + str(random.randint(0, 1000)) ):
""" function for authenticating tradfri and getting apikey """
tradfriHub = 'coaps://{}:5684/15011/9063'.format(hubip)
payload = '{"9090":"' + apiuser + '"}'

api = '{} -m post -u "Client_identity" -k "{}" -e \'{}\' "{}"'.format(coap, securitycode,
payload, tradfriHub)

if os.path.exists(coap):
result = os.popen(api)
else:
sys.stderr.write('[-] libcoap: could not find libcoap\n')
sys.exit(1)

try:
apikey = json.loads(result.read().strip('\n').split('\n')[-1])["9091"]
except ValueError:
raise Exception("Didn't receive valid apikey. This is because the api isn't reachable or the api user already exists.")

return apiuser,apikey

def get_color_dict():
return {
'blue' : '4a418a',
Expand Down

0 comments on commit 95a6db3

Please sign in to comment.