From ba077b13c1981432ba7fc0e4ded44992ff09ece4 Mon Sep 17 00:00:00 2001 From: Trevor Date: Tue, 30 Aug 2022 08:27:12 -0700 Subject: [PATCH] Onboarding discovery mapping flow (#365) --- .gencode_hash.txt | 47 +- _includes/head-custom.html | 10 + bin/pull_message | 13 +- .../java/com/google/udmi/util/SiteModel.java | 85 +- docs/specs/categories.md | 3 + docs/specs/onboarding.md | 150 +- docs/tools/gcloud.md | 4 +- gencode/docs/command_mapping.html | 1794 +++++++++++++ gencode/docs/config.html | 4 +- gencode/docs/config_mapping.html | 2208 ++++++++++++++++ gencode/docs/envelope.html | 2 +- gencode/docs/event_discovery.html | 128 +- gencode/docs/event_mapping.html | 1794 +++++++++++++ gencode/docs/event_system.html | 64 +- gencode/docs/event_validation.html | 121 +- gencode/docs/index.html | 2 +- gencode/docs/state.html | 511 +++- gencode/docs/state_mapping.html | 2352 +++++++++++++++++ gencode/docs/state_pointset.html | 128 +- gencode/docs/state_validation.html | 128 +- gencode/java/udmi/schema/BuildingConfig.java | 90 + .../schema/BuildingConfigTranslation.java | 59 + gencode/java/udmi/schema/Category.java | 5 + .../java/udmi/schema/DeviceMappingConfig.java | 80 + .../java/udmi/schema/DeviceMappingState.java | 107 + gencode/java/udmi/schema/Envelope.java | 2 +- .../udmi/schema/FamilyDiscoveryConfig.java | 1 + gencode/java/udmi/schema/MappingConfig.java | 71 + gencode/java/udmi/schema/MappingState.java | 71 + gencode/python/udmi/schema/__init__.py | 11 +- gencode/python/udmi/schema/building_config.py | 56 + .../schema/building_config_translation.py | 46 + gencode/python/udmi/schema/category.py | 6 +- gencode/python/udmi/schema/command_mapping.py | 35 + gencode/python/udmi/schema/config_mapping.py | 47 + .../udmi/schema/config_mapping_device.py | 51 + gencode/python/udmi/schema/event_mapping.py | 20 +- gencode/python/udmi/schema/state_mapping.py | 47 + .../udmi/schema/state_mapping_device.py | 63 + pubber/bin/build | 2 +- .../main/java/daq/pubber/MqttPublisher.java | 47 +- pubber/src/main/java/daq/pubber/Pubber.java | 12 +- schema/building_config.json | 36 + schema/building_config_translation.json | 17 + schema/category.json | 1 + schema/command_mapping.json | 8 + schema/config_discovery_family.json | 5 +- schema/config_mapping.json | 29 + schema/config_mapping_device.json | 26 + schema/envelope.json | 2 +- schema/event_mapping.json | 24 +- schema/state_mapping.json | 29 + schema/state_mapping_device.json | 41 + tests/command_mapping.tests/mapping.json | 31 + tests/command_mapping.tests/mapping.out | 0 tests/config.tests/continuous.json | 1 + tests/config_mapping.tests/mapping.json | 31 + tests/config_mapping.tests/mapping.out | 0 tests/event_mapping.tests/mapping.json | 31 + tests/event_mapping.tests/mapping.out | 0 tests/event_mapping.tests/prediction.json | 13 + tests/event_mapping.tests/prediction.out | 2 + .../staged_equip_response.txt | 52 + tests/event_system.tests/errors.out | 2 +- tests/state_mapping.tests/mapping.json | 31 + tests/state_mapping.tests/mapping.out | 0 validator/.idea/misc.xml | 1 + .../.idea/runConfigurations/IotCoreProxy.xml | 2 +- .../.idea/runConfigurations/MappingAgent.xml | 17 + .../.idea/runConfigurations/MappingEngine.xml | 17 + validator/bin/mapping | 41 + validator/build.gradle | 3 +- .../bos/iot/core/proxy/IotCoreProxy.java | 13 +- .../iot/core/proxy/IotReflectorClient.java | 1 + .../bos/iot/core/proxy/MqttPublisher.java | 9 +- .../bos/iot/core/proxy/NullPublisher.java | 1 + .../bos/iot/core/proxy/ProxyTarget.java | 1 + .../bos/iot/core/proxy/PubSubClient.java | 119 - .../google/daq/mqtt/mapping/MappingAgent.java | 68 + .../google/daq/mqtt/mapping/MappingBase.java | 84 + .../daq/mqtt/mapping/MappingEngine.java | 42 + .../google/daq/mqtt/registrar/Registrar.java | 20 +- .../daq/mqtt/registrar/RegistrarTest.java | 21 +- .../daq/mqtt/sequencer/SequenceRunner.java | 34 +- .../google/daq/mqtt/util/CloudIotConfig.java | 1 + .../google/daq/mqtt/util/CloudIotManager.java | 29 +- .../java/com/google/daq/mqtt/util/Common.java | 5 + .../daq/mqtt/util/ConfigDiffEngine.java | 35 - .../com/google/daq/mqtt/util/ConfigUtil.java | 1 - .../google/daq/mqtt/util/FileDataSink.java | 1 - .../com/google/daq/mqtt/util/JsonUtil.java | 38 +- .../google/daq/mqtt/util/MessageHandler.java | 37 + .../mqtt/util}/MessagePublisher.java | 5 +- .../java/com/google/daq/mqtt/util/Pair.java | 18 + .../google/daq/mqtt/util/PubSubClient.java | 151 +- .../mqtt/validator/MessageReadingClient.java | 2 +- .../google/daq/mqtt/validator/Validator.java | 13 +- validator/validator.iml | 3 + 98 files changed, 11174 insertions(+), 548 deletions(-) create mode 100644 _includes/head-custom.html create mode 100644 gencode/docs/command_mapping.html create mode 100644 gencode/docs/config_mapping.html create mode 100644 gencode/docs/event_mapping.html create mode 100644 gencode/docs/state_mapping.html create mode 100644 gencode/java/udmi/schema/BuildingConfig.java create mode 100644 gencode/java/udmi/schema/BuildingConfigTranslation.java create mode 100644 gencode/java/udmi/schema/DeviceMappingConfig.java create mode 100644 gencode/java/udmi/schema/DeviceMappingState.java create mode 100644 gencode/java/udmi/schema/MappingConfig.java create mode 100644 gencode/java/udmi/schema/MappingState.java create mode 100644 gencode/python/udmi/schema/building_config.py create mode 100644 gencode/python/udmi/schema/building_config_translation.py create mode 100644 gencode/python/udmi/schema/command_mapping.py create mode 100644 gencode/python/udmi/schema/config_mapping.py create mode 100644 gencode/python/udmi/schema/config_mapping_device.py create mode 100644 gencode/python/udmi/schema/state_mapping.py create mode 100644 gencode/python/udmi/schema/state_mapping_device.py create mode 100644 schema/building_config.json create mode 100644 schema/building_config_translation.json create mode 100644 schema/command_mapping.json create mode 100644 schema/config_mapping.json create mode 100644 schema/config_mapping_device.json create mode 100644 schema/state_mapping.json create mode 100644 schema/state_mapping_device.json create mode 100644 tests/command_mapping.tests/mapping.json create mode 100644 tests/command_mapping.tests/mapping.out create mode 100644 tests/config_mapping.tests/mapping.json create mode 100644 tests/config_mapping.tests/mapping.out create mode 100644 tests/event_mapping.tests/mapping.json create mode 100644 tests/event_mapping.tests/mapping.out create mode 100644 tests/event_mapping.tests/prediction.json create mode 100644 tests/event_mapping.tests/prediction.out create mode 100644 tests/event_mapping.tests/staged_equip_response.txt create mode 100644 tests/state_mapping.tests/mapping.json create mode 100644 tests/state_mapping.tests/mapping.out create mode 100644 validator/.idea/runConfigurations/MappingAgent.xml create mode 100644 validator/.idea/runConfigurations/MappingEngine.xml create mode 100755 validator/bin/mapping delete mode 100644 validator/src/main/java/com/google/bos/iot/core/proxy/PubSubClient.java create mode 100644 validator/src/main/java/com/google/daq/mqtt/mapping/MappingAgent.java create mode 100644 validator/src/main/java/com/google/daq/mqtt/mapping/MappingBase.java create mode 100644 validator/src/main/java/com/google/daq/mqtt/mapping/MappingEngine.java create mode 100644 validator/src/main/java/com/google/daq/mqtt/util/MessageHandler.java rename validator/src/main/java/com/google/{bos/iot/core/proxy => daq/mqtt/util}/MessagePublisher.java (77%) create mode 100644 validator/src/main/java/com/google/daq/mqtt/util/Pair.java diff --git a/.gencode_hash.txt b/.gencode_hash.txt index 31dd4c35f6..cfc856474d 100644 --- a/.gencode_hash.txt +++ b/.gencode_hash.txt @@ -1,32 +1,40 @@ 52e5e736587cb4d9615b5b48dda53d385fb4c7091864e5d7ebaf804a46519852 gencode/docs/cloud_iot_config.html 36842bbf9d023a83a3e8958fc3ae607424f4ada5b1e72be35fe2ac443cfd31cc gencode/docs/command_discovery.html -a9cf25fa459ab0122be8df276ab4d95c6b1f2ed2256e1cf202f18c178e6906c0 gencode/docs/config.html +4f5f58997cc9f95ce7f7c251db954fad3e38f5579ce943922d3911d0e55cd57a gencode/docs/command_mapping.html +d755727827955c38c6679869a4e9177e44a83770a1c6a046f953954792a6d4a4 gencode/docs/config.html +6cffb39b5071680f39a7b96bdeb8330b6a8f5fa71ed4c4d42b82d7896080dcd9 gencode/docs/config_mapping.html 62a5f579661625c0fa53320557be47711e289566b14bd0399b45395cea87ae27 gencode/docs/config_pointset.html 34e05b6966c611afd4591bdb2f1a606123326c922b0747a3b0861383d68c1177 gencode/docs/configuration_endpoint.html -90679d3d866579501e7aa00b515af05d42fc9fe399eafacaacf297d1e4a22884 gencode/docs/envelope.html -c17060843155c5605e02572a28a02c2c8272028a9874d754894a34d69ee4916f gencode/docs/event_discovery.html +01ee911c3d85ce9d5de98a77d15a78e7719bc151efdf5149082c8056b7a60bc1 gencode/docs/envelope.html +b8972d7b07d1dc6bdb82988e1e9955603a80477cac18e7745ecbd7fe78c104ba gencode/docs/event_discovery.html +71c21b380bec6723e62f9f0c44b085a5d7c49f29a3f04d01cd93bed64061169e gencode/docs/event_mapping.html 8133e380e40f27c56accbffc665b2eeb56ec84a4da3b52ba7aa5e439c9c40572 gencode/docs/event_pointset.html -095f4d562634f91fa895ae7d8b5b2faf02d4100af39c19d7527dec78566bc019 gencode/docs/event_system.html -aaf67e935fd0c99f6e4d108733e1e184c84c0c55aa03fbfd1ba31ecc9c9f0d95 gencode/docs/event_validation.html -f09d46f93fcfe0ef2ecf981bab3f9a4981da6327fb4a3b35bf12b82db2f07e56 gencode/docs/index.html +ac05c443556b92de96ec1867e72c668da27bc53012fe5821a8035a81ed46aaaf gencode/docs/event_system.html +51cc24f8ebe5daa9f165ec401cf4745994823037ba6a0753730339ef81a57fa6 gencode/docs/event_validation.html +469909f7061efeaed0942e3aad43468e56dbeb335c664412c976d9f1e4bc44c9 gencode/docs/index.html 6d5081d04c86f8bd444efb41cd788826aa66802d37e8f98e93b6b75425542d5e gencode/docs/metadata.html a5263284652e52822c82a863fc27db765eb55861f96316f07836619376323bce gencode/docs/model_pointset.html 741b880216be3743f6747800a042f2dbd89f3b0344c6b0a965f4bc010f03a930 gencode/docs/schema_doc.css 878ea88206c974f40643c3cc430875f9c4e8c5e3fd6bcd6358bd3eb6d48699a9 gencode/docs/schema_doc.min.js 7ed934930aee763e0beebc349725ba3909115e8d346bb762f28bcbe745bb163a gencode/docs/schema_extras.js -d1cf0d9d652d7004ec60cb67fbee92dcc0b3529affafd6543ae93e8ee428cd8e gencode/docs/state.html -01e2b72dd4f3599bffc589a97c328a7069a6716a3271fde3eeacdd8cfc2e7d03 gencode/docs/state_pointset.html -f4fca4557ef479f363644fe0603fddc943f6de4f1908b3cc5e2bb8d7c79f66c7 gencode/docs/state_validation.html +7dab133dd7e23d2b61b325516a274be5007ae9fc739ced3d244bb05ba0dac648 gencode/docs/state.html +053656d21797603350e92d836e8d6cdcab6733e8c20d2ae47db5cc14bc3a61e5 gencode/docs/state_mapping.html +b0c4bf203dd8ea482d0d6b7ec9549bd8ddf597faf7afdc410351e527f4cc68b1 gencode/docs/state_pointset.html +f680b255d4b185cc96347a2c6425bb33c847cf7468d309c33aa7901567cd02b7 gencode/docs/state_validation.html d39d7fe37a41c74a40080af7b0a429d201ab1fdff7444428c4b98eb7b38c332b gencode/java/udmi/schema/Asset.java 0825a5cec83003bb0a6488c4ed7010a04ae0d3848ef36fe01bb4e6718ba7b96d gencode/java/udmi/schema/Aux.java 1f2757c67215cf657297a009a01288108a04daeea919713871a2d34ea903b5f9 gencode/java/udmi/schema/BlobBlobsetConfig.java a7c57d119adcd0cf6363cc5301ce562004222522242e8ffd1d0cd7010f235ae1 gencode/java/udmi/schema/BlobBlobsetState.java b9f903444ab08907e41eb123286434ff3207b1edd01397af3ddefb8475bbdadc gencode/java/udmi/schema/BlobsetConfig.java fcbed49f1af8b791d8c52bcbe18f65521a79d9ac3eb33ec3afd9b342ab2bfc56 gencode/java/udmi/schema/BlobsetState.java -c13c6cf8a5712fbfe8e4b10f19c1e74f1a09f13e1a0a4c8458469d5d46cb0735 gencode/java/udmi/schema/Category.java +3e5f6f89b08a1174b5786eb20fc781b36c81db6ce999b970744a0f9644c6d3a5 gencode/java/udmi/schema/BuildingConfig.java +ae7a42eadbd26d66d4d168ac090b933598c90b126346c0a72f6b82705c6324ce gencode/java/udmi/schema/BuildingConfigTranslation.java +5655b896f000b0108f438f9b04bfc092764ad5af63b70bbf750ba58b5f5527fa gencode/java/udmi/schema/Category.java d6875f63ce67d1b945a0b75a4a660bd083cc52492371a7350c4109f6bf54968b gencode/java/udmi/schema/CloudIotConfig.java a2eeff86f4302272736d84602e2ca36a64d27c8ef6761cc05ffb8ad17b030d4d gencode/java/udmi/schema/CloudModel.java ff79de9390aa25bb45fb3e2ebb682c865ccab764f56d9644377d9d28c0ab10e4 gencode/java/udmi/schema/Config.java +10d67bf2080403fd196f63097e4ce2151edaafe3cf4ac77598ef83e06f94cb05 gencode/java/udmi/schema/DeviceMappingConfig.java +5ffb3bf92436c469eee16fe1e472efc89d1c466785be6ce30148188439314afe gencode/java/udmi/schema/DeviceMappingState.java d4a82e132b2d223c4a82384d22455283c0b64aba3100fc210e72f9700b9df2d0 gencode/java/udmi/schema/DeviceValidationEvent.java 587d67a67431349939dffd37b880c44e798a1eb607d54bd6d8a077bbac668067 gencode/java/udmi/schema/DiscoveryCommand.java d8a80ab3180d33bfa17564c969018e1d4350a47dbc70c4ae8a5abbfb25cfedc9 gencode/java/udmi/schema/DiscoveryConfig.java @@ -35,9 +43,9 @@ d8a80ab3180d33bfa17564c969018e1d4350a47dbc70c4ae8a5abbfb25cfedc9 gencode/java/u 9962b0eb7d5adf52af6160e9f3131f8eeb52ae9e518954dbb6aead1bcad0245e gencode/java/udmi/schema/DiscoveryState.java f9faaa8622aa289c878cf2b9bcc05ac0c90ec5b40b39a607f5b7981fac0086fc gencode/java/udmi/schema/EndpointConfiguration.java 885859ea9de29217186c34f3a90b112411d1beddaf58a88b85e7934cd3c92b6f gencode/java/udmi/schema/Entry.java -cd362f94454eba8fd5ce3fce5d5e2b5f046d0dd9c35b01de69ef4d2e38413cc5 gencode/java/udmi/schema/Envelope.java +9b92e03774ed0b9159ff3ab462822699ef7f824161b166a881889ea1eb6a62ad gencode/java/udmi/schema/Envelope.java e9f5c77be81486b6b8c6d88f70f2d50583d8c3fafa2ac09ead80f44b8d5e751e gencode/java/udmi/schema/Event.java -aa0885ca43ab38c7597eacc38b7c512940a1a9fa061abd47d02c28e66b6fd93e gencode/java/udmi/schema/FamilyDiscoveryConfig.java +2e77a29988e6c17875d3f781be931e3b835bb310639f60d3bb28f24405a86bed gencode/java/udmi/schema/FamilyDiscoveryConfig.java ae4a645f199c8e24b3303463d428ca17af7603ae9ae9238397a6a82e752ab454 gencode/java/udmi/schema/FamilyDiscoveryEvent.java 0afc15acd72874e5a0c47f546abc0c4569f5bc37838fdcac77bc7bd55cc53a6d gencode/java/udmi/schema/FamilyDiscoveryState.java 9959a84eea3e549c142c3edf637c86eb56eca138108ebd51fc2985e45aa41484 gencode/java/udmi/schema/FamilyDiscoveryTestingModel.java @@ -49,6 +57,8 @@ a5e5adfc187709e8646a11c92e804acfb67743f9d72149008aaca954df3177f6 gencode/java/u 07fd4911363437b274c19b024759b04b116152176702da8d4203c4ff4cb55b7f gencode/java/udmi/schema/LocalnetConfig.java 910c68183db7703b00bcb81146ad73e6fe0d4bbc4caec4dc9c621f3cc2e5eee5 gencode/java/udmi/schema/LocalnetModel.java 2df4ae32d0bbecc21f7c3f6a416a195baa766a6210cfa8abca4a7bb45b9c7961 gencode/java/udmi/schema/Location.java +0f6f85a4aaffb90735acc2565e8e4afa349d3ded5781cb1dce1ebbaa237feaa7 gencode/java/udmi/schema/MappingConfig.java +d2bf4eea0ca3df47b9ffe31481a52170e2d2bc3a0e7f2eab582e93cc20ccc886 gencode/java/udmi/schema/MappingState.java 304164da05dc722b6e94cfa68659f0120e2425c94bfb5f5a4c6d796fe13da885 gencode/java/udmi/schema/Metadata.java a4e8f69100ab678a8236f481c558d677bbaea3e76c853bbd9262113d2a9c031d gencode/java/udmi/schema/Metrics.java 5e1c5411fae4d7c47391ceb5d19ae864fcd484df75ac6b6db39fd2d12647dec8 gencode/java/udmi/schema/Physical_tag.java @@ -83,11 +93,14 @@ d3968b92497e83a63f18cc0e74484a9807f1bb92db0c92d556ec2caaa143d645 gencode/java/u ac6f8fd87c8986cce01e872460c15ff6fe71e3816f9bde610acfe25f7d38c8d4 gencode/java/udmi/schema/ValidationEvent.java f7d117dc8b9764acf0c95a13a2bfdfbdf31d1a8ec83a707448aa4d7391ef07e2 gencode/java/udmi/schema/ValidationState.java e007ddd1ceeae3603c85110c33e1bb4a418ff9c7a791ca0df25b7ea3caeafd36 gencode/java/udmi/schema/ValidationSummary.java -8db92d02ed31738ac46969a7a24dbd23d330f7855afced2a84abd9e8f44fdcc2 gencode/python/udmi/schema/__init__.py +f5f6434d1c2ba0bcbff080c6d180b3c410bbf8b25a72b3f670d3fffc2304de43 gencode/python/udmi/schema/__init__.py 4b25dd95f863059b761269f93adcae7049507924a1c6e74d6856849203c179db gencode/python/udmi/schema/ancillary_properties.py -8783e8235fb51ae3d13b241967219c6d4160627b8d62f7bfe7f0658b2a9bdcb5 gencode/python/udmi/schema/category.py +ffca96a15730668a1af22e79800a4f25e689cb801bacce0a3f9c2951dd03653c gencode/python/udmi/schema/building_config.py +1049bf13a56024a84c3ab0c64bf96fa65dd63bf64007fda23601e19ec2046d56 gencode/python/udmi/schema/building_config_translation.py +d4269e665695f7a431108233a427313e609764f421d7657a23bd68d046f11e83 gencode/python/udmi/schema/category.py a61b1c5732f01b7efda41a773d5786fad755f371193ce4478b458387ca2a8fe8 gencode/python/udmi/schema/cloud_iot_config.py 6578d68f65b87b781086e72566de910db4bef365599fe3188862d4d8a81e84fb gencode/python/udmi/schema/command_discovery.py +6da1039b08d3b502efa5f483f9e29d7fbdf4482c9b79fa484ff99df01946c6ba gencode/python/udmi/schema/command_mapping.py c5a62f92328e2ede167fc1f53bece6e48696a0ab0e37e3a41f65cd98494ba0d7 gencode/python/udmi/schema/common.py b975892df78076dabc797b4c0be87f20b33eacda11f9d1ac1c09be33d4937a87 gencode/python/udmi/schema/config.py 79eb0299b3751d93c01a5de65eacc717283e99caf0996f3db48a15247f69c8eb gencode/python/udmi/schema/config_blobset.py @@ -96,6 +109,8 @@ ec6c6ab1fb0f37a29b7ebd162aa77da7f1e261e80da376942a3b39d17ccf1be4 gencode/python a5edb9ac5ecd5a4459f93ce613691735f299f35718f2e35410206fc91c263dd1 gencode/python/udmi/schema/config_discovery_family.py b461bdc24310ef972faf579b5be577b5af67fb0977d6afb4c42955211b26e3d5 gencode/python/udmi/schema/config_gateway.py 8b2bf3e753c09e375f0fd59dcf1f0be61205ed247160b7a8718cb3b9ebef2c30 gencode/python/udmi/schema/config_localnet.py +ac3facbd96f7cb2f7e387e7497d6a36af379a2687329571f250c5670f9933244 gencode/python/udmi/schema/config_mapping.py +1867ee8f1f4552ff121b7a2a62815817b2c9939a8817f1e093fbd688b8faa1a4 gencode/python/udmi/schema/config_mapping_device.py 9eab64849e04b25203d5da47856c3f8dda2b96903e4dc43ab932ee35014700bd gencode/python/udmi/schema/config_pointset.py 607c5047df878a1333df3ce88dcce34668959b0b315f6954bf1a4963dcf7839e gencode/python/udmi/schema/config_pointset_point.py ba37d2d54df565aba42ef055a0ec961175d180c2e8092a914e62029bc5388857 gencode/python/udmi/schema/config_system.py @@ -107,7 +122,7 @@ ba37d2d54df565aba42ef055a0ec961175d180c2e8092a914e62029bc5388857 gencode/python 82182e3f569ad80dc0751027959c7db9135d10072fbe79f896d63a4cd2f4771f gencode/python/udmi/schema/event_discovery.py ad33b91a7fabb4eed7e49c30a983a2106c96330facbe0f376f94d06e2263d6d0 gencode/python/udmi/schema/event_discovery_family.py 42e6fb6edda2b6aeae5e5b48ae66f87a5daf336bca1e746b1157e8f1ce31d5d5 gencode/python/udmi/schema/event_discovery_point.py -abe4044d2e3be6693ed39edc8ccaed4eee4eb8acad991e820b21d6ecf3812dd9 gencode/python/udmi/schema/event_mapping.py +24e71ef8c175466cb91612bd2e4428511dbb27030638221ab8cb02c5ee9ea294 gencode/python/udmi/schema/event_mapping.py ddf849bfeb2b87d071cefd5e6feacabc57375a7fff6d72b6d42ffb89f33c859b gencode/python/udmi/schema/event_pointset.py 44aff1bc930dbdbadd51ac3fe0e7d9c83ad84a6a9f9d1c809b3fce66cbcd5e00 gencode/python/udmi/schema/event_pointset_point.py c3bf9959c821ccc8d0847a2e022e847ac3da8309dc6d35681af3d20148464ee4 gencode/python/udmi/schema/event_system.py @@ -135,6 +150,8 @@ a58f8c98e837a5b56126ca0f410e02f1e9cfcd80a8cb429e0ef522defab1f690 gencode/python 26443a1f6d0be3469ff93aa7fdb4e6682e0439a3b29a8e237998dcebec5f6901 gencode/python/udmi/schema/state_discovery.py 187400078dfc89912062ca1ad92f61e32d28126ae56119d83e6767d58cda1117 gencode/python/udmi/schema/state_discovery_family.py 05e82aa15c64842e206ae8ce3d5810d115bb890d009ea5d657822fad0e0d2165 gencode/python/udmi/schema/state_gateway.py +cb6a5558fe87dea5bce9e1cc6b22984a7d8c379babc4941c50df13edad36579a gencode/python/udmi/schema/state_mapping.py +f2a76b32a5568d87a8c9ca8b32dc8a129bc7386f9522c5399d32db433be4cb70 gencode/python/udmi/schema/state_mapping_device.py 3520ad936af70b414d9e7f90e606a011768bc4ee3bf1248714acc517ee9b393d gencode/python/udmi/schema/state_pointset.py 837ecc89c477abe3a1faf837733ca05475774891b55353d84ca231d90a1fbf31 gencode/python/udmi/schema/state_pointset_point.py 8184e783f3e2da5a6d3fb7e7fac105aaeb28106a7c146e82b610049554abf184 gencode/python/udmi/schema/state_system.py diff --git a/_includes/head-custom.html b/_includes/head-custom.html new file mode 100644 index 0000000000..567b51d031 --- /dev/null +++ b/_includes/head-custom.html @@ -0,0 +1,10 @@ + + diff --git a/bin/pull_message b/bin/pull_message index 414388fdb6..3237ff9d4e 100755 --- a/bin/pull_message +++ b/bin/pull_message @@ -1,6 +1,10 @@ #!/bin/bash -e +# +# For simple debugging, just run in a shell loop: +# while true; do bin/pull_message PROJECT_ID; done +# -subscription=validation-debug +subscription=$USER-debug out_file=/tmp/captured.json if [[ $# -ne 1 ]]; then @@ -13,12 +17,17 @@ shift gcloud --format=json --project=$project_id pubsub subscriptions pull $subscription --auto-ack > $out_file || true +subType=$(jq -r '.[0].message.attributes.subType' $out_file 2> /dev/null) subFolder=$(jq -r '.[0].message.attributes.subFolder' $out_file 2> /dev/null) deviceId=$(jq -r '.[0].message.attributes.deviceId' $out_file 2> /dev/null) timestamp=$(jq -r '.[0].message.data' $out_file 2>/dev/null | base64 --decode | jq -r .timestamp 2> /dev/null) || true +if [[ $subType == null ]]; then + subType=event +fi + if [[ $subFolder != null ]]; then - echo $subFolder $deviceId $timestamp + echo $subFolder $subType for $deviceId at $timestamp else echo No matching messages found. fi diff --git a/common/src/main/java/com/google/udmi/util/SiteModel.java b/common/src/main/java/com/google/udmi/util/SiteModel.java index a26858913e..1918dbb417 100644 --- a/common/src/main/java/com/google/udmi/util/SiteModel.java +++ b/common/src/main/java/com/google/udmi/util/SiteModel.java @@ -7,12 +7,13 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.util.ISO8601DateFormat; import com.google.common.base.Preconditions; -import daq.pubber.MqttPublisher; import java.io.File; import java.util.Arrays; import java.util.Map; import java.util.Set; import java.util.function.BiConsumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import udmi.schema.CloudIotConfig; import udmi.schema.CloudModel.Auth_type; @@ -23,30 +24,38 @@ public class SiteModel { + private static final String ID_FORMAT = "projects/%s/locations/%s/registries/%s/devices/%s"; private static final String KEY_SITE_PATH_FORMAT = "%s/devices/%s/%s_private.pkcs8"; private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() .enable(SerializationFeature.INDENT_OUTPUT) .setDateFormat(new ISO8601DateFormat()) .setSerializationInclusion(JsonInclude.Include.NON_NULL); private static final String DEFAULT_ENDPOINT_HOSTNAME = "mqtt.googleapis.com"; + private static final Pattern ID_PATTERN = Pattern.compile( + "projects/(.*)/locations/(.*)/registries/(.*)/devices/(.*)"); final String sitePath; private Map allMetadata; - private EndpointConfiguration endpointConfig; + private CloudIotConfig cloudIotConfig; public SiteModel(String sitePath) { this.sitePath = sitePath; } - public static EndpointConfiguration extractEndpointConfig(String projectId, + public static EndpointConfiguration makeEndpointConfig(String projectId, CloudIotConfig cloudIotConfig, String deviceId) { EndpointConfiguration endpoint = new EndpointConfiguration(); - endpoint.client_id = MqttPublisher.getClientId(projectId, + endpoint.client_id = getClientId(projectId, cloudIotConfig.cloud_region, cloudIotConfig.registry_id, deviceId); endpoint.hostname = DEFAULT_ENDPOINT_HOSTNAME; return endpoint; } + public static String getClientId(String projectId, String cloudRegion, String registryId, + String deviceId) { + return String.format(ID_FORMAT, projectId, cloudRegion, registryId, deviceId); + } + private static CloudIotConfig makeCloudIotConfig(Envelope attributes) { CloudIotConfig cloudIotConfig = new CloudIotConfig(); cloudIotConfig.registry_id = Preconditions.checkNotNull(attributes.deviceRegistryId, @@ -58,7 +67,34 @@ private static CloudIotConfig makeCloudIotConfig(Envelope attributes) { public static EndpointConfiguration makeEndpointConfig(Envelope attributes) { CloudIotConfig cloudIotConfig = makeCloudIotConfig(attributes); - return extractEndpointConfig(attributes.projectId, cloudIotConfig, attributes.deviceId); + return makeEndpointConfig(attributes.projectId, cloudIotConfig, attributes.deviceId); + } + + /** + * Parse a GCP clientId string into component parts including project, etc... + * + * @param clientId client id to parse + * @return bucket of parameters + */ + public static ClientInfo parseClientId(String clientId) { + if (clientId == null) { + throw new IllegalArgumentException("client_id not specified"); + } + Matcher matcher = ID_PATTERN.matcher(clientId); + if (!matcher.matches()) { + throw new IllegalArgumentException( + String.format("client_id %s does not match pattern %s", clientId, ID_PATTERN.pattern())); + } + ClientInfo clientInfo = new ClientInfo(); + clientInfo.projectId = matcher.group(1); + clientInfo.cloudRegion = matcher.group(2); + clientInfo.registryId = matcher.group(3); + clientInfo.deviceId = matcher.group(4); + return clientInfo; + } + + public EndpointConfiguration makeEndpointConfig(String projectId, String deviceId) { + return makeEndpointConfig(projectId, cloudIotConfig, deviceId); } private Set getAllDevices() { @@ -93,24 +129,19 @@ public void forEachDevice(BiConsumer consumer) { allMetadata.forEach(consumer); } - private void loadEndpointConfig(String projectId, String deviceId) { + private void loadSiteConfig() { Preconditions.checkState(sitePath != null, "sitePath not defined in configuration"); File cloudConfig = new File(new File(sitePath), "cloud_iot_config.json"); try { - endpointConfig = extractEndpointConfig(projectId, - OBJECT_MAPPER.readValue(cloudConfig, CloudIotConfig.class), deviceId); + cloudIotConfig = OBJECT_MAPPER.readValue(cloudConfig, CloudIotConfig.class); } catch (Exception e) { throw new RuntimeException("While reading config file " + cloudConfig.getAbsolutePath(), e); } } - public EndpointConfiguration getEndpointConfig() { - return endpointConfig; - } - - public void initialize(String projectId, String deviceId) { - loadEndpointConfig(projectId, deviceId); + public void initialize() { + loadSiteConfig(); loadAllDeviceMetadata(); } @@ -134,4 +165,30 @@ private String getDeviceKeyPrefix(String targetId) { Auth_type auth_type = getMetadata(targetId).cloud.auth_type; return auth_type.value().startsWith("RS") ? "rsa" : "ec"; } + + /** + * Get the site registry name. + * + * @return site registry + */ + public String getRegistryId() { + return cloudIotConfig.registry_id; + } + + /** + * Get the update topic for the site, if defined. + * + * @return update topic + */ + public String getUpdateTopic() { + return cloudIotConfig.update_topic; + } + + public static class ClientInfo { + + public String cloudRegion; + public String projectId; + public String registryId; + public String deviceId; + } } diff --git a/docs/specs/categories.md b/docs/specs/categories.md index 68318b74e9..a822e278a7 100644 --- a/docs/specs/categories.md +++ b/docs/specs/categories.md @@ -39,6 +39,9 @@ implicit expected `level` values, indicated by '(**LEVEL**)' in the hierarchy be * _enumerate_: (**INFO**) Handling point enumeration for a given device * _point_: Conditions specific to point enumeration * _describe_: (**INFO**) Relating to describing a particular point +* _mapping_: Mapping processing for devices + * _device_: Relating to a specific individual device + * _apply_: (**INFO**) Stage of applying a device mapping * _blobset_: Handling update of device data blobs * _blob_: Conditions specific to an individual blob * _receive_: (**DEBUG**) About receiving a blob update diff --git a/docs/specs/onboarding.md b/docs/specs/onboarding.md index 07fa6a6ff3..79cc8a44c1 100644 --- a/docs/specs/onboarding.md +++ b/docs/specs/onboarding.md @@ -3,96 +3,110 @@ # Onboarding The overall "onboarding" flow consists of a number of separate subflows stitched together for a complete -end-to-end process. This generall starts from an "unknown" device in the system through to a UDMI-compliant -device that's properly integrated with backend services. +end-to-end process to take an "unknown" device and ensure that it's properly integrated with backend services. -At a high-level, the overall process involves different message subgroups that handle slightly different +At a high-level, the process involves different message subgroups that handle slightly different scopes of device data: * **(Native)**: Device communicaiton using some non-UDMI native protocol (e.g. BACnet, Modbus, etc...) * **[Discovery](discovery.md)**: Messages relating to the discovery (and provisioning) of devices (e.g. messy BACnet info) * **[Mapping](mapping.md)**: Messages relating to a 'resolved' device type and ID (e.g. the device is an `AHU` called `AHU-1`) * **[Pointset](../messages/pointset.md)**: Messages relating to actual data flow (e.g. temperature reading), essentially the interesting stuff +* **(Onboard)**: Interactions with an external (non-UDMI) entity of some kind to facilitate onboarding of devices ## Sequence Diagram The overall onboarding sequence involves multiple components that work together to provide the overall flow: -* **Device**: The target thing that needs to be discovered, configured, and ultimately communications point data +* **Devices**: The target things that need to be discovered, configured, and ultimately communicate point data. * **Spotter**: A on-prem node responsible for handling discovery scans of devices. -* **Cloud**: The on-prem/in-cloud boundary. Things to the left are things in the building, to the right are in the cloud -* **Agent**: Responsible for managing the overall _discovery_ process (how often, what color, etc...) -* **Mapper**: Uses hueristics, ML, or a UI to convert discovery information into a concrete device/sink mapping -* **Sink**: Ultimate recepient of pointset information. The thing that cares about 'temperature' in a room +* **Agent**: Cloud-based agent responsible for managing the overall _discovery_ and _mapping_ process (how often, what color, etc...). +* **Engine**: Mapping engine that uses hueristics, ML, or a UI to convert discovery information into a concrete device/sink mapping. +* **Sink**: Ultimate recepient of pointset information, The thing that cares about 'temperature' in a room. Notes & Caveats: 1. Only "interesting" messages are shown in the diagram, there's other control flow things that go on (e.g. to configure when the *Spotter* should activate) to complete the overall flow. -2. This just shows one-of-many potential provisioning (handling keys) techniques. There's other paths -that would be possible (including manually, which is the baseline default). -3. This shows the flow for a direct-connect (no IoT Gateway) device. The overall flow for a proxied device -(with IoT Gateway) would more or less be the same, just different details about exact communication mechanisms. +2. This shows the flow for a direct-connect (no IoT Gateway involved) device. The overall flow for a proxied device +(with IoT Gateway) would more or less be the same with some additional intermediaries. -``` -+---------+ +---------+ +-------+ +-------+ +--------+ +-------+ -| Device | | Spotter | | Cloud | | Agent | | Mapper | | Sink | -+---------+ +---------+ +-------+ +-------+ +--------+ +-------+ - | | | | | | - | (Info) | | | | | - |----------------------->| | | | | - | | | | | | - | | Discovery Event | | | - | |------------------------------------------------------->| | - | | | | | | - | | | | | Mapping Event | - | | | | |------------------>| - | | | | | | - | | | | Mapping Event | | - | | | |<-------------------| | - | | | | | | - | | | (Cloud Provision) | | | - | | |<----------------------| | | - | | | | | | - | | | Discovery Command | | | - | |<----------------------------------| | | - | | | | | | - | (Device Provision) | | | | | - |<-----------------------| | | | | - | | | | | | - | | | | | Pointset Config | - |<----------------------------------------------------------------------------------------------------| - | | | | | | - | Pointset Event | | | | | - |---------------------------------------------------------------------------------------------------->| - | | | | | | +```mermaid +sequenceDiagram + participant Devices + participant Spotter + participant Agent + participant Engine + participant Sink + Note over Agent: Generation Start + activate Agent + Agent->>Spotter: Discovery Config + loop Devices + Spotter-->Devices: (Fieldbus Discovery) + Spotter->>Engine: Discovery Events + end + Agent->>Engine: Mapping Config + Engine->>Agent: Mapping State + loop Devices + Engine->>Agent: Mapping Events + Agent-->>Sink: (Onboard Info) + end + deactivate Agent + Note over Agent: Generation End + Devices->>Sink: Telemetry Events ``` -1. **(Info)** contains natively-encoded _Device_ information (format out of scope for UDMI) +1. **[Discovery Config](../../tests/config.tests/discovery.json)** indicates that the _spotter_ should do the needful and scan the local network. +1. *(Fieldbus Discovery)* scan for fieldbus _device_ information from devices (e.g. BACnet, format out of scope for UDMI): * "I am device `78F936`, with points { `room_temp`, `step_size`, and `operation_count` }, and public key `XYZZYZ`" -2. **[Discovery Event](../../tests/event_discovery.tests/enumeration.json)** from _Spotter_ wraps up the device info into a UDMI-normalized format +2. **[Discovery Events](../../tests/event_discovery.tests/enumeration.json)** wraps the device info from the _spotter_ into a UDMI-normalized format, e.g.: * "Device `78F936` has points { }, with a public key `XYZZYZ`" -3. **Mapping Event** from the _Mapper_ (recieved by both _Sink_ and _Agent_) +3. **[Mapping Config](../../tests/config_mapping.tests/mapping.json)** from the _agent_ indicates that the _engine_ should export responses. +3. **[Mapping Events](../../tests/event_mapping.tests/mapping.json)** from the _engine_ contain actual calculated point mappings: * "Device `78F936` is an `AHU` called `AHU-183`, and `room_temp` is really a `flow_temperatue`" -5. **(Cloud Provision)** from _Agent_ sets up the _Cloud_ layer using the IoT Core API. - * "Device `AHU-183` exists and has public key `XYZZYZ`" -4. **[Discovery Command](../../tests/command_discovery.tests/provision.json)** from the _Agent_ to the _Spotter_ contains information necessary to provision the device - * "Device `78F936` should call itself `AHU-183` when connecting to the cloud" -5. **(Device Provision)** uses some natively-encoded mechanism for setting up the device with relevant cloud info - * "Device `78F936`, you are celled `AHU-183` when connecting to the cloud" -7. **[Pointset Config](../../tests/config.tests/example.json)** from the _Sink_ can go directly to the _Device_ (after it connects to the cloud) - * "Device `AHU-183`, you should send the `room_temp` data point every `10 minutes`" -8. **[Pointset Events](../../tests/event_pointset.tests/example.json)** sends telemetry events from the _Device_ to _Sink_... business as usual! +4. *(Onboard Info)* are sent to the appropriate _sink_ to onboard a device (contents are defined by _sink_ and out of scope for UDMI). +8. **[Telemetry Events](../../tests/event_pointset.tests/example.json)** are data events from _device_ to _sink_... business as usual: * "I am `AHU-183`, and my `room_temp` is `73`" -## Source -Created using https://textart.io/sequence# +## Example Test Setup + +A standlone test-setup can be used to emulate all the requiste parts of the system. + +Cloud PubSub subscriptions (the defaults) on the `udmi_target` topic (need to be manually added): +* `mapping-agent`: Used by the agent to coordinate on-prem discovery and mapping engine activities. +* `mapping-engine`: Used by the engine to process discovery and mapping information. + +Local environment setup (e.g.): +* project_id=test-gcp-project + +### Mock Device and Spotter + +The `pubber` reference provides for both ther `device` and `spotter` bits of functionality (`AHU-1` in this case). + +``` +$ bin/pubber sites/udmi_site_model/ $project_id AHU-1 832172 +... +INFO daq.pubber.Pubber - 2022-08-30T01:46:29Z Discovery scan starting virtual as 2022-08-30T01:46:29Z +... +INFO daq.pubber.Pubber - 2022-08-30T01:45:57Z Sent 1 discovery events from virtual for Mon Aug 29 18:45:43 PDT 2022 +... +``` + +### Mapping Agent + +The mapping `agent` configures the on-prem discovery node (`AHU-1`) to perform periodic discovery runs. + +``` +$ validator/bin/mapping agent sites/udmi_site_model/ $project_id AHU-1 +... +Received new family virtual generation Mon Aug 29 18:47:43 PDT 2022 +... +``` + +### Mock Mapping Engine + +The mapping `engine` receives discovery and mapping events to perform the mapping function. + ``` -object Device Spotter Cloud Agent Mapper Sink -Device->Spotter: (Info) -Spotter->Mapper: Discovery Event -Mapper->Sink: Mapping Event -Mapper->Agent: Mapping Event -Agent->Cloud: (Cloud Provision) -Agent->Spotter: Discovery Command -Spotter->Device: (Device Provision) -Sink->Device: Pointset Config -Device->Sink: Pointset Event +$ validator/bin/mapping engine sites/udmi_site_model/ $project_id +... +Received discovery event for generation Mon Aug 29 18:48:43 PDT 2022 +... ``` diff --git a/docs/tools/gcloud.md b/docs/tools/gcloud.md index e36d87f411..e46db6dcbf 100644 --- a/docs/tools/gcloud.md +++ b/docs/tools/gcloud.md @@ -5,7 +5,9 @@ them to work out-of-the-box without a deeper understanding of what's going on! # Viewing subscription -`bin/pull_message:gcloud --format=json --project=$project_id pubsub subscriptions pull $subscription --auto-ack` +`bin/pull_message` + +`gcloud --format=json --project=$project_id pubsub subscriptions pull $subscription --auto-ack` # View cloud function logs diff --git a/gencode/docs/command_mapping.html b/gencode/docs/command_mapping.html new file mode 100644 index 0000000000..be0fb77c49 --- /dev/null +++ b/gencode/docs/command_mapping.html @@ -0,0 +1,1794 @@ + + + + + + + + + + + + + + + + Mapping Command + +

Mapping Command

+ + +
+ + Type: object
+

Mapping command for provisioning

+
+ + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

RFC 3339 timestamp the configuration was generated

+
+ + + + + +
+
Example:
+
"2019-01-17T14:02:29.364Z"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Version of the UDMI schema

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

device guid

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

A human-readable one-line description of the entry

+
+ + + + + +
+
Example:
+
"Point is not writable"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

An optional extensive entry which can include more detail, e.g. a complete program stack-trace

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + +

+ +

+
+ + + Type: object
+Must match regular expression: ^system\.base\.start$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.base\.shutdown$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.base\.ready$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.parse$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.network\.connection$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.network\.disconnect$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.login$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.logout$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.fail$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.applied$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.updating$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.overridden$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.failure$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.invalid$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.family\.scan$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.device\.enumerate$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.point\.describe$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^mapping\.device\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.fetch$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.device\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ + + + + + + +
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Timestamp the condition was triggered, or most recently updated

+
+ + + + + +
+
Example:
+
"2018-08-26T21:39:28.364Z"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: integer
+

The status level should conform to the numerical Stackdriver LogEntry levels. The DEFAULT value of 0 is not allowed (lowest value is 100, maximum 800).

+
+ + + +

Value must be greater or equal to 100 and lesser or equal to 800 and a multiple of 1

+ +
+
Example:
+
600
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+

Point translations

+
No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+

+ +

+

All property whose name matches the following regular expression must respect the following conditions

+ Property name regular expression: +
+ + Type: object
+

Discovery result with implicit enumeration

+
+ + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

dotted path to present_value field

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gencode/docs/config.html b/gencode/docs/config.html index fa48a01193..3e01efdda1 100644 --- a/gencode/docs/config.html +++ b/gencode/docs/config.html @@ -591,7 +591,7 @@

+ aria-expanded="" aria-controls="discovery_enumeration_generation" onclick="setAnchor('#discovery_enumeration_generation')">generation Required

@@ -875,7 +875,7 @@

+ aria-expanded="" aria-controls="discovery_families_pattern1_generation" onclick="setAnchor('#discovery_families_pattern1_generation')">generation Required

diff --git a/gencode/docs/config_mapping.html b/gencode/docs/config_mapping.html new file mode 100644 index 0000000000..d3bfaac9ba --- /dev/null +++ b/gencode/docs/config_mapping.html @@ -0,0 +1,2208 @@ + + + + + + + + + + + + + + + + Mapping Config + +

Mapping Config

+ + +
+ + Type: object
+

Configuration for mapping

+
No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

RFC 3339 timestamp the configuration was generated

+
+ + + + + +
+
Example:
+
"2019-01-17T14:02:29.364Z"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Version of the UDMI schema

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+

Configuration of mapped devices

+
No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+

+ +

+

All property whose name matches the following regular expression must respect the following conditions

+ Property name regular expression: +
+ + Type: object
+

Configuration for mapping

+
+ + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Device guid

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Last time the mapping was successfully applied for this device

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Timestamp of requested device model export

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

A human-readable one-line description of the entry

+
+ + + + + +
+
Example:
+
"Point is not writable"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

An optional extensive entry which can include more detail, e.g. a complete program stack-trace

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + +

+ +

+
+ + + Type: object
+Must match regular expression: ^system\.base\.start$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.base\.shutdown$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.base\.ready$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.parse$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.network\.connection$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.network\.disconnect$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.login$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.logout$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.fail$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.applied$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.updating$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.overridden$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.failure$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.invalid$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.family\.scan$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.device\.enumerate$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.point\.describe$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^mapping\.device\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.fetch$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.device\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ + + + + + + +
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Timestamp the condition was triggered, or most recently updated

+
+ + + + + +
+
Example:
+
"2018-08-26T21:39:28.364Z"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: integer
+

The status level should conform to the numerical Stackdriver LogEntry levels. The DEFAULT value of 0 is not allowed (lowest value is 100, maximum 800).

+
+ + + +

Value must be greater or equal to 100 and lesser or equal to 800 and a multiple of 1

+ +
+
Example:
+
600
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gencode/docs/envelope.html b/gencode/docs/envelope.html index 5a716deadd..568c58a983 100644 --- a/gencode/docs/envelope.html +++ b/gencode/docs/envelope.html @@ -218,7 +218,7 @@

subFolderType: enum (of string)

Must be one of:

-
  • "update"
  • "audit"
  • "discovery"
  • "system"
  • "gateway"
  • "swarm"
  • "localnet"
  • "pointset"
  • "blobset"
+
  • "update"
  • "discovery"
  • "mapping"
  • "system"
  • "gateway"
  • "swarm"
  • "localnet"
  • "pointset"
  • "blobset"
diff --git a/gencode/docs/event_discovery.html b/gencode/docs/event_discovery.html index 9e89fc5afa..26c76d8a54 100644 --- a/gencode/docs/event_discovery.html +++ b/gencode/docs/event_discovery.html @@ -414,6 +414,11 @@

id="status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_status_category_oneOf_i24" role="tab" onclick="setAnchor('#status_category_oneOf_i24')" >Option 25 +
@@ -1208,7 +1213,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -1248,7 +1253,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -1288,7 +1293,7 @@

/> item 21Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -1328,7 +1333,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -1368,7 +1373,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -1408,7 +1413,47 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -2501,6 +2546,11 @@

id="uniqs_pattern1_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_uniqs_pattern1_status_category_oneOf_i24" role="tab" onclick="setAnchor('#uniqs_pattern1_status_category_oneOf_i24')" >Option 25 +
@@ -3575,7 +3625,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -3629,7 +3679,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -3683,7 +3733,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -3737,7 +3787,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -3791,7 +3841,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -3845,7 +3895,61 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ diff --git a/gencode/docs/event_mapping.html b/gencode/docs/event_mapping.html new file mode 100644 index 0000000000..3fbb20f56a --- /dev/null +++ b/gencode/docs/event_mapping.html @@ -0,0 +1,1794 @@ + + + + + + + + + + + + + + + + Mapping Event + +

Mapping Event

+ + +
+ + Type: object
+

Mapping result with implicit enumeration

+
+ + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

RFC 3339 timestamp the configuration was generated

+
+ + + + + +
+
Example:
+
"2019-01-17T14:02:29.364Z"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Version of the UDMI schema

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

device guid

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

A human-readable one-line description of the entry

+
+ + + + + +
+
Example:
+
"Point is not writable"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

An optional extensive entry which can include more detail, e.g. a complete program stack-trace

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + +

+ +

+
+ + + Type: object
+Must match regular expression: ^system\.base\.start$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.base\.shutdown$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.base\.ready$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.parse$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.network\.connection$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.network\.disconnect$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.login$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.logout$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.fail$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.applied$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.updating$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.overridden$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.failure$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.invalid$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.family\.scan$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.device\.enumerate$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.point\.describe$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^mapping\.device\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.fetch$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.device\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ + + + + + + +
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Timestamp the condition was triggered, or most recently updated

+
+ + + + + +
+
Example:
+
"2018-08-26T21:39:28.364Z"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: integer
+

The status level should conform to the numerical Stackdriver LogEntry levels. The DEFAULT value of 0 is not allowed (lowest value is 100, maximum 800).

+
+ + + +

Value must be greater or equal to 100 and lesser or equal to 800 and a multiple of 1

+ +
+
Example:
+
600
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+

Point translations

+
No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+

+ +

+

All property whose name matches the following regular expression must respect the following conditions

+ Property name regular expression: +
+ + Type: object
+

Discovery result with implicit enumeration

+
+ + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

dotted path to present_value field

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gencode/docs/event_system.html b/gencode/docs/event_system.html index 79ea2e6350..02212975c7 100644 --- a/gencode/docs/event_system.html +++ b/gencode/docs/event_system.html @@ -423,6 +423,11 @@

id="logentries_items_category_oneOf_i24" data-toggle="tab" href="#tab-pane_logentries_items_category_oneOf_i24" role="tab" onclick="setAnchor('#logentries_items_category_oneOf_i24')" >Option 25 +
@@ -1357,7 +1362,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -1404,7 +1409,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -1451,7 +1456,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -1498,7 +1503,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -1545,7 +1550,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -1592,7 +1597,54 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ diff --git a/gencode/docs/event_validation.html b/gencode/docs/event_validation.html index 1409cf17c3..8ab17f674c 100644 --- a/gencode/docs/event_validation.html +++ b/gencode/docs/event_validation.html @@ -444,6 +444,11 @@

id="status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_status_category_oneOf_i24" role="tab" onclick="setAnchor('#status_category_oneOf_i24')" >Option 25 +
@@ -1238,7 +1243,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -1278,7 +1283,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -1318,7 +1323,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -1358,7 +1363,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -1398,7 +1403,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -1438,7 +1443,47 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -2059,6 +2104,11 @@

id="errors_items_category_oneOf_i24" data-toggle="tab" href="#tab-pane_errors_items_category_oneOf_i24" role="tab" onclick="setAnchor('#errors_items_category_oneOf_i24')" >Option 25 +
@@ -2993,7 +3043,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -3040,7 +3090,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -3087,7 +3137,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -3134,7 +3184,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -3181,7 +3231,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -3228,7 +3278,54 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ diff --git a/gencode/docs/index.html b/gencode/docs/index.html index 8cbbd7edf3..a03b47499a 100644 --- a/gencode/docs/index.html +++ b/gencode/docs/index.html @@ -21,6 +21,6 @@

UDMI Schema


- + \ No newline at end of file diff --git a/gencode/docs/state.html b/gencode/docs/state.html index 97d0c9b07b..5782bd868e 100644 --- a/gencode/docs/state.html +++ b/gencode/docs/state.html @@ -1196,6 +1196,11 @@

id="system_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_system_status_category_oneOf_i24" role="tab" onclick="setAnchor('#system_status_category_oneOf_i24')" >Option 25 +
@@ -2130,7 +2135,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -2177,7 +2182,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -2224,7 +2229,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -2271,7 +2276,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -2318,7 +2323,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -2365,7 +2370,54 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -2965,6 +3017,11 @@

id="gateway_devices_additionalProperties_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_gateway_devices_additionalProperties_status_category_oneOf_i24" role="tab" onclick="setAnchor('#gateway_devices_additionalProperties_status_category_oneOf_i24')" >Option 25 +
@@ -4179,7 +4236,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -4240,7 +4297,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -4301,7 +4358,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -4362,7 +4419,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -4423,7 +4480,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -4484,7 +4541,68 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -5149,6 +5267,11 @@

id="discovery_enumeration_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_discovery_enumeration_status_category_oneOf_i24" role="tab" onclick="setAnchor('#discovery_enumeration_status_category_oneOf_i24')" >Option 25 +
@@ -6223,7 +6346,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -6277,7 +6400,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -6331,7 +6454,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -6385,7 +6508,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -6439,7 +6562,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -6493,7 +6616,61 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -7195,6 +7372,11 @@

id="discovery_families_pattern1_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_discovery_families_pattern1_status_category_oneOf_i24" role="tab" onclick="setAnchor('#discovery_families_pattern1_status_category_oneOf_i24')" >Option 25 +
@@ -8409,7 +8591,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -8470,7 +8652,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -8531,7 +8713,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -8592,7 +8774,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -8653,7 +8835,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -8714,7 +8896,68 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -9416,6 +9659,11 @@

id="blobset_blobs_pattern1_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_blobset_blobs_pattern1_status_category_oneOf_i24" role="tab" onclick="setAnchor('#blobset_blobs_pattern1_status_category_oneOf_i24')" >Option 25 +
@@ -10630,7 +10878,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -10691,7 +10939,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -10752,7 +11000,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -10813,7 +11061,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -10874,7 +11122,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -10935,7 +11183,68 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -11564,6 +11873,11 @@

id="pointset_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_pointset_status_category_oneOf_i24" role="tab" onclick="setAnchor('#pointset_status_category_oneOf_i24')" >Option 25 +
@@ -12498,7 +12812,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -12545,7 +12859,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -12592,7 +12906,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -12639,7 +12953,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -12686,7 +13000,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -12733,7 +13047,54 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -13420,6 +13781,11 @@

id="pointset_points_pattern1_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_pointset_points_pattern1_status_category_oneOf_i24" role="tab" onclick="setAnchor('#pointset_points_pattern1_status_category_oneOf_i24')" >Option 25 +
@@ -14634,7 +15000,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -14695,7 +15061,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -14756,7 +15122,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -14817,7 +15183,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -14878,7 +15244,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -14939,7 +15305,68 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ diff --git a/gencode/docs/state_mapping.html b/gencode/docs/state_mapping.html new file mode 100644 index 0000000000..be911210fb --- /dev/null +++ b/gencode/docs/state_mapping.html @@ -0,0 +1,2352 @@ + + + + + + + + + + + + + + + + Mapping State + +

Mapping State

+ + +
+ + Type: object
+

State for mapping

+
No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

RFC 3339 timestamp the configuration was generated

+
+ + + + + +
+
Example:
+
"2019-01-17T14:02:29.364Z"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Version of the UDMI schema

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+

Mapping state for all devices

+
No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+

+ +

+

All property whose name matches the following regular expression must respect the following conditions

+ Property name regular expression: +
+ + Type: object
+

State for mapping

+
+ + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Device guid

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Last time the mapping was imported

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Last received discovery message

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Last recommendation staging (result of automatic prediction)

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Last recommendation promotion (result of manual QA)

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Last time this device mapping was exported

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + + No Additional Properties + + + + + + +
+
+
+

+ +

+
+ +
+
+ + Type: string
+

A human-readable one-line description of the entry

+
+ + + + + +
+
Example:
+
"Point is not writable"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

An optional extensive entry which can include more detail, e.g. a complete program stack-trace

+
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: object
+ + +

+ +

+
+ + + Type: object
+Must match regular expression: ^system\.base\.start$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.base\.shutdown$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.base\.ready$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.parse$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.config\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.network\.connection$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.network\.disconnect$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.login$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.logout$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^system\.auth\.fail$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.applied$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.updating$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.overridden$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.failure$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^pointset\.point\.invalid$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.family\.scan$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.device\.enumerate$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^discovery\.point\.describe$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^mapping\.device\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.fetch$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^blobset\.blob\.apply$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.device\.receive$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ + + + + + + +
+ + + + + + +
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: string
+

Timestamp the condition was triggered, or most recently updated

+
+ + + + + +
+
Example:
+
"2018-08-26T21:39:28.364Z"
+
+
+
+
+
+
+
+
+
+

+ +

+
+ +
+
+ + Type: integer
+

The status level should conform to the numerical Stackdriver LogEntry levels. The DEFAULT value of 0 is not allowed (lowest value is 100, maximum 800).

+
+ + + +

Value must be greater or equal to 100 and lesser or equal to 800 and a multiple of 1

+ +
+
Example:
+
600
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/gencode/docs/state_pointset.html b/gencode/docs/state_pointset.html index 5cc7cf5211..2237841e93 100644 --- a/gencode/docs/state_pointset.html +++ b/gencode/docs/state_pointset.html @@ -411,6 +411,11 @@

id="status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_status_category_oneOf_i24" role="tab" onclick="setAnchor('#status_category_oneOf_i24')" >Option 25 +
@@ -1205,7 +1210,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -1245,7 +1250,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -1285,7 +1290,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -1325,7 +1330,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -1365,7 +1370,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -1405,7 +1410,47 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -2022,6 +2067,11 @@

id="points_pattern1_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_points_pattern1_status_category_oneOf_i24" role="tab" onclick="setAnchor('#points_pattern1_status_category_oneOf_i24')" >Option 25 +
@@ -3096,7 +3146,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -3150,7 +3200,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -3204,7 +3254,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -3258,7 +3308,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -3312,7 +3362,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -3366,7 +3416,61 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ diff --git a/gencode/docs/state_validation.html b/gencode/docs/state_validation.html index ad95af68b8..c600e77e43 100644 --- a/gencode/docs/state_validation.html +++ b/gencode/docs/state_validation.html @@ -410,6 +410,11 @@

id="status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_status_category_oneOf_i24" role="tab" onclick="setAnchor('#status_category_oneOf_i24')" >Option 25 +
@@ -1204,7 +1209,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -1244,7 +1249,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -1284,7 +1289,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -1324,7 +1329,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -1364,7 +1369,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -1404,7 +1409,47 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ @@ -2349,6 +2394,11 @@

id="devices_pattern1_status_category_oneOf_i24" data-toggle="tab" href="#tab-pane_devices_pattern1_status_category_oneOf_i24" role="tab" onclick="setAnchor('#devices_pattern1_status_category_oneOf_i24')" >Option 25 +
@@ -3423,7 +3473,7 @@

/> item 19

Type: object
-Must match regular expression: ^blobset\.blob\.receive$ +Must match regular expression: ^mapping\.device\.apply$ @@ -3477,7 +3527,7 @@

/> item 20

Type: object
-Must match regular expression: ^blobset\.blob\.fetch$ +Must match regular expression: ^blobset\.blob\.receive$ @@ -3531,7 +3581,7 @@

/> item 21

Type: object
-Must match regular expression: ^blobset\.blob\.apply$ +Must match regular expression: ^blobset\.blob\.fetch$ @@ -3585,7 +3635,7 @@

/> item 22Type: object
-Must match regular expression: ^validation\.device\.receive$ +Must match regular expression: ^blobset\.blob\.apply$ @@ -3639,7 +3689,7 @@

/> item 23Type: object
-Must match regular expression: ^validation\.device\.result$ +Must match regular expression: ^validation\.device\.receive$ @@ -3693,7 +3743,61 @@

/> item 24Type: object
-Must match regular expression: ^validation\.summary\.report$ +Must match regular expression: ^validation\.device\.result$ + + + + + + +
+ + + Type: object
+Must match regular expression: ^validation\.summary\.report$ diff --git a/gencode/java/udmi/schema/BuildingConfig.java b/gencode/java/udmi/schema/BuildingConfig.java new file mode 100644 index 0000000000..3ff4a42703 --- /dev/null +++ b/gencode/java/udmi/schema/BuildingConfig.java @@ -0,0 +1,90 @@ + +package udmi.schema; + +import java.util.Date; +import java.util.HashMap; +import javax.annotation.processing.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Building Config + *

+ * [Discovery result](../docs/specs/discovery.md) with implicit enumeration + * + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "timestamp", + "version", + "guid", + "status", + "translation" +}) +@Generated("jsonschema2pojo") +public class BuildingConfig { + + /** + * RFC 3339 timestamp the configuration was generated + * + */ + @JsonProperty("timestamp") + @JsonPropertyDescription("RFC 3339 timestamp the configuration was generated") + public Date timestamp; + /** + * Version of the UDMI schema + * + */ + @JsonProperty("version") + @JsonPropertyDescription("Version of the UDMI schema") + public java.lang.String version; + /** + * device guid + * + */ + @JsonProperty("guid") + @JsonPropertyDescription("device guid") + public java.lang.String guid; + /** + * Entry + *

+ * + * + */ + @JsonProperty("status") + public Entry status; + /** + * Point translations + * + */ + @JsonProperty("translation") + @JsonPropertyDescription("Point translations") + public HashMap translation; + + @Override + public int hashCode() { + int result = 1; + result = ((result* 31)+((this.translation == null)? 0 :this.translation.hashCode())); + result = ((result* 31)+((this.guid == null)? 0 :this.guid.hashCode())); + result = ((result* 31)+((this.version == null)? 0 :this.version.hashCode())); + result = ((result* 31)+((this.timestamp == null)? 0 :this.timestamp.hashCode())); + result = ((result* 31)+((this.status == null)? 0 :this.status.hashCode())); + return result; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof BuildingConfig) == false) { + return false; + } + BuildingConfig rhs = ((BuildingConfig) other); + return ((((((this.translation == rhs.translation)||((this.translation!= null)&&this.translation.equals(rhs.translation)))&&((this.guid == rhs.guid)||((this.guid!= null)&&this.guid.equals(rhs.guid))))&&((this.version == rhs.version)||((this.version!= null)&&this.version.equals(rhs.version))))&&((this.timestamp == rhs.timestamp)||((this.timestamp!= null)&&this.timestamp.equals(rhs.timestamp))))&&((this.status == rhs.status)||((this.status!= null)&&this.status.equals(rhs.status)))); + } + +} diff --git a/gencode/java/udmi/schema/BuildingConfigTranslation.java b/gencode/java/udmi/schema/BuildingConfigTranslation.java new file mode 100644 index 0000000000..b36bb2b398 --- /dev/null +++ b/gencode/java/udmi/schema/BuildingConfigTranslation.java @@ -0,0 +1,59 @@ + +package udmi.schema; + +import javax.annotation.processing.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Building Config Translation + *

+ * [Discovery result](../docs/specs/discovery.md) with implicit enumeration + * + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "present_value", + "units", + "states" +}) +@Generated("jsonschema2pojo") +public class BuildingConfigTranslation { + + /** + * dotted path to present_value field + * + */ + @JsonProperty("present_value") + @JsonPropertyDescription("dotted path to present_value field") + public String present_value; + @JsonProperty("units") + public Object units; + @JsonProperty("states") + public Object states; + + @Override + public int hashCode() { + int result = 1; + result = ((result* 31)+((this.units == null)? 0 :this.units.hashCode())); + result = ((result* 31)+((this.present_value == null)? 0 :this.present_value.hashCode())); + result = ((result* 31)+((this.states == null)? 0 :this.states.hashCode())); + return result; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof BuildingConfigTranslation) == false) { + return false; + } + BuildingConfigTranslation rhs = ((BuildingConfigTranslation) other); + return ((((this.units == rhs.units)||((this.units!= null)&&this.units.equals(rhs.units)))&&((this.present_value == rhs.present_value)||((this.present_value!= null)&&this.present_value.equals(rhs.present_value))))&&((this.states == rhs.states)||((this.states!= null)&&this.states.equals(rhs.states)))); + } + +} diff --git a/gencode/java/udmi/schema/Category.java b/gencode/java/udmi/schema/Category.java index 6bd7804df1..941490a2da 100644 --- a/gencode/java/udmi/schema/Category.java +++ b/gencode/java/udmi/schema/Category.java @@ -110,6 +110,11 @@ public class Category { public static final Level DISCOVERY_POINT_DESCRIBE_LEVEL = INFO; static { LEVEL.put(DISCOVERY_POINT_DESCRIBE, INFO); } + // Stage of applying a device mapping + public static final String MAPPING_DEVICE_APPLY = "mapping.device.apply"; + public static final Level MAPPING_DEVICE_APPLY_LEVEL = INFO; + static { LEVEL.put(MAPPING_DEVICE_APPLY, INFO); } + // About receiving a blob update public static final String BLOBSET_BLOB_RECEIVE = "blobset.blob.receive"; public static final Level BLOBSET_BLOB_RECEIVE_LEVEL = DEBUG; diff --git a/gencode/java/udmi/schema/DeviceMappingConfig.java b/gencode/java/udmi/schema/DeviceMappingConfig.java new file mode 100644 index 0000000000..c56448fdf3 --- /dev/null +++ b/gencode/java/udmi/schema/DeviceMappingConfig.java @@ -0,0 +1,80 @@ + +package udmi.schema; + +import java.util.Date; +import javax.annotation.processing.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Device Mapping Config + *

+ * Configuration for [mapping](../docs/specs/mapping.md) + * + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "guid", + "applied", + "requested", + "status" +}) +@Generated("jsonschema2pojo") +public class DeviceMappingConfig { + + /** + * Device guid + * + */ + @JsonProperty("guid") + @JsonPropertyDescription("Device guid") + public String guid; + /** + * Last time the mapping was successfully applied for this device + * + */ + @JsonProperty("applied") + @JsonPropertyDescription("Last time the mapping was successfully applied for this device") + public Date applied; + /** + * Timestamp of requested device model export + * + */ + @JsonProperty("requested") + @JsonPropertyDescription("Timestamp of requested device model export") + public Date requested; + /** + * Entry + *

+ * + * + */ + @JsonProperty("status") + public Entry status; + + @Override + public int hashCode() { + int result = 1; + result = ((result* 31)+((this.guid == null)? 0 :this.guid.hashCode())); + result = ((result* 31)+((this.requested == null)? 0 :this.requested.hashCode())); + result = ((result* 31)+((this.applied == null)? 0 :this.applied.hashCode())); + result = ((result* 31)+((this.status == null)? 0 :this.status.hashCode())); + return result; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof DeviceMappingConfig) == false) { + return false; + } + DeviceMappingConfig rhs = ((DeviceMappingConfig) other); + return (((((this.guid == rhs.guid)||((this.guid!= null)&&this.guid.equals(rhs.guid)))&&((this.requested == rhs.requested)||((this.requested!= null)&&this.requested.equals(rhs.requested))))&&((this.applied == rhs.applied)||((this.applied!= null)&&this.applied.equals(rhs.applied))))&&((this.status == rhs.status)||((this.status!= null)&&this.status.equals(rhs.status)))); + } + +} diff --git a/gencode/java/udmi/schema/DeviceMappingState.java b/gencode/java/udmi/schema/DeviceMappingState.java new file mode 100644 index 0000000000..29872d9f69 --- /dev/null +++ b/gencode/java/udmi/schema/DeviceMappingState.java @@ -0,0 +1,107 @@ + +package udmi.schema; + +import java.util.Date; +import javax.annotation.processing.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Device Mapping State + *

+ * State for [mapping](../docs/specs/mapping.md) + * + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "guid", + "imported", + "discovered", + "predicted", + "promoted", + "exported", + "status" +}) +@Generated("jsonschema2pojo") +public class DeviceMappingState { + + /** + * Device guid + * + */ + @JsonProperty("guid") + @JsonPropertyDescription("Device guid") + public String guid; + /** + * Last time the mapping was imported + * + */ + @JsonProperty("imported") + @JsonPropertyDescription("Last time the mapping was imported") + public Date imported; + /** + * Last received discovery message + * + */ + @JsonProperty("discovered") + @JsonPropertyDescription("Last received discovery message") + public Date discovered; + /** + * Last recommendation staging (result of automatic prediction) + * + */ + @JsonProperty("predicted") + @JsonPropertyDescription("Last recommendation staging (result of automatic prediction)") + public Date predicted; + /** + * Last recommendation promotion (result of manual QA) + * + */ + @JsonProperty("promoted") + @JsonPropertyDescription("Last recommendation promotion (result of manual QA)") + public Date promoted; + /** + * Last time this device mapping was exported + * + */ + @JsonProperty("exported") + @JsonPropertyDescription("Last time this device mapping was exported") + public Date exported; + /** + * Entry + *

+ * + * + */ + @JsonProperty("status") + public Entry status; + + @Override + public int hashCode() { + int result = 1; + result = ((result* 31)+((this.exported == null)? 0 :this.exported.hashCode())); + result = ((result* 31)+((this.discovered == null)? 0 :this.discovered.hashCode())); + result = ((result* 31)+((this.imported == null)? 0 :this.imported.hashCode())); + result = ((result* 31)+((this.guid == null)? 0 :this.guid.hashCode())); + result = ((result* 31)+((this.promoted == null)? 0 :this.promoted.hashCode())); + result = ((result* 31)+((this.predicted == null)? 0 :this.predicted.hashCode())); + result = ((result* 31)+((this.status == null)? 0 :this.status.hashCode())); + return result; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof DeviceMappingState) == false) { + return false; + } + DeviceMappingState rhs = ((DeviceMappingState) other); + return ((((((((this.exported == rhs.exported)||((this.exported!= null)&&this.exported.equals(rhs.exported)))&&((this.discovered == rhs.discovered)||((this.discovered!= null)&&this.discovered.equals(rhs.discovered))))&&((this.imported == rhs.imported)||((this.imported!= null)&&this.imported.equals(rhs.imported))))&&((this.guid == rhs.guid)||((this.guid!= null)&&this.guid.equals(rhs.guid))))&&((this.promoted == rhs.promoted)||((this.promoted!= null)&&this.promoted.equals(rhs.promoted))))&&((this.predicted == rhs.predicted)||((this.predicted!= null)&&this.predicted.equals(rhs.predicted))))&&((this.status == rhs.status)||((this.status!= null)&&this.status.equals(rhs.status)))); + } + +} diff --git a/gencode/java/udmi/schema/Envelope.java b/gencode/java/udmi/schema/Envelope.java index 99ac30ca03..46d5f18e33 100644 --- a/gencode/java/udmi/schema/Envelope.java +++ b/gencode/java/udmi/schema/Envelope.java @@ -99,8 +99,8 @@ public boolean equals(Object other) { public enum SubFolder { UPDATE("update"), - AUDIT("audit"), DISCOVERY("discovery"), + MAPPING("mapping"), SYSTEM("system"), GATEWAY("gateway"), SWARM("swarm"), diff --git a/gencode/java/udmi/schema/FamilyDiscoveryConfig.java b/gencode/java/udmi/schema/FamilyDiscoveryConfig.java index 11b86ffd25..40c2615859 100644 --- a/gencode/java/udmi/schema/FamilyDiscoveryConfig.java +++ b/gencode/java/udmi/schema/FamilyDiscoveryConfig.java @@ -27,6 +27,7 @@ public class FamilyDiscoveryConfig { /** * Generational marker for controlling discovery + * (Required) * */ @JsonProperty("generation") diff --git a/gencode/java/udmi/schema/MappingConfig.java b/gencode/java/udmi/schema/MappingConfig.java new file mode 100644 index 0000000000..c9f7e6e994 --- /dev/null +++ b/gencode/java/udmi/schema/MappingConfig.java @@ -0,0 +1,71 @@ + +package udmi.schema; + +import java.util.Date; +import java.util.HashMap; +import javax.annotation.processing.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Mapping Config + *

+ * Configuration for [mapping](../docs/specs/mapping.md) + * + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "timestamp", + "version", + "devices" +}) +@Generated("jsonschema2pojo") +public class MappingConfig { + + /** + * RFC 3339 timestamp the configuration was generated + * + */ + @JsonProperty("timestamp") + @JsonPropertyDescription("RFC 3339 timestamp the configuration was generated") + public Date timestamp; + /** + * Version of the UDMI schema + * + */ + @JsonProperty("version") + @JsonPropertyDescription("Version of the UDMI schema") + public java.lang.String version; + /** + * Configuration of mapped devices + * + */ + @JsonProperty("devices") + @JsonPropertyDescription("Configuration of mapped devices") + public HashMap devices; + + @Override + public int hashCode() { + int result = 1; + result = ((result* 31)+((this.version == null)? 0 :this.version.hashCode())); + result = ((result* 31)+((this.devices == null)? 0 :this.devices.hashCode())); + result = ((result* 31)+((this.timestamp == null)? 0 :this.timestamp.hashCode())); + return result; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof MappingConfig) == false) { + return false; + } + MappingConfig rhs = ((MappingConfig) other); + return ((((this.version == rhs.version)||((this.version!= null)&&this.version.equals(rhs.version)))&&((this.devices == rhs.devices)||((this.devices!= null)&&this.devices.equals(rhs.devices))))&&((this.timestamp == rhs.timestamp)||((this.timestamp!= null)&&this.timestamp.equals(rhs.timestamp)))); + } + +} diff --git a/gencode/java/udmi/schema/MappingState.java b/gencode/java/udmi/schema/MappingState.java new file mode 100644 index 0000000000..27509fbddb --- /dev/null +++ b/gencode/java/udmi/schema/MappingState.java @@ -0,0 +1,71 @@ + +package udmi.schema; + +import java.util.Date; +import java.util.HashMap; +import javax.annotation.processing.Generated; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + + +/** + * Mapping State + *

+ * State for [mapping](../docs/specs/mapping.md) + * + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "timestamp", + "version", + "devices" +}) +@Generated("jsonschema2pojo") +public class MappingState { + + /** + * RFC 3339 timestamp the configuration was generated + * + */ + @JsonProperty("timestamp") + @JsonPropertyDescription("RFC 3339 timestamp the configuration was generated") + public Date timestamp; + /** + * Version of the UDMI schema + * + */ + @JsonProperty("version") + @JsonPropertyDescription("Version of the UDMI schema") + public java.lang.String version; + /** + * Mapping state for all devices + * + */ + @JsonProperty("devices") + @JsonPropertyDescription("Mapping state for all devices") + public HashMap devices; + + @Override + public int hashCode() { + int result = 1; + result = ((result* 31)+((this.version == null)? 0 :this.version.hashCode())); + result = ((result* 31)+((this.devices == null)? 0 :this.devices.hashCode())); + result = ((result* 31)+((this.timestamp == null)? 0 :this.timestamp.hashCode())); + return result; + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof MappingState) == false) { + return false; + } + MappingState rhs = ((MappingState) other); + return ((((this.version == rhs.version)||((this.version!= null)&&this.version.equals(rhs.version)))&&((this.devices == rhs.devices)||((this.devices!= null)&&this.devices.equals(rhs.devices))))&&((this.timestamp == rhs.timestamp)||((this.timestamp!= null)&&this.timestamp.equals(rhs.timestamp)))); + } + +} diff --git a/gencode/python/udmi/schema/__init__.py b/gencode/python/udmi/schema/__init__.py index b2fe6668e8..63d10f3327 100644 --- a/gencode/python/udmi/schema/__init__.py +++ b/gencode/python/udmi/schema/__init__.py @@ -1,7 +1,10 @@ from .ancillary_properties import AncillaryProperties -from .category import Object4DEED257 +from .building_config import BuildingConfig +from .building_config_translation import BuildingConfigTranslation +from .category import Object812241E8 from .cloud_iot_config import CloudIotConfig from .command_discovery import DiscoveryCommand +from .command_mapping import MappingCommand from .common import Common from .config import Config from .config_blobset import BlobsetConfig @@ -10,6 +13,8 @@ from .config_discovery_family import FamilyDiscoveryConfig from .config_gateway import GatewayConfig from .config_localnet import LocalnetConfig +from .config_mapping import MappingConfig +from .config_mapping_device import DeviceMappingConfig from .config_pointset import PointsetConfig from .config_pointset_point import PointPointsetConfig from .config_system import SystemConfig @@ -21,7 +26,7 @@ from .event_discovery import DiscoveryEvent from .event_discovery_family import FamilyDiscoveryEvent from .event_discovery_point import PointEnumerationEvent -from .event_mapping import DiscoveryEvent +from .event_mapping import MappingEvent from .event_pointset import PointsetEvent from .event_pointset_point import PointPointsetEvent from .event_system import SystemEvent @@ -49,6 +54,8 @@ from .state_discovery import DiscoveryState from .state_discovery_family import FamilyDiscoveryState from .state_gateway import GatewayState +from .state_mapping import MappingState +from .state_mapping_device import DeviceMappingState from .state_pointset import PointsetState from .state_pointset_point import PointPointsetState from .state_system import SystemState diff --git a/gencode/python/udmi/schema/building_config.py b/gencode/python/udmi/schema/building_config.py new file mode 100644 index 0000000000..a0ee709eb4 --- /dev/null +++ b/gencode/python/udmi/schema/building_config.py @@ -0,0 +1,56 @@ +"""Generated class for building_config.json""" +from .common import Entry +from .building_config_translation import BuildingConfigTranslation + + +class BuildingConfig: + """Generated schema class""" + + def __init__(self): + self.timestamp = None + self.version = None + self.guid = None + self.status = None + self.translation = None + + @staticmethod + def from_dict(source): + if not source: + return None + result = BuildingConfig() + result.timestamp = source.get('timestamp') + result.version = source.get('version') + result.guid = source.get('guid') + result.status = Entry.from_dict(source.get('status')) + result.translation = BuildingConfigTranslation.map_from(source.get('translation')) + return result + + @staticmethod + def map_from(source): + if not source: + return None + result = {} + for key in source: + result[key] = BuildingConfig.from_dict(source[key]) + return result + + @staticmethod + def expand_dict(input): + result = {} + for property in input: + result[property] = input[property].to_dict() if input[property] else {} + return result + + def to_dict(self): + result = {} + if self.timestamp: + result['timestamp'] = self.timestamp # 5 + if self.version: + result['version'] = self.version # 5 + if self.guid: + result['guid'] = self.guid # 5 + if self.status: + result['status'] = self.status.to_dict() # 4 + if self.translation: + result['translation'] = BuildingConfigTranslation.expand_dict(self.translation) # 2 + return result diff --git a/gencode/python/udmi/schema/building_config_translation.py b/gencode/python/udmi/schema/building_config_translation.py new file mode 100644 index 0000000000..9fdbf18e0b --- /dev/null +++ b/gencode/python/udmi/schema/building_config_translation.py @@ -0,0 +1,46 @@ +"""Generated class for building_config_translation.json""" + + +class BuildingConfigTranslation: + """Generated schema class""" + + def __init__(self): + self.present_value = None + self.units = None + self.states = None + + @staticmethod + def from_dict(source): + if not source: + return None + result = BuildingConfigTranslation() + result.present_value = source.get('present_value') + result.units = source.get('units') + result.states = source.get('states') + return result + + @staticmethod + def map_from(source): + if not source: + return None + result = {} + for key in source: + result[key] = BuildingConfigTranslation.from_dict(source[key]) + return result + + @staticmethod + def expand_dict(input): + result = {} + for property in input: + result[property] = input[property].to_dict() if input[property] else {} + return result + + def to_dict(self): + result = {} + if self.present_value: + result['present_value'] = self.present_value # 5 + if self.units: + result['units'] = self.units # 5 + if self.states: + result['states'] = self.states # 5 + return result diff --git a/gencode/python/udmi/schema/category.py b/gencode/python/udmi/schema/category.py index 0711872d6d..94731340be 100644 --- a/gencode/python/udmi/schema/category.py +++ b/gencode/python/udmi/schema/category.py @@ -1,7 +1,7 @@ """Generated class for category.json""" -class Object4DEED257: +class Object812241E8: """Generated schema class""" def __init__(self): @@ -11,7 +11,7 @@ def __init__(self): def from_dict(source): if not source: return None - result = Object4DEED257() + result = Object812241E8() return result @staticmethod @@ -20,7 +20,7 @@ def map_from(source): return None result = {} for key in source: - result[key] = Object4DEED257.from_dict(source[key]) + result[key] = Object812241E8.from_dict(source[key]) return result @staticmethod diff --git a/gencode/python/udmi/schema/command_mapping.py b/gencode/python/udmi/schema/command_mapping.py new file mode 100644 index 0000000000..76fddb3161 --- /dev/null +++ b/gencode/python/udmi/schema/command_mapping.py @@ -0,0 +1,35 @@ +"""Generated class for command_mapping.json""" + + +class MappingCommand: + """Generated schema class""" + + def __init__(self): + pass + + @staticmethod + def from_dict(source): + if not source: + return None + result = MappingCommand() + return result + + @staticmethod + def map_from(source): + if not source: + return None + result = {} + for key in source: + result[key] = MappingCommand.from_dict(source[key]) + return result + + @staticmethod + def expand_dict(input): + result = {} + for property in input: + result[property] = input[property].to_dict() if input[property] else {} + return result + + def to_dict(self): + result = {} + return result diff --git a/gencode/python/udmi/schema/config_mapping.py b/gencode/python/udmi/schema/config_mapping.py new file mode 100644 index 0000000000..0fb0679526 --- /dev/null +++ b/gencode/python/udmi/schema/config_mapping.py @@ -0,0 +1,47 @@ +"""Generated class for config_mapping.json""" +from .config_mapping_device import DeviceMappingConfig + + +class MappingConfig: + """Generated schema class""" + + def __init__(self): + self.timestamp = None + self.version = None + self.devices = None + + @staticmethod + def from_dict(source): + if not source: + return None + result = MappingConfig() + result.timestamp = source.get('timestamp') + result.version = source.get('version') + result.devices = DeviceMappingConfig.map_from(source.get('devices')) + return result + + @staticmethod + def map_from(source): + if not source: + return None + result = {} + for key in source: + result[key] = MappingConfig.from_dict(source[key]) + return result + + @staticmethod + def expand_dict(input): + result = {} + for property in input: + result[property] = input[property].to_dict() if input[property] else {} + return result + + def to_dict(self): + result = {} + if self.timestamp: + result['timestamp'] = self.timestamp # 5 + if self.version: + result['version'] = self.version # 5 + if self.devices: + result['devices'] = DeviceMappingConfig.expand_dict(self.devices) # 2 + return result diff --git a/gencode/python/udmi/schema/config_mapping_device.py b/gencode/python/udmi/schema/config_mapping_device.py new file mode 100644 index 0000000000..0bd9aeaf43 --- /dev/null +++ b/gencode/python/udmi/schema/config_mapping_device.py @@ -0,0 +1,51 @@ +"""Generated class for config_mapping_device.json""" +from .common import Entry + + +class DeviceMappingConfig: + """Generated schema class""" + + def __init__(self): + self.guid = None + self.applied = None + self.requested = None + self.status = None + + @staticmethod + def from_dict(source): + if not source: + return None + result = DeviceMappingConfig() + result.guid = source.get('guid') + result.applied = source.get('applied') + result.requested = source.get('requested') + result.status = Entry.from_dict(source.get('status')) + return result + + @staticmethod + def map_from(source): + if not source: + return None + result = {} + for key in source: + result[key] = DeviceMappingConfig.from_dict(source[key]) + return result + + @staticmethod + def expand_dict(input): + result = {} + for property in input: + result[property] = input[property].to_dict() if input[property] else {} + return result + + def to_dict(self): + result = {} + if self.guid: + result['guid'] = self.guid # 5 + if self.applied: + result['applied'] = self.applied # 5 + if self.requested: + result['requested'] = self.requested # 5 + if self.status: + result['status'] = self.status.to_dict() # 4 + return result diff --git a/gencode/python/udmi/schema/event_mapping.py b/gencode/python/udmi/schema/event_mapping.py index fac601b6a7..990e38d2a3 100644 --- a/gencode/python/udmi/schema/event_mapping.py +++ b/gencode/python/udmi/schema/event_mapping.py @@ -1,23 +1,17 @@ """Generated class for event_mapping.json""" -from .common import Entry -class DiscoveryEvent: +class MappingEvent: """Generated schema class""" def __init__(self): - self.timestamp = None - self.version = None - self.status = None + pass @staticmethod def from_dict(source): if not source: return None - result = DiscoveryEvent() - result.timestamp = source.get('timestamp') - result.version = source.get('version') - result.status = Entry.from_dict(source.get('status')) + result = MappingEvent() return result @staticmethod @@ -26,7 +20,7 @@ def map_from(source): return None result = {} for key in source: - result[key] = DiscoveryEvent.from_dict(source[key]) + result[key] = MappingEvent.from_dict(source[key]) return result @staticmethod @@ -38,10 +32,4 @@ def expand_dict(input): def to_dict(self): result = {} - if self.timestamp: - result['timestamp'] = self.timestamp # 5 - if self.version: - result['version'] = self.version # 5 - if self.status: - result['status'] = self.status.to_dict() # 4 return result diff --git a/gencode/python/udmi/schema/state_mapping.py b/gencode/python/udmi/schema/state_mapping.py new file mode 100644 index 0000000000..92c73cb192 --- /dev/null +++ b/gencode/python/udmi/schema/state_mapping.py @@ -0,0 +1,47 @@ +"""Generated class for state_mapping.json""" +from .state_mapping_device import DeviceMappingState + + +class MappingState: + """Generated schema class""" + + def __init__(self): + self.timestamp = None + self.version = None + self.devices = None + + @staticmethod + def from_dict(source): + if not source: + return None + result = MappingState() + result.timestamp = source.get('timestamp') + result.version = source.get('version') + result.devices = DeviceMappingState.map_from(source.get('devices')) + return result + + @staticmethod + def map_from(source): + if not source: + return None + result = {} + for key in source: + result[key] = MappingState.from_dict(source[key]) + return result + + @staticmethod + def expand_dict(input): + result = {} + for property in input: + result[property] = input[property].to_dict() if input[property] else {} + return result + + def to_dict(self): + result = {} + if self.timestamp: + result['timestamp'] = self.timestamp # 5 + if self.version: + result['version'] = self.version # 5 + if self.devices: + result['devices'] = DeviceMappingState.expand_dict(self.devices) # 2 + return result diff --git a/gencode/python/udmi/schema/state_mapping_device.py b/gencode/python/udmi/schema/state_mapping_device.py new file mode 100644 index 0000000000..648909a94e --- /dev/null +++ b/gencode/python/udmi/schema/state_mapping_device.py @@ -0,0 +1,63 @@ +"""Generated class for state_mapping_device.json""" +from .common import Entry + + +class DeviceMappingState: + """Generated schema class""" + + def __init__(self): + self.guid = None + self.imported = None + self.discovered = None + self.predicted = None + self.promoted = None + self.exported = None + self.status = None + + @staticmethod + def from_dict(source): + if not source: + return None + result = DeviceMappingState() + result.guid = source.get('guid') + result.imported = source.get('imported') + result.discovered = source.get('discovered') + result.predicted = source.get('predicted') + result.promoted = source.get('promoted') + result.exported = source.get('exported') + result.status = Entry.from_dict(source.get('status')) + return result + + @staticmethod + def map_from(source): + if not source: + return None + result = {} + for key in source: + result[key] = DeviceMappingState.from_dict(source[key]) + return result + + @staticmethod + def expand_dict(input): + result = {} + for property in input: + result[property] = input[property].to_dict() if input[property] else {} + return result + + def to_dict(self): + result = {} + if self.guid: + result['guid'] = self.guid # 5 + if self.imported: + result['imported'] = self.imported # 5 + if self.discovered: + result['discovered'] = self.discovered # 5 + if self.predicted: + result['predicted'] = self.predicted # 5 + if self.promoted: + result['promoted'] = self.promoted # 5 + if self.exported: + result['exported'] = self.exported # 5 + if self.status: + result['status'] = self.status.to_dict() # 4 + return result diff --git a/pubber/bin/build b/pubber/bin/build index 1a43c94ed2..7eef9b55fc 100755 --- a/pubber/bin/build +++ b/pubber/bin/build @@ -10,7 +10,7 @@ cd $rundir/.. newest=$(ls -rt `find src/ ../gencode/java -type f` | tail -n 1) jarfile=build/libs/pubber-1.0-SNAPSHOT-all.jar -if [[ -f $jarfile && $jarfile -nt $newest ]]; then +if [[ -z $check && -f $jarfile && $jarfile -nt $newest ]]; then echo $jarfile up to date, skipping build. exit 0 fi diff --git a/pubber/src/main/java/daq/pubber/MqttPublisher.java b/pubber/src/main/java/daq/pubber/MqttPublisher.java index 6c787fa929..4c950b2ddb 100644 --- a/pubber/src/main/java/daq/pubber/MqttPublisher.java +++ b/pubber/src/main/java/daq/pubber/MqttPublisher.java @@ -8,8 +8,9 @@ import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.util.ISO8601DateFormat; import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableMap; import com.google.common.hash.Hashing; +import com.google.udmi.util.SiteModel; +import com.google.udmi.util.SiteModel.ClientInfo; import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; @@ -30,8 +31,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.http.ConnectionClosedException; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; @@ -51,7 +50,6 @@ */ public class MqttPublisher { - private static final String ID_FORMAT = "projects/%s/locations/%s/registries/%s/devices/%s"; private static final Logger LOG = LoggerFactory.getLogger(MqttPublisher.class); private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) @@ -66,8 +64,6 @@ public class MqttPublisher { private static final int INITIALIZE_TIME_MS = 20000; private static final String MESSAGE_TOPIC_FORMAT = "/devices/%s/%s"; private static final String BROKER_URL_FORMAT = "ssl://%s:%s"; - private static final Pattern ID_PATTERN = Pattern.compile( - "projects/(.*)/locations/(.*)/registries/(.*)/devices/(.*)"); private static final int PUBLISH_THREAD_COUNT = 10; private static final String HANDLER_KEY_FORMAT = "%s/%s"; private static final int TOKEN_EXPIRY_MINUTES = 60; @@ -99,7 +95,7 @@ public class MqttPublisher { MqttPublisher(PubberConfiguration configuration, Consumer onError) { this.configuration = configuration; - ClientInfo clientIdParts = parseClientId(configuration.endpoint.client_id); + ClientInfo clientIdParts = SiteModel.parseClientId(configuration.endpoint.client_id); this.projectId = clientIdParts.projectId; this.cloudRegion = clientIdParts.cloudRegion; this.registryId = clientIdParts.registryId; @@ -107,48 +103,13 @@ public class MqttPublisher { validateCloudIotOptions(); } - static class ClientInfo { - String projectId; - String cloudRegion; - String registryId; - String deviceId; - } - - /** - * Parse a GCP clientId string into component parts including project, etc... - * - * @param clientId client id to parse - * @return bucket of parameters - */ - public static ClientInfo parseClientId(String clientId) { - if (clientId == null) { - throw new IllegalArgumentException("client_id not specified"); - } - Matcher matcher = ID_PATTERN.matcher(clientId); - if (!matcher.matches()) { - throw new IllegalArgumentException( - String.format("client_id %s does not match pattern %s", clientId, ID_PATTERN.pattern())); - } - ClientInfo clientInfo = new ClientInfo(); - clientInfo.projectId = matcher.group(1); - clientInfo.cloudRegion = matcher.group(2); - clientInfo.registryId = matcher.group(3); - clientInfo.deviceId = matcher.group(4); - return clientInfo; - } - - public static String getClientId(String projectId, String cloudRegion, String registryId, - String deviceId) { - return String.format(ID_FORMAT, projectId, cloudRegion, registryId, deviceId); - } - private String getClientId(String deviceId) { // Create our MQTT client. The mqttClientId is a unique string that identifies this device. For // Google Cloud IoT, it must be in the format below. if (configuration.endpoint.client_id != null) { return configuration.endpoint.client_id; } - return getClientId(projectId, cloudRegion, registryId, deviceId); + return SiteModel.getClientId(projectId, cloudRegion, registryId, deviceId); } boolean isActive() { diff --git a/pubber/src/main/java/daq/pubber/Pubber.java b/pubber/src/main/java/daq/pubber/Pubber.java index b7421db6b8..77a5053c86 100644 --- a/pubber/src/main/java/daq/pubber/Pubber.java +++ b/pubber/src/main/java/daq/pubber/Pubber.java @@ -18,7 +18,7 @@ import com.google.daq.mqtt.util.CatchingScheduledThreadPoolExecutor; import com.google.udmi.util.GeneralUtils; import com.google.udmi.util.SiteModel; -import daq.pubber.MqttPublisher.ClientInfo; +import com.google.udmi.util.SiteModel.ClientInfo; import daq.pubber.MqttPublisher.PublisherException; import daq.pubber.PubSubClient.Bundle; import java.io.ByteArrayOutputStream; @@ -177,7 +177,7 @@ public Pubber(String configPath) { configuration = sanitizeConfiguration( OBJECT_MAPPER.readValue(configFile, PubberConfiguration.class)); checkArgument(MQTT.equals(configuration.endpoint.protocol), "protocol mismatch"); - ClientInfo clientInfo = MqttPublisher.parseClientId(configuration.endpoint.client_id); + ClientInfo clientInfo = SiteModel.parseClientId(configuration.endpoint.client_id); projectId = clientInfo.projectId; deviceId = clientInfo.deviceId; outDir = new File(PUBBER_OUT); @@ -347,8 +347,8 @@ private void initializeDevice() { if (configuration.sitePath != null) { siteModel = new SiteModel(configuration.sitePath); - siteModel.initialize(projectId, deviceId); - configuration.endpoint = siteModel.getEndpointConfig(); + siteModel.initialize(); + configuration.endpoint = siteModel.makeEndpointConfig(projectId, deviceId); processDeviceMetadata(siteModel.getMetadata(configuration.deviceId)); } else if (pubSubClient != null) { pullDeviceMessage(); @@ -929,8 +929,8 @@ private BlobBlobsetState ensureBlobsetState(SystemBlobsets iotEndpointConfig) { } private String getClientId(String forRegistry) { - String cloudRegion = MqttPublisher.parseClientId(configuration.endpoint.client_id).cloudRegion; - return MqttPublisher.getClientId(projectId, cloudRegion, forRegistry, deviceId); + String cloudRegion = SiteModel.parseClientId(configuration.endpoint.client_id).cloudRegion; + return SiteModel.getClientId(projectId, cloudRegion, forRegistry, deviceId); } private String extractConfigBlob(String blobName) { diff --git a/schema/building_config.json b/schema/building_config.json new file mode 100644 index 0000000000..676062cb86 --- /dev/null +++ b/schema/building_config.json @@ -0,0 +1,36 @@ +{ + "title": "Building Config", + "description": "[Discovery result](../docs/specs/discovery.md) with implicit enumeration", + "type": "object", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "timestamp": { + "description": "RFC 3339 timestamp the configuration was generated", + "type": "string", + "format": "date-time", + "examples": ["2019-01-17T14:02:29.364Z"] + }, + "version": { + "description": "Version of the UDMI schema", + "type": "string" + }, + "guid": { + "description": "device guid", + "type": "string" + }, + "status": { + "$ref": "file:common.json#/definitions/entry" + }, + "translation": { + "description": "Point translations", + "existingJavaType": "java.util.HashMap", + "additionalProperties": false, + "patternProperties": { + "": { + "$ref": "file:building_config_translation.json" + } + } + } + } +} diff --git a/schema/building_config_translation.json b/schema/building_config_translation.json new file mode 100644 index 0000000000..96f6ce9330 --- /dev/null +++ b/schema/building_config_translation.json @@ -0,0 +1,17 @@ +{ + "title": "Building Config Translation", + "description": "[Discovery result](../docs/specs/discovery.md) with implicit enumeration", + "type": "object", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "present_value": { + "description": "dotted path to present_value field", + "type": "string" + }, + "units": { + }, + "states": { + } + } +} diff --git a/schema/category.json b/schema/category.json index 1affce7342..51afc2fcb2 100644 --- a/schema/category.json +++ b/schema/category.json @@ -20,6 +20,7 @@ { "pattern": "^discovery\\.family\\.scan$" }, { "pattern": "^discovery\\.device\\.enumerate$" }, { "pattern": "^discovery\\.point\\.describe$" }, + { "pattern": "^mapping\\.device\\.apply$" }, { "pattern": "^blobset\\.blob\\.receive$" }, { "pattern": "^blobset\\.blob\\.fetch$" }, { "pattern": "^blobset\\.blob\\.apply$" }, diff --git a/schema/command_mapping.json b/schema/command_mapping.json new file mode 100644 index 0000000000..490aee2ba3 --- /dev/null +++ b/schema/command_mapping.json @@ -0,0 +1,8 @@ +{ + "title": "Mapping Command", + "description": "[Mapping command](../docs/specs/mapping.md) for provisioning", + "type": "object", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "$ref": "file:building_config.json" +} diff --git a/schema/config_discovery_family.json b/schema/config_discovery_family.json index 37e3c35ba3..ff8e073058 100644 --- a/schema/config_discovery_family.json +++ b/schema/config_discovery_family.json @@ -24,5 +24,8 @@ "description": "Indicates implicit enumeration of discovered devices", "type": "boolean" } - } + }, + "required": [ + "generation" + ] } diff --git a/schema/config_mapping.json b/schema/config_mapping.json new file mode 100644 index 0000000000..67898b0028 --- /dev/null +++ b/schema/config_mapping.json @@ -0,0 +1,29 @@ +{ + "title": "Mapping Config", + "description": "Configuration for [mapping](../docs/specs/mapping.md)", + "type": "object", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "timestamp": { + "description": "RFC 3339 timestamp the configuration was generated", + "type": "string", + "format": "date-time", + "examples": ["2019-01-17T14:02:29.364Z"] + }, + "version": { + "description": "Version of the UDMI schema", + "type": "string" + }, + "devices": { + "description": "Configuration of mapped devices", + "existingJavaType": "java.util.HashMap", + "additionalProperties": false, + "patternProperties": { + "": { + "$ref": "file:config_mapping_device.json" + } + } + } + } +} diff --git a/schema/config_mapping_device.json b/schema/config_mapping_device.json new file mode 100644 index 0000000000..26fcf2fd7a --- /dev/null +++ b/schema/config_mapping_device.json @@ -0,0 +1,26 @@ +{ + "title": "Device Mapping Config", + "description": "Configuration for [mapping](../docs/specs/mapping.md)", + "type": "object", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "guid": { + "description": "Device guid", + "type": "string" + }, + "applied": { + "description": "Last time the mapping was successfully applied for this device", + "type": "string", + "format": "date-time" + }, + "requested": { + "description": "Timestamp of requested device model export", + "type": "string", + "format": "date-time" + }, + "status": { + "$ref": "file:common.json#/definitions/entry" + } + } +} diff --git a/schema/envelope.json b/schema/envelope.json index 4aec304079..1d153849b8 100644 --- a/schema/envelope.json +++ b/schema/envelope.json @@ -26,8 +26,8 @@ "subFolder": { "enum": [ "update", - "audit", "discovery", + "mapping", "system", "gateway", "swarm", diff --git a/schema/event_mapping.json b/schema/event_mapping.json index 5524cdc63a..e5ed24e517 100644 --- a/schema/event_mapping.json +++ b/schema/event_mapping.json @@ -1,26 +1,8 @@ { - "title": "Discovery Event", - "description": "[Discovery result](../docs/specs/discovery.md) with implicit enumeration", + "title": "Mapping Event", + "description": "[Mapping result](../docs/specs/mapping.md) with implicit enumeration", "type": "object", "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": false, - "properties": { - "timestamp": { - "description": "RFC 3339 timestamp the discover telemetry event was generated", - "type": "string", - "format": "date-time", - "examples": ["2019-01-17T14:02:29.364Z"] - }, - "version": { - "description": "Version of the UDMI schema", - "type": "string" - }, - "status": { - "$ref": "file:common.json#/definitions/entry" - } - }, - "required": [ - "timestamp", - "version" - ] + "$ref": "file:building_config.json" } diff --git a/schema/state_mapping.json b/schema/state_mapping.json new file mode 100644 index 0000000000..f903089941 --- /dev/null +++ b/schema/state_mapping.json @@ -0,0 +1,29 @@ +{ + "title": "Mapping State", + "description": "State for [mapping](../docs/specs/mapping.md)", + "type": "object", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "timestamp": { + "description": "RFC 3339 timestamp the configuration was generated", + "type": "string", + "format": "date-time", + "examples": ["2019-01-17T14:02:29.364Z"] + }, + "version": { + "description": "Version of the UDMI schema", + "type": "string" + }, + "devices": { + "description": "Mapping state for all devices", + "additionalProperties": false, + "existingJavaType": "java.util.HashMap", + "patternProperties": { + "": { + "$ref": "file:state_mapping_device.json" + } + } + } + } +} diff --git a/schema/state_mapping_device.json b/schema/state_mapping_device.json new file mode 100644 index 0000000000..7b1b9f6fc6 --- /dev/null +++ b/schema/state_mapping_device.json @@ -0,0 +1,41 @@ +{ + "title": "Device Mapping State", + "description": "State for [mapping](../docs/specs/mapping.md)", + "type": "object", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "guid": { + "description": "Device guid", + "type": "string" + }, + "imported": { + "description": "Last time the mapping was imported", + "type": "string", + "format": "date-time" + }, + "discovered": { + "description": "Last received discovery message", + "type": "string", + "format": "date-time" + }, + "predicted": { + "description": "Last recommendation staging (result of automatic prediction)", + "type": "string", + "format": "date-time" + }, + "promoted": { + "description": "Last recommendation promotion (result of manual QA)", + "type": "string", + "format": "date-time" + }, + "exported": { + "description": "Last time this device mapping was exported", + "type": "string", + "format": "date-time" + }, + "status": { + "$ref": "file:common.json#/definitions/entry" + } + } +} diff --git a/tests/command_mapping.tests/mapping.json b/tests/command_mapping.tests/mapping.json new file mode 100644 index 0000000000..97a26464e7 --- /dev/null +++ b/tests/command_mapping.tests/mapping.json @@ -0,0 +1,31 @@ +// +// This message represents an import of an existing device mapping into the mapper. +// +// Note that the building and device id are included as part of the message envelope. +// +{ + "version": "1.3.14", + "timestamp": "2018-08-26T21:39:29.364Z", + "guid": "21387BBA787ADD", + "translation": { + "zone_air_temperature_sensor": { + "present_value": "points.temp_1.present_value", + "units": { + "key": "pointset.points.temp_1.units", + "values": { + "degrees_celsius": "degC" + } + } + }, + "supply_air_isolation_damper_command": { + "present_value": "points.damper_1.present_value", + "states": { + "OPEN": "1", + "CLOSED": [ + "2", + "3" + ] + } + } + } +} diff --git a/tests/command_mapping.tests/mapping.out b/tests/command_mapping.tests/mapping.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/config.tests/continuous.json b/tests/config.tests/continuous.json index 2a8b485b49..1f650657d9 100644 --- a/tests/config.tests/continuous.json +++ b/tests/config.tests/continuous.json @@ -8,6 +8,7 @@ "discovery": { "families": { "bacnet": { + "generation": "2018-08-26T21:39:29.364Z", "scan_interval_sec": 600 } } diff --git a/tests/config_mapping.tests/mapping.json b/tests/config_mapping.tests/mapping.json new file mode 100644 index 0000000000..b464b1f057 --- /dev/null +++ b/tests/config_mapping.tests/mapping.json @@ -0,0 +1,31 @@ +// +// This message represents the entire high-level config of a recommendation model, +// as given to the mapping component. It therefore reflects the external (to a mapping engine) +// view of what has happened outside of the mapping engine itself. +// +// The building id is defined by the message envelope. +// +// General overview of the external representation: +// 1. Applied: An exported recommendation was received and applied to the system. +// 2. Request: Last time an export was requested from the system. +// +// Comaprison of timestamps would trigger action by the external (non-mapper) system: +// imported < applied: The system should import (send command) the applied mapping into the mapper +// +{ + "version": "1.3.14", + "timestamp": "2018-08-28T21:39:29.364Z", + "devices": { + "FCU-123": { + "guid": "21387BBA787ADD", + "applied": "2018-08-27T22:39:12.364Z", // Last time a mapping was successfully applied externally + "requested": "2018-08-27T22:39:12.364Z", // Timestamp of requested model export + "status": { + "message": "Update in progress", + "category": "mapping.device.apply", + "timestamp": "2018-08-28T21:39:30.364Z", + "level": 500 + } + } + } +} diff --git a/tests/config_mapping.tests/mapping.out b/tests/config_mapping.tests/mapping.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/event_mapping.tests/mapping.json b/tests/event_mapping.tests/mapping.json new file mode 100644 index 0000000000..895e1e40f6 --- /dev/null +++ b/tests/event_mapping.tests/mapping.json @@ -0,0 +1,31 @@ +// +// This message represents an output from the mapper for the mapping of a particular device. +// +// Note that the building and device id are included as part of the message envelope. +// +{ + "version": "1.3.14", + "timestamp": "2018-08-26T21:39:29.364Z", + "guid": "21387BBA787ADD", + "translation": { + "zone_air_temperature_sensor": { + "present_value": "points.temp_1.present_value", + "units": { + "key": "pointset.points.temp_1.units", + "values": { + "degrees_celsius": "degC" + } + } + }, + "supply_air_isolation_damper_command": { + "present_value": "points.damper_1.present_value", + "states": { + "OPEN": "1", + "CLOSED": [ + "2", + "3" + ] + } + } + } +} diff --git a/tests/event_mapping.tests/mapping.out b/tests/event_mapping.tests/mapping.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/event_mapping.tests/prediction.json b/tests/event_mapping.tests/prediction.json new file mode 100644 index 0000000000..5ed99f1f28 --- /dev/null +++ b/tests/event_mapping.tests/prediction.json @@ -0,0 +1,13 @@ +// +// This message represents a predictive model for a device. Includes all the +// probabalistic information necessary for an agent (human or otherwise) to +// specify what the actual translation should be. This is an intermediate +// state that requires 'promotion' before being properly exported. +// +{ + "version": "1.3.14", + "timestamp": "2018-08-26T21:39:29.364Z", + "prediction": { + // TODO: Include details from staged_equip_response.txt + } +} diff --git a/tests/event_mapping.tests/prediction.out b/tests/event_mapping.tests/prediction.out new file mode 100644 index 0000000000..11a2bfe8cf --- /dev/null +++ b/tests/event_mapping.tests/prediction.out @@ -0,0 +1,2 @@ +1 schema violations found + object instance has properties which are not allowed by the schema: ["prediction"] diff --git a/tests/event_mapping.tests/staged_equip_response.txt b/tests/event_mapping.tests/staged_equip_response.txt new file mode 100644 index 0000000000..d7e69fbb21 --- /dev/null +++ b/tests/event_mapping.tests/staged_equip_response.txt @@ -0,0 +1,52 @@ +{ + "building_name": "US-MTV-1804", // building id from discovery message + "equipment": + [ + { + "data": + { + "device_id": "4b:9a:84:17:17:6c", // from UDMI discovery, ties back to a specific device + "model.equip_type_predictions": // top five predictions + { + "AHU": 0.10, + "BLR": 0.15, + "HX": 0.20, + "MAU": 0.25, + "VAV": 0.30 + }, + "entity_type": "VAV", // top prediction + "model.equip_name": "VAV-1", // predicted equipment instance ID + "guid": "8cf8c6ea-c8aa-412c-914d-947947fa51ba", // UUID V4 + "model.parent": "AHU-1", // predicted parent equipment ID + }, + "created": "2022-03-25T18:16:36+00:00", + "last_promoted": null, + "modified": null, + } + ], + "points_by_equip_name": + { + "VAV-1": + [ + { + "data": + { + "object_identifier": "('analogInupt', 1)", // from UDMI discovery + "model.point_type_predictions": // top five predictions + { + "building_air_static_pressure_sensor": 0.10, + "condensing_supply_water_temperature_sensor": 0.15, + "exhaust_fan_power_sensor": 0.20, + "discharge_fan_speed_percentage_sensor": 0.25, + "zone_air_relative_humidity_sensor": 0.30 + }, + "telemetry_field_name": "zone_air_relative_humidity_sensor", // top prediction + }, + "created": "2022-03-25T18:16:36+00:00", + "last_promoted": null, + "modified": null, + "entity.guid": "8cf8c6ea-c8aa-412c-914d-947947fa51ba", + } + ] + } +} diff --git a/tests/event_system.tests/errors.out b/tests/event_system.tests/errors.out index 9e2dc926d2..c8bce310b4 100644 --- a/tests/event_system.tests/errors.out +++ b/tests/event_system.tests/errors.out @@ -1,5 +1,5 @@ 4 schema violations found - instance failed to match exactly one schema (matched 0 out of 25) + instance failed to match exactly one schema (matched 0 out of 26) instance type (string) does not match any allowed primitive type (allowed: ["object"]) numeric instance is lower than the required minimum (minimum: 100, found: 60) object has missing required properties (["message","timestamp"]) diff --git a/tests/state_mapping.tests/mapping.json b/tests/state_mapping.tests/mapping.json new file mode 100644 index 0000000000..4919b7608b --- /dev/null +++ b/tests/state_mapping.tests/mapping.json @@ -0,0 +1,31 @@ +// +// This message represents the entire high-level state of a recommendation, +// as given by the mapping component. It therefore reflects the internal state +// of the mapper as might be of interest to the outside world. +// +// Note that building id is defined as part of the message envelope. +// +// General workflow is (not all steps will always be present): +// 1. Import: Existing mappings can be imported from an external source +// 2. Discovery: Mapper receives discovery message +// 3. Prediction: Internal algorithm predicts what it might be and gives options +// 4. Promotion: Some process for promoting a single option based on prediction +// 5. Export: Result of promotion are exported for external consumption +// +// Comparison of timestamps with the related config block would trigger action by the mapper: +// requested > exported: The mapper should export (send event) the indicated mapping +// +{ + "version": "1.3.14", + "timestamp": "2018-08-26T21:39:29.364Z", + "devices": { + "FCU-123": { + "guid": "21387BBA787ADD", + "imported": "2018-08-26T21:39:28.364Z", // Last time the mapping was imported + "discovered": "2018-08-26T21:39:29.364Z", // Last received discovery message + "predicted": "2018-08-28T21:59:18.364Z", // Last recommendation staging (result of automatic prediction) + "promoted": "2018-08-28T22:39:12.364Z", // Last recommendation promotion (result of manual QA) + "exported": "2018-08-28T22:39:12.364Z" // Last time this device mapping was exported + } + } +} diff --git a/tests/state_mapping.tests/mapping.out b/tests/state_mapping.tests/mapping.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/validator/.idea/misc.xml b/validator/.idea/misc.xml index cce25b5886..6d74213105 100644 --- a/validator/.idea/misc.xml +++ b/validator/.idea/misc.xml @@ -1,6 +1,7 @@ + diff --git a/validator/.idea/runConfigurations/IotCoreProxy.xml b/validator/.idea/runConfigurations/IotCoreProxy.xml index 287a89a782..f3c80629b5 100644 --- a/validator/.idea/runConfigurations/IotCoreProxy.xml +++ b/validator/.idea/runConfigurations/IotCoreProxy.xml @@ -6,7 +6,7 @@