From 21aa776487f7e9c31ff3147b29d6b8bc0d7d9207 Mon Sep 17 00:00:00 2001 From: Bob Florian Date: Fri, 21 Aug 2020 10:12:12 -0400 Subject: [PATCH 1/2] feat: added device view --- packages/cli/README.md | 267 +++++++++++++----- .../cli/src/commands/deviceprofiles/create.ts | 222 +++++++++++++-- .../cli/src/commands/deviceprofiles/update.ts | 7 +- .../cli/src/commands/deviceprofiles/view.ts | 175 ++++++++++++ .../commands/deviceprofiles/view/create.ts | 83 ++++++ .../commands/deviceprofiles/view/update.ts | 87 ++++++ 6 files changed, 761 insertions(+), 80 deletions(-) create mode 100644 packages/cli/src/commands/deviceprofiles/view.ts create mode 100644 packages/cli/src/commands/deviceprofiles/view/create.ts create mode 100644 packages/cli/src/commands/deviceprofiles/view/update.ts diff --git a/packages/cli/README.md b/packages/cli/README.md index 059e00812..2e35bba97 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -115,6 +115,9 @@ that maps to that hierarchy. * [`smartthings deviceprofiles:presentation [ID]`](#smartthings-deviceprofilespresentation-id) * [`smartthings deviceprofiles:publish [ID]`](#smartthings-deviceprofilespublish-id) * [`smartthings deviceprofiles:update [ID]`](#smartthings-deviceprofilesupdate-id) +* [`smartthings deviceprofiles:view [ID]`](#smartthings-deviceprofilesview-id) +* [`smartthings deviceprofiles:view:create`](#smartthings-deviceprofilesviewcreate) +* [`smartthings deviceprofiles:view:update [ID]`](#smartthings-deviceprofilesviewupdate-id) * [`smartthings devices [ID]`](#smartthings-devices-id) * [`smartthings devices:capability-status [ID] [COMPONENT] [CAPABILITY]`](#smartthings-devicescapability-status-id-component-capability) * [`smartthings devices:commands [ID] [COMMAND]`](#smartthings-devicescommands-id-command) @@ -181,7 +184,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/apps.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps.ts)_ +_See code: [dist/commands/apps.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps.ts)_ ## `smartthings apps:authorize ARN` @@ -211,7 +214,7 @@ EXAMPLES It requires your machine to be configured to run the AWS CLI ``` -_See code: [dist/commands/apps/authorize.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/authorize.ts)_ +_See code: [dist/commands/apps/authorize.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/authorize.ts)_ ## `smartthings apps:create` @@ -236,7 +239,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/apps/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/create.ts)_ +_See code: [dist/commands/apps/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/create.ts)_ ## `smartthings apps:delete [ID]` @@ -255,7 +258,7 @@ OPTIONS -t, --token=token the auth token to use ``` -_See code: [dist/commands/apps/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/delete.ts)_ +_See code: [dist/commands/apps/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/delete.ts)_ ## `smartthings apps:oauth [ID]` @@ -280,7 +283,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/apps/oauth.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/oauth.ts)_ +_See code: [dist/commands/apps/oauth.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/oauth.ts)_ ## `smartthings apps:oauth:generate [ID]` @@ -306,7 +309,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/apps/oauth/generate.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/oauth/generate.ts)_ +_See code: [dist/commands/apps/oauth/generate.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/oauth/generate.ts)_ ## `smartthings apps:oauth:update [ID]` @@ -332,7 +335,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/apps/oauth/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/oauth/update.ts)_ +_See code: [dist/commands/apps/oauth/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/oauth/update.ts)_ ## `smartthings apps:register [ID]` @@ -351,7 +354,7 @@ OPTIONS -t, --token=token the auth token to use ``` -_See code: [dist/commands/apps/register.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/register.ts)_ +_See code: [dist/commands/apps/register.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/register.ts)_ ## `smartthings apps:settings [ID]` @@ -376,7 +379,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/apps/settings.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/settings.ts)_ +_See code: [dist/commands/apps/settings.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/settings.ts)_ ## `smartthings apps:settings:update [ID]` @@ -402,7 +405,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/apps/settings/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/settings/update.ts)_ +_See code: [dist/commands/apps/settings/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/settings/update.ts)_ ## `smartthings apps:update [ID]` @@ -429,7 +432,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/apps/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/apps/update.ts)_ +_See code: [dist/commands/apps/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/apps/update.ts)_ ## `smartthings autocomplete [SHELL]` @@ -480,7 +483,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/capabilities.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/capabilities.ts)_ +_See code: [dist/commands/capabilities.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/capabilities.ts)_ ## `smartthings capabilities:create` @@ -505,7 +508,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/capabilities/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/capabilities/create.ts)_ +_See code: [dist/commands/capabilities/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/capabilities/create.ts)_ ## `smartthings capabilities:delete [ID] [VERSION]` @@ -525,7 +528,7 @@ OPTIONS -t, --token=token the auth token to use ``` -_See code: [dist/commands/capabilities/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/capabilities/delete.ts)_ +_See code: [dist/commands/capabilities/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/capabilities/delete.ts)_ ## `smartthings capabilities:namespaces` @@ -547,7 +550,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/capabilities/namespaces.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/capabilities/namespaces.ts)_ +_See code: [dist/commands/capabilities/namespaces.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/capabilities/namespaces.ts)_ ## `smartthings capabilities:presentation [ID] [VERSION]` @@ -574,7 +577,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/capabilities/presentation.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/capabilities/presentation.ts)_ +_See code: [dist/commands/capabilities/presentation.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/capabilities/presentation.ts)_ ## `smartthings capabilities:presentation:create [ID] [VERSION]` @@ -601,7 +604,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/capabilities/presentation/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/capabilities/presentation/create.ts)_ +_See code: [dist/commands/capabilities/presentation/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/capabilities/presentation/create.ts)_ ## `smartthings capabilities:presentation:update [ID] [VERSION]` @@ -628,7 +631,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/capabilities/presentation/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/capabilities/presentation/update.ts)_ +_See code: [dist/commands/capabilities/presentation/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/capabilities/presentation/update.ts)_ ## `smartthings capabilities:update [ID] [VERSION]` @@ -655,7 +658,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/capabilities/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/capabilities/update.ts)_ +_See code: [dist/commands/capabilities/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/capabilities/update.ts)_ ## `smartthings config [NAME]` @@ -681,7 +684,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/config.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/config.ts)_ +_See code: [dist/commands/config.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/config.ts)_ ## `smartthings deviceprofiles [ID]` @@ -718,11 +721,11 @@ EXAMPLES $ smartthings deviceprofiles 4 -j -o profile.json # write the profile to the file "profile.json" ``` -_See code: [dist/commands/deviceprofiles.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/deviceprofiles.ts)_ +_See code: [dist/commands/deviceprofiles.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles.ts)_ ## `smartthings deviceprofiles:create` -create a new device profile +Create a new device profile ``` USAGE @@ -741,12 +744,18 @@ OPTIONS --expanded use expanded table format with a line between each body row --indent=indent specify indentation for formatting JSON or YAML output +DESCRIPTION + Creates a new device profile. If a vid field is not present in the meta + then a default device presentation will be created for this profile and the + vid set to reference it. + EXAMPLES $ smartthings deviceprofiles:create -i myprofile.json # create a device profile from the JSON file definition $ smartthings deviceprofiles:create -i myprofile.yaml # create a device profile from the YAML file definition + $ smartthings deviceprofiles:create # create a device profile with interactive dialog ``` -_See code: [dist/commands/deviceprofiles/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/deviceprofiles/create.ts)_ +_See code: [dist/commands/deviceprofiles/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles/create.ts)_ ## `smartthings deviceprofiles:delete [ID]` @@ -769,7 +778,7 @@ EXAMPLES $ smartthings deviceprofiles:delete 5 # delete the 5th profile in the list ``` -_See code: [dist/commands/deviceprofiles/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/deviceprofiles/delete.ts)_ +_See code: [dist/commands/deviceprofiles/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles/delete.ts)_ ## `smartthings deviceprofiles:device-config [ID]` @@ -794,7 +803,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/deviceprofiles/device-config.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/deviceprofiles/device-config.ts)_ +_See code: [dist/commands/deviceprofiles/device-config.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles/device-config.ts)_ ## `smartthings deviceprofiles:presentation [ID]` @@ -819,7 +828,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/deviceprofiles/presentation.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/deviceprofiles/presentation.ts)_ +_See code: [dist/commands/deviceprofiles/presentation.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles/presentation.ts)_ ## `smartthings deviceprofiles:publish [ID]` @@ -844,7 +853,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/deviceprofiles/publish.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/deviceprofiles/publish.ts)_ +_See code: [dist/commands/deviceprofiles/publish.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles/publish.ts)_ ## `smartthings deviceprofiles:update [ID]` @@ -870,7 +879,139 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/deviceprofiles/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/deviceprofiles/update.ts)_ +_See code: [dist/commands/deviceprofiles/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles/update.ts)_ + +## `smartthings deviceprofiles:view [ID]` + +Show device profile and device configuration in a single, consolidated view + +``` +USAGE + $ smartthings deviceprofiles:view [ID] + +ARGUMENTS + ID Device profile UUID or the number from list + +OPTIONS + -h, --help show CLI help + -j, --json use JSON format of input and/or output + -o, --output=output specify output file + -p, --profile=profile [default: default] configuration profile + -t, --token=token the auth token to use + -y, --yaml use YAML format of input and/or output + --compact use compact table format with no lines between body rows + --expanded use expanded table format with a line between each body row + --indent=indent specify indentation for formatting JSON or YAML output +``` + +_See code: [dist/commands/deviceprofiles/view.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles/view.ts)_ + +## `smartthings deviceprofiles:view:create` + +Create a new device profile and device configuration. + +``` +USAGE + $ smartthings deviceprofiles:view:create + +OPTIONS + -d, --dry-run produce JSON but don't actually submit + -h, --help show CLI help + -i, --input=input specify input file + -j, --json use JSON format of input and/or output + -o, --output=output specify output file + -p, --profile=profile [default: default] configuration profile + -t, --token=token the auth token to use + -y, --yaml use YAML format of input and/or output + --compact use compact table format with no lines between body rows + --expanded use expanded table format with a line between each body row + --indent=indent specify indentation for formatting JSON or YAML output + +DESCRIPTION + Creates a new device profile and device configuration. Unlike deviceprofiles:create, + this command accepts a consolidated object that can include a device configration + in a property named "view". + +EXAMPLES + $ smartthings deviceprofiles:view:create -i test.json + + This test.json file defines a switch that cannot be controlled by the automations builder: + + name: Test Switch + components: + - id: main + capabilities: + - id: switch + view: + dashboard: + states: + - capability: switch + actions: + - capability: switch + detailView: + - capability: switch + automation: + conditions: + - capability: switch +``` + +_See code: [dist/commands/deviceprofiles/view/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles/view/create.ts)_ + +## `smartthings deviceprofiles:view:update [ID]` + +Update a device profile and configuration. + +``` +USAGE + $ smartthings deviceprofiles:view:update [ID] + +ARGUMENTS + ID Device profile UUID or the number from list + +OPTIONS + -h, --help show CLI help + -i, --input=input specify input file + -j, --json use JSON format of input and/or output + -o, --output=output specify output file + -p, --profile=profile [default: default] configuration profile + -t, --token=token the auth token to use + -y, --yaml use YAML format of input and/or output + --compact use compact table format with no lines between body rows + --expanded use expanded table format with a line between each body row + --indent=indent specify indentation for formatting JSON or YAML output + +DESCRIPTION + Updates a device profile and device configuration and sets the vid of the profile + to the vid of the updated configuration. Unlike deviceprofiles:update this + command accepts a consolidated object that can include a device configration + in a property named "view". + +EXAMPLES + $ smartthings deviceprofiles:view:update 84042863-0d34-4c5c-b497-808daf230787 -i test.json + + This test.json file adds the powerMeter capability to the device and makes it available in + the device detail view but not the rule builder: + + components: + - id: main + capabilities: + - id: switch + - id: powerMeter + view: + dashboard: + states: + - capability: switch + actions: + - capability: switch + detailView: + - capability: switch + - capability: powerMeter + automation: + conditions: + - capability: switch +``` + +_See code: [dist/commands/deviceprofiles/view/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/deviceprofiles/view/update.ts)_ ## `smartthings devices [ID]` @@ -914,7 +1055,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/devices.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices.ts)_ +_See code: [dist/commands/devices.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices.ts)_ ## `smartthings devices:capability-status [ID] [COMPONENT] [CAPABILITY]` @@ -941,7 +1082,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/devices/capability-status.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices/capability-status.ts)_ +_See code: [dist/commands/devices/capability-status.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices/capability-status.ts)_ ## `smartthings devices:commands [ID] [COMMAND]` @@ -968,7 +1109,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/devices/commands.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices/commands.ts)_ +_See code: [dist/commands/devices/commands.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices/commands.ts)_ ## `smartthings devices:component-status [ID] [COMPONENT]` @@ -994,7 +1135,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/devices/component-status.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices/component-status.ts)_ +_See code: [dist/commands/devices/component-status.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices/component-status.ts)_ ## `smartthings devices:delete [ID]` @@ -1013,7 +1154,7 @@ OPTIONS -t, --token=token the auth token to use ``` -_See code: [dist/commands/devices/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices/delete.ts)_ +_See code: [dist/commands/devices/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices/delete.ts)_ ## `smartthings devices:health [ID]` @@ -1038,7 +1179,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/devices/health.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices/health.ts)_ +_See code: [dist/commands/devices/health.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices/health.ts)_ ## `smartthings devices:presentation [ID]` @@ -1063,7 +1204,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/devices/presentation.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices/presentation.ts)_ +_See code: [dist/commands/devices/presentation.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices/presentation.ts)_ ## `smartthings devices:rename [ID] [LABEL]` @@ -1089,7 +1230,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/devices/rename.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices/rename.ts)_ +_See code: [dist/commands/devices/rename.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices/rename.ts)_ ## `smartthings devices:status [ID]` @@ -1114,7 +1255,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/devices/status.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices/status.ts)_ +_See code: [dist/commands/devices/status.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices/status.ts)_ ## `smartthings devices:update [ID]` @@ -1140,7 +1281,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/devices/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/devices/update.ts)_ +_See code: [dist/commands/devices/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/devices/update.ts)_ ## `smartthings generate:java` @@ -1155,7 +1296,7 @@ OPTIONS -p, --profile=profile [default: default] configuration profile ``` -_See code: [dist/commands/generate/java.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/generate/java.ts)_ +_See code: [dist/commands/generate/java.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/generate/java.ts)_ ## `smartthings generate:node` @@ -1170,7 +1311,7 @@ OPTIONS -p, --profile=profile [default: default] configuration profile ``` -_See code: [dist/commands/generate/node.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/generate/node.ts)_ +_See code: [dist/commands/generate/node.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/generate/node.ts)_ ## `smartthings help [COMMAND]` @@ -1213,7 +1354,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/installedapps.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/installedapps.ts)_ +_See code: [dist/commands/installedapps.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/installedapps.ts)_ ## `smartthings installedapps:delete [ID]` @@ -1232,7 +1373,7 @@ OPTIONS -t, --token=token the auth token to use ``` -_See code: [dist/commands/installedapps/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/installedapps/delete.ts)_ +_See code: [dist/commands/installedapps/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/installedapps/delete.ts)_ ## `smartthings installedapps:rename [ID] [NAME]` @@ -1258,7 +1399,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/installedapps/rename.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/installedapps/rename.ts)_ +_See code: [dist/commands/installedapps/rename.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/installedapps/rename.ts)_ ## `smartthings locations [IDORINDEX]` @@ -1283,7 +1424,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/locations.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/locations.ts)_ +_See code: [dist/commands/locations.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/locations.ts)_ ## `smartthings locations:create` @@ -1307,7 +1448,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/locations/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/locations/create.ts)_ +_See code: [dist/commands/locations/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/locations/create.ts)_ ## `smartthings locations:delete [ID]` @@ -1326,7 +1467,7 @@ OPTIONS -t, --token=token the auth token to use ``` -_See code: [dist/commands/locations/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/locations/delete.ts)_ +_See code: [dist/commands/locations/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/locations/delete.ts)_ ## `smartthings locations:rooms [IDORINDEX]` @@ -1355,7 +1496,7 @@ ALIASES $ smartthings rooms ``` -_See code: [dist/commands/locations/rooms.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/locations/rooms.ts)_ +_See code: [dist/commands/locations/rooms.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/locations/rooms.ts)_ ## `smartthings locations:rooms:create` @@ -1383,7 +1524,7 @@ ALIASES $ smartthings rooms:create ``` -_See code: [dist/commands/locations/rooms/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/locations/rooms/create.ts)_ +_See code: [dist/commands/locations/rooms/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/locations/rooms/create.ts)_ ## `smartthings locations:rooms:delete [ID]` @@ -1406,7 +1547,7 @@ ALIASES $ smartthings rooms:delete ``` -_See code: [dist/commands/locations/rooms/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/locations/rooms/delete.ts)_ +_See code: [dist/commands/locations/rooms/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/locations/rooms/delete.ts)_ ## `smartthings locations:rooms:update [ID]` @@ -1436,7 +1577,7 @@ ALIASES $ smartthings rooms:update ``` -_See code: [dist/commands/locations/rooms/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/locations/rooms/update.ts)_ +_See code: [dist/commands/locations/rooms/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/locations/rooms/update.ts)_ ## `smartthings locations:update [ID]` @@ -1462,7 +1603,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/locations/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/locations/update.ts)_ +_See code: [dist/commands/locations/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/locations/update.ts)_ ## `smartthings plugins` @@ -1605,7 +1746,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/presentation.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/presentation.ts)_ +_See code: [dist/commands/presentation.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/presentation.ts)_ ## `smartthings presentation:device-config VID` @@ -1630,7 +1771,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/presentation/device-config.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/presentation/device-config.ts)_ +_See code: [dist/commands/presentation/device-config.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/presentation/device-config.ts)_ ## `smartthings presentation:device-config:create` @@ -1654,7 +1795,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/presentation/device-config/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/presentation/device-config/create.ts)_ +_See code: [dist/commands/presentation/device-config/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/presentation/device-config/create.ts)_ ## `smartthings presentation:device-config:generate ID` @@ -1683,7 +1824,7 @@ OPTIONS integrations ``` -_See code: [dist/commands/presentation/device-config/generate.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/presentation/device-config/generate.ts)_ +_See code: [dist/commands/presentation/device-config/generate.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/presentation/device-config/generate.ts)_ ## `smartthings rules [IDORINDEX]` @@ -1709,7 +1850,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/rules.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/rules.ts)_ +_See code: [dist/commands/rules.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/rules.ts)_ ## `smartthings rules:create` @@ -1734,7 +1875,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/rules/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/rules/create.ts)_ +_See code: [dist/commands/rules/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/rules/create.ts)_ ## `smartthings rules:delete [ID]` @@ -1754,7 +1895,7 @@ OPTIONS -t, --token=token the auth token to use ``` -_See code: [dist/commands/rules/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/rules/delete.ts)_ +_See code: [dist/commands/rules/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/rules/delete.ts)_ ## `smartthings rules:update [ID]` @@ -1781,7 +1922,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/rules/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/rules/update.ts)_ +_See code: [dist/commands/rules/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/rules/update.ts)_ ## `smartthings schema [ID]` @@ -1807,7 +1948,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/schema.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/schema.ts)_ +_See code: [dist/commands/schema.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/schema.ts)_ ## `smartthings schema:create` @@ -1832,7 +1973,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/schema/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/schema/create.ts)_ +_See code: [dist/commands/schema/create.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/schema/create.ts)_ ## `smartthings schema:delete [ID]` @@ -1851,7 +1992,7 @@ OPTIONS -t, --token=token the auth token to use ``` -_See code: [dist/commands/schema/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/schema/delete.ts)_ +_See code: [dist/commands/schema/delete.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/schema/delete.ts)_ ## `smartthings schema:update ID` @@ -1878,7 +2019,7 @@ OPTIONS --indent=indent specify indentation for formatting JSON or YAML output ``` -_See code: [dist/commands/schema/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.7/dist/commands/schema/update.ts)_ +_See code: [dist/commands/schema/update.ts](https://github.com/SmartThingsCommunity/smartthings-cli/blob/v0.0.0-pre.8/dist/commands/schema/update.ts)_ # Logging diff --git a/packages/cli/src/commands/deviceprofiles/create.ts b/packages/cli/src/commands/deviceprofiles/create.ts index 0ae4a8233..466d65cc2 100644 --- a/packages/cli/src/commands/deviceprofiles/create.ts +++ b/packages/cli/src/commands/deviceprofiles/create.ts @@ -1,30 +1,77 @@ -import { DeviceProfile, DeviceProfileRequest } from '@smartthings/core-sdk' +import { + DeviceProfile, + DeviceProfileRequest, + PresentationDeviceConfigCreate, + SmartThingsClient, +} from '@smartthings/core-sdk' import { InputOutputAPICommand } from '@smartthings/cli-lib' - import { buildTableOutput } from '../deviceprofiles' +import {DeviceDefinitionRequest} from './view' +import inquirer from 'inquirer' -export default class DeviceProfileCreateCommand extends InputOutputAPICommand { - static description = 'create a new device profile' +const capabilityBlacklist = ['healthCheck', 'execute'] - static flags = InputOutputAPICommand.flags +export async function generateDefaultConfig(client: SmartThingsClient, deviceProfileId: string, deviceProfile: DeviceProfileRequest | DeviceDefinitionRequest): Promise { + // Generate the default config + const deviceConfig = await client.presentation.generate(deviceProfileId) - static examples = [ - '$ smartthings deviceprofiles:create -i myprofile.json # create a device profile from the JSON file definition', - '$ smartthings deviceprofiles:create -i myprofile.yaml # create a device profile from the YAML file definition', - ] + // Edit the dashboard entries to include only the first capability in the profile + if (deviceProfile.components && deviceConfig.dashboard) { + const firstComponent = deviceProfile.components[0] + if (firstComponent.capabilities && firstComponent.capabilities.length > 0) { + const firstCapability = firstComponent.capabilities[0] + const capability = await client.capabilities.get(firstCapability.id, firstCapability.version || 1) - protected buildTableOutput = buildTableOutput + if (capability.attributes && Object.keys(capability.attributes).length > 0) { + deviceConfig.dashboard.states = deviceConfig.dashboard.states.filter(it => + it.component === firstComponent.id && it.capability === firstCapability.id) + } else { + deviceConfig.dashboard.states = [] + } - async run(): Promise { - const { args, argv, flags } = this.parse(DeviceProfileCreateCommand) - await super.setup(args, argv, flags) + if (capability.commands && Object.keys(capability.commands).length > 0) { + deviceConfig.dashboard.actions = deviceConfig.dashboard.actions.filter(it => + it.component === firstComponent.id && it.capability === firstCapability.id) + } else { + deviceConfig.dashboard.actions = [] + } + } + } - this.processNormally((data) => { - return this.client.deviceProfiles.create(cleanupRequest(data)) - }) + // Filter capabilities with no UI + if (deviceConfig.detailView) { + deviceConfig.detailView = deviceConfig.detailView.filter(it => !(capabilityBlacklist.includes(it.capability))) + } + + // Filter automation entries + if (deviceConfig.automation) { + + // Filter out conditions for capabilities that don't have attributes + if (deviceConfig.automation.conditions) { + const capabilities = await Promise.all(deviceConfig.automation.conditions.map(it => { + return client.capabilities.get(it.capability, it.version || 1) + })) + deviceConfig.automation.conditions = deviceConfig.automation.conditions.filter((_v, index) => { + const capability = capabilities[index] + return capability.attributes && Object.keys(capability.attributes).length > 0 && !(capabilityBlacklist.includes(capability.id || '')) + }) + } + + // Filter out automation actions for capabilities that don't have commands + if (deviceConfig.automation.actions) { + const capabilities = await Promise.all(deviceConfig.automation.actions.map(it => { + return client.capabilities.get(it.capability, it.version || 1) + })) + deviceConfig.automation.actions = deviceConfig.automation.actions.filter((_v, index) => { + const capability = capabilities[index] + return capability.commands && Object.keys(capability.commands).length > 0 && !(capabilityBlacklist.includes(capability.id || '')) + }) + } } + + return deviceConfig } // Cleanup is done so that the result of a device profile get can be modified and @@ -42,3 +89,146 @@ export function cleanupRequest(deviceProfileRequest: Partial { + static description = 'Create a new device profile\n' + + 'Creates a new device profile. If a vid field is not present in the meta\n' + + 'then a default device presentation will be created for this profile and the\n' + + 'vid set to reference it.' + + static flags = InputOutputAPICommand.flags + + static examples = [ + '$ smartthings deviceprofiles:create -i myprofile.json # create a device profile from the JSON file definition', + '$ smartthings deviceprofiles:create -i myprofile.yaml # create a device profile from the YAML file definition', + '$ smartthings deviceprofiles:create # create a device profile with interactive dialog', + ] + + protected buildTableOutput = buildTableOutput + + async run(): Promise { + const { args, argv, flags } = this.parse(DeviceProfileCreateCommand) + await super.setup(args, argv, flags) + + this.processNormally(async (data) => { + if (data.view) { + throw new Error('Input contains "view" property. Use deviceprofiles:view:create instead.') + } + + let profile = await this.client.deviceProfiles.create(cleanupRequest(data)) + + if (!data.metadata?.vid) { + // Generate the default config + const deviceConfigData = await generateDefaultConfig(this.client, profile.id, profile) + + // Create the config using the default + const deviceConfig = await this.client.presentation.create(deviceConfigData) + + // Update the profile to use the vid from the config + const profileId = profile.id + cleanupRequest(profile) + delete profile.name + if (!profile.metadata) { + profile.metadata = {} + } + profile.metadata.vid = deviceConfig.vid + profile.metadata.mnmn = deviceConfig.mnmn + profile = await this.client.deviceProfiles.update(profileId, profile) + } + + return profile + }) + } + + protected async promptAndAddCapability(deviceProfile: DeviceProfileRequest, componentId: string, message = 'Capability ID'): Promise { + const capabilityId: string = (await inquirer.prompt({ + type: 'input', + name: 'capabilityId', + message: message + ': ', + validate: (input) => { + return input.length > 0 || 'Invalid capability name' + }, + })).capabilityId + + if (capabilityId) { + const component = deviceProfile.components?.find(it => it.id === componentId) + if (component) { + component.capabilities?.push({id: capabilityId, version: 1}) + } else { + throw new Error(`Component ${componentId} not defined in profile`) + } + } + } + + protected async promptAndAddComponent(deviceProfile: DeviceProfileRequest, previousComponentId: string): Promise { + const components = deviceProfile.components || [] + let componentId: string = (await inquirer.prompt({ + type: 'input', + name: 'componentId', + message: 'ComponentId ID: ', + validate: (input) => { + return (new RegExp(/^[0-9a-zA-Z]{1,100}$/).test(input) && !components.find(it => it.id === input)) || 'Invalid component name' + }, + })).componentId + + if (componentId) { + components.push({id: componentId, capabilities: []}) + } else { + componentId = previousComponentId + } + return componentId + } + + protected async getInputFromUser(): Promise { + const name = (await inquirer.prompt({ + type: 'input', + name: 'deviceProfileName', + message: 'Device Profile Name:', + validate: (input: string) => { + return new RegExp(/^(?!\s)[-_!.~'() *0-9a-zA-Z]{1,100}(? { +export default class DeviceProfileUpdateCommand extends SelectingInputOutputAPICommand { static description = 'update a device profile' static flags = SelectingInputOutputAPICommand.flags @@ -41,6 +42,10 @@ export default class DeviceProfileUpdateCommand extends SelectingInputOutputAPIC this.processNormally(args.id, () => { return this.client.deviceProfiles.list() }, async (id, data) => { + if (data.view) { + throw new Error('Input contains "view" property. Use deviceprofiles:view:update instead.') + } + return this.client.deviceProfiles.update(id, cleanupRequest(data)) }) } diff --git a/packages/cli/src/commands/deviceprofiles/view.ts b/packages/cli/src/commands/deviceprofiles/view.ts new file mode 100644 index 000000000..70f5f0a11 --- /dev/null +++ b/packages/cli/src/commands/deviceprofiles/view.ts @@ -0,0 +1,175 @@ +import { DeviceProfile, DeviceProfileRequest, PresentationDeviceConfigEntry, PresentationDeviceConfig } from '@smartthings/core-sdk' + +import { + APICommand, + SelectingOutputAPICommand, +} from '@smartthings/cli-lib' + + +export interface DeviceView { + dashboard?: { + states: PresentationDeviceConfigEntry[] + actions: PresentationDeviceConfigEntry[] + } + detailView?: PresentationDeviceConfigEntry[] + automation?: { + conditions: PresentationDeviceConfigEntry[] + actions: PresentationDeviceConfigEntry[] + } +} + +export interface DeviceDefinition extends DeviceProfile { + view?: DeviceView +} + +export interface DeviceDefinitionRequest extends DeviceProfileRequest { + view?: DeviceView +} + +function entryValues(entries: PresentationDeviceConfigEntry[]): string { + return entries.map(entry => entry.component ? `${entry.component}/${entry.capability}` : `${entry.capability}`).join('\n') +} + +export function buildTableOutput(this: APICommand, data: DeviceDefinition): string { + const table = this.tableGenerator.newOutputTable() + table.push(['Name', data.name]) + for (const comp of data.components) { + table.push([`${comp.id} component`, comp.capabilities ? comp.capabilities.map(it => it.id).join('\n') : '']) + } + table.push(['Id', data.id]) + table.push(['Device Type', data.metadata?.deviceType ?? '']) + table.push(['OCF Device Type', data.metadata?.ocfDeviceType ?? '']) + table.push(['mnmn', data.metadata?.mnmn ?? '']) + table.push(['vid', data.metadata?.vid ?? '']) + table.push(['Status', data.status]) + if (data.view) { + if (data.view.dashboard) { + if (data.view.dashboard.states) { + table.push(['Dashboard states', entryValues(data.view.dashboard.states)]) + } + if (data.view.dashboard.actions) { + table.push(['Dashboard actions', entryValues(data.view.dashboard.actions)]) + } + } + if (data.view.detailView) { + table.push(['Detail view', entryValues(data.view.detailView)]) + } + if (data.view.automation) { + if (data.view.automation.conditions) { + table.push(['Automation conditions', entryValues(data.view.automation.conditions)]) + } + if (data.view.automation.actions) { + table.push(['Automation actions', entryValues(data.view.automation.actions)]) + } + } + } + return table.toString() +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function prunePresentation(view: { [key: string]: any }): void { + delete view.mnmn + delete view.vid + delete view.type + if (view.dpInfo === null) { + delete view.dpInfo + } + if (view.iconUrl === null) { + delete view.iconUrl + } +} + +function prunePresentationEntries(entries?: PresentationDeviceConfigEntry[]): void { + if (entries) { + const mcd = entries.find(it => it.component !== 'main') + for (const entry of entries) { + if (entry.version === 1) { + delete entry.version + } + if (entry.values && entry.values.length === 0) { + delete entry.values + } + if (!entry.visibleCondition) { + delete entry.visibleCondition + } + if (!mcd) { + delete entry.component + } + } + } +} + +export function prunePresentationValues(view: DeviceView): DeviceView { + prunePresentation(view) + prunePresentationEntries(view.dashboard?.states) + prunePresentationEntries(view.dashboard?.actions) + prunePresentationEntries(view.detailView) + prunePresentationEntries(view.automation?.conditions) + prunePresentationEntries(view.automation?.actions) + return view +} + +function augmentPresentationEntries(entries?: PresentationDeviceConfigEntry[]): void { + if (entries) { + for (const entry of entries) { + if (!entry.version) { + entry.version = 1 + } + if (!entry.component) { + entry.component = 'main' + } + } + } +} + +export function augmentPresentationValues(view: DeviceView): DeviceView { + augmentPresentationEntries(view.dashboard?.states) + augmentPresentationEntries(view.dashboard?.actions) + augmentPresentationEntries(view.detailView) + augmentPresentationEntries(view.automation?.conditions) + augmentPresentationEntries(view.automation?.actions) + return view +} + +export default class DeviceViewCommand extends SelectingOutputAPICommand { + static description = 'Show device profile and device configuration in a single, consolidated view' + + static flags = { + ...SelectingOutputAPICommand.flags, + } + + static args = [{ + name: 'id', + description: 'Device profile UUID or the number from list', + }] + + primaryKeyName = 'id' + sortKeyName = 'name' + acceptIndexId = true + + protected buildTableOutput = buildTableOutput + + async run(): Promise { + const { args, argv, flags } = this.parse(DeviceViewCommand) + await super.setup(args, argv, flags) + + this.processNormally( + args.id, + () => { return this.client.deviceProfiles.list() }, + async (id) => { + const profile = await this.client.deviceProfiles.get(id) + if (profile.metadata) { + try { + const view = await this.client.presentation.get(profile.metadata.vid) + prunePresentationValues(view) + return {...profile, view} + } catch (error) { + return profile + } + } else { + return profile + } + }, + ) + } +} diff --git a/packages/cli/src/commands/deviceprofiles/view/create.ts b/packages/cli/src/commands/deviceprofiles/view/create.ts new file mode 100644 index 000000000..cf60db7b7 --- /dev/null +++ b/packages/cli/src/commands/deviceprofiles/view/create.ts @@ -0,0 +1,83 @@ +import { InputOutputAPICommand } from '@smartthings/cli-lib' +import {cleanupRequest, generateDefaultConfig} from '../create' +import { buildTableOutput, prunePresentationValues, augmentPresentationValues, DeviceDefinition, DeviceDefinitionRequest } from '../view' + + +export default class DeviceDefCreateCommand extends InputOutputAPICommand { + static description = 'Create a new device profile and device configuration.\n' + + 'Creates a new device profile and device configuration. Unlike deviceprofiles:create,\n' + + 'this command accepts a consolidated object that can include a device configration \n' + + 'in a property named "view".' + + static flags = InputOutputAPICommand.flags + + static examples = [ + '$ smartthings deviceprofiles:view:create -i test.json', + '', + 'This test.json file defines a switch that cannot be controlled by the automations builder:', + '', + 'name: Test Switch', + 'components:', + ' - id: main', + ' capabilities:', + ' - id: switch', + 'view:', + ' dashboard:', + ' states:', + ' - capability: switch', + ' actions:', + ' - capability: switch', + ' detailView:', + ' - capability: switch', + ' automation:', + ' conditions:', + ' - capability: switch ', + ] + + protected buildTableOutput = buildTableOutput + + async run(): Promise { + const { args, argv, flags } = this.parse(DeviceDefCreateCommand) + await super.setup(args, argv, flags) + + this.processNormally(async (data) => { + let profile + let deviceConfig + if (data.view) { + // Create the config + deviceConfig = await this.client.presentation.create(augmentPresentationValues(data.view)) + + // Set the vid and mnmn from the config + if (!data.metadata) { + data.metadata = {} + } + data.metadata.vid = deviceConfig.vid + data.metadata.mnmn = deviceConfig.mnmn + delete data.view + + profile = await this.client.deviceProfiles.create(cleanupRequest(data)) + } else { + // Create the profile + profile = await this.client.deviceProfiles.create(cleanupRequest(data)) + + // Generate the default config + const deviceConfigData = await generateDefaultConfig(this.client, profile.id, profile) + + // Create the config using the default + deviceConfig = await this.client.presentation.create(deviceConfigData) + + // Update the profile to use the vid from the config + const profileId = profile.id + cleanupRequest(profile) + delete profile.name + if (!profile.metadata) { + profile.metadata = {} + } + profile.metadata.vid = deviceConfig.vid + profile.metadata.mnmn = deviceConfig.mnmn + profile = await this.client.deviceProfiles.update(profileId, profile) + } + return {...profile, presentation: prunePresentationValues(deviceConfig)} + }) + } +} diff --git a/packages/cli/src/commands/deviceprofiles/view/update.ts b/packages/cli/src/commands/deviceprofiles/view/update.ts new file mode 100644 index 000000000..6f9d6c6de --- /dev/null +++ b/packages/cli/src/commands/deviceprofiles/view/update.ts @@ -0,0 +1,87 @@ +import { SelectingInputOutputAPICommand } from '@smartthings/cli-lib' +import {buildTableOutput, DeviceDefinition, DeviceDefinitionRequest, prunePresentationValues, augmentPresentationValues} from '../view' +import {generateDefaultConfig} from '../create' +import {cleanupRequest} from '../update' + + +export default class CapabilitiesUpdate extends SelectingInputOutputAPICommand { + static description = 'Update a device profile and configuration.\n' + + 'Updates a device profile and device configuration and sets the vid of the profile\n' + + 'to the vid of the updated configuration. Unlike deviceprofiles:update this\n' + + 'command accepts a consolidated object that can include a device configration\n' + + 'in a property named "view".' + + static examples = [ + '$ smartthings deviceprofiles:view:update 84042863-0d34-4c5c-b497-808daf230787 -i test.json', + '', + 'This test.json file adds the powerMeter capability to the device and makes it available in', + 'the device detail view but not the rule builder:', + '', + 'components:', + ' - id: main', + ' capabilities:', + ' - id: switch', + ' - id: powerMeter', + 'view:', + ' dashboard:', + ' states:', + ' - capability: switch', + ' actions:', + ' - capability: switch', + ' detailView:', + ' - capability: switch', + ' - capability: powerMeter', + ' automation:', + ' conditions:', + ' - capability: switch ', + ] + + static flags = SelectingInputOutputAPICommand.flags + + static args = [{ + name: 'id', + description: 'Device profile UUID or the number from list', + }] + + primaryKeyName = 'id' + sortKeyName = 'name' + + protected listTableFieldDefinitions = ['name', 'status', 'id'] + + protected buildTableOutput = buildTableOutput + + async run(): Promise { + const { args, argv, flags } = this.parse(CapabilitiesUpdate) + await super.setup(args, argv, flags) + + this.processNormally(args.id, + () => { return this.client.deviceProfiles.list() }, + async (id, data) => { + const profileData = data + let presentationData = data.view + delete profileData.view + + if (presentationData) { + presentationData = augmentPresentationValues(presentationData) + } else { + // eslint-disable-next-line no-console + //console.log('Generating presentation') + presentationData = await generateDefaultConfig(this.client, id, profileData) + } + + // eslint-disable-next-line no-console + //console.log(`Creating presentation from ${JSON.stringify(presentationData, null, 2)}`) + const presentation = await this.client.presentation.create(presentationData) + if (!profileData.metadata) { + profileData.metadata = {} + } + profileData.metadata.vid = presentation.vid + profileData.metadata.mnmn = presentation.mnmn + // eslint-disable-next-line no-console + console.log(`Updating profile from ${JSON.stringify(cleanupRequest(profileData), null, 2)}`) + const profile = await this.client.deviceProfiles.update(id, cleanupRequest(profileData)) + + return {...profile, presentation: prunePresentationValues(presentation)} + }) + } +} From e81c346fb2df32b82a390cd4f80a6adaca019219 Mon Sep 17 00:00:00 2001 From: Bob Florian Date: Fri, 28 Aug 2020 12:35:04 -0400 Subject: [PATCH 2/2] feat: added device view, incorporated feedback --- .../cli/src/commands/deviceprofiles/create.ts | 67 ++++++++++++------- .../cli/src/commands/deviceprofiles/view.ts | 2 +- .../commands/deviceprofiles/view/create.ts | 64 ++++++++---------- .../commands/deviceprofiles/view/update.ts | 4 -- 4 files changed, 71 insertions(+), 66 deletions(-) diff --git a/packages/cli/src/commands/deviceprofiles/create.ts b/packages/cli/src/commands/deviceprofiles/create.ts index 466d65cc2..8ef4d066e 100644 --- a/packages/cli/src/commands/deviceprofiles/create.ts +++ b/packages/cli/src/commands/deviceprofiles/create.ts @@ -1,17 +1,17 @@ import { DeviceProfile, - DeviceProfileRequest, + DeviceProfileRequest, PresentationDeviceConfig, PresentationDeviceConfigCreate, SmartThingsClient, } from '@smartthings/core-sdk' import { InputOutputAPICommand } from '@smartthings/cli-lib' import { buildTableOutput } from '../deviceprofiles' -import {DeviceDefinitionRequest} from './view' +import { DeviceDefinitionRequest } from './view' import inquirer from 'inquirer' -const capabilityBlacklist = ['healthCheck', 'execute'] +const capabilitiesWithoutPresentations = ['healthCheck', 'execute'] export async function generateDefaultConfig(client: SmartThingsClient, deviceProfileId: string, deviceProfile: DeviceProfileRequest | DeviceDefinitionRequest): Promise { // Generate the default config @@ -42,7 +42,7 @@ export async function generateDefaultConfig(client: SmartThingsClient, devicePro // Filter capabilities with no UI if (deviceConfig.detailView) { - deviceConfig.detailView = deviceConfig.detailView.filter(it => !(capabilityBlacklist.includes(it.capability))) + deviceConfig.detailView = deviceConfig.detailView.filter(it => !(capabilitiesWithoutPresentations.includes(it.capability))) } // Filter automation entries @@ -55,7 +55,7 @@ export async function generateDefaultConfig(client: SmartThingsClient, devicePro })) deviceConfig.automation.conditions = deviceConfig.automation.conditions.filter((_v, index) => { const capability = capabilities[index] - return capability.attributes && Object.keys(capability.attributes).length > 0 && !(capabilityBlacklist.includes(capability.id || '')) + return capability.attributes && Object.keys(capability.attributes).length > 0 && !(capabilitiesWithoutPresentations.includes(capability.id || '')) }) } @@ -66,7 +66,7 @@ export async function generateDefaultConfig(client: SmartThingsClient, devicePro })) deviceConfig.automation.actions = deviceConfig.automation.actions.filter((_v, index) => { const capability = capabilities[index] - return capability.commands && Object.keys(capability.commands).length > 0 && !(capabilityBlacklist.includes(capability.id || '')) + return capability.commands && Object.keys(capability.commands).length > 0 && !(capabilitiesWithoutPresentations.includes(capability.id || '')) }) } } @@ -74,6 +74,39 @@ export async function generateDefaultConfig(client: SmartThingsClient, devicePro return deviceConfig } +export interface DeviceProfileAndConfig { + deviceProfile: DeviceProfile + deviceConfig: PresentationDeviceConfig +} + +export async function createWithDefaultConfig(client: SmartThingsClient, data: DeviceDefinitionRequest): Promise { + + // Create the profile + let deviceProfile = await client.deviceProfiles.create(cleanupRequest(data)) + + // Generate the default config + const deviceConfigData = await generateDefaultConfig(client, deviceProfile.id, deviceProfile) + + // Create the config using the default + const deviceConfig = await client.presentation.create(deviceConfigData) + + // Update the profile to use the vid from the config + const profileId = deviceProfile.id + cleanupRequest(deviceProfile) + delete deviceProfile.name + if (!deviceProfile.metadata) { + deviceProfile.metadata = {} + } + deviceProfile.metadata.vid = deviceConfig.vid + deviceProfile.metadata.mnmn = deviceConfig.mnmn + + // Update the profile with the vid and mnmn + deviceProfile = await client.deviceProfiles.update(profileId, deviceProfile) + + // Return the composite object + return {deviceProfile, deviceConfig} +} + // Cleanup is done so that the result of a device profile get can be modified and // used in an update operation without having to delete the status, owner, and // component name fields, which aren't accepted in the update API call. @@ -115,28 +148,12 @@ export default class DeviceProfileCreateCommand extends InputOutputAPICommand { - const { args, argv, flags } = this.parse(DeviceDefCreateCommand) - await super.setup(args, argv, flags) + private async createWithCustomConfig(data: DeviceDefinitionRequest): Promise { + if (!data.view) { + throw Error('View property not defined') + } - this.processNormally(async (data) => { - let profile - let deviceConfig - if (data.view) { - // Create the config - deviceConfig = await this.client.presentation.create(augmentPresentationValues(data.view)) + // create the device config from the view data + const deviceConfig = await this.client.presentation.create(augmentPresentationValues(data.view)) + + // Set the vid and mnmn from the config + if (!data.metadata) { + data.metadata = {} + } + data.metadata.vid = deviceConfig.vid + data.metadata.mnmn = deviceConfig.mnmn + delete data.view - // Set the vid and mnmn from the config - if (!data.metadata) { - data.metadata = {} - } - data.metadata.vid = deviceConfig.vid - data.metadata.mnmn = deviceConfig.mnmn - delete data.view + // Create the profile + const profile = await this.client.deviceProfiles.create(cleanupRequest(data)) - profile = await this.client.deviceProfiles.create(cleanupRequest(data)) - } else { - // Create the profile - profile = await this.client.deviceProfiles.create(cleanupRequest(data)) + // Return the composite object + return {...profile, view: prunePresentationValues(deviceConfig)} + } - // Generate the default config - const deviceConfigData = await generateDefaultConfig(this.client, profile.id, profile) - // Create the config using the default - deviceConfig = await this.client.presentation.create(deviceConfigData) + async run(): Promise { + const { args, argv, flags } = this.parse(DeviceDefCreateCommand) + await super.setup(args, argv, flags) - // Update the profile to use the vid from the config - const profileId = profile.id - cleanupRequest(profile) - delete profile.name - if (!profile.metadata) { - profile.metadata = {} - } - profile.metadata.vid = deviceConfig.vid - profile.metadata.mnmn = deviceConfig.mnmn - profile = await this.client.deviceProfiles.update(profileId, profile) + this.processNormally(async (data) => { + if (data.view) { + return this.createWithCustomConfig(data) } - return {...profile, presentation: prunePresentationValues(deviceConfig)} + const profileAndConfig = await createWithDefaultConfig(this.client, data) + return {...profileAndConfig.deviceProfile, view: prunePresentationValues(profileAndConfig.deviceConfig)} }) } } diff --git a/packages/cli/src/commands/deviceprofiles/view/update.ts b/packages/cli/src/commands/deviceprofiles/view/update.ts index 6f9d6c6de..a2d25305e 100644 --- a/packages/cli/src/commands/deviceprofiles/view/update.ts +++ b/packages/cli/src/commands/deviceprofiles/view/update.ts @@ -69,16 +69,12 @@ export default class CapabilitiesUpdate extends SelectingInputOutputAPICommand