Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/
dist/
.smartthings_cli.json
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM python:3.7

ADD . .
ADD .smartthings_cli.json /root/.smartthings_cli.json

RUN python setup.py install
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
9 changes: 7 additions & 2 deletions groovy/app.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down Expand Up @@ -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
Expand All @@ -136,7 +140,8 @@ def devices_for_type(type) {
acceleration: accelerations,
presence: presences,
battery: batteries,
threeAxis: threeaxes
threeAxis: threeaxes,
lock: locks
][type]
}

Expand Down Expand Up @@ -169,4 +174,4 @@ void runRoutine() {
} else {
home.execute(routine.label)
}
}
}
5 changes: 5 additions & 0 deletions smartthings.sh
Original file line number Diff line number Diff line change
@@ -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}
45 changes: 25 additions & 20 deletions smartthings_cli/smartthings_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ def main():
'acceleration',
'presence',
'battery',
'lock',
'threeAxis'
]

Expand All @@ -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)
Expand Down