diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e46c46e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build/ +dist/ +.smartthings_cli.json diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1faf0c6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM python:3.7 + +ADD . . +ADD .smartthings_cli.json /root/.smartthings_cli.json + +RUN python setup.py install diff --git a/README.md b/README.md index bfb87fa..f222abe 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,18 @@ Command line interface to query and control SmartThings devices # Usage -1. Log into https://graph.api.smartthings.com/ and under My SmartApps, create a new SmartApp with the code in groovy/app.groovy. +1. Log into https://graph.api.smartthings.com/ and under My SmartApps, create a new SmartApp with the code in `groovy/app.groovy`. 2. Click App Settings and under OAuth, click _Enable OAuth in Smart App_. Note down the _OAuth Client ID_ and _OAuth Client Secret_. Update the _OAuth Client Display_ to _SmartThings CLI Control_. Click _Update_. 3. Go back to _My SmartApps_ then click on _SmartThings CLI Control_. Click _Publish_ => _For Me_. -4. Clone the smartthings_cli repository, create a virtualenv if desired, then run the following commands, replacing CLIENTID and CLIENTSECRET with the ID and secret from step 2. +4. Clone the smartthings_cli repository, create a virtualenv if desired, then run the following commands, replacing `CLIENTID` and `CLIENTSECRET` with the ID and secret from step 2. ``` python setup.py install smartthings_cli --clientid CLIENTID --clientsecret CLIENTSECRET ``` -5. smartthings_cli will direct you to a URL to authorized access. Go to that URL in a browser and specify which devices the CLI should be able to access. Click _Authorize_ when finished. You should be redirected to a page reporting _smartthings_cli.py received auth code_. +5. `smartthings_cli` will direct you to a URL to authorized access. Go to that URL in a browser and specify which devices the CLI should be able to access. Click _Authorize_ when finished. You should be redirected to a page reporting _smartthings_cli.py received auth code_. 6. You can now use smartthings_cli.py to query and control devices managed by SmartThings. Examples: - 1. `smartthings_cli query switch all` - 2. `smartthings_cli query switch "Switch Name"` - 3. `smartthings_cli set switch "Switch Name" on` + * `smartthings_cli query switch all` + * `smartthings_cli query switch "Switch Name"` + * `smartthings_cli set switch "Switch Name" on` diff --git a/groovy/app.groovy b/groovy/app.groovy index 89832ee..76eac94 100644 --- a/groovy/app.groovy +++ b/groovy/app.groovy @@ -37,6 +37,7 @@ preferences { input "presences", "capability.presenceSensor", title: "Presence", required: false, multiple: true input "batteries", "capability.battery", title: "Battery", required: false, multiple: true input "threeaxes", "capability.threeAxis", title: "3 Axis", required: false, multiple: true + input "locks", "capability.lock", title: "Lock", required: false, multiple: true } } @@ -113,6 +114,9 @@ private device_to_json(device, type) { case "presence": values['state'] = (s?.value == "present") break + case "lock": + values['state'] = (s?.value == "locked") + break case "battery": values['state'] = s?.value.toFloat() / 100.0 break @@ -136,7 +140,8 @@ def devices_for_type(type) { acceleration: accelerations, presence: presences, battery: batteries, - threeAxis: threeaxes + threeAxis: threeaxes, + lock: locks ][type] } @@ -169,4 +174,4 @@ void runRoutine() { } else { home.execute(routine.label) } -} \ No newline at end of file +} diff --git a/smartthings.sh b/smartthings.sh new file mode 100755 index 0000000..7858cb4 --- /dev/null +++ b/smartthings.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +### Wrapper script to run smartthings_cli from a Docker container + +docker run -it --rm smartthings smartthings_cli ${1} ${2} ${3} diff --git a/smartthings_cli/smartthings_cli.py b/smartthings_cli/smartthings_cli.py index 86c9a33..0c6dc9d 100755 --- a/smartthings_cli/smartthings_cli.py +++ b/smartthings_cli/smartthings_cli.py @@ -280,6 +280,7 @@ def main(): 'acceleration', 'presence', 'battery', + 'lock', 'threeAxis' ] @@ -300,30 +301,34 @@ def main(): update_device(access_token, endpoint_base_url, endpoint_url, dev_lists[device_type], device_type, device_name, device_cmd) if cmd == 'query': - device_type = cmd_list.pop(0) - device_name = cmd_list.pop(0) - - if not device_type in valid_device_types: - logging.error("Invalid device type: %s", device_type) - continue + device_type_raw = cmd_list.pop(0) + device_name_raw = cmd_list.pop(0) - if not device_type in dev_lists: - dev_lists[device_type] = get_status(access_token, endpoint_base_url, endpoint_url, device_type) + check_types = valid_device_types if device_type_raw == 'all' else [device_type_raw] + for device_type in check_types: + if not device_type in valid_device_types: + logging.error("Invalid device type: %s", device_type) + continue - if device_name == 'all': - for device_name in dev_lists[device_type]: - device_state = dev_lists[device_type][device_name]['state'] - logging.info('%s %s: %s', device_type, device_name, device_state) + if not device_type in dev_lists: + # Get status only once for the device_type + logging.debug("Retrieving status for device type: %s", device_type) + dev_lists[device_type] = get_status(access_token, endpoint_base_url, endpoint_url, device_type) + + if device_name_raw == 'all': + for device_name in dev_lists[device_type]: + device_state = dev_lists[device_type][device_name]['state'] + logging.info('%s | "%s": %s', device_type, device_name, device_state) + if device_state: + return_code = 1 + else: + if not device_name_raw in dev_lists[device_type]: + logging.error('%s | "%s" does not exist!', device_type, device_name_raw) + continue + device_state = dev_lists[device_type][device_name_raw]['state'] + logging.info('%s | "%s": %s', device_type, device_name_raw, device_state) if device_state: return_code = 1 - else: - if not device_name in dev_lists[device_type]: - logging.error('%s "%s" does not exist!', device_type, device_name) - continue - device_state = dev_lists[device_type][device_name]['state'] - logging.info('%s %s: %s', device_type, device_name, device_state) - if device_state: - return_code = 1 save_config(config) sys.exit(return_code)