[
    {
        "id": "c81e9ded.1f863",
        "type": "uibuilder",
        "z": "18cb249f.38bafb",
        "name": "",
        "topic": "",
        "url": "uiswitch",
        "fwdInMessages": false,
        "allowScripts": false,
        "allowStyles": false,
        "copyIndex": true,
        "showfolder": false,
        "x": 620,
        "y": 1080,
        "wires": [
            [
                "9f8d4d57.3157e",
                "16aa3d7.761c5c3"
            ],
            [
                "ec4e6395.b7646"
            ]
        ]
    },
    {
        "id": "53ecf4d4.dfab4c",
        "type": "inject",
        "z": "18cb249f.38bafb",
        "name": "at_home: true",
        "topic": "",
        "payload": "{\"name\":\"at_home\",\"service_name\":\"at_home\",\"characteristic\":\"On\",\"value\":true}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 170,
        "y": 1060,
        "wires": [
            [
                "61f76ec.b2a469"
            ]
        ]
    },
    {
        "id": "8df7c15b.e3cc4",
        "type": "inject",
        "z": "18cb249f.38bafb",
        "name": "at_home: false",
        "topic": "",
        "payload": "{\"name\":\"at_home\",\"service_name\":\"at_home\",\"characteristic\":\"On\",\"value\":false}",
        "payloadType": "json",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 160,
        "y": 1100,
        "wires": [
            [
                "61f76ec.b2a469"
            ]
        ]
    },
    {
        "id": "b912e4ce.5a69e8",
        "type": "link in",
        "z": "18cb249f.38bafb",
        "name": "home-replay",
        "links": [
            "9f8d4d57.3157e",
            "ec4e6395.b7646",
            "6327f550.24f41c"
        ],
        "x": 215,
        "y": 1020,
        "wires": [
            [
                "61f76ec.b2a469"
            ]
        ]
    },
    {
        "id": "9f8d4d57.3157e",
        "type": "link out",
        "z": "18cb249f.38bafb",
        "name": "home-controls",
        "links": [
            "b912e4ce.5a69e8"
        ],
        "x": 755,
        "y": 1020,
        "wires": []
    },
    {
        "id": "ec4e6395.b7646",
        "type": "link out",
        "z": "18cb249f.38bafb",
        "name": "",
        "links": [
            "ae0fd0a1.2f9f7",
            "b912e4ce.5a69e8"
        ],
        "x": 755,
        "y": 1100,
        "wires": []
    },
    {
        "id": "61f76ec.b2a469",
        "type": "function",
        "z": "18cb249f.38bafb",
        "name": "cache by payload.name",
        "func": "/* jshint asi: true */\n\n// cache variable name - needs to be unique for each cache\nconst cacheVarName = 'ui_msgs'\n\n// saved context\nlet ui_msgs = context.get(cacheVarName) || {}\n\n// Handle cache control messages\nif (msg.hasOwnProperty('cacheControl')) {\n    // Replay cache if requested\n    if (msg.cacheControl === 'REPLAY') {\n        for (let name in ui_msgs) {\n            node.send({\n                \"topic\": name,\n                \"payload\": ui_msgs[name],\n                \"_socketId\": msg._socketId\n            })\n        }\n        return null\n    } else if (msg.cacheControl === 'CLEAR') {\n        // Or clear the cach (no msg sent)\n        context.set(cacheVarName, {})\n        return null\n    } else {\n        // or do nothing\n        return null\n    }\n}\n\n\n// ignore other uibuilder control messages\nif (msg.hasOwnProperty('uibuilderCtrl')) return null\n\nif (msg.hasOwnProperty('payload') && msg.payload.hasOwnProperty('name')) {\n    // Keep the last msg.payload by msg.payload.name\n    ui_msgs[msg.payload.name] = msg.payload\n    \n    // save context for next time\n    context.set(cacheVarName, ui_msgs)\n    \n    msg._socketId = null\n} else {\n    node.warn(\"no payload or payload.name\")\n    msg = null\n}\n\n// Show number of cached msgs in status\nnode.status({fill:'green',shape:'ring',text:'Cached: ' + Object.keys(ui_msgs).length})\n\nreturn msg;\n",
        "outputs": 1,
        "noerr": 0,
        "x": 410,
        "y": 1080,
        "wires": [
            [
                "c81e9ded.1f863"
            ]
        ]
    },
    {
        "id": "16aa3d7.761c5c3",
        "type": "debug",
        "z": "18cb249f.38bafb",
        "name": "uib output",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "x": 800,
        "y": 1060,
        "wires": []
    },
    {
        "id": "affc4151.63336",
        "type": "comment",
        "z": "18cb249f.38bafb",
        "name": "index.html",
        "info": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes\">\n\n    <title>Node-RED UI Builder</title>\n    <meta name=\"description\" content=\"Node-RED UI Builder - VueJS + bootstrap-vue version\">\n\n    <link rel=\"icon\" href=\"./images/node-blue.ico\">\n\n    <!-- See https://goo.gl/OOhYW5 -->\n    <link rel=\"manifest\" href=\"./manifest.json\">\n    <meta name=\"theme-color\" content=\"#3f51b5\">\n    <link type=\"text/css\" rel=\"stylesheet\" href=\"../uibuilder/vendor/bootstrap/dist/css/bootstrap.min.css\" />\n    <link type=\"text/css\" rel=\"stylesheet\" href=\"../uibuilder/vendor/bootstrap-vue/dist/bootstrap-vue.css\" />\n    \n    <link rel=\"stylesheet\" href=\"./index.css\" media=\"all\">\n</head>\n<body>\n    <div id=\"app\" v-cloak>\n      <b-container id=\"app_container\">           \n        <b-card no-body>\n          <b-tabs card small>\n            <b-tab title=\"Main\" active>\n              <b-card header=\"Control\" border-variant=\"primary\">\n                <acc-switch name=\"at_home\" v-model=\"v_value.at_home\" badge></acc-switch>\n                <acc-switch name=\"security_system\" v-model=\"v_value.security_system\"></acc-switch>\n                <acc-switch name=\"heating\" v-model=\"v_value.heating\"></acc-switch>\n                <acc-switch name=\"greenhouse\" v-model=\"v_value.greenhouse\"></acc-switch>\n              </b-card>\n            </b-tab>\n\n            <b-tab title=\"Accessories\">\n              <b-card header=\"Accessories\" border-variant=\"primary\">\n                <b-card-text>an accessories list ...</b-card-text>\n              </b-card>\n            </b-tab>\n          </b-tabs>\n          \n          <b-card v-if=debug header=\"Debug\" border-variant=\"info\">\n            <b-card-text v-if=\"msg\">last msg: {{msg.payload}}</b-card-text>\n            <b-card-text>accessories: {{accessories}}</b-card-text>\n            <b-card-text>v_value: {{v_value}}</b-card-text>\n          </b-card>\n        </b-card>\n      </b-container>\n    </div>\n    \n    <script src=\"../uibuilder/vendor/socket.io/socket.io.js\"></script>\n\n    <!--  Vendor Libraries - Load in the right order -->\n    <script src=\"../uibuilder/vendor/vue/dist/vue.js\"></script> <!-- dev version with component compiler -->\n    <!-- <script src=\"../uibuilder/vendor/vue/dist/vue.min.js\"></script>   prod version with component compiler -->\n    <!-- <script src=\"../uibuilder/vendor/vue/dist/vue.runtime.min.js\"></script>   prod version without component compiler -->\n    <script src=\"../uibuilder/vendor/bootstrap-vue/dist/bootstrap-vue.js\"></script>\n    <!-- Loading from CDN -->\n    <!-- <script src=\"https://unpkg.com/http-vue-loader\"></script> -->\n    <!-- Loading from npm installed version -->\n    <script src=\"../uibuilder/vendor/http-vue-loader/src/httpVueLoader.js\"></script>\n    \n    <!-- REQUIRED: Sets up Socket listeners and the msg object -->\n    <!-- <script src=\"./uibuilderfe.js\"></script>   //dev version -->\n    <script src=\"./uibuilderfe.min.js\"></script> <!--    //prod version -->\n    <!-- OPTIONAL: You probably want this. Put your custom code here -->\n    <script src=\"./index.js\"></script>\n</body>\n</html>\n\n",
        "x": 480,
        "y": 980,
        "wires": [],
        "icon": "node-red/parser-html.svg"
    },
    {
        "id": "9bd5106a.eb76",
        "type": "comment",
        "z": "18cb249f.38bafb",
        "name": "index.js",
        "info": "'use strict'\n\nnew Vue({\n  el: '#app',\n  components: {\n    'acc-switch': httpVueLoader('acc-switch.vue'),\n  },\n  \n  data: {\n    msg: {},\n    accessories: {},\n    v_value: {},\n    debug: false\n  },\n  \n  methods: {    \n  \n  },\n\n  mounted: function() {\n    //console.debug('[mounted] app mounted - setting up uibuilder watchers')\n    uibuilder.start()\n    \n    uibuilder.onChange('msg', function(msg) {\n      this.msg = msg\n      \n      if (msg.payload.value !== this.v_value[msg.payload.name]) {\n        console.debug('[uibuilder.onChange]', msg.payload)\n        Vue.set(this.accessories, msg.payload.name, msg.payload)\n        Vue.set(this.v_value, msg.payload.name, msg.payload.value)\n      }\n    }.bind(this))\n  }\n})\n",
        "x": 610,
        "y": 980,
        "wires": [],
        "icon": "font-awesome/fa-file-code-o"
    },
    {
        "id": "a362192e.f34228",
        "type": "comment",
        "z": "18cb249f.38bafb",
        "name": "acc-switch.vue",
        "info": "<template>\n  <div>\n    <b-form-checkbox\n      v-bind:checked=\"checked\"\n      v-on:change.native=\"sw_onChange($event.target.checked)\"\n      switch size=\"lg\"\n      >{{name}}\n      <b-badge v-if=\"badge\" variant=\"info\">{{checked? 'on': 'off'}}</b-badge>\n    </b-form-checkbox>\n  </div>\n</template>\n\n<script>\nmodule.exports = {\n  model: {\n    prop: 'checked',\n    event: 'change'\n  },\n  props: {\n    checked: Boolean,\n    name: String,\n    badge: {type: Boolean, default: false},\n  },\n  \n  data: function() {\n    return {\n    \n    }\n  },\n\n  methods: {\n    sw_onChange: function(value) {\n      console.debug('[sw_onChange]',this.name, value)\n      uibuilder.send({\n        \"topic\": \"sw_onChange\",\n        \"payload\": {\n          \"name\": this.name,\n          \"service_name\": this.name,\n          \"characteristic\":\"On\",\n          \"value\": value\n        }\n      })\n    }\n  },\n}\n</script>",
        "x": 760,
        "y": 980,
        "wires": [],
        "icon": "node-red/hash.svg"
    },
    {
        "id": "c8bec69.6d66c38",
        "type": "comment",
        "z": "18cb249f.38bafb",
        "name": "Cache Example: Instructions",
        "info": "Many thanks to cflurin for this example.\n\n## To install this example:\n\n1. Install `node-red-contrib-uibuilder` & import\n  from the library\n\n2. In the uibuilder Front-End Library Manager \n  add `http-vue-loader`\n\n3. Copy the code from the comment nodes \n  (index.htm and index.js) and paste into the \n  corresponding files.\n\n4. Copy the code from the comment node \n  acc-switch.vue and paste into a new file \n  `acc-switch.vue`.\n\n5. Change the name of the cache variable if copying this function.\n\nSee here for further details: https://discourse.nodered.org/t/front-end-based-on-uibuilder-1-component-acc-switch-vue/14962\n\nAuthor: https://discourse.nodered.org/u/cflurin\n\n## To try\n\n1. Click one of the inject nodes and watch \nthe \"At Home\" switch in the ui change.\n\n2, Click any of the switches in the ui and\nsee the debug output.\n\n3. Having set some of the switches, load a new\nbrowser tab (or a different browser) to the same\nui page and note that the cache ensures that\nall of the switches are the same.\n\n4. Change a switch on one of the tabs and note\nthat the other tab also changes.\n\n## Other things to try\n\nTry altering the cache function so that different \nbrowser tabs can have different switch settings.\n\nWhile this doesn't make particular sense for \nthis example as written, it is good to know\nthat you can do it if needed.\n\nHint: You will need to retain the socket ID.",
        "x": 280,
        "y": 980,
        "wires": []
    },
    {
        "id": "a87ef10c.5f61a",
        "type": "inject",
        "z": "18cb249f.38bafb",
        "name": "",
        "topic": "",
        "payload": "",
        "payloadType": "str",
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "x": 315,
        "y": 1140,
        "wires": [
            [
                "6c9d6822.3667c8"
            ]
        ],
        "l": false
    },
    {
        "id": "6c9d6822.3667c8",
        "type": "change",
        "z": "18cb249f.38bafb",
        "name": "Clear Cache",
        "rules": [
            {
                "t": "set",
                "p": "cacheControl",
                "pt": "msg",
                "to": "CLEAR",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 410,
        "y": 1140,
        "wires": [
            [
                "6327f550.24f41c"
            ]
        ]
    },
    {
        "id": "6327f550.24f41c",
        "type": "link out",
        "z": "18cb249f.38bafb",
        "name": "",
        "links": [
            "b912e4ce.5a69e8"
        ],
        "x": 515,
        "y": 1140,
        "wires": []
    }
]