From a4801113d96192e9fefe2f85caac504f0baf5a1b Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Wed, 31 Jan 2018 14:55:16 -0800 Subject: [PATCH 01/10] Adding "lock" as a valid device type --- groovy/app.groovy | 9 +++++++-- smartthings_cli/smartthings_cli.py | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) 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_cli/smartthings_cli.py b/smartthings_cli/smartthings_cli.py index 86c9a33..2a1e2fb 100755 --- a/smartthings_cli/smartthings_cli.py +++ b/smartthings_cli/smartthings_cli.py @@ -280,6 +280,7 @@ def main(): 'acceleration', 'presence', 'battery', + 'lock', 'threeAxis' ] From e5eabd04fefe5c37a60d31098800bee950baa9bd Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Wed, 31 Jan 2018 14:57:44 -0800 Subject: [PATCH 02/10] Ignore build and dist dirs --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dae7b5e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build/ +dist/ + From ca9122a43ff6687e3d475f07a09c4ae1a0aa441d Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Wed, 31 Jan 2018 15:14:39 -0800 Subject: [PATCH 03/10] Update formatting --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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` From 6fa6014c4d772868755599d2cd5e44bc6e1573f5 Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Thu, 5 Dec 2019 00:32:36 -0800 Subject: [PATCH 04/10] Make multi-word device names more clear --- smartthings_cli/smartthings_cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smartthings_cli/smartthings_cli.py b/smartthings_cli/smartthings_cli.py index 2a1e2fb..41c6261 100755 --- a/smartthings_cli/smartthings_cli.py +++ b/smartthings_cli/smartthings_cli.py @@ -314,15 +314,15 @@ def main(): 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) + logging.info('%s - "%s": %s', device_type, device_name, 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) + 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) + logging.info('%s - "%s": %s', device_type, device_name, device_state) if device_state: return_code = 1 From 0b0f31a66e7f4a80e053e40981c4980900c1e01d Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Thu, 5 Dec 2019 00:33:51 -0800 Subject: [PATCH 05/10] use pipe to separate type from device name --- smartthings_cli/smartthings_cli.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/smartthings_cli/smartthings_cli.py b/smartthings_cli/smartthings_cli.py index 41c6261..ad9856d 100755 --- a/smartthings_cli/smartthings_cli.py +++ b/smartthings_cli/smartthings_cli.py @@ -314,15 +314,15 @@ def main(): 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) + logging.info('%s | "%s": %s', device_type, device_name, 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) + 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) + logging.info('%s | "%s": %s', device_type, device_name, device_state) if device_state: return_code = 1 From 240d291daa8004247ccb0522591e8d62edd072d7 Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Thu, 5 Dec 2019 00:41:33 -0800 Subject: [PATCH 06/10] add debug message and comment to clarify behavior --- smartthings_cli/smartthings_cli.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/smartthings_cli/smartthings_cli.py b/smartthings_cli/smartthings_cli.py index ad9856d..effa7bb 100755 --- a/smartthings_cli/smartthings_cli.py +++ b/smartthings_cli/smartthings_cli.py @@ -309,6 +309,8 @@ def main(): continue 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 == 'all': From c65feff0efeb1d16871aad65f0759faf78b9f326 Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Thu, 5 Dec 2019 00:55:25 -0800 Subject: [PATCH 07/10] support querying of all devices in one shot; disambiguate use of variable name 'device_name' --- smartthings_cli/smartthings_cli.py | 46 ++++++++++++++++-------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/smartthings_cli/smartthings_cli.py b/smartthings_cli/smartthings_cli.py index effa7bb..0c6dc9d 100755 --- a/smartthings_cli/smartthings_cli.py +++ b/smartthings_cli/smartthings_cli.py @@ -301,32 +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: - # 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) + 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) From 8f0f540eb64b482e110e700bdf698fd9b9929416 Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Thu, 21 May 2020 11:56:26 -0700 Subject: [PATCH 08/10] adding dockerfile for isolation --- .gitignore | 2 +- Dockerfile | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 Dockerfile diff --git a/.gitignore b/.gitignore index dae7b5e..e46c46e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +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 From 5ca1b693591dd0b3e45e1f1ed0f36fffa4fe6b71 Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Fri, 11 Feb 2022 00:03:09 -0800 Subject: [PATCH 09/10] Add wrapper script to run from Docker container --- smartthings.sh | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 smartthings.sh diff --git a/smartthings.sh b/smartthings.sh new file mode 100644 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} From 465c5cd24b1fab97ad0feb1498dc95a528b83483 Mon Sep 17 00:00:00 2001 From: Richard Yen Date: Fri, 11 Feb 2022 00:03:43 -0800 Subject: [PATCH 10/10] chmod --- smartthings.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 smartthings.sh diff --git a/smartthings.sh b/smartthings.sh old mode 100644 new mode 100755