diff --git a/netatmo-security-connector/.gitignore b/netatmo-security-connector/.gitignore new file mode 100644 index 0000000..dc2ebd4 --- /dev/null +++ b/netatmo-security-connector/.gitignore @@ -0,0 +1 @@ +NetatmoSecurity/node_modules/ diff --git a/netatmo-security-connector/NetatmoSecurity/.flowapprc b/netatmo-security-connector/NetatmoSecurity/.flowapprc new file mode 100644 index 0000000..5648956 --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/.flowapprc @@ -0,0 +1 @@ +{"service_name":"NetatmoSecurity_fl91ccd279ad5dcd19d902bc"} \ No newline at end of file diff --git a/netatmo-security-connector/NetatmoSecurity/action/v1/gethomedata.js b/netatmo-security-connector/NetatmoSecurity/action/v1/gethomedata.js new file mode 100644 index 0000000..ba7f3fb --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/action/v1/gethomedata.js @@ -0,0 +1,76 @@ +module.exports = { + + name: "gethomedata", + + title: "Gethomedata", + + description: "", + version: "v1", + + input:{ + title: "Gethomedata", + type: "object", + properties: { + home_id :{ + title: "home_id", + displayTitle: "Home ID", + type: "string" + } + } + }, + + output: { + title: "output", + type: "object", + displayTitle: "Output", + properties: { + + } + }, + + mock_input:{}, + + execute: function(input, output){ + // to access auth info use input.auth , eg: input.auth.username + // and to return output use output callback like this output(null, { 'notice' : 'successful'}) + // your code here + // output(null, { data : "OK"}); + var request = require("request"); + + var options = { + "method": "get", + "url": "https://api.netatmo.com/api/gethomedata", + "headers": { + "Accept": "application/json", + "Authorization": "Bearer " + input.auth.access_token + } + } + request(options, function(err, response, body) { + if (err) { + return output(err); + } + try { + if (body && typeof(body) === "string") { + body = JSON.parse(body); + } + } catch (e) { + return output(body); + }; + if (response.statusCode === 401) { + return output("Invalid access token"); + } + if (response.statusCode !== 200) { + return output("Error Details"); + } + if (response.statusCode === 200) { + return output(null, body); + } + output(body); + + }) + + + + } + +} diff --git a/netatmo-security-connector/NetatmoSecurity/action/v1/gethomestatus.js b/netatmo-security-connector/NetatmoSecurity/action/v1/gethomestatus.js new file mode 100644 index 0000000..5b8d5f4 --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/action/v1/gethomestatus.js @@ -0,0 +1,77 @@ +module.exports = { + + name: "gethomestatus", + + title: "Gethomestatus", + + description: "", + version: "v1", + + input:{ + title: "Gethomestatus", + type: "object", + properties: { + home_id :{ + title: "home_id", + displayTitle: "Home ID", + type: "string" + } + } + }, + + output: { + title: "output", + type: "object", + displayTitle: "Output", + properties: { + + } + }, + + mock_input:{}, + + execute: function(input, output){ + // to access auth info use input.auth , eg: input.auth.username + // and to return output use output callback like this output(null, { 'notice' : 'successful'}) + // your code here + // output(null, { data : "OK"}); + + + var request = require("request"); + + var options = { + "method": "get", + "url": "https://api.netatmo.com/api/homestatus?home_id=" + input.home_id, + "headers": { + "Accept": "application/json", + "Authorization": "Bearer " + input.auth.access_token + } + } + request(options, function(err, response, body) { + if (err) { + return output(err); + } + try { + if (body && typeof(body) === "string") { + body = JSON.parse(body); + } + } catch (e) { + return output(body); + }; + if (response.statusCode === 401) { + return output("Invalid access token"); + } + if (response.statusCode !== 200) { + return output(body); + } + if (response.statusCode === 200) { + return output(null, body); + } + output(body); + + }) + + + } + +} diff --git a/netatmo-security-connector/NetatmoSecurity/action/v1/getnextevents.js b/netatmo-security-connector/NetatmoSecurity/action/v1/getnextevents.js new file mode 100644 index 0000000..52d8ec2 --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/action/v1/getnextevents.js @@ -0,0 +1,83 @@ +module.exports = { + + name: "getnextevents", + + title: "Getnextevents", + + description: "", + version: "v1", + + input:{ + title: "Getnextevents", + type: "object", + properties: { + home_id :{ + title: "home_id", + displayTitle: "Home ID", + type: "string" + }, + event_id :{ + title: "event_id", + displayTitle: "Before this event", + type: "string" + }, + size: { + title: "size", + displayTitle: "Number of events (default 30)", + type: "string" + } + } + }, + + output: { + title: "output", + type: "object", + displayTitle: "Output", + properties: { + } + }, + + mock_input:{}, + + execute: function(input, output){ + // to access auth info use input.auth , eg: input.auth.username + // and to return output use output callback like this output(null, { 'notice' : 'successful'}) + // your code here + + var request = require("request"); + + var options = { + "method": "get", + "url": "https://api.netatmo.com/api/getnextevents?home_id=" + input.home_id + "&event_id=" + input.event_id + "&size=" + input.size, + "headers": { + "Accept": "application/json", + "Authorization": "Bearer " + input.auth.access_token + } + } + request(options, function(err, response, body) { + if (err) { + return output(err); + } + try { + if (body && typeof(body) === "string") { + body = JSON.parse(body); + } + } catch (e) { + return output(body); + }; + if (response.statusCode === 401) { + return output("Invalid access token"); + } + if (response.statusCode !== 200) { + return output(body); + } + if (response.statusCode === 200) { + return output(null, body); + } + output(body); + + }) + + } + +} diff --git a/netatmo-security-connector/NetatmoSecurity/auth.conf b/netatmo-security-connector/NetatmoSecurity/auth.conf new file mode 100644 index 0000000..44e0d89 --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/auth.conf @@ -0,0 +1,4 @@ +{ + "username": "", + "password": "" +} diff --git a/netatmo-security-connector/NetatmoSecurity/authentication.js b/netatmo-security-connector/NetatmoSecurity/authentication.js new file mode 100644 index 0000000..9fb4ce5 --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/authentication.js @@ -0,0 +1,13 @@ +module.exports = { + label: "Connect to NetatmoSecurity", + mock_input: { + access_token: "" + }, + oauth: "netatmo_camera_4a4b969c20", + validate: function (input, output) { + // auth credentials will be available in input.auth.access_token + // callback pattern + // output(error, success) + output(null, true) + } +} \ No newline at end of file diff --git a/netatmo-security-connector/NetatmoSecurity/icon/icon.png b/netatmo-security-connector/NetatmoSecurity/icon/icon.png new file mode 100644 index 0000000..c2b65dc Binary files /dev/null and b/netatmo-security-connector/NetatmoSecurity/icon/icon.png differ diff --git a/netatmo-security-connector/NetatmoSecurity/index.json b/netatmo-security-connector/NetatmoSecurity/index.json new file mode 100644 index 0000000..6e50433 --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/index.json @@ -0,0 +1,17 @@ +{ + "name": "NetatmoSecurity", + "description": "Netatmo Security Camera connector", + "triggers": [], + "actions": [ + "/v1/gethomedata", + "/v1/gethomestatus", + "/v1/getnextevents" + ], + "version": 1, + "auth_type": "oauth", + "docs_link": "http://docs.example.com", + "oauth_provider": "netatmo_camera_4a4b969c20", + "oauthStatus": "deployed", + "appId": "44e90f51-9b6c-4651-a22a-bf756bf0adce", + "guid": "8be1585c-a8c5-4d57-9b1d-fc3780d6cc69" +} \ No newline at end of file diff --git a/netatmo-security-connector/NetatmoSecurity/oauth.json b/netatmo-security-connector/NetatmoSecurity/oauth.json new file mode 100644 index 0000000..fbb54e3 --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/oauth.json @@ -0,0 +1,51 @@ +{ + "type": "oauth2", + "title": "netatmo_camera", + "clientId": "", + "clientSecret": "", + "authURL": "https://api.netatmo.com/oauth2/authorize", + "tokenURL": "https://api.netatmo.com/oauth2/token", + "preAuthProcessing": { + }, + "authQueryParams": { + "state": "ab82aff8dd2caf097e6", + "scope": "read_camera" + }, + + "preTokenProcessing": { + }, + + "tokenParams": { + "method": "", + "headers": {}, + "data": { + "client_id": "{client_id}", + "client_secret": "{client_secret}", + "redirect_uri": "{redirect_uri}", + "grant_type": "authorization_code" + } + }, + "preRefreshProcessing": { + }, + "refreshParams": { + "client_id": "{client_id}", + "client_secret": "{client_secret}", + "redirect_uri": "{redirect_uri}", + "grant_type": "refresh_token" + }, + "requiredParams": [ + ], + "refreshURL": "{tokenURL}", + "scope": { + "Read Camera Scope": "read_camera" + }, + "validate": { + "url": "ANY API URL TO VALIDATE TOKEN OF THIRD PARTY SERVICE", + "headers": { + "Authorization": "Bearer {access_token}" + }, + "query": { + } + }, + "redirectURL": "https://auth-int.webmethods.io/auth/oauth/netatmo_camera_4a4b969c20/fl91ccd279ad5dcd19d902bc/return" +} \ No newline at end of file diff --git a/netatmo-security-connector/NetatmoSecurity/package-lock.json b/netatmo-security-connector/NetatmoSecurity/package-lock.json new file mode 100644 index 0000000..381c802 --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/package-lock.json @@ -0,0 +1,383 @@ +{ + "name": "netatmosecurity", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@webmethodsio/cli-sdk": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@webmethodsio/cli-sdk/-/cli-sdk-1.0.0.tgz", + "integrity": "sha512-XQycpmMscE6V3rVNlcFI1BWNKuVKSQOViovr05GRqlA2PR5Sl1Qc8xki70N5LovoDcP1QbM7567CIx1Tmn22oA==", + "requires": { + "lodash": "4.17.5" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "asn1": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", + "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=" + }, + "assert-plus": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", + "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=" + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "aws-sign2": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", + "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=" + }, + "bl": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", + "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", + "requires": { + "readable-stream": "~1.0.26" + } + }, + "bluebird": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=" + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.x.x" + } + }, + "caseless": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.9.0.tgz", + "integrity": "sha1-t7Zc5r8UE4hlOc/VM/CzDv+pz4g=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "combined-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", + "requires": { + "delayed-stream": "0.0.5" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.x.x" + } + }, + "ctype": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", + "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=" + }, + "delayed-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", + "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", + "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=", + "requires": { + "async": "~0.9.0", + "combined-stream": "~0.0.4", + "mime-types": "~2.0.3" + } + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "^1.0.0" + } + }, + "har-validator": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-1.8.0.tgz", + "integrity": "sha1-2DhCsOtMQ1lgrrEIoGejqpTA7rI=", + "requires": { + "bluebird": "^2.9.30", + "chalk": "^1.0.0", + "commander": "^2.8.1", + "is-my-json-valid": "^2.12.0" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "hawk": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-2.3.1.tgz", + "integrity": "sha1-HnMc45RH+h0PbXB/e87r7A/R7B8=", + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + } + }, + "hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=" + }, + "http-signature": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", + "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", + "requires": { + "asn1": "0.1.11", + "assert-plus": "^0.1.5", + "ctype": "0.5.3" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==" + }, + "is-my-json-valid": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz", + "integrity": "sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==", + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=" + }, + "lodash": { + "version": "4.17.5", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", + "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==" + }, + "mime-db": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", + "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=" + }, + "mime-types": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", + "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=", + "requires": { + "mime-db": "~1.12.0" + } + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, + "oauth-sign": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.6.0.tgz", + "integrity": "sha1-fb6uRPbKRU4fFoRR1jB0ZzWBPOM=" + }, + "psl": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", + "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.4.2.tgz", + "integrity": "sha1-9854jld33wtQENp/fE5zujJHD1o=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "request": { + "version": "2.55.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.55.0.tgz", + "integrity": "sha1-11wc32eddrsQD5v/4f5VG1wk6T0=", + "requires": { + "aws-sign2": "~0.5.0", + "bl": "~0.9.0", + "caseless": "~0.9.0", + "combined-stream": "~0.0.5", + "forever-agent": "~0.6.0", + "form-data": "~0.2.0", + "har-validator": "^1.4.0", + "hawk": "~2.3.0", + "http-signature": "~0.10.0", + "isstream": "~0.1.1", + "json-stringify-safe": "~5.0.0", + "mime-types": "~2.0.1", + "node-uuid": "~1.4.0", + "oauth-sign": "~0.6.0", + "qs": "~2.4.0", + "stringstream": "~0.0.4", + "tough-cookie": ">=0.12.0", + "tunnel-agent": "~0.4.0" + } + }, + "sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "requires": { + "hoek": "2.x.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/netatmo-security-connector/NetatmoSecurity/package.json b/netatmo-security-connector/NetatmoSecurity/package.json new file mode 100644 index 0000000..16f27a1 --- /dev/null +++ b/netatmo-security-connector/NetatmoSecurity/package.json @@ -0,0 +1,9 @@ +{ + "name": "netatmosecurity", + "version": "1.0.0", + "description": "Netatmo Security Camera connector", + "dependencies": { + "request": "2.55.0", + "@webmethodsio/cli-sdk": "*" + } +} diff --git a/netatmo-security-connector/README.md b/netatmo-security-connector/README.md new file mode 100644 index 0000000..a76c671 --- /dev/null +++ b/netatmo-security-connector/README.md @@ -0,0 +1,146 @@ +# Custom connector for Netatmo Security Camera + +This is a simple home automation example based on a Netatmo security camera (custom connector) as well as an integration to Philips Hue Lighting system. + +A simple workflow is triggered by the security camera detecting a person, and if the person is recognized, the Hue lights are controlled based on the individual's profile. + +The custom connector is based on the Netatmo camera (https://www.netatmo.com) and controlled by an app available on https://dev.netatmo.com. + +## Prerequisites + +To set up this example you need the following hardware devices: +- Netatmo Security Camera: https://www.netatmo.com/en-us/security/cam-indoor +- PHilips Hue Bridge and attached lighting: https://www2.meethue.com/en-us/starter-kits + +The corresponding user accounts need to be created in the respective web applications: +- Netatmo : [https://dev.netatmo.com] (dev.netatmo.com) +- Philips Hue: [https://account.meethue.com/account] (www.meethue.com) + +Additionally, you need valid credentials for webMethods.io Integration - [https://www.softwareag.cloud/site/product/webmethods-io-integration.html#/](https://www.softwareag.cloud/site/product/webmethods-io-integration.html#/). + + +## Create a custom connector for Netatmo security + +Follow the instructions on [https://docs.webmethods.io/integration/developer_guide/connector_builder/#gsc.tab=0](https://docs.webmethods.io/integration/developer_guide/connector_builder/#gsc.tab=0) to set up the connector framework by first installing the correct node.js version and then testing it. + +To deploy the custom connector example in the directory you need to first create an app and customize the oauth.json.template file with the correct credentials. + +### Create a new workflow with a Webhook triggered + +We need to first create a new workflow, triggered by a Webhook, so that we can tell Netatmo where to send event notifications. +This workflow will get invoked by the Netatmo security camera on all relevant events, e.g. movement detection, person detection events and others. + +![P1](./images/Image001.png) + +Copy the Webhook link created into the clipboard using the symbol at the right of the URL. + +![P2](./images/Image002.png) + +To test the Webhook trigger, you can enter the following test data into the body of the next page: + +{ + "user_id": "5c810xxxxxxx45f4", + "snapshot_id": "5d19bxxxxxx6380342", + "snapshot_key": "f0134210ff83fxxxxxxxf770090a423d9a5", + "snapshot_url": "https://netatmocameraimage.blob.core.windows.net/production/5d1xxxa5", + "event_type": "movement", + "camera_id": "70:exxxxxdd:a7", + "device_id": "70:exxxxdd:a7", + "home_id": "5c5d79xxxx08cd594", + "home_name": "Boulogne Billan.", + "event_id": "5d19baae369359e896380341", + "message": "Boulogne Billan: Movement detected by Indoor Camera", + "push_type": "NACamera-movement" +} + +![P3](./images/Image003.png) + +Connect the Trigger step to the end step and save the workflow for the moment. + +### Create a Netatmo app + +Log in to the Netatmo developer homepage at [https://dev.netatmo.com](https://dev.netatmo.com) and navigate to the myApps area. +Create a new app by providing name, description and email-id as required. + +![P4](./images/Image004.png) + +Scrolling down to the section "App Technical Parameters", fill in the webhook URL that you have copied from your workflow trigger. + +Take a note of the client ID and client secret keys listed here. You will need these to configure the oauth file before deployment of the custom connector. +Leave the redirect URL empty for now, we will come back to fill it out later. + +### Customize the oauth Authentication + +Edit the file oauth.json in the custom connector directory ./NetatmoSecurity. + +Fill in the client ID and secret that you have copied from the Netatmo app area replacing the text in the fields marked with <> brackets. +Save the oauth.json file and test the consistency of the custom connector by running: + +**_wmio test_** + +from the NetatmoSecurity directory. +Deploy the oauth custom authentication module by running: + +**_wmio oauth deploy_** + +![P5](./images/Image005.png) + +### Deploy the custom connector + +Finish by deploying the custom connector to your webMethods.io instance. + +**_wmio deploy_** + +![P6](./images/Image006.png) + +### Finish the Netatmo app configuration + +As a last step, we need to configure the callback URL in the netatmo app for the oauth credential process. +For this, you need to copy the URL at the end of the oauth.json file ("redirectURL") into the appropriate Netatmo app field ("redirect URI") that we had left blank before. +Don't forget to save the modified Netatmo app. + + +## Configure the home automation workflow + +### Netatmo custom connector steps + +You can now use the custom connector to view security camera information, for example by invoking the Gethomedata function to retrieve camera and other IDs: + +The first time you use the custom connector (called NetatmoSecurity) you will need to configure the credentials as usual by logging into the Netatmo callback link and providing the credentials: + +![P7](./images/Image007.png) + +After that, you can use the connector as usual to retrieve data from the security camera: + +![P8](./images/Image008.png) + +### A small example worflow to demonstrate home automation. + +The following small example can be used to also demonstrate Webhooks triggered by the Security camera and subsequent control of lighting elements, for example to automate lighting based on the person detected. + +![P9](./images/Image009.png) + + +## Summary + +A custom connector to integrate a Security camera (from Netatmo) has been used to demonstrate custom connector development for home automation purposes. +A possible application to control home lighting based on events (e.g. motion or person detection) would be a possible application. +Other possible applications would be triggering of alarms or notifications based on motion events. + + + + + + + + + + + + + + + + + + diff --git a/netatmo-security-connector/images/Image001.png b/netatmo-security-connector/images/Image001.png new file mode 100644 index 0000000..9400c48 Binary files /dev/null and b/netatmo-security-connector/images/Image001.png differ diff --git a/netatmo-security-connector/images/Image002.png b/netatmo-security-connector/images/Image002.png new file mode 100644 index 0000000..0806f4b Binary files /dev/null and b/netatmo-security-connector/images/Image002.png differ diff --git a/netatmo-security-connector/images/Image003.png b/netatmo-security-connector/images/Image003.png new file mode 100644 index 0000000..9aa0839 Binary files /dev/null and b/netatmo-security-connector/images/Image003.png differ diff --git a/netatmo-security-connector/images/Image004.png b/netatmo-security-connector/images/Image004.png new file mode 100644 index 0000000..53dc64e Binary files /dev/null and b/netatmo-security-connector/images/Image004.png differ diff --git a/netatmo-security-connector/images/Image005.png b/netatmo-security-connector/images/Image005.png new file mode 100644 index 0000000..efe46d6 Binary files /dev/null and b/netatmo-security-connector/images/Image005.png differ diff --git a/netatmo-security-connector/images/Image006.png b/netatmo-security-connector/images/Image006.png new file mode 100644 index 0000000..43e097f Binary files /dev/null and b/netatmo-security-connector/images/Image006.png differ diff --git a/netatmo-security-connector/images/Image007.png b/netatmo-security-connector/images/Image007.png new file mode 100644 index 0000000..04f208d Binary files /dev/null and b/netatmo-security-connector/images/Image007.png differ diff --git a/netatmo-security-connector/images/Image008.png b/netatmo-security-connector/images/Image008.png new file mode 100644 index 0000000..3c6c6d8 Binary files /dev/null and b/netatmo-security-connector/images/Image008.png differ diff --git a/netatmo-security-connector/images/Image009.png b/netatmo-security-connector/images/Image009.png new file mode 100644 index 0000000..550be4c Binary files /dev/null and b/netatmo-security-connector/images/Image009.png differ