{
  "context": {
    "name": "MQTT",
    "options": {
      "formatter": [
        {
          "transform": ".toLowerCase()"
        },
        {
          "regexkey": "\\s",
          "replace": "",
          "description": "Remove whitespace"
        },
        {
          "regexkey": "\\/",
          "replace": "",
          "description": "Remove /"
        },
        {
          "regexkey": "\\+",
          "replace": "",
          "description": "Remove +"
        },
        {
          "regexkey": "\\$",
          "replace": "",
          "description": "Remove $"
        },
        {
          "regexkey": "\\#",
          "replace": "",
          "description": "Remove #"
        }
      ],
      "rootTopic-DIRECTIONS": "You can override the root topic by renaming _rootTopic to rootTopic",
      "_rootTopic": "@bind=(state.equipment.alias).replace(' ','-').replace('/','').toLowerCase();",
      "clientId": "@bind='mqttjs_njsPC_'+Math.random().toString(16).substr(2, 8);",
      "willTopic": "state/status",
      "willPayload": "{\"val\":3,\"name\":\"lost\",\"desc\":\"Connection Lost\",\"percent\":0}"
    }
  },
  "events": [
    {
      "name": "config",
      "description": "Don't flood the MQTT bus.",
      "enabled": false
    },
    {
      "name": "controller",
      "description": "Emit time every minute",
      "enabled": true,
      "topics": [
        {
          "topic": "state/time",
          "message": "@bind=data.time;",
          "filter": "@bind=data.status.percent === 100;"
        },
        {
          "topic": "alias",
          "message": "@bind=data.alias;"
        },
        {
          "topic": "state/status",
          "message": "@bind=data.status;"
        },
        {
          "topic": "state/mode",
          "message": "@bind=data.mode;"
        },
        {
          "topic": "state/startTime",
          "message": "@bind=data.startTime;"
        }
      ]
    },
    {
      "name": "circuit",
      "description": "Populate the circuits topics",
      "topics": [
        {
          "topic": "state/circuits/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';,\"endTime\":\"@bind=data.endTime;\"}",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/circuits/@bind=data.id;/@bind=data.name;/isOn/string",
          "message": "@bind=data.isOn?'on':'off';",
          "description": "Bind 'on'/'off' as a message to the topic.",
          "enabled": false
        },
        {
          "topic": "state/circuits/@bind=data.id;/@bind=data.name;/isOn/boolean",
          "message": "@bind=data.isOn;",
          "description": "SAMPLE: Bind the isOn as a message to the topic.",
          "enabled": false
        },
        {
          "topic": "state/circuits/@bind=data.id;/@bind=data.name;/lightingTheme",
          "message": "{\"lightingTheme\":@bind=data.lightingTheme;}",
          "description": "SAMPLE: Bind the lighting theme to the topic.",
          "filter": "@bind=data.type.isLight === true;"
        },
        {
          "topic": "state/circuits/@bind=data.id;/customTopicFormatter/@bind=data.name;/isOn",
          "message": "@bind=data.isOn;",
          "description": "SAMPLE: Bind the isOn as a message to the topic with a custom replacer, qos and retain setting.",
          "formatter": [
            {
              "transform": ".toLowerCase()"
            },
            {
              "regexkey": "\\s",
              "replace": "__",
              "description": "Remove whitespace and replace with __"
            },
            {
              "regexkey": "\\/",
              "replace": "__",
              "description": "Remove / and replace with __"
            }
          ],
          "options": { "qos": 2 },
          "enabled": false
        },
        {
          "topic": "state/circuits/@bind=data.id;/@bind=data.name;/endTime",
          "message": "{\"id\":@bind=data.id;,\"endTime\":@bind=data.endTime;}",
          "description": "Bind endTime as a message to the state topic."
        },
        {
          "topic": "state/circuits/@bind=data.id;/@bind=data.name;/object",
          "message": "@bind=data;",
          "description": "SAMPLE: Bind a JSON object as a message to the topic.",
          "enabled": false
        }
      ]
    },
    {
      "name": "virtualCircuit",
      "description": "Populate the virtual circuits topics",
      "topics": [
        {
          "topic": "state/virtualcircuits/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
          "description": "Bind 'on'/'off' as a message to the state topic."
        }
      ]
    },
    {
      "name": "valve",
      "description": "Populate the valve topics",
      "topics": [
        {
          "topic": "state/valve/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isDiverted?'\"on\"':'\"off\"';,\"isVirtual\":@bind=data.isVirtual? true: false;,\"pinId\": @bind=data.pinId;}",
          "description": "Bind 'on'/'off' as a message to the valve state topic."
        }
      ]
    },
    {
      "name": "feature",
      "description": "Populate the features topics",
      "topics": [
        {
          "topic": "state/features/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';,\"endTime\":\"@bind=data.endTime;\"}",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/features/@bind=data.id;/@bind=data.name;/endTime",
          "message": "{\"id\":@bind=data.id;,\"endTime\":@bind=data.endTime;}",
          "description": "Bind endTime as a message to the state topic."
        }
      ]
    },
    {
      "name": "temps",
      "description": "Populate the temps topics",
      "topics": [
        {
          "topic": "state/temps/air",
          "message": "{\"temp\":@bind=data.air;}",
          "description": "Send air temp."
        },
        {
          "topic": "state/temps/solar",
          "message": "{\"temp\":@bind=data.solar;}",
          "description": "Send solar temp.",
          "filter": "@bind=typeof data.solar !== 'undefined';"
        },
        {
          "topic": "state/temps/solarSensor2",
          "message": "{\"temp\":@bind=data.solarSensor2;}",
          "description": "Solar temp",
          "filter": "@bind=typeof data.solarSensor2 !== 'undefined';"
        },
        {
          "topic": "state/temps/solarSensor3",
          "message": "{\"temp\":@bind=data.solarSensor3;}",
          "description": "Solar temp",
          "filter": "@bind=typeof data.solarSensor3 !== 'undefined';"
        },
        {
          "topic": "state/temps/solarSensor4",
          "message": "{\"temp\":@bind=data.solarSensor4;}",
          "description": "Solar temp",
          "filter": "@bind=typeof data.solarSensor4 !== 'undefined';"
        },

        {
          "topic": "state/temps/waterSensor1",
          "message": "{\"temp\":@bind=data.waterSensor1;}",
          "description": "Water temp sensor 1",
          "filter": "@bind=typeof data.waterSensor1 !== 'undefined';"
        },
        {
          "topic": "state/temps/waterSensor2",
          "message": "{\"temp\":@bind=data.waterSensor2;}",
          "description": "Water temp sensor 2",
          "filter": "@bind=typeof data.waterSensor2 !== 'undefined';"
        },
        {
          "topic": "state/temps/waterSensor3",
          "message": "{\"temp\":@bind=data.waterSensor3;}",
          "description": "Water temp sensor 3",
          "filter": "@bind=typeof data.waterSensor3 !== 'undefined';"
        },
        {
          "topic": "state/temps/waterSensor4",
          "message": "{\"temp\":@bind=data.waterSensor4;}",
          "description": "Water temp sensor 4",
          "filter": "@bind=typeof data.waterSensor4 !== 'undefined';"
        },
        {
          "topic": "state/temps/units",
          "message": "{\"units\":@bind=data.units;}"
        }
      ]
    },
    {
      "name": "circuitGroup",
      "description": "Populate the circuitGroup topic",
      "topics": [
        {
          "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';,\"endTime\":\"@bind=data.endTime;\"}",
          "description": "Bind name to the state topic."
        },
        {
          "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;/isOn",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
          "description": "Bind the on/off status to the topic.",
          "enabled": false
        },
        {
          "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;/type",
          "message": "{\"type\":@bind=data.type;}",
          "enabled": false
        },
        {
          "topic": "state/circuitGroups/@bind=data.id;/@bind=data.name;/showInFeatures",
          "message": "{\"showInFeatures\":@bind=data.showInFeatures;}",
          "description": "Indicates wether the item should show in features."
        }

      ]
    },
    {
      "name": "body",
      "description": "Populate the body topic",
      "topics": [
        {
          "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/heatMode",
          "message": "{\"heatMode\":@bind=data.heatMode;}",
          "description": "Send heat mode."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/heatStatus",
          "message": "{\"heatStatus\":@bind=data.heatStatus;}",
          "description": "Send heat status."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/setPoint",
          "message": "{\"setPoint\":@bind=data.setPoint;}",
          "description": "Send set point."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/heatSetpoint",
          "message": "{\"heatSetpoint\":@bind=data.setPoint;}",
          "description": "Send heat set point."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/coolSetpoint",
          "message": "{\"coolSetpoint\":@bind=data.coolSetpoint;}",
          "description": "Send cool set point."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/@bind=data.name;/temp",
          "message": "{\"temp\":@bind=data.temp;}",
          "description": "Send temp."
        }
      ]
    },
    {
      "name": "chlorinator",
      "description": "Populate the chlorinator topic",
      "topics": [
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.currentOutput > 0 ?'\"on\"':'\"off\"';}",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/currentOutput",
          "message": "{\"currentOutput\":@bind=data.currentOutput;}",
          "description": "Send current output."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/poolSetpoint",
          "message": "{\"poolSetpoint\":@bind=data.poolSetpoint;}",
          "description": "Send pool setpoint."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/spaSetpoint",
          "message": "{\"spaSetpoint\":@bind=data.spaSetpoint;}",
          "description": "Send set point."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/status",
          "message": "{\"status\":@bind=data.status;}",
          "description": "Send status."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/superChlor",
          "message": "{\"superChlor\":@bind=data.superChlor?'\"on\"':'\"off\"';}",
          "description": "Send superChlor."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/superChlorHours",
          "message": "{\"superChlorHours\":@bind=data.superChlorHours;}",
          "description": "Send superChlorHours."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltLevel",
          "message": "{\"saltLevel\":@bind=data.saltLevel;}",
          "description": "Send salt level."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltRequired",
          "message": "{\"saltRequired\":@bind=data.saltRequired;}",
          "description": "Send the calculated salt requirement."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltTarget",
          "message": "{\"saltTarget\":@bind=data.saltTarget;}",
          "description": "Send the target salt level."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/type",
          "message": "{\"type\":@bind=data.type;}",
          "description": "Send type."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/model",
          "message": "{\"type\":@bind=data.model;}",
          "description": "Send Model."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/targetOutput",
          "message": "{\"targetOutput\":@bind=data.targetOutput;}",
          "description": "Send targetOutput."
        }
      ]
    },
    {
      "name": "lightGroup",
      "description": "Populate the lightGroup topic",
      "topics": [
        {
          "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/action",
          "message": "{\"action\":@bind=data.action;}"
        },
        {
          "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/lightingTheme",
          "message": "{\"lightingTheme\":@bind=data.lightingTheme;}"
        },
        {
          "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/type",
          "message": "{\"type\":@bind=data.type;}"
        },
        {
          "topic": "state/lightgroups/@bind=data.id;/@bind=data.name;/endTime",
          "message": "{\"endTime\":@bind=data.endTime;}"
        }
      ]
    },
    {
      "name": "pump",
      "description": "Populate the pumps topic",
      "topics": [
        {
          "topic": "state/pumps/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.flow > 0 || data.rpm > 0?'\"on\"':'\"off\"';}",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/pumps/@bind=data.id;/@bind=data.name;/rpm",
          "message": "{\"rpm\":@bind=data.rpm;}"
        },
        {
          "topic": "state/pumps/@bind=data.id;/@bind=data.name;/flow",
          "message": "{\"flow\":@bind=data.flow;}"
        },
        {
          "topic": "state/pumps/@bind=data.id;/@bind=data.name;/watts",
          "message": "{\"watts\":@bind=data.watts;}"
        },
        {
          "topic": "state/pumps/@bind=data.id;/@bind=data.name;/status",
          "message": "{\"status\":@bind=data.status;}"
        }
      ]
    },
    {
      "name": "chemController",
      "description": "Populate the chemControllers topic",
      "vars": {
        "cfg": "@bind=sys.chemControllers.getItemById(data.id).get();"
      },
      "topics": [
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/tankLevel",
          "message": "@bind=data.ph.tank.level;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/setpoint",
          "message": "@bind=data.ph.setpoint;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/level",
          "message": "@bind=data.ph.level;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/doseTime",
          "message": "@bind=data.ph.doseTime;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/ph/doseVolume",
          "message": "@bind=data.ph.doseVolume;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/tankLevel",
          "message": "@bind=data.orp.tank.level;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/setpoint",
          "message": "@bind=data.orp.setpoint;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/level",
          "message": "@bind=data.orp.level;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/demand",
          "message": "@bind=data.orp.demand;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/doseTime",
          "message": "@bind=data.orp.doseTime;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/doseVolume",
          "message": "@bind=data.orp.doseVolume;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orp/saltLevel",
          "message": "@bind=data.orp.saltLevel;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/acidTankLevel",
          "message": "{\"acidTankLevel\":@bind=data.ph.tank.level;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpTankLevel",
          "message": "{\"orpTankLevel\":@bind=data.orp.tank.level;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpDosingTime",
          "message": "{\"orpDosingTime\":@bind=data.orp.doseTime;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHDosingTime",
          "message": "{\"pHDosingTime\":@bind=data.ph.doseTime;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHDosingVolume",
          "message": "{\"pHDosingVolume\":@bind=data.ph.doseVolume;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpDosingVolume",
          "message": "{\"orpDosingVolume\":@bind=data.orp.doseVolume;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpSetpoint",
          "message": "{\"orpSetpoint\":@bind=data.orp.setpoint;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHSetpoint",
          "message": "{\"pHSetpoint\":@bind=data.ph.setpoint;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpLevel",
          "message": "{\"orpLevel\":@bind=data.orp.level;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/pHLevel",
          "message": "{\"pHLevel\":@bind=data.ph.level;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/saltLevel",
          "message": "{\"saltLevel\":@bind=data.orp.probe.saltLevel;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/saturationIndex",
          "message": "{\"saturationIndex\":@bind=data.saturationIndex;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/status",
          "message": "@bind=data.status;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/type",
          "message": "@bind=data.type;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alkalinity",
          "message": "@bind=vars.cfg.alkalinity;"
        },
        {
          "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/alkalinity",
          "message": "{\"alkalinity\":@bind=vars.cfg.alkalinity;}"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/calciumHardness",
          "message": "@bind=vars.cfg.calciumHardness;"
        },
        {
          "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/calciumHardness",
          "message": "@bind=vars.cfg.calciumHardness;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/cyanuricAcid",
          "message": "@bind=vars.cfg.cyanuricAcid;"
        },
        {
          "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/cyanuricAcid",
          "message": "@bind=vars.cfg.cyanuricAcid;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/borates",
          "message": "@bind=vars.cfg.borates;"
        },
        {
          "topic": "config/chemControllers/@bind=data.id;/@bind=data.name;/borates",
          "message": "@bind=vars.cfg.borates;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/acidDemand",
          "message": "@bind=data.ph.demand;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/orpDemand",
          "message": "@bind=data.orp.demand;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/flow",
          "message": "@bind=data.alarms.flow;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/ph",
          "message": "@bind=data.alarms.pH;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/orp",
          "message": "@bind=data.alarms.orp;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/phTank",
          "message": "@bind=data.alarms.pHTank;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/orpTank",
          "message": "@bind=data.alarms.orpTank;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/orpProbeFault",
          "message": "@bind=data.alarms.orpProbeFault;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/alarms/pHProbeFault",
          "message": "@bind=data.alarms.pHProbeFault;"
        },

        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/waterChemistry",
          "message": "@bind=data.warnings.waterChemistry;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/pHLockout",
          "message": "@bind=data.warnings.pHLockout;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/pHDailyLimitReached",
          "message": "@bind=data.warnings.pHDailyLimitReached;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/orpDailyLimitReached",
          "message": "@bind=data.warnings.orpDailyLimitReached;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/invalidSetup",
          "message": "@bind=data.warnings.invalidSetup;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.name;/warnings/chlorinatorCommError",
          "message": "@bind=data.warnings.chlorinatorCommError;"
        }
      ]
    },
    {
      "name": "chemicalDose",
      "description": "Event when a chemical is being dosed",
      "topics": [
        {
          "topic": "state/chemControllers/@bind=data.id;/@bind=data.chem;",
          "message": "@bind=data;",
          "enabled": true
        }
      ]
    },
    {
      "name": "filter",
      "description": "Populate the filter topic",
      "topics": [
        {
          "topic": "state/filters/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isOn\":@bind=data.isOn?'\"on\"':'\"off\"';}",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/filters/@bind=data.id;/@bind=data.name;/pressure",
          "message": "{\"pressure\":@bind=data.pressure;}",
          "description": "Send current pressure."
        },
        {
          "topic": "state/filters/@bind=data.id;/@bind=data.name;/refPressure",
          "message": "{\"refPressure\":@bind=data.refPressure;}",
          "description": "Send reference pressure (when circuits are on)."
        },
        {
          "topic": "state/filters/@bind=data.id;/@bind=data.name;/body",
          "message": "{\"body\":@bind=data.body.desc;}",
          "description": "Send associated body."
        },
        {
          "topic": "state/filters/@bind=data.id;/@bind=data.name;/filterType",
          "message": "{\"filterType\":@bind=data.filterType.desc;}",
          "description": "Send filter type."
        },
        {
          "topic": "state/filters/@bind=data.id;/@bind=data.name;/pressureUnits",
          "message": "{\"pressureUnits\":@bind=data.pressureUnits.desc;}",
          "description": "Send pressureUnits."
        },
        {
          "topic": "state/filters/@bind=data.id;/@bind=data.name;/cleanPercentage",
          "message": "{\"cleanPercentage\":@bind=data.cleanPercentage;}",
          "description": "Send cleanPercentage."
        }
      ]
    },
    {
      "name": "cover",
      "description": "Populate the cover topic",
      "topics": [
        {
          "topic": "state/covers/@bind=data.id;/@bind=data.name;",
          "message": "{\"id\":@bind=data.id;,\"isClosed\":@bind=data.isClosed?'\"true\"':'\"false\"';}",
          "description": "Bind isClosed as a message to the state topic."
        }
      ]
    },
    {
      "name": "*",
      "description": "DEFAULT: Sends the entire emitted response.",
      "body": "@bind=data;",
      "enabled": false
    }
  ]
}