├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── doc ├── automation.md ├── smcp-intro.md ├── splot-book │ ├── .gitignore │ ├── README.md │ ├── book.toml │ └── src │ │ ├── SUMMARY.md │ │ ├── automation │ │ ├── actionable.md │ │ ├── examples.md │ │ ├── expressions.md │ │ ├── intro.md │ │ ├── pairings.md │ │ ├── primitives.md │ │ ├── recipes.md │ │ ├── rules.md │ │ └── timers.md │ │ ├── design-goals.md │ │ ├── intro.md │ │ ├── smcp │ │ ├── cloud_control.md │ │ ├── examples.md │ │ └── intro.md │ │ ├── som │ │ ├── arch.md │ │ ├── children.md │ │ ├── groups.md │ │ ├── intro.md │ │ ├── methods.md │ │ ├── properties.md │ │ ├── splot-object-model.svg │ │ ├── technologies.md │ │ ├── things.md │ │ ├── trait-profiles.md │ │ └── traits.md │ │ ├── ssm │ │ ├── arch.md │ │ ├── identities.md │ │ ├── intro.md │ │ ├── keychain.md │ │ ├── lost-secret-recovery.md │ │ ├── sessions.md │ │ ├── splot-security-model.svg │ │ ├── spske.md │ │ └── unresolved-issues.md │ │ ├── terminology.md │ │ ├── title-page.md │ │ └── trait-def │ │ ├── auto │ │ ├── actionable.md │ │ ├── intro.md │ │ ├── pairing-manager.md │ │ ├── pairing.md │ │ ├── rule-manager.md │ │ ├── rule.md │ │ ├── timer-manager.md │ │ └── timer.md │ │ ├── core │ │ ├── base.md │ │ ├── group.md │ │ ├── intro.md │ │ ├── scene.md │ │ └── transition.md │ │ ├── sec │ │ ├── access-rule.md │ │ ├── identity.md │ │ ├── intro.md │ │ ├── keychain-item.md │ │ └── keychain.md │ │ └── std │ │ ├── ambient-environment.md │ │ ├── battery.md │ │ ├── button.md │ │ ├── enabled.md │ │ ├── energy.md │ │ ├── intro.md │ │ ├── level.md │ │ ├── light.md │ │ ├── on-off.md │ │ └── presence.md └── splot-object-model-intro.md ├── pom.xml ├── smcp-example-server ├── .gitignore ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── example │ └── smcp │ └── server │ ├── App.java │ ├── MyLightBulb.java │ └── SystemInfo.java ├── smcp ├── .gitignore ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── iot │ │ └── smcp │ │ ├── FuncResource.java │ │ ├── GroupsResource.java │ │ ├── HostedThingAdapter.java │ │ ├── SectionResource.java │ │ ├── Smcp.java │ │ ├── SmcpDiscoveryBuilder.java │ │ ├── SmcpDiscoveryQuery.java │ │ ├── SmcpException.java │ │ ├── SmcpGroup.java │ │ ├── SmcpRemoteException.java │ │ ├── SmcpResourceLink.java │ │ ├── SmcpRuntimeException.java │ │ ├── SmcpTechnology.java │ │ ├── SmcpThing.java │ │ ├── TraitChildrenResource.java │ │ ├── TransactionFuture.java │ │ ├── Utils.java │ │ └── package-info.java │ └── test │ └── java │ └── com │ └── google │ └── iot │ └── smcp │ ├── ExecutorTestBase.java │ ├── FakeExecutorTestBase.java │ ├── FakeScheduledExecutorService.java │ ├── HostedThingAdapterTest.java │ ├── SmcpDiscoveryQueryTest.java │ ├── SmcpGroupTest.java │ ├── SmcpPairingTest.java │ ├── SmcpTestBase.java │ └── SmcpThingTest.java ├── splot-base ├── .gitignore ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── iot │ │ └── m2m │ │ ├── annotation │ │ ├── Method.java │ │ ├── Property.java │ │ ├── Trait.java │ │ └── package-info.java │ │ ├── base │ │ ├── BadStateForPropertyValueException.java │ │ ├── ChildListener.java │ │ ├── CorruptPersistentStateException.java │ │ ├── DiscoveryBuilder.java │ │ ├── DiscoveryQuery.java │ │ ├── Group.java │ │ ├── GroupNotAvailableException.java │ │ ├── GroupsNotSupportedException.java │ │ ├── InvalidMethodArgumentsException.java │ │ ├── InvalidModifierListException.java │ │ ├── InvalidPropertyValueException.java │ │ ├── InvalidSectionException.java │ │ ├── InvalidValueException.java │ │ ├── LocalTrait.java │ │ ├── MethodException.java │ │ ├── MethodKey.java │ │ ├── MethodNotFoundException.java │ │ ├── Modifier.java │ │ ├── Operation.java │ │ ├── ParamKey.java │ │ ├── PersistentStateInterface.java │ │ ├── PersistentStateListener.java │ │ ├── PersistentStateManager.java │ │ ├── PropertyException.java │ │ ├── PropertyKey.java │ │ ├── PropertyListener.java │ │ ├── PropertyNotFoundException.java │ │ ├── PropertyOperationUnsupportedException.java │ │ ├── PropertyReadOnlyException.java │ │ ├── PropertyWriteOnlyException.java │ │ ├── Section.java │ │ ├── SectionListener.java │ │ ├── Splot.java │ │ ├── Technology.java │ │ ├── TechnologyCannotHostException.java │ │ ├── TechnologyException.java │ │ ├── TechnologyRuntimeException.java │ │ ├── Thing.java │ │ ├── TypeConverter.java │ │ ├── TypedKey.java │ │ ├── TypedKeyValue.java │ │ ├── UnacceptableThingException.java │ │ ├── UnassociatedResourceException.java │ │ ├── UnknownResourceException.java │ │ └── package-info.java │ │ └── util │ │ ├── FilePersistentStateManager.java │ │ ├── Identity.java │ │ ├── IdentityException.java │ │ ├── NestedPersistentStateManager.java │ │ └── package-info.java │ └── test │ └── java │ └── com │ └── google │ └── iot │ └── m2m │ ├── base │ ├── ModifierTest.java │ ├── TechnologyTest.java │ └── TypedKeyTest.java │ └── util │ ├── FilePersistentStateManagerTest.java │ ├── IdentityTest.java │ └── NestedPersistentStateManagerTest.java ├── splot-local ├── .gitignore ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ └── google │ │ └── iot │ │ └── m2m │ │ └── local │ │ ├── AbstractResourceLink.java │ │ ├── LazyResourceLink.java │ │ ├── LocalActions.java │ │ ├── LocalAutomationManager.java │ │ ├── LocalGroup.java │ │ ├── LocalPairing.java │ │ ├── LocalPairingManagerTrait.java │ │ ├── LocalRule.java │ │ ├── LocalRuleManagerTrait.java │ │ ├── LocalSceneThing.java │ │ ├── LocalTechnology.java │ │ ├── LocalThing.java │ │ ├── LocalTimer.java │ │ ├── LocalTimerManagerTrait.java │ │ ├── LocalTransitioningThing.java │ │ ├── PropertyResourceLink.java │ │ ├── ResourceLink.java │ │ ├── ResourceLinkManager.java │ │ ├── SectionResourceLink.java │ │ ├── Utils.java │ │ ├── package-info.java │ │ └── rpn │ │ ├── RPNContext.java │ │ ├── RPNException.java │ │ ├── RPNFunction.java │ │ ├── RPNInvalidTypeForOperatorException.java │ │ ├── RPNOperation.java │ │ ├── RPNStack.java │ │ ├── RPNStackOverflowException.java │ │ ├── RPNStackUnderflowException.java │ │ ├── RPNSyntaxErrorException.java │ │ ├── RPNUnknownVariableException.java │ │ └── package-info.java │ └── test │ └── java │ └── com │ └── google │ └── iot │ └── m2m │ └── local │ ├── LocalGroupTest.java │ ├── LocalPairingTest.java │ ├── LocalRuleTest.java │ ├── LocalThingTest.java │ ├── LocalTimerTest.java │ ├── TestBase.java │ └── rpn │ └── RPNContextTest.java ├── splot-processor ├── .gitignore ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── google │ └── iot │ └── m2m │ └── processor │ ├── AbortProcessingException.java │ ├── LocalTraitClassBuilder.java │ ├── NameMangle.java │ ├── TraitProcessor.java │ └── package-info.java └── splot-traits ├── .gitignore ├── pom.xml └── src └── main └── java └── com └── google └── iot └── m2m └── trait ├── ActionsTrait.java ├── AmbientEnvironmentTrait.java ├── AutomationPairingManagerTrait.java ├── AutomationPairingTrait.java ├── AutomationRuleManagerTrait.java ├── AutomationRuleTrait.java ├── AutomationTimerManagerTrait.java ├── AutomationTimerTrait.java ├── BaseTrait.java ├── BatteryTrait.java ├── EnabledDisabledTrait.java ├── EnergyTrait.java ├── GroupTrait.java ├── KeychainItemTrait.java ├── KeychainTrait.java ├── LevelTrait.java ├── LightTrait.java ├── OnOffTrait.java ├── PresenceTrait.java ├── SceneTrait.java ├── SystemTrait.java ├── TextDisplayTrait.java ├── TransitionTrait.java └── package-info.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | *.swp 3 | .gradle 4 | /local.properties 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/caches 9 | /.idea 10 | .DS_Store 11 | /build 12 | /captures 13 | /target 14 | .externalNativeBuild 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | 3 | jdk: 4 | - oraclejdk8 5 | 6 | install: mvn install -DskipTests=true 7 | script: mvn test 8 | 9 | branches: 10 | except: 11 | - gh-pages 12 | 13 | notifications: 14 | email: false 15 | 16 | sudo: false 17 | 18 | cache: 19 | directories: 20 | - $HOME/.m2 21 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ========== 3 | 4 | ## Version 0.02.00 5 | _2019-04-09_ 6 | * ABI/API breaking changes across codebase 7 | * General refactoring and documentation improvements across codebase 8 | * Implemented automation primitives: pairings, timers, and rules 9 | * splot-traits: Updated and new traits: 10 | * AutomationPairingTrait 11 | * AutomationRuleTrait 12 | * AutomationTimerTrait 13 | * ActionsTrait 14 | * splot-local: Implemented individual automation primitives: 15 | * LocalPairing 16 | * LocalRule 17 | * LocalTimer 18 | * splot-local: Added LocalAutomationManager to facilitate in-band management 19 | * splot-local: Implemented [Splot Automation Expressions](doc/automation.md) 20 | * splot-base: Moved implicit type conversion code to its own class: TypeConverter 21 | * splot-base: Move various string constants to the 'Splot' pseudo class 22 | * splot-base: New PropertyException: BadStateForPropertyValueException 23 | * splot-base: FilePersistentStateManager updates: 24 | * Minor refactoring and warning fixes 25 | * When debugging, log a dump of CBOR data 26 | * If backing is corrupt move it instead of deleting it 27 | * splot-base: FunctionalEndpoint: Introduced Modifiers 28 | * splot-base: FunctionalEndpoint: Method arguments can now be specified using TypedKeyValue 29 | * splot-base: FunctionalEndpoint: Changed argument order of child listener registration 30 | * splot-base: Sections are now identified using an enumeration 31 | * splot-local: Introduced ResourceLinks and ResourceLinkManager 32 | * splot-local: LocalFunctionalEndpoint: Ensure listeners get initial call immediately 33 | * splot-local: LocalTransitioningFunctionalEndpoint: Improved update frequency clamp 34 | * splot-local: LocalTransitioningFunctionalEndpoint: Improved on/off/level handling 35 | * smcp: SmcpTechnology: Ensure the group resource is added to .well-known/core 36 | * smcp: SectionResource: Whitespace and error message improvements. 37 | * smcp: Improved reliability of CoAP UDP tests. 38 | * pom.xml: Now using CoapBlaster v0.02.01 39 | * pom.xml: Now using CborTree v0.01.01 40 | * pom.xml: Fixed building with Java 10 41 | 42 | ## Version 0.01.00 43 | _2018-11-16_ 44 | * Initial Release 45 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributor License Agreement 2 | ----------------------------- 3 | 4 | Contributions to any Google project must be accompanied by a Contributor 5 | License Agreement. This is not a copyright _assignment_; it simply gives 6 | Google permission to use and redistribute your contributions as part of the 7 | project. 8 | 9 | - If you are an individual writing original source code and you're sure you 10 | own the intellectual property, then you'll need to sign an [individual 11 | CLA][]. Please include your GitHub username. 12 | - If you work for a company that wants to allow you to contribute your work, 13 | then you'll need to sign a [corporate CLA][]. 14 | 15 | You generally only need to submit a CLA once, so if you've already submitted 16 | one (even if it was for a different project), you probably don't need to do it 17 | again. 18 | 19 | [individual CLA]: https://cla.developers.google.com/about/google-individual 20 | [corporate CLA]: https://developers.google.com/open-source/cla/corporate 21 | -------------------------------------------------------------------------------- /doc/automation.md: -------------------------------------------------------------------------------- 1 | # Splot Automation # 2 | 3 | This document has moved to the [Automation Section](https://google.github.io/splot-java/splot-book/automation/intro.html) 4 | of the [Splot Design Documentation](https://google.github.io/splot-java/splot-book/). 5 | 6 | -------------------------------------------------------------------------------- /doc/smcp-intro.md: -------------------------------------------------------------------------------- 1 | Splot Monitoring and Control Protocol (SMCP) 2 | ============================================ 3 | 4 | SMCP is an experimental RESTful machine-to-machine/thing-to-thing 5 | protocol designed for monitoring and controlling networked devices, as 6 | well as automating direct machine-to-machine interactions. SMCP can be 7 | used via either CoAP or HTTP. 8 | 9 | This document has moved to the [SMCP Section](https://google.github.io/splot-java/splot-book/smcp/intro.html) 10 | of the [Splot Design Documentation](https://google.github.io/splot-java/splot-book/). 11 | 12 | -------------------------------------------------------------------------------- /doc/splot-book/.gitignore: -------------------------------------------------------------------------------- 1 | book 2 | -------------------------------------------------------------------------------- /doc/splot-book/README.md: -------------------------------------------------------------------------------- 1 | Splot Design Documentation Source 2 | ================================= 3 | 4 | This folder contains the sources for the Splot Design Documentation. 5 | 6 | You can read the documentation directly from the sources or 7 | you can read the rendered documentation [here](https://google.github.io/splot-java/splot-book/). 8 | 9 | ## Requirements 10 | 11 | Building the documentation requires [mdBook](https://github.com/rust-lang-nursery/mdBook). 12 | To get it: 13 | 14 | $ cargo install mdbook 15 | 16 | ## Building 17 | 18 | To build the documentation, type: 19 | 20 | $ mdbook build 21 | 22 | The output will be in the `book` directory. To check it out, open 23 | [`book/index.html`](book/index.html) in your web browser. 24 | -------------------------------------------------------------------------------- /doc/splot-book/book.toml: -------------------------------------------------------------------------------- 1 | [book] 2 | authors = ["Robert Quattlebaum"] 3 | language = "en" 4 | multilingual = false 5 | src = "src" 6 | title = "[DRAFT] Splot Design Documentation" 7 | -------------------------------------------------------------------------------- /doc/splot-book/src/SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Splot Design Documentation 2 | 3 | [Splot Design Documentation](./title-page.md) 4 | 5 | - [Introduction](./intro.md) 6 | - [Design Goals](./design-goals.md) 7 | - [Terminology](./terminology.md) 8 | 9 | - [Splot Object Model](./som/intro.md) 10 | - [Architecture](./som/arch.md) 11 | - [Things](./som/things.md) 12 | - [Properties](./som/properties.md) 13 | - [Methods](./som/methods.md) 14 | - [Traits](./som/traits.md) 15 | - [Children](./som/children.md) 16 | - [Trait Profiles](./som/trait-profiles.md) 17 | - [Groups](./som/groups.md) 18 | - [Technologies](./som/technologies.md) 19 | 20 | - [Automation](./automation/intro.md) 21 | - [Primitives](./automation/primitives.md) 22 | - [Pairings](./automation/pairings.md) 23 | - [Rules](./automation/rules.md) 24 | - [Timers](./automation/timers.md) 25 | - [Actionable Primitives](./automation/actionable.md) 26 | - [Automation Expressions](./automation/expressions.md) 27 | - [Automation Recipes](./automation/recipes.md) 28 | - [Pulling it All Together](./automation/examples.md) 29 | 30 | - [Splot Security Model](./ssm/intro.md) 31 | - [Architecture](./ssm/arch.md) 32 | - [Security Sessions](./ssm/sessions.md) 33 | - [Identities](./ssm/identities.md) 34 | - [Keychain](./ssm/keychain.md) 35 | - [Lost Secret Recovery](./ssm/lost-secret-recovery.md) 36 | - [Single-Purpose Shared Key Establishment](./ssm/spske.md) 37 | - [Unresolved Issues](./ssm/unresolved-issues.md) 38 | 39 | - [Splot Monitoring and Control Protocol](./smcp/intro.md) 40 | - [Introductory Example](./smcp/examples.md) 41 | - [Remote Monitoring and Control](./smcp/cloud_control.md) 42 | 43 | # Trait Documentation 44 | 45 | - [Core Traits](./trait-def/core/intro.md) 46 | - [Base](./trait-def/core/base.md) 47 | - [Group](./trait-def/core/group.md) 48 | - [Scene](./trait-def/core/scene.md) 49 | - [Transition](./trait-def/core/transition.md) 50 | 51 | - [Standard Traits](./trait-def/std/intro.md) 52 | - [OnOff](./trait-def/std/on-off.md) 53 | - [Level](./trait-def/std/level.md) 54 | - [Light](./trait-def/std/light.md) 55 | - [Enabled](./trait-def/std/enabled.md) 56 | - [Energy](./trait-def/std/energy.md) 57 | - [Battery](./trait-def/std/battery.md) 58 | - [AmbientEnvironment](./trait-def/std/ambient-environment.md) 59 | - [Button](./trait-def/std/button.md) 60 | - [Presence](./trait-def/std/presence.md) 61 | 62 | - [Automation Traits](./trait-def/auto/intro.md) 63 | - [Pairing](./trait-def/auto/pairing.md) 64 | - [PairingManager](./trait-def/auto/pairing-manager.md) 65 | - [Actionable](./trait-def/auto/actionable.md) 66 | - [Rule](./trait-def/auto/rule.md) 67 | - [RuleManager](./trait-def/auto/rule-manager.md) 68 | - [Timer](./trait-def/auto/timer.md) 69 | - [TimerManager](./trait-def/auto/timer-manager.md) 70 | 71 | - [Security Traits](./trait-def/sec/intro.md) 72 | - [Keychain](./trait-def/sec/keychain.md) 73 | - [KeychainItem](./trait-def/sec/keychain-item.md) 74 | - [Identity](./trait-def/sec/identity.md) 75 | - [AccessRule](./trait-def/sec/access-rule.md) 76 | -------------------------------------------------------------------------------- /doc/splot-book/src/automation/actionable.md: -------------------------------------------------------------------------------- 1 | ## Actionable Primitives 2 | 3 | Rules and Timers are both actionable automation primitives, meaning 4 | that they when either are "triggered" they invoke actions. The 5 | machinery and interface that performs these actions is identical 6 | between the two. When an actionable automation primitive is triggered, 7 | it performs zero or more "actions". You can think of an action as 8 | similar to a [webhook](https://en.wikipedia.org/wiki/Webhook). 9 | 10 | An action is specified by the following important parameters: 11 | 12 | * A URI. Required. 13 | * A REST method (PUT, POST, DELETE, etc) to perform on that URI. 14 | Optional: defaults to POST. 15 | * A body to pass along while performing the method. Optional: 16 | defaults to empty. 17 | * An enumeration value that determines if the action should be 18 | evaluated synchronously or asynchronously, as well as what to do 19 | in the event of an error. Optional: defaults to asynchronous 20 | firing (later actions don't wait for this action to finish before 21 | firing). 22 | * Security context information. Optional: defaults to no security 23 | context. 24 | -------------------------------------------------------------------------------- /doc/splot-book/src/automation/intro.md: -------------------------------------------------------------------------------- 1 | # Automation # 2 | 3 | One of the key design goals for Splot was to support the use of 4 | in-band-configurable automation primitives, enabling complex 5 | device-to-device relationships that have no external dependencies once 6 | configured. 7 | 8 | Automation primitives can act like virtual wires, making 9 | properties on different devices dependent on each other, or they can 10 | act as scheduled timers that trigger actions at programmable times of 11 | the week. 12 | 13 | Additionally, since these automation primitives are defined 14 | in terms of simple JSON/[CBOR][] values and REST-ful actions on URLs, they 15 | can even be used to automate devices which have a RESTful interface 16 | but don’t use the Splot Object Model. 17 | 18 | [CBOR]: https://tools.ietf.org/html/rfc7049 19 | -------------------------------------------------------------------------------- /doc/splot-book/src/automation/pairings.md: -------------------------------------------------------------------------------- 1 | ## Pairings 2 | 3 | Pairings are automation primitives that connect two [resources][], which 4 | are referred to as the *source* and *destination*. Changes observed to 5 | the source resource can be automatically applied to the destination 6 | resource, and vise-versa. 7 | 8 | [resources]: https://tools.ietf.org/html/rfc2616#section-5.2 9 | 10 | In *forward propagation*, changes observed to the source are applied 11 | to the destination. 12 | In *reverse propagation*, changes observed to the destination are applied 13 | to the source. Both propagation modes can be enabled simultaneously, 14 | allowing for resource value synchronization. 15 | 16 | In addition to basic value mirroring, two custom transforms can be 17 | specified: a *forward transform* that is applied to changes from the 18 | source to the destination, and a *reverse transform* that is applied 19 | to changes from the destination to the source. These transforms 20 | are written using the expression language outlined in (#sae). 21 | 22 | All pairings implement the *AutomationPairing* trait, described 23 | in (#trait-automation-pairing). 24 | -------------------------------------------------------------------------------- /doc/splot-book/src/automation/primitives.md: -------------------------------------------------------------------------------- 1 | ## Primitives 2 | 3 | Splot Automation Primitives are themselves Things, meaning they can be 4 | created and then configured in-band just like any other Thing. 5 | 6 | Splot currently defines three types of “standard” automation 7 | primitives: 8 | 9 | * Pairings 10 | * Rules 11 | * Timers 12 | 13 | Ultimately, the automation primitives described here are experimental. 14 | There is always room for improvement and changes in behavior should be 15 | expected until the protocol stabilizes. 16 | -------------------------------------------------------------------------------- /doc/splot-book/src/automation/rules.md: -------------------------------------------------------------------------------- 1 | ### Rules 2 | 3 | Rules are actionable automation primitives that consist of one or more 4 | *conditions*. Each condition can evaluate to "true" or "false". A rule 5 | can be configured to trigger when ALL conditions match or when ANY 6 | condition matches. 7 | 8 | A condition monitors a specific URI value and defines how that value 9 | should be interpreted in the form of a Splot Automation Expression, as 10 | described above. Similar to pairings, the previous value is pushed 11 | onto the stack before the current value: allowing for edge triggers. 12 | -------------------------------------------------------------------------------- /doc/splot-book/src/automation/timers.md: -------------------------------------------------------------------------------- 1 | ## Timers 2 | 3 | Timers are actionable automation primitives that allow you to 4 | implement the following types of time-based actions: 5 | 6 | * One-off timers 7 | * Repeating timers 8 | * Scheduled timers 9 | 10 | The behavior of a timer is ultimately defined by two Splot Automation 11 | Expressions: 12 | 13 | * Schedule 14 | * Predicate 15 | 16 | Evaluating the schedule expression yields the number of seconds to 17 | wait until the predicate expression should be evaluated. If the 18 | predicate expression evaluates to *true* then the action(s) are 19 | triggered. Otherwise, the schedule expression is re-evaluated and the 20 | timer resets. 21 | 22 | While this is more than enough for one-off timers and repeating 23 | timers, it does not itself allow you to schedule events. To enable 24 | that, Splot Automation Expressions supports several operations for 25 | probing a real-time-clock: 26 | 27 | * `c`: The number of times this timer has fired since it was last 28 | reset. 29 | * `rtc.y`: Pushes Gregorian year. 30 | * `rtc.dow`: Pushes Day of week. 0-6. Monday is 0, Sunday is 6. 31 | * `rtc.dom`: Pushes Day of month. Zero-based Integer, 0-30. 32 | * `rtc.tod`: Pushes Time of day, in fractional hours. 0.000 - 33 | 23\.999. 34 | * `rtc.moy`: Pushes Current month. zero-based Integer, 0 = January, 35 | 11 = December 36 | * `rtc.awm`: Aligned week of month. Pushes Number of times this 37 | weekday has happened this month. zero-based Integer. 38 | * `rtc.wom`: Pushes Week of month. zero-based Integer. 39 | * `rtc.woy`: Pushes Week of year. zero-based Integer, 0-51. Week 40 | starts on monday. 41 | * `H>S`: Convert hours to seconds. 42 | * `D>S`: Convert days to seconds. 43 | 44 | The combination of a schedule expression and a predicate expression 45 | allow for the evaluation of very complex schedules (like easter) even 46 | on constrained devices. The schedule expression is used to determine 47 | *when* to check the predicate, whereas the predicate is used to 48 | determine if it is indeed the right time. 49 | 50 | For example, to schedule an event to happen at 1:30pm every second 51 | Wednesday of the month, you could use the following expressions: 52 | 53 | * schedule: `"13.5 rtc.tod - 24 % H>S"` (Seconds until the next 54 | 1:30pm) 55 | * predicate: `"2 rtc.dow == 1 rtc.awm == &&"` (Is it the second 56 | Wednesday of this month?) 57 | 58 | This will cause the predicate to be evaluated every day at 1:30pm. 59 | When the predicate finally evaluates to true on the second Wednesday 60 | of the month, the actions are triggered. 61 | -------------------------------------------------------------------------------- /doc/splot-book/src/design-goals.md: -------------------------------------------------------------------------------- 1 | # Design Goals 2 | 3 | An ideal IoT application technology would satisfy the following goals: 4 | 5 | * Flexible enough to be considered relatively “future-proof” 6 | * Automatable without requiring extra hardware or internet access 7 | * Defined as an open standard with at least one open-source 8 | reference implementation 9 | * Simple enough that can be implemented on highly-constrained devices 10 | * Secure, honoring the principle of least privilege. 11 | * Suitable for residential, commercial, and industrial environments 12 | * Include proper support for groups, scenes, and smooth transitions (where 13 | appropriate) 14 | 15 | Splot is an exploratory attempt to bridge these requirements into a single 16 | cohesive technology and application protocol with the following goals: 17 | 18 | * Secure, low-latency monitoring and control of (potentially 19 | constrained) networked devices 20 | * Elegant support for scenes, groups/rooms, and smooth transitions 21 | * Expressive and reliable device-to-device automation 22 | 23 | In addition satisfying these goals, the [SOM][] was designed, to the extent 24 | practical, to express a superset of functionality commonly provided 25 | by other existing IoT protocols, making it reasonably efficient to 26 | monitor and control non-SOM-based using a SOM-based API. This 27 | feature allows for the straightforward implementation of adaptation 28 | layers and enables cross-protocol automation. 29 | 30 | [SOM]: ./som/intro.md 31 | 32 | 44 | -------------------------------------------------------------------------------- /doc/splot-book/src/intro.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | An ongoing problem in the IoT industry is early unexpected 4 | obsolescence: there are many documented cases where shortly after a 5 | product’s release the manufacturer either got acquired, went out of 6 | business, or simply decided to no longer maintain the infrastructure 7 | required to support a product: resulting in all of the devices being 8 | rendered effectively useless. In some cases this results in 9 | significant financial burden if the company wants to maintain goodwill 10 | in the brand by buying-back the useless devices. In all cases it 11 | represents an additional electronic-waste disposal burden. 12 | 13 | Even when the device is fully functional on a well-supported 14 | ecosystem, end-users may want to use their devices in ways that the 15 | manufacturer did not anticipate. For example, ZigBee Light-Link 16 | remote-controls are only capable of controlling things that describe 17 | themselves as ZigBee Light-Link lights—in general, you cannot 18 | repurpose such a controller to instead adjust your television volume, 19 | for example. 20 | 21 | In much the same way that a manufacturer of power switches does not 22 | specify what kind of device it can power on or off, *Splot* represents 23 | an exploratory effort to improve the long-term value of IoT devices by 24 | allowing them to be used in ways not limited by the imagination of 25 | the device manufacturer or software developer. Stated more succinctly: 26 | 27 | > IoT device software should not need to know anything specific about 28 | > other IoT devices in order to be configured to usefully interact. 29 | 30 | This document elaborates on the implications of this precept as 31 | "Splot", along with all of the related pieces to turn it into a workable 32 | collection of standards. 33 | 34 | "Splot" is a Polish noun meaning "weave" or "tangle". 35 | -------------------------------------------------------------------------------- /doc/splot-book/src/smcp/cloud_control.md: -------------------------------------------------------------------------------- 1 | # Remote Monitoring and Control 2 | 3 | While not a part of the the original design consideration, 4 | the fact that SMCP is built on top of CoAP provides a straightforward path to 5 | enabling secure, low-latency remote monitoring and control. 6 | 7 | There are a few different possible approaches, of which I will sketch out two: 8 | 9 | 1. Local Reverse CoAP Proxy 10 | 2. Direct DTLS tunnel from the device to the cloud service 11 | 12 | In both cases, the connection from the remote phone to whatever server is being used 13 | would be secured with DTLS, but in the more secure version OSCORE would additionally 14 | be used inside of that tunnel to secure the messaging with end devices. This ensures 15 | that the access control rules remain in-force. 16 | 17 | ## Local Reverse CoAP Proxy 18 | 19 | In this case, devices would register themselves with a special reverse CoAP proxy on the local network. 20 | These devices would not themselves need internet access, but the reverse CoAP proxy would have internet 21 | access. 22 | 23 | Once registered, the reverse proxy can forward remote requests it receives to devices on the local network. 24 | The remote requests themselves can reach the proxy in one of two ways: 25 | 26 | 1. The local reverse proxy registers itself with a cloud service, which is either another reverse proxy or 27 | some proprietary protocol. 28 | 2. The local reverse proxy uses [Dynamic DNS][] and [NAT-PMP][]/[UPnP][] to become its own cloud server. 29 | 30 | [UPnP]: https://en.wikipedia.org/wiki/Universal_Plug_and_Play 31 | [NAT-PMP]: https://tools.ietf.org/html/rfc6886 32 | [Dynamic DNS]: https://en.wikipedia.org/wiki/Dynamic_DNS 33 | 34 | ### Pros and Cons 35 | 36 | * Pros: 37 | * Controlled devices (except, of course, the reverse proxy) can be firewalled off from direct 38 | internet access, reducing attack surface area. 39 | * Remote control of groups is straightforward. 40 | * Can use [Dynamic DNS][] and [NAT-PMP][]/[UPnP][] to avoid use of cloud proxy server. 41 | * Relatively off-the-shelf use of CoAP proxy servers. 42 | * Cons: 43 | * Requires some additional hardware on the local network. 44 | 45 | ## Direct DTLS Tunnel 46 | 47 | In this case, the device would be configured to register itself with a special 48 | cloud-based CoAP caching proxy server. This registration would happen using DTLS 49 | to secure the connection. Once the registration is complete, that DTLS tunnel is 50 | used to send requests back to the device. 51 | 52 | ### Pros and Cons 53 | 54 | * Pros: 55 | * Very low-latency 56 | * No additional hardware required 57 | * Cons: 58 | * Requires each device to send keep-alive packets to ensure firewall doesn't 59 | close the UDP port. (Not a problem for sleepy devices) 60 | * Requires each device to have at least some limited amount of internet access. 61 | Should be heavily firewalled to limit attack surface area. 62 | * Proper support for groups requires devices to keep cloud proxy informed about 63 | group membership, adding some mild complexity. 64 | * Group control operations may "Popcorn". 65 | -------------------------------------------------------------------------------- /doc/splot-book/src/smcp/intro.md: -------------------------------------------------------------------------------- 1 | # Splot Monitoring and Control Protocol 2 | 3 | The Splot Monitoring and Control Protocol (SMCP) is an experimental 4 | RESTful machine-to-machine/thing-to-thing 5 | protocol designed for monitoring and controlling networked devices, as 6 | well as automating direct machine-to-machine interactions. SMCP can be 7 | used via either CoAP or HTTP, although CoAP is recommended. 8 | 9 | SMCP was designed simultaneously with the [Splot Object Model 10 | (SOM)][SOM]. Thus, it shares much of the same 11 | nomenclature: Things, Traits, Properties, and Methods 12 | are all fundamental concepts in SMCP. However, whereas the Splot 13 | Object Model defines the process and interfaces for how you can 14 | discover, manipulate, and automate things, SMCP defines what that can 15 | actually look like on the wire. 16 | 17 | SMCP is still in the experimental and developmental stages, but SMCP 18 | is ultimately intended to be used for monitoring and controlling a large 19 | variety of device types: 20 | 21 | * Consumer IoT equipment: Temperature sensors, smart light 22 | bulbs, smart buttons, and network cameras. 23 | * Networking equipment: Smart switches, routers, and 24 | workstations. 25 | * Industrial equipment: Vehicle traffic signals, street lights, power 26 | distribution management. 27 | 28 | [SOM]: ../som/intro.md 29 | -------------------------------------------------------------------------------- /doc/splot-book/src/som/arch.md: -------------------------------------------------------------------------------- 1 | ## Architecture ## 2 | 3 | ![Splot Object Model UML Diagram](splot-object-model.svg) 4 | 5 | Breaking this down: 6 | 7 | * A *physical device* can host one or more *things*. 8 | * A *thing* can have multiple *properties* and *methods*, each 9 | defined by a *trait*. 10 | * A *thing* can host other *things* that it owns (children). 11 | * While not illustrated in the previous diagram, each child is 12 | associated with a single trait on its parent, in much the same way 13 | that properties and methods are. 14 | -------------------------------------------------------------------------------- /doc/splot-book/src/som/children.md: -------------------------------------------------------------------------------- 1 | ## Children # 2 | 3 | A trait's definition can indicate if it has child things, 4 | and, if so, how those things behave and what 5 | traits the children themselves implement. 6 | 7 | For example, the scene trait allows a thing to save the 8 | values of the properties in its state section and associating them 9 | with a scene-id. The scene itself is represented as a child thing 10 | that can be manipulated independently. 11 | 12 | Each child thing can be identified by a combination of 13 | the trait identifier and a child-id. 14 | 15 | For example, if I used `f/scen?save` to create a scene with a scene-id 16 | (child-id) of `evening`, the resulting child would be identified by 17 | the tuple (`scen`, `evening`). 18 | 19 | The exact mechanism for how you reference children is implementation 20 | specific, but in [SMCP][] for example, it would be referenced as 21 | `f/scen/evening/`, relative to the parent. 22 | 23 | The nesting of child things is allowed. 24 | 25 | [SMCP]: ./smcp/intro.md 26 | -------------------------------------------------------------------------------- /doc/splot-book/src/som/groups.md: -------------------------------------------------------------------------------- 1 | ## Groups ## 2 | 3 | A group is a collection of things (members) which can be 4 | controlled as a single thing. 5 | 6 | Groups are always owned by a [technology](technology.md). 7 | Members of a group must be associated with that group's 8 | technology. 9 | 10 | The state section of a group is special in that 11 | any operation performed on it will be 12 | applied to the state section of all of the group's members. 13 | 14 | By comparison, the configuration and metadata sections belong to the 15 | group itself. Thus, it is not possible to change a configuration or 16 | metadata property across the members of a group in a single operation 17 | like you can with state properties. 18 | 19 | The behavior of reading state properties on a group is currently 20 | undefined by the SOM and thus the behavior is technology-specific. 21 | This may change at some point. 22 | -------------------------------------------------------------------------------- /doc/splot-book/src/som/intro.md: -------------------------------------------------------------------------------- 1 | # Splot Object Model 2 | 3 | The Splot Object Model is a collection of interfaces for monitoring 4 | and controlling things. It defines the general mechanisms and nomenclature 5 | for how network-connected things can be described, configured, monitored, 6 | and automated. 7 | 8 | Keep in mind that while the SOM informs the design of Splot-based APIs 9 | and protocols, it is only an object model: It defines vocabulary, 10 | concepts, and object relationships. It is not an IoT application 11 | protocol; it is a framework for describing and interacting with IoT 12 | devices in a uniform way. 13 | 14 | The SOM-native application protocol, [SMCP](../smcp/intro.md), is defined in a 15 | separate chapter, but other IoT application protocols can be adapted 16 | to be monitored, controlled, and automated in terms of the SOM. 17 | -------------------------------------------------------------------------------- /doc/splot-book/src/som/methods.md: -------------------------------------------------------------------------------- 1 | ## Methods 2 | 3 | Methods are a way to manipulate a thing in ways that would not 4 | translate well to being represented with properties. The most common 5 | example is for creating new child things, but the mechanism is defined 6 | to be open-ended. 7 | 8 | Methods take a named set of arguments as input and are defined to 9 | output a single value or indicate an error. Arguments are identified 10 | by a short string rather than by their order. Arguments and return 11 | values share the same set of value types that are used by properties, 12 | with the addition that an method may return a direct reference to a 13 | child thing. (This is used to return created or updated child things). 14 | 15 | Methods are defined by traits just like properties are. The trait 16 | defines what the named arguments are, what their types should be, 17 | which arguments are required, and what the method return type will be. 18 | 19 | Just like properties, methods are scoped by trait. They have a special 20 | section designated "`f`"(This scope gets double-duty in SMCP with also 21 | handling child things, but I digress). The short-identifiers of the 22 | scope, trait, and method are combined similarly to properties, except 23 | that the second slash is instead a question mark: 24 | 25 | * `f/scen?save`: Save current state to a new or existing scene 26 | * `f/gmgr?create`: Create a new group 27 | 28 | -------------------------------------------------------------------------------- /doc/splot-book/src/som/things.md: -------------------------------------------------------------------------------- 1 | ### Things 2 | 3 | Things are the fundamental control surface objects in the SOM. 4 | Physical devices host one or more Things. 5 | 6 | Things provide: 7 | 8 | * *Properties* that can be monitored, changed, or mutated 9 | * *Methods* that take named arguments and return values 10 | * Child things (*children*) which it owns and manages 11 | 12 | Some hypothetical examples of Things and their relationship to 13 | physical devices: 14 | 15 | * A smart light bulb that hosts a single Thing that is used to 16 | control and monitor the state of the light bulb. 17 | * A smart power strip that hosts one Thing per outlet, used to 18 | control the state of each outlet and monitor power usage. 19 | * A proprietary wireless sensor gateway hosting one (or more) Things 20 | for each associated wireless sensor, used to monitor temperature 21 | and humidity. 22 | * A device could have any number of automation primitives, with each 23 | one being a thing. 24 | -------------------------------------------------------------------------------- /doc/splot-book/src/som/trait-profiles.md: -------------------------------------------------------------------------------- 1 | ## Trait Profiles 2 | 3 | A trait profile is a named, versioned set of required-to-implement 4 | traits and an associated list of required-to-implement properties and 5 | methods from those traits. When a thing indicates that it supports a 6 | given trait profile, it is promising that it fully supports all of the 7 | properties and methods that the trait profile requires. 8 | 9 | Trait profiles provide a way for software to quickly classify the 10 | functionality of a thing and ensure that certain types of things have 11 | the appropriate minimal level of common functionality to ensure they 12 | meet user expectations. 13 | 14 | For example, a trait profile for a "Dimmable Lamp" might require the 15 | [`Base`][], [`OnOff`][], [`Level`][], [`Energy`][], and [`Light`][] traits, additionally 16 | requiring some additional subset of the optional properties from those 17 | traits to be implemented. The trait profile for a "Full-Color Lamp" 18 | would require the exact same traits but also include an expanded list 19 | of required-to-implement properties from those traits. A thing can 20 | implement more than one trait profile, and some trait profiles require 21 | that other specific trait profiles also be supported. 22 | 23 | [`Base`]: ../trait-def/core/base.md 24 | [`OnOff`]: ../trait-def/std/on-off.md 25 | [`Level`]: ../trait-def/std/level.md 26 | [`Energy`]: ../trait-def/std/energy.md 27 | [`Light`]: ../trait-def/std/light.md 28 | -------------------------------------------------------------------------------- /doc/splot-book/src/som/traits.md: -------------------------------------------------------------------------------- 1 | ## Traits 2 | 3 | Specific properties and methods are defined by *Traits*. A 4 | *Thing* can implement properties and methods from several 5 | traits. [Children](children.md) are also scoped to specific traits. 6 | 7 | A Trait is a set of properties and methods that are related to a 8 | purpose. For example, the [OnOff][] trait provides the concept of being 9 | on or off, whereas the [Level][] trait provides the concept of a dimmer 10 | switch or volume knob. These traits expose distinct behaviors that 11 | are independent from the [Light][] trait which 12 | provides additional properties for correlated color temperature and 13 | sRGB values, but none that are suitable substitutes for the properties 14 | provided by *OnOff* and *Level*: the Light trait is designed to be used 15 | alongside these traits. 16 | 17 | [OnOff]: ../trait-def/std/on-off.md 18 | [Level]: ../trait-def/std/level.md 19 | [Light]: ../trait-def/std/light.md 20 | 21 | Some traits, like the [Scene][] trait, define children. In the case 22 | of the Scene trait, each child *thing* represents a scene that can be 23 | recalled, modified, or deleted. A "save" method is also provided by 24 | the trait to allow the current state to be saved to a new or existing 25 | scene. 26 | 27 | [Scene]: ../trait-def/core/scene.md 28 | 29 | Traits are scoped to be as general as practical so that they can be 30 | applied to many different sorts of *things*. For example, 31 | the [Level][] trait could be applied to a light bulb to control dimming, 32 | or applied to a ceiling fan to control speed, or to a window 33 | controller to control how far open the window is. 34 | 35 | Each trait is defined to have both a human-readable name ([OnOff][], 36 | [Level][], [Keychain][]), a short trait-id ("`onof`", "`levl`", 37 | "`keyc`"), and a unique URI identifier. 38 | 39 | [Keychain]: ../trait-def/sec/keychain.md 40 | 41 | ## Trait Definitions 42 | 43 | Traits definitions are specified in a JSON format. This trait 44 | definition can then be translated into either markdown documentation, 45 | Rust, or Java using the `som-trait-conv` tool. 46 | 47 | Splot provides the following collections of trait definitions: 48 | 49 | * [*Core Traits*](../trait-def/core/intro.md) (`core`): Traits which are fundamental to the Splot Object Model. 50 | * [*Standard Traits*](../trait-def/std/intro.md) (`std`): Traits which represent behaviors which are common 51 | enough to be standardized. 52 | * [*Automation Traits*](../trait-def/auto/intro.md) (`auto`): Traits related to automation. 53 | * [*Security Traits*](../trait-def/sec/intro.md) (`sec`): Traits related to the Splot Security Model. 54 | -------------------------------------------------------------------------------- /doc/splot-book/src/ssm/arch.md: -------------------------------------------------------------------------------- 1 | # Architecture # 2 | 3 | ![Splot Security Model UML Diagram](splot-security-model.svg) 4 | 5 | The key takeaways from the diagram above are: 6 | 7 | * Each *device* has... 8 | * ...a *[Keychain][]*, which manages *Keychain Items*. 9 | * ... a set of *[Identities][]*, which have *Access Rules*. 10 | * A *Keychain Item* can be either a *shared secret*, *password*, or 11 | *certificate*. 12 | * The *Keychain*, *Keychain Items*, *Identities*, and *Access Rules* 13 | are all *[Things][]*, and can be managed in-band. 14 | * *Keychain Items* can optionally reference a single *Identity*. 15 | 16 | ## Layer Security Protocols ## 17 | 18 | While technically an implementation detail, the Splot Security Model 19 | was written with two security layer protocols in mind: 20 | [DTLS][] and [OSCORE][]. 21 | 22 | [Things]: ../som/things.md 23 | [Identities]: identities.md 24 | [Keychain]: keychain.md 25 | [DTLS]: https://tools.ietf.org/html/rfc6347 26 | [OSCORE]: https://tools.ietf.org/html/rfc8613 27 | 28 | [DTLS][] is intended to be used for security sessions authenticated with 29 | certificates or low-entropy passwords (supporting monitoring/control 30 | and initial commissioning). [OSCORE][] is intended to be used to secure 31 | device-to-device interactions with high-entropy shared secrets. [OSCORE][] 32 | is supported specifically to enable secure multicast device-to-device 33 | interactions. 34 | -------------------------------------------------------------------------------- /doc/splot-book/src/ssm/identities.md: -------------------------------------------------------------------------------- 1 | ## Identities ## 2 | 3 | An *identity* is a named set of mandatory access control rules on 4 | a given *server*. The scope of an identity is limited to that 5 | server. Identities can be managed in-band as *Things*. 6 | 7 | When establishing a session, a client uses the *keychain item 8 | identifier* to establish the session, *not the *identity* 9 | (which is purely a server-side concept). An identity can be 10 | associated with multiple *keychain items*, whereas a keychain 11 | item identifier identifies a single keychain item on a device. 12 | 13 | ### Standard Identities ### 14 | 15 | The security model has five pre-defined identities with standardized 16 | names and behaviors: Admin (NOTE: The name "root" was specifically 17 | avoided to prevent confusion about what an identity with such a name 18 | would be capable of.), Init, User, Read, and Anon. 19 | 20 | * `admin` — Used by the administrator of the device. `admin` 21 | may read, write, or mutate any property in any section of any Thing 22 | on this device. May initiate software updates, manage the 23 | keychain, manage permissions, and manage connectivity. There are 24 | two actions that are not allowed: A factory reset MUST NOT be 25 | allowed. Also, this identity MUST NOT be allowed to read the 26 | secret share of any keychain item (writing is allowed). 27 | * `init` — Special identity that can only be assumed when the 28 | device pairing code is used to authenticate. It assumes all of the 29 | permissions of “admin”, but can also perform a factory reset 30 | and/or read secret shares from items in the keychain. The ability 31 | to use this identity generally requires physical access to the 32 | device to put it into a particular state where you can 33 | authenticate using the pairing code. Intended only for initial 34 | commissioning and recovering administrative credentials. Unlike 35 | all other built-in identities, capabilities associated with this 36 | identity cannot be changed. 37 | * `user` — For identities of the device. `user` may read, 38 | write, or mutate all properties in the operational state of any Thing 39 | on this device, and may read any property from any Thing on this 40 | device (same exceptions as `admin`). No access is granted to 41 | any other resource. 42 | * `read` — For read-only identities of the device. `read` may 43 | read any property in any section of any Thing on this device (same 44 | exceptions as `admin`). No access is granted to any other 45 | resource. 46 | * `anon` — Used when the client did not authenticate itself to the 47 | server. By default, all requests will be denied (can be overridden 48 | for certain circumstances). 49 | 50 | Additional custom identities can be created with very limited scopes. 51 | All standardized identities (except `init`) can have their ACLs 52 | overridden. 53 | 54 | ### Access Rules ### 55 | 56 | The access rules for an identity allow access control decisions based 57 | on: 58 | 59 | * REST Method (GET, PUT, POST, DELETE, etc) 60 | * Path (Can start or end with a wildcard) 61 | * Query (can match individual fields) 62 | * Presence of CoAP observation/block-transfer options 63 | * Match rules from another *identity* 64 | -------------------------------------------------------------------------------- /doc/splot-book/src/ssm/lost-secret-recovery.md: -------------------------------------------------------------------------------- 1 | ## Lost Secret Recovery ## 2 | 3 | Keychain items can optionally support the ability for someone with 4 | physical access to *n* of *m* devices within a certain window of time 5 | to recover the underlying secret or private key. 6 | 7 | Each keychain item has a nominally write-only field that is intended 8 | to be used to contain a share of the secret (calculated using 9 | [libgfshare](http://www.digital-scurf.org/software/libgfshare)). The 10 | value of this field can only be read by the "init" identity, but can 11 | be written by the “admin” identity. 12 | 13 | This allows for a new owner of a house to securely take over the 14 | network without performing a factory reset on every single device, as 15 | long as the new owner can physically manipulate at least *n* devices 16 | within the share secret reset period (generally months, but may be 17 | indefinite). 18 | 19 | The shares are periodically recalculated, such as when a device is 20 | removed from the network or when a new device is added to the network. 21 | -------------------------------------------------------------------------------- /doc/splot-book/src/ssm/sessions.md: -------------------------------------------------------------------------------- 1 | ## Security Sessions ## 2 | 3 | Secure requests sent from a client to one or more servers (and 4 | responses vise-versa) are performed within the context of a 5 | *security session* established between the devices. 6 | 7 | Security sessions are secure channels between a *client* (who 8 | initiates the session and sends requests) and one or more *servers* 9 | (which can respond to the requests). The creation of a security 10 | session is always initiated by the client. If the server needs to send 11 | requests to the client, a new security session SHALL be established 12 | where the roles of the devices are reversed. 13 | 14 | On the client side, a security session is uniquely identified by a 15 | tuple of the following information: 16 | 17 | * The URL of the server endpoint 18 | * The client keychain item used to authenticate the client to the 19 | server. 20 | * A (possibly empty) set of acceptable client keychain items that 21 | the server can use to authenticate itself. 22 | 23 | Any request from a client that needs a security session with the same 24 | three properties above can re-use any existing security session with 25 | those properties. Otherwise, a new security session MUST be 26 | established. 27 | 28 | On the server side, a security session has the following properties: 29 | 30 | * The *identity* to assume for any incoming request from the 31 | client, determined from the keychain item on the server that the 32 | client used to initially authenticate. This *identity* 33 | determines what actions the *client* may perform on the 34 | *server* using this security session. 35 | * *OPTIONAL:* The set of keychain items that the client associated 36 | with this session has proven it satisfies. Used for attestation. 37 | First item is the one that determined the identity. Usually only 38 | contains one item. This may be empty if no authentication has 39 | taken place. 40 | -------------------------------------------------------------------------------- /doc/splot-book/src/ssm/spske.md: -------------------------------------------------------------------------------- 1 | ## Single-Purpose Shared Key Establishment ## 2 | 3 | Single-Purpose Shared Key Establishment (SPSKE) is a mechanism for 4 | establishing a shared-secret keychain item on two or more devices 5 | in-band without an administrator ever learning the shared secret. This 6 | enables the establishment of long-lived automation relationships. This 7 | shared key can then be associated with a very limited single-purpose 8 | identity to allow devices to perform actions on each other without 9 | granting the ability to perform unauthorized actions. The intent is to 10 | enable a "capability-like" security model. 11 | 12 | There are two variants: one for establishing a shared key between two 13 | devices, and one for establishing a shared key between a group of 14 | devices. The exact mechanism is TBD, but it would generally work like 15 | this: 16 | 17 | * The administrator calculates a temporary shared secret, *P*. 18 | * A "prepare-SPSKE" command is sent to Device A with the desired key 19 | identifier and the value of *P*. 20 | * Upon success, a location *LOC* is returned, which (if 21 | relative) is expanded to a fully specified URI. When the 22 | process is finished, this will be the address of the newly 23 | created keychain item for Device A. Next step must be 24 | completed within five minutes or *LOC* will become 25 | invalid. 26 | * A "calc-SPSKE" command is sent to Device B with the desired key 27 | identifier, the value of *P*, and the value of *LOC*. 28 | * Upon success, a location to the newly created keychain item 29 | for Device B is returned. *LOC* can then be considered the 30 | location of the newly created keychain item for Device A. 31 | * The administrator can then configure the newly created keychain 32 | items as appropriate, without ever learning the shared secret they 33 | contain. 34 | -------------------------------------------------------------------------------- /doc/splot-book/src/ssm/unresolved-issues.md: -------------------------------------------------------------------------------- 1 | # Unresolved Issues # 2 | 3 | ## Secure Multicast Discovery ## 4 | 5 | It would be desirable for someone with the appropriate credentials to 6 | be able to quickly discover devices that they can monitor/control. 7 | However, in order to avoid the case where the loss of a single device 8 | leads to the compromise of the entire network, monitoring/control 9 | credentials are typically asymmetric. While OSCORE does support secure 10 | multicast, it only works with a symmetric key. 11 | 12 | Possible solutions: 13 | 14 | * Have two keys: An asymmetric one for monitoring/control, and a 15 | symmetric one for multicast discovery. 16 | * Pros: Fast. 17 | * Cons: Difficult to manage or revoke discovery key. 18 | * Use unsecured multicast to discover devices which support SOM+SSM 19 | and then follow up each one with a secure unicast discovery 20 | request. 21 | * Pros: Secure. Single certificate means easier key management. 22 | * Cons: Slow when there are lots of devices. Must negotiate a 23 | new security session with each device. 24 | 25 | Either approach could be adopted without any changes to the underlying 26 | security model. 27 | 28 | ## Certificate Format ## 29 | 30 | The certificate format is currently undefined, but assumed to 31 | ultimately be based on X.509. However, there could be benefits to 32 | having a compressed certificate format that expands to X.509, similar 33 | to [Nest Weave Digital Certificates][NWDC]. 34 | 35 | [NWDC]: https://github.com/openweave/openweave-core/blob/b506d9e3c28eee887517c1f31f605f6e8151c039/doc/specs/protocol-specification-weave-digital-certificates.pdf 36 | -------------------------------------------------------------------------------- /doc/splot-book/src/terminology.md: -------------------------------------------------------------------------------- 1 | ## Terminology 2 | 3 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 4 | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 5 | document are to be interpreted as described in [RFC2119][]. 6 | 7 | [RFC2119]: https://tools.ietf.org/html/rfc2119 8 | 9 | This specification makes use of the following terminology: 10 | 11 | action 12 | : A behavior triggered by some criteria that manipulates a resource 13 | in the configured way. 14 | 15 | group 16 | : A collection of *things* that can be controlled as though it 17 | were a single thing. 18 | 19 | management application 20 | : An application on a computer, smart-phone, or the cloud, that provides 21 | a user-friendly interface for monitoring, controlling, configuring, and 22 | automating Things. 23 | 24 | method 25 | : A named function/action that a *thing* can be directed to perform, 26 | optionally taking a set of named arguments and returning a value. 27 | Each method is defined by a *trait*. 28 | 29 | property 30 | : A named value associated with a *thing* that can be 31 | fetched, monitored and/or controlled. Each property is defined by 32 | a *trait*. 33 | 34 | resource 35 | : The underlying object identified by a URI. 36 | 37 | section 38 | : *Properties* are categorized into sections, similar to how one might 39 | categorize files into folders. Each property belongs to a single 40 | section, of which there are three: *state*, *config*, and *metadata*. 41 | 42 | SMCP 43 | : Abbreviation for Splot Monitoring and Control Protocol, an application 44 | protocol that is based on the SOM (Splot Object Model). 45 | 46 | SOM 47 | : Abbreviation for Splot Object Model. 48 | 49 | technology 50 | : *WRITEME* 51 | 52 | thing 53 | : An abstraction of a physical or virtual mechanism, sensor, or 54 | automation. Physical devices can host one or more *things*. 55 | 56 | trait 57 | : A named collection of related *property* and *method* definitions. 58 | *Things* implement properties and methods that are defined by traits. 59 | 60 | trait-profile 61 | : A named collection of *properties* and/or *methods* that a 62 | thing can advertise itself as implementing. These *properties* and 63 | *methods* can belong to one or more *traits*. 64 | 65 | UID 66 | : Unique ID. A short, administratively-assigned, opaque identifier that 67 | uniquely identifies a Thing in an administrative scope. -------------------------------------------------------------------------------- /doc/splot-book/src/title-page.md: -------------------------------------------------------------------------------- 1 | Splot Design Documentation 2 | ========================== 3 | 4 | *Splot* is an exploratory effort to develop an [object 5 | model][SOM] and [applicaiton protocol][SMCP] that allows IoT devices to be used in ways 6 | unconstrained by the imagination of the device manufacturer or software 7 | developer, with the goal of improving the long-term value of such devices. 8 | 9 | > Note: This document is a work-in-progress and is subject to change at any time. 10 | 11 | [SOM]: ./som/intro.md 12 | [SMCP]: ./smcp/intro.md 13 | 14 | *Splot is not an official Google project.* 15 | 16 | ----------------- 17 | 18 | Copyright © 2019 Google LLC 19 | 20 | Licensed under the Apache License, Version 2.0 (the "License"); 21 | you may not use this file except in compliance with the License. 22 | You may obtain a copy of the License at 23 | 24 | 25 | 26 | Unless required by applicable law or agreed to in writing, software 27 | distributed under the License is distributed on an "AS IS" BASIS, 28 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 | See the License for the specific language governing permissions and 30 | limitations under the License. 31 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/auto/intro.md: -------------------------------------------------------------------------------- 1 | # Automation Traits 2 | 3 | The `automation` Splot traits are traits for implementing and managing 4 | [automation primitives](../../automation/primitives.md). 5 | 6 | * [`Pairing`](./pairing.md): Trait for automation pairings, which are automation primitives 7 | that link the value of two different resources. 8 | * [`PairingManager`](./pairing-manager.md): Trait for things that create or delete 9 | automation pairings. 10 | * [`Actionable`](./actionable.md): Trait for automation primitives that can 11 | be triggered to perform specific actions. Implemented by Rules and Timers. 12 | * [`Rule`](./rule.md): Trait for automation rules, which are [actionable](./actionable.md) 13 | automation primitives that trigger once one or all of the configured conditions 14 | have been satisfied. 15 | * [`RuleManager`](./rule-manager.md): Trait for things that create or delete 16 | automation rules. 17 | * [`Timer`](./timer.md): Trait for automation timers, which are [actionable](./actionable.md) 18 | automation primitives that trigger after a delay, at regular intervals, or at specific 19 | times or dates. 20 | * [`TimerManager`](./timer-manager.md): Trait for things that create or delete 21 | automation timers. 22 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/auto/pairing-manager.md: -------------------------------------------------------------------------------- 1 | # AutomationPairingManager Trait (`pmgr`) 2 | 3 | 4 | Experimental trait for managing automation pairings. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:pairing-manager:v1:v0#r0` | 9 | | Short-Id | `pmgr` | 10 | | Has-Children | yes | 11 | 12 | 13 | 14 | ## Metadata Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | TraitURI | `m/pmgr/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 19 | 20 | ### `m/pmgr/turi` : TraitURI 21 | 22 | The URI that uniquely identifies the specification used to implement this trait. 23 | 24 | | Attribute | Value | 25 | |----:|-------------| 26 | | Value Type | URI-reference | 27 | | Flags | `CONST`, `REQ`| 28 | 29 | 30 | 31 | ## Methods 32 | 33 | | Key | Description | 34 | |-----|-------------| 35 | | `f/pmgr?create` | Creates a new automation pairing. | 36 | 37 | ### `f/pmgr?create` : Create 38 | 39 | Creates a new automation pairing. 40 | 41 | | Arg | Req | Returns | Description | 42 | |-----|-----|---------|-------------| 43 | | `xfwd` | | text string | Maps to `c/pair/xfwd` | 44 | | `dst` | X | URI-reference | Maps to `c/pair/dst` | 45 | | `erev` | | boolean | Maps to `c/pair/erev` | 46 | | `en` | | boolean | Maps to `c/enab/v` | 47 | | `src` | X | URI-reference | Maps to `c/pair/src` | 48 | | `name` | | text string | Maps to `m/base/name` | 49 | | `xrev` | | text string | Maps to `c/pair/xrev` | 50 | | `efwd` | | boolean | Maps to `c/pair/efwd` | 51 | 52 | 53 | Returns URI for the created pairing. 54 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/auto/rule-manager.md: -------------------------------------------------------------------------------- 1 | # AutomationRuleManager Trait (`rmgr`) 2 | 3 | 4 | Experimental trait for managing automation rules. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:rule-manager:v1:v0#r0` | 9 | | Short-Id | `rmgr` | 10 | | Has-Children | yes | 11 | 12 | 13 | 14 | ## Metadata Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | TraitURI | `m/rmgr/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 19 | 20 | ### `m/rmgr/turi` : TraitURI 21 | 22 | The URI that uniquely identifies the specification used to implement this trait. 23 | 24 | | Attribute | Value | 25 | |----:|-------------| 26 | | Value Type | URI-reference | 27 | | Flags | `CONST`, `REQ`| 28 | 29 | 30 | 31 | ## Methods 32 | 33 | | Key | Description | 34 | |-----|-------------| 35 | | `f/rmgr?create` | Creates a new automation rule. | 36 | 37 | ### `f/rmgr?create` : Create 38 | 39 | Creates a new automation rule. 40 | 41 | | Arg | Req | Returns | Description | 42 | |-----|-----|---------|-------------| 43 | | `actm` | | text string | Method for a single action. | 44 | | `en` | | boolean | Determines if the created rule will be immediately enabled or not. | 45 | | `name` | | text string | Descriptive name for the created rule. | 46 | | `recy` | | boolean | Determines if the created pairing should be recyclable. | 47 | | `mtch` | | text string | | 48 | | `actb` | | splot value | Body for a single action. | 49 | | `actp` | | URI-reference | Path for a single action. | 50 | | `acti` | | array containing maps of nullable splot values | List of Actions. | 51 | | `cond` | | array containing maps of nullable splot values | List of conditions | 52 | 53 | 54 | Returns URI for the created rule. 55 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/auto/timer-manager.md: -------------------------------------------------------------------------------- 1 | # AutomationTimerManager Trait (`tmgr`) 2 | 3 | 4 | Experimental trait for managing automation timers. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:timer-manager:v1:v0#r0` | 9 | | Short-Id | `tmgr` | 10 | | Has-Children | yes | 11 | 12 | 13 | 14 | ## Metadata Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | TraitURI | `m/tmgr/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 19 | 20 | ### `m/tmgr/turi` : TraitURI 21 | 22 | The URI that uniquely identifies the specification used to implement this trait. 23 | 24 | | Attribute | Value | 25 | |----:|-------------| 26 | | Value Type | URI-reference | 27 | | Flags | `CONST`, `REQ`| 28 | 29 | 30 | 31 | ## Methods 32 | 33 | | Key | Description | 34 | |-----|-------------| 35 | | `f/tmgr?create` | Creates a new automation timer. | 36 | 37 | ### `f/tmgr?create` : Create 38 | 39 | Creates a new automation timer. 40 | 41 | | Arg | Req | Returns | Description | 42 | |-----|-----|---------|-------------| 43 | | `pred` | | text string | Predicate program. | 44 | | `name` | | text string | Descriptive name for the created timer. | 45 | | `recy` | | boolean | Determines if the created timer should be recyclable. | 46 | | `acti` | | array containing maps of nullable splot values | List of Actions. | 47 | | `actm` | | text string | Method for a single action. | 48 | | `mtch` | | text string | | 49 | | `actp` | | URI-reference | Path for a single action. | 50 | | `en` | | boolean | Determines if the created timer will be immediately enabled or not. | 51 | | `actb` | | splot value | Body for a single action. | 52 | | `adel` | | boolean | Auto delete flag. | 53 | | `dura` | | real number | Duration of the timer. | 54 | | `arst` | | boolean | Auto reset flag. | 55 | | `schd` | | text string | Schedule Program. | 56 | 57 | 58 | Returns URI for the created timer. 59 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/core/group.md: -------------------------------------------------------------------------------- 1 | # Group Trait (`grup`) 2 | 3 | 4 | Trait for groups of things. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:group:v1:v0#r0` | 9 | | Short-Id | `grup` | 10 | | Has-Children | no | 11 | 12 | 13 | 14 | ## Config Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | Members | `c/grup/memb` | X | ? | | URLs of group members | 19 | | GroupAddress | `c/grup/addr` | X | ? | | Multicast Group Address | 20 | | Version | `c/grup/vers` | X | ? | | Incremented whenever group configuration has changed. | 21 | 22 | ### `c/grup/memb` : Members 23 | 24 | URLs of group members. 25 | 26 | | Attribute | Value | 27 | |----:|-------------| 28 | | Value Type | array containing URI-references | 29 | | Flags | `GET`, `OPT_SET`, `OBS`| 30 | 31 | 32 | 33 | ### `c/grup/addr` : GroupAddress 34 | 35 | Multicast Group Address. 36 | 37 | | Attribute | Value | 38 | |----:|-------------| 39 | | Value Type | text string | 40 | | Flags | `GET`, `OPT_SET`| 41 | 42 | 43 | 44 | ### `c/grup/vers` : Version 45 | 46 | Incremented whenever group configuration has changed. 47 | 48 | | Attribute | Value | 49 | |----:|-------------| 50 | | Value Type | integer | 51 | | Flags | `GET`, `OPT_SET`| 52 | 53 | 54 | 55 | ## Metadata Properties 56 | 57 | | Name | Key | R | W | Req | Description | 58 | |-----|---|----|----|----|----| 59 | | TraitURI | `m/grup/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 60 | 61 | ### `m/grup/turi` : TraitURI 62 | 63 | The URI that uniquely identifies the specification used to implement this trait. 64 | 65 | | Attribute | Value | 66 | |----:|-------------| 67 | | Value Type | URI-reference | 68 | | Flags | `CONST`, `REQ`| 69 | 70 | 71 | 72 | ## Associated Constants 73 | 74 | | Name | Value | Description | 75 | |-----|------|-------| 76 | | `PARAM_GROUP_ID` | "gid" | Group ID | 77 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/core/intro.md: -------------------------------------------------------------------------------- 1 | # Core Traits 2 | 3 | The `core` Splot traits are traits that are fundamental to Splot. There are 4 | currently just four: 5 | 6 | * [`Base`](./base.md): Descriptive metadata, Traps, Hidden flag, Context Info 7 | * [`Group`](./group.md): All groups of things implement this trait. 8 | * [`Scene`](./scene.md): For things that support scenes. 9 | * [`Transition`](./transition.md): For things that support smooth state transitions. 10 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/core/scene.md: -------------------------------------------------------------------------------- 1 | # Scene Trait (`scen`) 2 | 3 | 4 | Support for Scenes. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:scene:v1:v0#r0` | 9 | | Short-Id | `scen` | 10 | | Has-Children | yes | 11 | 12 | Provides scene support for a thing: named collections of state properties that can be easily recalled. 13 | 14 | ## State Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | SceneId | `s/scen/sid` | X | X | X | Current scene identifier. | 19 | 20 | ### `s/scen/sid` : SceneId 21 | 22 | Current scene identifier. 23 | 24 | | Attribute | Value | 25 | |----:|-------------| 26 | | Value Type | nullable text string | 27 | | Flags | `REQ`, `RW`, `VOLATILE`| 28 | 29 | When written to, applies the scene to the state. When read, it will return the last state that was loaded if no changes to the state have been made since that time. Otherwise reading will return null. 30 | 31 | ## Config Properties 32 | 33 | | Name | Key | R | W | Req | Description | 34 | |-----|---|----|----|----|----| 35 | | SceneIdPowerOn | `c/scen/spor` | X | X | | Scene identifier to use at power-up. | 36 | 37 | ### `c/scen/spor` : SceneIdPowerOn 38 | 39 | Scene identifier to use at power-up. 40 | 41 | | Attribute | Value | 42 | |----:|-------------| 43 | | Value Type | nullable text string | 44 | | Flags | `EXPERIMENTAL`, `RW`| 45 | 46 | If not null, this property identifies the scene that will be automatically loaded at power-on or reset. Not all implementations support changing this value. 47 | 48 | ## Metadata Properties 49 | 50 | | Name | Key | R | W | Req | Description | 51 | |-----|---|----|----|----|----| 52 | | TraitURI | `m/scen/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 53 | 54 | ### `m/scen/turi` : TraitURI 55 | 56 | The URI that uniquely identifies the specification used to implement this trait. 57 | 58 | | Attribute | Value | 59 | |----:|-------------| 60 | | Value Type | URI-reference | 61 | | Flags | `CONST`, `REQ`| 62 | 63 | 64 | 65 | ## Methods 66 | 67 | | Key | Description | 68 | |-----|-------------| 69 | | `f/scen?save` | Saves the current state to the given SceneId. | 70 | 71 | ### `f/scen?save` : Save 72 | 73 | Saves the current state to the given SceneId. 74 | 75 | | Arg | Req | Returns | Description | 76 | |-----|-----|---------|-------------| 77 | | `sid` | | text string | Scene ID | 78 | 79 | 80 | Returns URI for the created scene. 81 | 82 | 83 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/core/transition.md: -------------------------------------------------------------------------------- 1 | # Transition Trait (`tran`) 2 | 3 | 4 | Smooth value transitions. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:transition:v1:v0#r0` | 9 | | Short-Id | `tran` | 10 | | Has-Children | no | 11 | 12 | This trait is implemented by things that support smooth transitions for some properties. Only properties in the *state* section can be transitioned smoothly. 13 | 14 | ## State Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | Duration | `s/tran/d` | X | X | X | Transition duration, in seconds | 19 | | Speed | `s/tran/sp` | X | X | | Transition duration, in percentage of maximum speed | 20 | 21 | ### `s/tran/d` : Duration 22 | 23 | Transition duration, in seconds. 24 | 25 | | Attribute | Value | 26 | |----:|-------------| 27 | | Value Type | nullable real number | 28 | | Flags | `REQ`, `RW`, `VOLATILE`, `NO_TRANS`| 29 | 30 | When updated simultaneously with other state changes, it indicates the duration of the transition between the old state and the specified state. When read it indicates the time remaining in the current transition. The current transition can be halted by setting this to zero. Sometimes physical limitations will force a minimum duration that is longer than specified. The maximum value that is required to be supported is 604800, or one week. The resolution must be at or below one tenth of a second for durations of less than one hour. 31 | 32 | ### `s/tran/sp` : Speed 33 | 34 | Transition duration, in percentage of maximum speed. 35 | 36 | | Attribute | Value | 37 | |----:|-------------| 38 | | Value Type | nullable percentage (0.0-1.0) | 39 | | Flags | `EXPERIMENTAL`, `RW`, `VOLATILE`, `NO_TRANS`| 40 | 41 | This is an alternative to specifying the duration of a transition for Things where certain properties cannot be physically transitioned faster than a certain speed. The units of this property are a percentage of full speed. The implementation SHOULD allow this parameter to be adjusted as the transition is occurring. This property SHOULD NOT be implemented unless it makes sense for the underlying hardware. 42 | 43 | ## Metadata Properties 44 | 45 | | Name | Key | R | W | Req | Description | 46 | |-----|---|----|----|----|----| 47 | | TraitURI | `m/tran/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 48 | 49 | ### `m/tran/turi` : TraitURI 50 | 51 | The URI that uniquely identifies the specification used to implement this trait. 52 | 53 | | Attribute | Value | 54 | |----:|-------------| 55 | | Value Type | URI-reference | 56 | | Flags | `CONST`, `REQ`| 57 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/sec/identity.md: -------------------------------------------------------------------------------- 1 | # Identity Trait (`iden`) 2 | 3 | 4 | Trait representing an identity. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:identity:v1:v0#r0` | 9 | | Short-Id | `iden` | 10 | | Has-Children | yes | 11 | | Requires | `tag:google.com,2018:m2m:traits:base:v1:v0#r0`| 12 | 13 | This trait is a work in progress. 14 | 15 | ## Metadata Properties 16 | 17 | | Name | Key | R | W | Req | Description | 18 | |-----|---|----|----|----|----| 19 | | TraitURI | `m/iden/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 20 | 21 | ### `m/iden/turi` : TraitURI 22 | 23 | The URI that uniquely identifies the specification used to implement this trait. 24 | 25 | | Attribute | Value | 26 | |----:|-------------| 27 | | Value Type | URI-reference | 28 | | Flags | `CONST`, `REQ`| 29 | 30 | 31 | 32 | ## Methods 33 | 34 | | Key | Description | 35 | |-----|-------------| 36 | | `f/iden?add` | Adds a new rule to the identity. | 37 | 38 | ### `f/iden?add` : AddRule 39 | 40 | Adds a new rule to the identity. 41 | 42 | | Arg | Req | Returns | Description | 43 | |-----|-----|---------|-------------| 44 | | `type` | X | integer | Keychain item type parameter. | 45 | | `secr` | | byte string | Symmetric shared secret, or private key if `cert` is present. | 46 | | `iden` | | text string | Identity to assume for any client using this item. | 47 | | `cert` | | byte string | Certificate parameter. | 48 | 49 | 50 | Returns URI for the created keychain item. 51 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/sec/intro.md: -------------------------------------------------------------------------------- 1 | # Security Traits 2 | 3 | The `security` Splot trait collection defines traits for implementing the 4 | [Splot Security Model](../../ssm/intro.md). 5 | 6 | * [`Keychain`](./keychain.md): Trait for things that manage [Keychain Items](../../ssm/keychain.md#keychain-items). 7 | * [`KeychainItem`](./keychain-item.md): Trait for things that represent cryptographic credentials. 8 | * [`Identity`](./identity.md): Trait for things that represent [authenticated client identities](../../ssm/identities.md). 9 | * [`AccessRule`](./access-rule.md): A trait for a single 10 | [access rule](../../ssm/identities.md#access-rules) that is associated with a 11 | specific [identity](../../ssm/identities.md). 12 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/sec/keychain.md: -------------------------------------------------------------------------------- 1 | # Keychain Trait (`keyc`) 2 | 3 | 4 | Trait for managing a cryptographic keychain. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:keychain:v1:v0#r0` | 9 | | Short-Id | `keyc` | 10 | | Has-Children | yes | 11 | 12 | 13 | 14 | ## Metadata Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | TraitURI | `m/keyc/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 19 | 20 | ### `m/keyc/turi` : TraitURI 21 | 22 | The URI that uniquely identifies the specification used to implement this trait. 23 | 24 | | Attribute | Value | 25 | |----:|-------------| 26 | | Value Type | URI-reference | 27 | | Flags | `CONST`, `REQ`| 28 | 29 | 30 | 31 | ## Methods 32 | 33 | | Key | Description | 34 | |-----|-------------| 35 | | `f/keyc?create` | Creates a new keychain item | 36 | 37 | ### `f/keyc?create` : Create 38 | 39 | Creates a new keychain item. 40 | 41 | | Arg | Req | Returns | Description | 42 | |-----|-----|---------|-------------| 43 | | `type` | X | integer | Keychain item type parameter. | 44 | | `secr` | | byte string | Symmetric shared secret, or private key if `cert` is present. | 45 | | `cert` | | byte string | Certificate parameter. | 46 | | `iden` | | text string | Identity to assume for any client using this item. | 47 | 48 | 49 | Returns URI for the created keychain item. 50 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/std/ambient-environment.md: -------------------------------------------------------------------------------- 1 | # AmbientEnvironment Trait (`aenv`) 2 | 3 | 4 | Trait for measuring ambient temperature, pressure, humidity, and light level. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:ambient-environment:v1:v0#r0` | 9 | | Short-Id | `aenv` | 10 | | Has-Children | no | 11 | 12 | This would typically be used by environmental sensors. 13 | 14 | ## State Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | Pressure | `s/aenv/pres` | X | | | Ambient air pressure. *Units TBD*. | 19 | | Temperature | `s/aenv/temp` | X | | | Ambient air temperature, in °C | 20 | | Humidity | `s/aenv/humi` | X | | | Relative ambient humidity | 21 | | LightLevel | `s/aenv/temp` | X | | | Ambient light level. *Units TBD*. | 22 | 23 | ### `s/aenv/pres` : Pressure 24 | 25 | Ambient air pressure. *Units TBD*. 26 | 27 | | Attribute | Value | 28 | |----:|-------------| 29 | | Value Type | real number | 30 | | Flags | `GET`, `OBS`| 31 | 32 | 33 | 34 | ### `s/aenv/temp` : Temperature 35 | 36 | Ambient air temperature, in °C. 37 | 38 | | Attribute | Value | 39 | |----:|-------------| 40 | | Value Type | real number | 41 | | Flags | `GET`, `OBS`| 42 | 43 | 44 | 45 | ### `s/aenv/humi` : Humidity 46 | 47 | Relative ambient humidity. 48 | 49 | | Attribute | Value | 50 | |----:|-------------| 51 | | Value Type | percentage (0.0-1.0) | 52 | | Flags | `GET`, `OBS`| 53 | 54 | Units TBD. 55 | 56 | ### `s/aenv/temp` : LightLevel 57 | 58 | Ambient light level. *Units TBD*. 59 | 60 | | Attribute | Value | 61 | |----:|-------------| 62 | | Value Type | real number | 63 | | Flags | `GET`, `OBS`| 64 | 65 | 66 | 67 | ## Metadata Properties 68 | 69 | | Name | Key | R | W | Req | Description | 70 | |-----|---|----|----|----|----| 71 | | TraitURI | `m/aenv/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 72 | 73 | ### `m/aenv/turi` : TraitURI 74 | 75 | The URI that uniquely identifies the specification used to implement this trait. 76 | 77 | | Attribute | Value | 78 | |----:|-------------| 79 | | Value Type | URI-reference | 80 | | Flags | `CONST`, `REQ`| 81 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/std/button.md: -------------------------------------------------------------------------------- 1 | # Button Trait (`bttn`) 2 | 3 | 4 | A button that can be pressed. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:button:v1:v0#r0` | 9 | | Short-Id | `bttn` | 10 | | Has-Children | no | 11 | 12 | 13 | 14 | ## State Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | Value | `s/bttn/v` | X | ? | X | Button State | 19 | | PressCount | `s/bttn/c_dn` | X | | X | The number of times this button has been *pressed*. | 20 | | ReleaseCount | `s/bttn/c_up` | X | | X | The number of times this button has been *released*. | 21 | | Last | `s/bttn/last` | X | | | The number of seconds ago that this button was pressed or released. | 22 | 23 | ### `s/bttn/v` : Value 24 | 25 | Button State. 26 | 27 | | Attribute | Value | 28 | |----:|-------------| 29 | | Value Type | boolean | 30 | | Flags | `REQ`, `GET`, `OPT_SET`, `OBS`| 31 | 32 | `true` while the button is pressed, `false` while the button is released. 33 | 34 | ### `s/bttn/c_dn` : PressCount 35 | 36 | The number of times this button has been *pressed*. 37 | 38 | | Attribute | Value | 39 | |----:|-------------| 40 | | Value Type | integer | 41 | | Flags | `REQ`, `GET`, `RESET`, `OBS`| 42 | 43 | This count may be reset by setting it to zero. The count is not preserved across power cycles. 44 | 45 | ### `s/bttn/c_up` : ReleaseCount 46 | 47 | The number of times this button has been *released*. 48 | 49 | | Attribute | Value | 50 | |----:|-------------| 51 | | Value Type | integer | 52 | | Flags | `REQ`, `GET`, `RESET`, `OBS`| 53 | 54 | This count may be reset by setting it to zero. The count is not preserved across power cycles. 55 | 56 | ### `s/bttn/last` : Last 57 | 58 | The number of seconds ago that this button was pressed or released. 59 | 60 | | Attribute | Value | 61 | |----:|-------------| 62 | | Value Type | integer | 63 | | Flags | `GET`, `NO_SET`, `OBS`, `VOLATILE`| 64 | 65 | This value is not cacheable. Observing it will only indicate when the value is reset to zero. 66 | 67 | ## Metadata Properties 68 | 69 | | Name | Key | R | W | Req | Description | 70 | |-----|---|----|----|----|----| 71 | | TraitURI | `m/bttn/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 72 | 73 | ### `m/bttn/turi` : TraitURI 74 | 75 | The URI that uniquely identifies the specification used to implement this trait. 76 | 77 | | Attribute | Value | 78 | |----:|-------------| 79 | | Value Type | URI-reference | 80 | | Flags | `CONST`, `REQ`| 81 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/std/enabled.md: -------------------------------------------------------------------------------- 1 | # Enabled Trait (`enab`) 2 | 3 | 4 | Enabled/Disabled. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:enabled:v1:v0#r0` | 9 | | Short-Id | `enab` | 10 | | Has-Children | no | 11 | 12 | Implemented by things that can be configured as enabled or disabled. 13 | 14 | ## Config Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | Value | `c/enab/v` | X | X | X | Enabled/Disabled state as a boolean | 19 | 20 | ### `c/enab/v` : Value 21 | 22 | Enabled/Disabled state as a boolean. 23 | 24 | | Attribute | Value | 25 | |----:|-------------| 26 | | Value Type | boolean | 27 | | Flags | `REQ`, `GET`, `SET`, `OBS`| 28 | 29 | Enabled is `true`, Disabled is `false` 30 | 31 | ## Metadata Properties 32 | 33 | | Name | Key | R | W | Req | Description | 34 | |-----|---|----|----|----|----| 35 | | TraitURI | `m/enab/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 36 | 37 | ### `m/enab/turi` : TraitURI 38 | 39 | The URI that uniquely identifies the specification used to implement this trait. 40 | 41 | | Attribute | Value | 42 | |----:|-------------| 43 | | Value Type | URI-reference | 44 | | Flags | `CONST`, `REQ`| 45 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/std/intro.md: -------------------------------------------------------------------------------- 1 | # Standard Traits 2 | 3 | The `standard` Splot traits are traits that represent common thing behaviors. 4 | For example, lots of things have the ability to turn them on or off, so this 5 | collection defines the [`OnOff`](on-off.md) trait. 6 | 7 | * [`OnOff`](./on-off.md): Trait for things that can be turned on or off. 8 | * [`Level`](./level.md): Trait for things that have a continuous value between 0% and 100%, 9 | such as lights, shades, or speed controllers. 10 | * [`Light`](./light.md): Trait that identifies lights, including full-color lights. 11 | * [`Enabled`](./enabled.md): Trait for things that can be enabled or disabled. 12 | * [`Energy`](./energy.md): Trait for things that need to describe, keep track of, or provide 13 | limits on energy consumption. 14 | * [`Battery`](./battery.md): Trait for things that have batteries/cells. 15 | * [`AmbientEnvironment`](./ambient-environment.md): Trait for things that monitor temperature, 16 | pressure, humidity, and/or light level. 17 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/std/level.md: -------------------------------------------------------------------------------- 1 | # Level Trait (`levl`) 2 | 3 | 4 | Level. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:level:v1:v0#r0` | 9 | | Short-Id | `levl` | 10 | | Has-Children | no | 11 | 12 | This trait is implemented by things that support smooth transitions for some properties. Only properties in the *state* section can be transitioned smoothly. 13 | 14 | ## State Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | Value | `s/levl/v` | ? | ? | X | Level value as a percentage | 19 | 20 | ### `s/levl/v` : Value 21 | 22 | Level value as a percentage. 23 | 24 | | Attribute | Value | 25 | |----:|-------------| 26 | | Value Type | percentage (0.0-1.0) | 27 | | Flags | `REQ`, `OPT_GET`, `OPT_SET`, `OBS`| 28 | 29 | The level is encoded as a floating-point value between 0.0 and 1.0. The exact meaning of this value is dependent on the type of device, but in general the value 0.0 represents one extreme state, the value 1.0 represents the opposite extreme state, and the values between those two represent a perceptually uniform distribution between those two states. When paired with the `OnOff` trait, the value 0.0 is intended to be closest to the off state that isn't actually off. 30 | 31 | Some things to note: 32 | 33 | * With the exception of physical actuators, perceptual uniformity is generally not linear. For example, reducing the light output by 50% will only reduce perceived light output by around 25%. 34 | * If this trait is paired with an OnOff trait, then setting the level to 0.0 will likely behave differently than if the OnOff trait was turned off. 35 | 36 | ## Metadata Properties 37 | 38 | | Name | Key | R | W | Req | Description | 39 | |-----|---|----|----|----|----| 40 | | TraitURI | `m/levl/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 41 | 42 | ### `m/levl/turi` : TraitURI 43 | 44 | The URI that uniquely identifies the specification used to implement this trait. 45 | 46 | | Attribute | Value | 47 | |----:|-------------| 48 | | Value Type | URI-reference | 49 | | Flags | `CONST`, `REQ`| 50 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/std/on-off.md: -------------------------------------------------------------------------------- 1 | # OnOff Trait (`onof`) 2 | 3 | 4 | On/Off. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:on_off:v1:v0#r0` | 9 | | Short-Id | `onof` | 10 | | Has-Children | no | 11 | 12 | Implemented by things that can be turned on or off, such as a light bulb or a power controller. 13 | 14 | ## State Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | Value | `s/onof/v` | ? | ? | X | On/Off state as a boolean | 19 | 20 | ### `s/onof/v` : Value 21 | 22 | On/Off state as a boolean. 23 | 24 | | Attribute | Value | 25 | |----:|-------------| 26 | | Value Type | boolean | 27 | | Flags | `REQ`, `OPT_GET`, `OPT_SET`, `OBS`| 28 | 29 | On is `true`, off is `false` 30 | 31 | ## Config Properties 32 | 33 | | Name | Key | R | W | Req | Description | 34 | |-----|---|----|----|----|----| 35 | | DurationOff | `c/onof/doff` | X | ? | | Default duration (in seconds) for transitions from 'on' to 'off' | 36 | | DurationOn | `c/onof/don` | X | ? | | Default duration (in seconds) for transitions from 'off' to 'on' | 37 | | SceneIdOn | `c/onof/scon` | X | ? | | Power-on scene. | 38 | | IsLuminary | `c/onof/lumi` | X | ? | | Flag for indicating if this thing is controlling a Luminary (light) | 39 | 40 | ### `c/onof/doff` : DurationOff 41 | 42 | Default duration (in seconds) for transitions from 'on' to 'off'. 43 | 44 | | Attribute | Value | 45 | |----:|-------------| 46 | | Value Type | real number | 47 | | Flags | `GET`, `OPT_SET`, `OBS`| 48 | 49 | Indicates the default duration (in seconds) when transitioning from the 'on' state to the 'off' state. This property is only present on things which also have the *Transition* trait. 50 | 51 | ### `c/onof/don` : DurationOn 52 | 53 | Default duration (in seconds) for transitions from 'off' to 'on'. 54 | 55 | | Attribute | Value | 56 | |----:|-------------| 57 | | Value Type | real number | 58 | | Flags | `EXPERIMENTAL`, `GET`, `OPT_SET`, `OBS`| 59 | 60 | Indicates the default duration (in seconds) when transitioning from the 'off' state to the 'on' state. This property is only present on things which also have the *Transition* trait. 61 | 62 | ### `c/onof/scon` : SceneIdOn 63 | 64 | Power-on scene. 65 | 66 | | Attribute | Value | 67 | |----:|-------------| 68 | | Value Type | text string | 69 | | Flags | `EXPERIMENTAL`, `GET`, `OPT_SET`, `OBS`| 70 | 71 | Indicates the scene to recall when the device is physically powered on or rebooted. On some types of devices this may be read-only. Only present on things that also implement the `Scene` trait. 72 | 73 | ### `c/onof/lumi` : IsLuminary 74 | 75 | Flag for indicating if this thing is controlling a Luminary (light). 76 | 77 | | Attribute | Value | 78 | |----:|-------------| 79 | | Value Type | boolean | 80 | | Flags | `EXPERIMENTAL`, `GET`, `OPT_SET`, `OBS`| 81 | 82 | This property allows a thing that controls a generic load (Like a smart power switch) to be explicitly identified as controlling a luminary (a light that is used for illumination). If this is set to `true`, this thing will be included in the “luminaries” group. If this thing implements the Luminary trait, then this thing is already assumed to be a luminary and this property **MUST NOT** be present. 83 | 84 | ## Metadata Properties 85 | 86 | | Name | Key | R | W | Req | Description | 87 | |-----|---|----|----|----|----| 88 | | TraitURI | `m/onof/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 89 | 90 | ### `m/onof/turi` : TraitURI 91 | 92 | The URI that uniquely identifies the specification used to implement this trait. 93 | 94 | | Attribute | Value | 95 | |----:|-------------| 96 | | Value Type | URI-reference | 97 | | Flags | `CONST`, `REQ`| 98 | -------------------------------------------------------------------------------- /doc/splot-book/src/trait-def/std/presence.md: -------------------------------------------------------------------------------- 1 | # Presence Trait (`pres`) 2 | 3 | 4 | Detects presence. 5 | 6 | | Attribute | Value | 7 | |----:|-------------| 8 | | Id | `tag:google.com,2018:m2m:traits:presence:v1:v0#r0` | 9 | | Short-Id | `pres` | 10 | | Has-Children | no | 11 | 12 | Implemented by things that can detect the presence of someone, such as motion sensors and pressure mats. 13 | 14 | ## State Properties 15 | 16 | | Name | Key | R | W | Req | Description | 17 | |-----|---|----|----|----|----| 18 | | Value | `s/pres/v` | X | ? | X | Presence Detected | 19 | | Count | `s/pres/c` | X | | X | Trip Count | 20 | | Last | `s/pres/last` | X | | | The number of seconds ago that presence was last detected. | 21 | 22 | ### `s/pres/v` : Value 23 | 24 | Presence Detected. 25 | 26 | | Attribute | Value | 27 | |----:|-------------| 28 | | Value Type | boolean | 29 | | Flags | `REQ`, `GET`, `OPT_SET`, `OBS`| 30 | 31 | `true` while presence is detected, `false` otherwise. 32 | 33 | The presence signal is generally momentary in nature, flipping back and forth between detected and not-detected as the sensor detects movement. 34 | 35 | ### `s/pres/c` : Count 36 | 37 | Trip Count. 38 | 39 | | Attribute | Value | 40 | |----:|-------------| 41 | | Value Type | integer | 42 | | Flags | `REQ`, `GET`, `RESET`, `OBS`| 43 | 44 | This count may be reset by setting it to zero. The count is not preserved across power cycles. 45 | 46 | ### `s/pres/last` : Last 47 | 48 | The number of seconds ago that presence was last detected. 49 | 50 | | Attribute | Value | 51 | |----:|-------------| 52 | | Value Type | integer | 53 | | Flags | `GET`, `NO_SET`, `OBS`, `VOLATILE`| 54 | 55 | This value is not cacheable. Observing it will only indicate when the value is reset to zero. 56 | 57 | ## Metadata Properties 58 | 59 | | Name | Key | R | W | Req | Description | 60 | |-----|---|----|----|----|----| 61 | | TraitURI | `m/pres/turi` | X | | X | The URI that uniquely identifies the specification used to implement this trait. | 62 | 63 | ### `m/pres/turi` : TraitURI 64 | 65 | The URI that uniquely identifies the specification used to implement this trait. 66 | 67 | | Attribute | Value | 68 | |----:|-------------| 69 | | Value Type | URI-reference | 70 | | Flags | `CONST`, `REQ`| 71 | -------------------------------------------------------------------------------- /doc/splot-object-model-intro.md: -------------------------------------------------------------------------------- 1 | Splot Object Model (SOM) 2 | ======================== 3 | 4 | The Splot Object Model (SOM) defines an experimental object model for 5 | facilitating the monitoring and control of individual things and 6 | groups of things. 7 | 8 | This document has moved to the [Splot Object Model Section](https://google.github.io/splot-java/splot-book/som/intro.html) 9 | of the [Splot Design Documentation](https://google.github.io/splot-java/splot-book/). 10 | -------------------------------------------------------------------------------- /smcp-example-server/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /out 3 | /target 4 | example-smcp-server.cbor 5 | *.temp 6 | -------------------------------------------------------------------------------- /smcp-example-server/README.md: -------------------------------------------------------------------------------- 1 | SMCP Example Server 2 | =================== 3 | 4 | This module implements an example SMCP server, hosting an 5 | automation manager, a light bulb, and system info. It demonstrates 6 | the following concepts: 7 | 8 | * How to set up a Technology instance 9 | * How to support non-volatile storage/retrieval of parameters using FilePersistentStateManager. 10 | * How to implement a Thing (MyLightBulb, SystemInfo) 11 | * How to host things on a Technology 12 | 13 | ## Building and Running ## 14 | 15 | Building and running the example server is fairly simple: 16 | 17 | $ cd smcp-example-server 18 | $ mvn compile exec:java 19 | 20 | Note that if you are not working from an official release, you may 21 | need to install the HEAD-SNAPSHOT libraries to your local maven 22 | repository first: 23 | 24 | $ cd .. 25 | $ mvn install 26 | 27 | ## Usage ## 28 | 29 | Once the server is running, you will find it on the default CoAP 30 | port 5683 on the local host. You can then interact with it using 31 | any CoAP tool, such as [nyocictl](https://github.com/darconeous/libnyoci#nyocictl) 32 | or [coap-client](http://manpages.ubuntu.com/manpages/cosmic/man5/coap-client.5.html). 33 | 34 | It has the following structure: 35 | 36 | * `/g/`: Group interface. All groups live here. 37 | * `/g/?add[&ep=xxx]`: Create/add a new group, optionally specifying the group id. 38 | * `/g/...`: Created groups 39 | * `/1/`: Local Automation Manager. 40 | * `/1/f/pmgr?create`: Command to create a new pairing 41 | * `/1/f/pmgr/...`: Created pairings 42 | * `/1/f/rmgr?create`: Command to create a new rule 43 | * `/1/f/rmgr/...`: Created rules 44 | * `/1/f/tmgr?create`: Command to create a new timer 45 | * `/1/f/tmgr/...`: Created timers 46 | * `/2/`: Fake light bulb. Supports transitions and scenes. 47 | * `/2/s/onof/v`: On/off. Observable, writable. 48 | * `/2/s/levl/v`: Light level. 0.0-1.0. Observable, writable. 49 | * `/3/`: System info. 50 | * `/3/s/syst/load`: 1-minute load average. Observable. 51 | * `/3/m/syst/ncpu`: Number of available CPUs. 52 | * `/3/m/syst/sysn`: Name of operating system. 53 | * `/3/m/syst/sysv`: Version of operating system. 54 | 55 | See the [automation introduction](../doc/automation.md) for more information 56 | on how to use automation primitives. 57 | -------------------------------------------------------------------------------- /smcp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /out 3 | /target 4 | -------------------------------------------------------------------------------- /smcp/src/main/java/com/google/iot/smcp/Smcp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.smcp; 17 | 18 | /** Contains SMCP-specific constants */ 19 | final class Smcp { 20 | 21 | private Smcp() {} 22 | 23 | /** Interface description for things (w/out version). */ 24 | public static final String IF_DESC_FE = "som.fe"; 25 | 26 | /** Interface description for properties. */ 27 | public static final String IF_DESC_PROP = "som.p"; 28 | 29 | /** Interface description for sections. */ 30 | public static final String IF_DESC_SECT = "som.s"; 31 | 32 | /** Interface description for groups container */ 33 | public static final String IF_DESC_GROUPS = "som.g"; 34 | 35 | /** Interface description for group thing */ 36 | public static final String IF_DESC_GROUP_FE = "som.g.fe"; 37 | 38 | /** Interface description for things (with version). */ 39 | public static final String IF_DESC_FE_FULL = IF_DESC_FE + "#r0"; 40 | 41 | /** Interface description prefix for trait profiles. */ 42 | public static final String IF_DESC_TP_PREFIX = "som.tp."; 43 | 44 | /** Resource type prefix for traits. */ 45 | public static final String RESOURCE_TYPE_PREFIX = "som.t."; 46 | 47 | /** URI path for thing discovery. */ 48 | public static final String DISCOVERY_QUERY_URI = "/.well-known/core?if=" + IF_DESC_FE + "*"; 49 | } 50 | -------------------------------------------------------------------------------- /smcp/src/main/java/com/google/iot/smcp/SmcpException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.smcp; 17 | 18 | import com.google.iot.m2m.base.TechnologyException; 19 | 20 | /** Checked {@link TechnologyException} specifically for SMCP issues. */ 21 | @SuppressWarnings("unused") 22 | public class SmcpException extends TechnologyException { 23 | public SmcpException() {} 24 | 25 | public SmcpException(String reason) { 26 | super(reason); 27 | } 28 | 29 | public SmcpException(String reason, Throwable t) { 30 | super(reason, t); 31 | } 32 | 33 | public SmcpException(Throwable t) { 34 | super(t); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /smcp/src/main/java/com/google/iot/smcp/SmcpRemoteException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.smcp; 17 | 18 | /** 19 | * Checked exception for problems that likely originate with other devices. This class of exceptions 20 | * would include things like parser errors or reported internal server errors. 21 | */ 22 | @SuppressWarnings("unused") 23 | public class SmcpRemoteException extends SmcpException { 24 | public SmcpRemoteException() {} 25 | 26 | public SmcpRemoteException(String reason) { 27 | super(reason); 28 | } 29 | 30 | public SmcpRemoteException(String reason, Throwable t) { 31 | super(reason, t); 32 | } 33 | 34 | public SmcpRemoteException(Throwable t) { 35 | super(t); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /smcp/src/main/java/com/google/iot/smcp/SmcpRuntimeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.smcp; 17 | 18 | import com.google.iot.m2m.base.TechnologyRuntimeException; 19 | 20 | /** Unhecked {@link TechnologyRuntimeException} specifically for SMCP issues. */ 21 | @SuppressWarnings("unused") 22 | public class SmcpRuntimeException extends TechnologyRuntimeException { 23 | public SmcpRuntimeException() {} 24 | 25 | public SmcpRuntimeException(String reason) { 26 | super(reason); 27 | } 28 | 29 | public SmcpRuntimeException(String reason, Throwable t) { 30 | super(reason, t); 31 | } 32 | 33 | public SmcpRuntimeException(Throwable t) { 34 | super(t); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /smcp/src/main/java/com/google/iot/smcp/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /** 17 | * An experimental implementation of a simple monitoring and control protocol written in Java. 18 | * 19 | *

Uses Splot for Java for the API and object 20 | * model, CoapBlaster for the CoAP stack, and CborTree for CBOR encoding/decoding. 22 | */ 23 | @ParametersAreNonnullByDefault 24 | @CheckReturnValue 25 | package com.google.iot.smcp; 26 | 27 | import com.google.errorprone.annotations.CheckReturnValue; 28 | import javax.annotation.ParametersAreNonnullByDefault; 29 | -------------------------------------------------------------------------------- /smcp/src/test/java/com/google/iot/smcp/FakeExecutorTestBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.smcp; 17 | 18 | import java.util.concurrent.ScheduledExecutorService; 19 | import java.util.logging.Logger; 20 | 21 | @SuppressWarnings("ConstantConditions") 22 | class FakeExecutorTestBase extends ExecutorTestBase { 23 | private static final boolean DEBUG = false; 24 | private static final Logger LOGGER = 25 | Logger.getLogger(ExecutorTestBase.class.getCanonicalName()); 26 | 27 | public ScheduledExecutorService createNewScheduledExecutorService() { 28 | return new FakeScheduledExecutorService() { 29 | @Override 30 | public void execute(Runnable command) { 31 | super.execute( 32 | () -> { 33 | try { 34 | command.run(); 35 | } catch (Throwable x) { 36 | LOGGER.info("Caught throwable: " + x); 37 | x.printStackTrace(); 38 | mThrowable = x; 39 | } 40 | }); 41 | } 42 | }; 43 | } 44 | 45 | public long nanoTime() { 46 | return ((FakeScheduledExecutorService) mOriginalExecutor).nanoTime(); 47 | } 48 | 49 | public void tick(int durationInMs) throws Exception { 50 | if (DEBUG) LOGGER.info("tick(" + durationInMs + ") ENTER"); 51 | super.tick(1); 52 | ((FakeScheduledExecutorService) mOriginalExecutor).tick(durationInMs); 53 | super.tick(1); 54 | if (DEBUG) LOGGER.info("tick(" + durationInMs + ") EXIT"); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /splot-base/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /out 3 | /target 4 | -------------------------------------------------------------------------------- /splot-base/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.google.iot.m2m 7 | splot-parent 8 | HEAD-SNAPSHOT 9 | 10 | splot-base 11 | HEAD-SNAPSHOT 12 | Splot Object Model Base Library 13 | 14 | 15 | 16 | maven-surefire-plugin 17 | 2.22.0 18 | 19 | 20 | maven-compiler-plugin 21 | 3.8.0 22 | 23 | javac-with-errorprone 24 | true 25 | 26 | 27 | 28 | 29 | org.codehaus.plexus 30 | plexus-compiler-javac-errorprone 31 | 2.5 32 | 33 | 34 | 35 | com.google.errorprone 36 | error_prone_core 37 | 2.2.0 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | com.google.errorprone 46 | error_prone_annotations 47 | 2.2.0 48 | 49 | 50 | com.google.iot.cbor 51 | cbor 52 | 0.01.01 53 | compile 54 | 55 | 56 | com.google.guava 57 | guava 58 | 23.5-android 59 | 60 | 61 | org.checkerframework 62 | checker-qual 63 | 2.5.6 64 | compile 65 | 66 | 67 | org.mockito 68 | mockito-core 69 | 2.7.22 70 | test 71 | 72 | 73 | org.junit.jupiter 74 | junit-jupiter-api 75 | 5.3.1 76 | test 77 | 78 | 79 | org.junit.jupiter 80 | junit-jupiter-engine 81 | 5.3.1 82 | test 83 | 84 | 85 | 86 | 1.8 87 | 1.8 88 | UTF-8 89 | UTF-8 90 | 91 | 92 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/annotation/Method.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.annotation; 17 | 18 | import java.lang.annotation.ElementType; 19 | import java.lang.annotation.Retention; 20 | import java.lang.annotation.RetentionPolicy; 21 | import java.lang.annotation.Target; 22 | 23 | /** 24 | * Annotation describing the characteristics of a method in a trait. This annotation is 25 | * applied to all {@link com.google.iot.m2m.base.MethodKey} fields designated as {@code public 26 | * static final} in a trait class. The value of this annotation is a bit-mask describing the 27 | * characteristics of the method. 28 | * 29 | *

Example

30 | * 31 | *

32 |  *     @Method(REQUIRED | WANTS_GROUP_ID)
33 |  *     public static final MethodKey METHOD_SAVE =
34 |  *             new MethodKey<>(TRAIT_ID, "save", Thing.class);
35 |  * 
36 | * 37 | * @see Trait 38 | * @see Property 39 | */ 40 | @Target(ElementType.FIELD) 41 | @Retention(RetentionPolicy.CLASS) 42 | public @interface Method { 43 | /** Indicates that this method is required for this trait. */ 44 | int REQUIRED = 1; 45 | 46 | /** 47 | * Indicates that if this method is called through a group that the group id (with the argument 48 | * key "{@code gid}" should be automatically added to the arguments, unless that key is already 49 | * present. 50 | */ 51 | int WANTS_GROUP_ID = (1 << 1); 52 | 53 | int value() default 0; 54 | } 55 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/annotation/Trait.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.annotation; 17 | 18 | /** 19 | * Annotation used to identify trait definition classes, such as {@link 20 | * com.google.iot.m2m.trait.BaseTrait}. 21 | * 22 | * @see Property 23 | * @see Method 24 | */ 25 | public @interface Trait {} 26 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/annotation/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | /** 17 | * Splot trait annotations. 18 | * 19 | *

These annotations are used for marking up trait definition classes so that they can be 20 | * properly interpreted by the trait processor in {@link com.google.iot.m2m.processor}. 21 | */ 22 | @CheckReturnValue 23 | @ParametersAreNonnullByDefault 24 | package com.google.iot.m2m.annotation; 25 | 26 | import com.google.errorprone.annotations.CheckReturnValue; 27 | import javax.annotation.ParametersAreNonnullByDefault; 28 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/BadStateForPropertyValueException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | /** 19 | * Checked exception thrown after an attempt to set a property to a value that is not acceptable 20 | * for the current state of the thing. 21 | * 22 | * @see Thing#setProperty(PropertyKey, Object) 23 | * @see Thing#incrementProperty(PropertyKey, Number) 24 | * @see Thing#addValueToProperty(PropertyKey, Object) 25 | * @see Thing#removeValueFromProperty(PropertyKey, Object) 26 | */ 27 | public class BadStateForPropertyValueException extends PropertyException { 28 | @SuppressWarnings("unused") 29 | public BadStateForPropertyValueException() {} 30 | 31 | public BadStateForPropertyValueException(String reason) { 32 | super(reason); 33 | } 34 | 35 | public BadStateForPropertyValueException(String reason, Throwable t) { 36 | super(reason, t); 37 | } 38 | 39 | public BadStateForPropertyValueException(Throwable t) { 40 | super(t.getMessage() != null ? t.getMessage() : t.toString(), t); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/ChildListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | import java.util.concurrent.Executor; 19 | 20 | /** 21 | * Interface for handling changes to a {@link Thing}'s children. 22 | * 23 | * @see Thing#registerChildListener(Executor, ChildListener, String) 24 | * @see Thing#unregisterChildListener(ChildListener, String) 25 | */ 26 | public interface ChildListener { 27 | void onChildAdded(Thing parent, String traitShortName, Thing child); 28 | 29 | void onChildRemoved(Thing parent, String traitShortName, Thing child); 30 | } 31 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/CorruptPersistentStateException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | import java.io.File; 19 | 20 | /** 21 | * Checked exception for when the underlying persistent state data is corrupted. 22 | * 23 | * @see PersistentStateManager 24 | * @see com.google.iot.m2m.util.FilePersistentStateManager#create(File) 25 | */ 26 | @SuppressWarnings("unused") 27 | public class CorruptPersistentStateException extends Exception { 28 | public CorruptPersistentStateException() {} 29 | 30 | public CorruptPersistentStateException(String reason) { 31 | super(reason); 32 | } 33 | 34 | public CorruptPersistentStateException(String reason, Throwable t) { 35 | super(reason, t); 36 | } 37 | 38 | public CorruptPersistentStateException(Throwable t) { 39 | super(t); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/GroupNotAvailableException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | /** 19 | * Checked exception which is thrown if one of the group-management methods of {@link Group} are 20 | * called after the group has been deleted or otherwise no longer available. 21 | * 22 | * @see Group#fetchMembers() 23 | * @see Group#addMember(Thing) 24 | * @see Group#removeMember(Thing) 25 | */ 26 | public class GroupNotAvailableException extends TechnologyException { 27 | @SuppressWarnings("unused") 28 | public GroupNotAvailableException() {} 29 | 30 | @SuppressWarnings("unused") 31 | public GroupNotAvailableException(String reason) { 32 | super(reason); 33 | } 34 | 35 | @SuppressWarnings("unused") 36 | public GroupNotAvailableException(String reason, Throwable t) { 37 | super(reason, t); 38 | } 39 | 40 | @SuppressWarnings("unused") 41 | public GroupNotAvailableException(Throwable t) { 42 | super(t); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/GroupsNotSupportedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | /** 19 | * Checked exception indicating that this {@link Technology} does not support groups. 20 | * 21 | * @see Technology#createNewGroup() 22 | */ 23 | public class GroupsNotSupportedException extends TechnologyException { 24 | public GroupsNotSupportedException() {} 25 | 26 | @SuppressWarnings("unused") 27 | public GroupsNotSupportedException(String reason) { 28 | super(reason); 29 | } 30 | 31 | @SuppressWarnings("unused") 32 | public GroupsNotSupportedException(String reason, Throwable t) { 33 | super(reason, t); 34 | } 35 | 36 | @SuppressWarnings("unused") 37 | public GroupsNotSupportedException(Throwable t) { 38 | super(t); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/InvalidMethodArgumentsException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | import java.util.Map; 19 | 20 | /** 21 | * Checked exception thrown when the arguments to a Splot method are invalid. 22 | * 23 | * @see Thing#invokeMethod(MethodKey, Map) 24 | * @see Thing#invokeMethod(MethodKey) 25 | * @see Thing#invokeMethod(MethodKey, ParamKey, Object...) 26 | */ 27 | public class InvalidMethodArgumentsException extends MethodException { 28 | @SuppressWarnings("unused") 29 | public InvalidMethodArgumentsException() {} 30 | 31 | public InvalidMethodArgumentsException(String reason) { 32 | super(reason); 33 | } 34 | 35 | @SuppressWarnings("unused") 36 | public InvalidMethodArgumentsException(String reason, Throwable t) { 37 | super(reason, t); 38 | } 39 | 40 | @SuppressWarnings("unused") 41 | public InvalidMethodArgumentsException(Throwable t) { 42 | super(t); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/InvalidModifierListException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | public class InvalidModifierListException extends TechnologyRuntimeException { 19 | @SuppressWarnings("unused") 20 | public InvalidModifierListException() {} 21 | 22 | @SuppressWarnings("unused") 23 | public InvalidModifierListException(String reason) { 24 | super(reason); 25 | } 26 | 27 | @SuppressWarnings("unused") 28 | public InvalidModifierListException(String reason, Throwable t) { 29 | super(reason, t); 30 | } 31 | 32 | @SuppressWarnings("unused") 33 | public InvalidModifierListException(Throwable t) { 34 | super(t); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/InvalidPropertyValueException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | /** 19 | * Checked exception thrown after an attempt to set a property to an invalid value. The value may 20 | * either be of the wrong type or it may be that the value it contains is out of range or in the 21 | * incorrect format. 22 | * 23 | * @see Thing#setProperty(PropertyKey, Object) 24 | * @see Thing#incrementProperty(PropertyKey, Number) 25 | * @see Thing#addValueToProperty(PropertyKey, Object) 26 | * @see Thing#removeValueFromProperty(PropertyKey, Object) 27 | */ 28 | public class InvalidPropertyValueException extends PropertyException { 29 | @SuppressWarnings("unused") 30 | public InvalidPropertyValueException() {} 31 | 32 | public InvalidPropertyValueException(String reason) { 33 | super(reason); 34 | } 35 | 36 | public InvalidPropertyValueException(String reason, Throwable t) { 37 | super(reason, t); 38 | } 39 | 40 | public InvalidPropertyValueException(Throwable t) { 41 | super(t); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/InvalidSectionException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | import java.util.Map; 19 | 20 | public class InvalidSectionException extends TechnologyException { 21 | public InvalidSectionException() {} 22 | 23 | public InvalidSectionException(String reason) { 24 | super(reason); 25 | } 26 | 27 | public InvalidSectionException(String reason, Throwable t) { 28 | super(reason, t); 29 | } 30 | 31 | public InvalidSectionException(Throwable t) { 32 | super(t); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/InvalidValueException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | import java.util.Map; 19 | 20 | /** 21 | * A checked exception specific to {@link TypedKey} that indicates that a cast or coercion has 22 | * failed. 23 | * 24 | * @see TypedKey#coerce(Object) 25 | * @see TypedKey#coerceFromMap(Map) 26 | * @see TypedKey#getFromMap(Map) 27 | */ 28 | public class InvalidValueException extends Exception { 29 | public InvalidValueException() {} 30 | 31 | public InvalidValueException(String reason) { 32 | super(reason); 33 | } 34 | 35 | public InvalidValueException(String reason, Throwable t) { 36 | super(reason, t); 37 | } 38 | 39 | public InvalidValueException(Throwable t) { 40 | super(t); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/MethodException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | /** 19 | * Checked exception indicating problems and errors related to invoking methods. 20 | * 21 | * @see MethodNotFoundException 22 | * @see InvalidMethodArgumentsException 23 | */ 24 | public class MethodException extends Exception { 25 | public MethodException() {} 26 | 27 | public MethodException(String reason) { 28 | super(reason); 29 | } 30 | 31 | public MethodException(String reason, Throwable t) { 32 | super(reason, t); 33 | } 34 | 35 | public MethodException(Throwable t) { 36 | super(t); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/MethodKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | import com.google.common.base.Preconditions; 19 | 20 | /** 21 | * A generic class for identifying and facilitating return-type-safety for methods. 22 | * 23 | * @see com.google.iot.m2m.annotation.Method 24 | */ 25 | public final class MethodKey extends TypedKey { 26 | 27 | private final String mName; 28 | 29 | /** 30 | * Constructs a method key object. 31 | * 32 | * @param fullName the name of the property, in the form {@code 33 | * f/<TRAIT-SHORT-ID>?<METHOD-NAME>}. 34 | * @param type the class for the value that will be associated with this property. 35 | */ 36 | private MethodKey(String fullName, Class type) { 37 | super(type); 38 | Preconditions.checkNotNull(fullName, "fullName cannot be null"); 39 | Preconditions.checkNotNull(type, "type cannot be null"); 40 | 41 | mName = fullName; 42 | } 43 | 44 | /** 45 | * Preferred constructor for MethodKey objects. 46 | * 47 | * @param trait the short name of the trait that owns this method 48 | * @param shortName the short name of the method 49 | * @param type the class for the value that will be associated with this property. 50 | */ 51 | public MethodKey(String trait, String shortName, Class type) { 52 | this(Splot.SECTION_FUNC + "/" + trait + "?" + shortName, type); 53 | } 54 | 55 | /** 56 | * Returns the full name of this property, in the form {@code 57 | * f/<TRAIT-SHORT-ID>?<METHOD-NAME>}. 58 | */ 59 | public final String getName() { 60 | return mName; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/MethodNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | import java.util.Map; 19 | 20 | /** 21 | * Checked exception that indicates that a given method could not be found on this {@link 22 | * Thing}. 23 | * 24 | * @see Thing#invokeMethod(MethodKey, Map) 25 | * @see Thing#invokeMethod(MethodKey) 26 | * @see Thing#invokeMethod(MethodKey, ParamKey, Object...) 27 | */ 28 | public class MethodNotFoundException extends MethodException { 29 | public MethodNotFoundException() {} 30 | 31 | public MethodNotFoundException(String reason) { 32 | super(reason); 33 | } 34 | 35 | @SuppressWarnings("unused") 36 | public MethodNotFoundException(String reason, Throwable t) { 37 | super(reason, t); 38 | } 39 | 40 | @SuppressWarnings("unused") 41 | public MethodNotFoundException(Throwable t) { 42 | super(t); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/Operation.java: -------------------------------------------------------------------------------- 1 | package com.google.iot.m2m.base; 2 | 3 | import org.checkerframework.checker.nullness.qual.Nullable; 4 | 5 | /** 6 | * Enum for specifying the operator acting on a property. 7 | */ 8 | public enum Operation { 9 | UNSPECIFIED(""), 10 | INCREMENT(Splot.PROP_METHOD_INCREMENT), 11 | TOGGLE(Splot.PROP_METHOD_TOGGLE), 12 | INSERT(Splot.PROP_METHOD_INSERT), 13 | REMOVE(Splot.PROP_METHOD_REMOVE); 14 | 15 | public final String id; 16 | 17 | Operation(String id) { 18 | this.id = id; 19 | } 20 | 21 | public static Operation fromId(String id) { 22 | switch (id) { 23 | case Splot.PROP_METHOD_INCREMENT: 24 | return INCREMENT; 25 | case Splot.PROP_METHOD_TOGGLE: 26 | return TOGGLE; 27 | case Splot.PROP_METHOD_INSERT: 28 | return INSERT; 29 | case Splot.PROP_METHOD_REMOVE: 30 | return REMOVE; 31 | default: 32 | return UNSPECIFIED; 33 | } 34 | } 35 | 36 | /** 37 | * Extracts the {@link Operation} from a URI query string 38 | * @param query The URI query string. May be null 39 | * @return The contained {@link Operation} 40 | */ 41 | public static Operation fromQuery(@Nullable String query) { 42 | if (query == null || "".equals(query)) { 43 | return UNSPECIFIED; 44 | } 45 | 46 | String[] queryComponents = query.split("[&;]"); 47 | 48 | for (String component : queryComponents) { 49 | Operation op = fromId(component); 50 | 51 | if (op.equals(UNSPECIFIED)) { 52 | continue; 53 | } 54 | 55 | return op; 56 | } 57 | 58 | return UNSPECIFIED; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/ParamKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | import com.google.common.base.Preconditions; 19 | 20 | /** A generic class for identifying and facilitating improved type-safety for method parameters. */ 21 | public final class ParamKey extends TypedKey { 22 | private final String mName; 23 | 24 | /** 25 | * Constructs a parameter key object. 26 | * 27 | * @param name the name of the parameter 28 | * @param type the class for the value that will be associated with this parameter 29 | */ 30 | public ParamKey(String name, Class type) { 31 | super(type); 32 | Preconditions.checkNotNull(name, "name cannot be null"); 33 | Preconditions.checkNotNull(type, "type cannot be null"); 34 | 35 | mName = name; 36 | } 37 | 38 | /** Returns the name of this parameter. */ 39 | public final String getName() { 40 | return mName; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /splot-base/src/main/java/com/google/iot/m2m/base/PersistentStateInterface.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.google.iot.m2m.base; 17 | 18 | import java.util.Map; 19 | import org.checkerframework.checker.nullness.qual.Nullable; 20 | 21 | /** 22 | * Interface for enabling the persistent storage of information related to an object. Intended to be 23 | * used in conjunction with a @{link PersistentStateManager}. 24 | * 25 | * @see PersistentStateManager 26 | */ 27 | public interface PersistentStateInterface { 28 | 29 | /** 30 | * Retrieves a copy of the state for the instance that should be saved to nonvolatile storage. 31 | * When reconstructing the associated instance, call {@link #initWithPersistentState} to restore 32 | * this state. 33 | * 34 | *

The data contained in the returned Map should be considered opaque unless specified 35 | * otherwise by the implementing technology. 36 | * 37 | *

The types for the values contained in the map are only guaranteed to be faithfully 38 | * restoreable if they are one of the following types: 39 | * 40 | *