{
    "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);"
        }
    },
  "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;"
        },
        {
          "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;/name",
          "message": "@bind=data.name;",
          "description": "Bind the name."
        },
        {
          "topic": "state/circuits/@bind=data.id;/isOn",
          "message": "@bind=data.isOn;",
          "description": "Bind the on/off status to the topic."
        },
        {
          "topic": "state/circuits/@bind=data.id;/type",
          "message": "@bind=data.type;",
          "description": "The type of circuit we are dealing with."
        },
        {
          "topic": "state/circuits/@bind=data.id;/endTime",
          "message": "@bind=data.endTime;",
          "description": "The end time for the circuit."
        },
        {
          "topic": "state/circuits/@bind=data.id;/lightingTheme",
          "message": "@bind=data.lightingTheme;",
          "description": "Bind the lighting theme to the topic.",
          "filter": "@bind=data.type.isLight === true;"
        },
        {
          "topic": "state/circuits/@bind=data.id;/showInFeatures",
          "message": "@bind=data.showInFeatures;",
          "description": "Indicates whether the item should show in features."
        },
        {
          "topic": "state/circuits/@bind=data.id;/endTime",
          "message": "@bind=data.endTime;",
          "description": "Indicates end time for a circuit (when it will turn off)."
        }
      ]
    },
    {
      "name": "feature",
      "description": "Populate the features topics",
      "topics": [
        {
          "topic": "state/features/@bind=data.id;/name",
          "message": "@bind=data.name;",
          "description": "Bind the name."
        },
        {
          "topic": "state/features/@bind=data.id;/isOn",
          "message": "@bind=data.isOn;",
          "description": "Bind the on/off status to the topic."
        },
        {
          "topic": "state/features/@bind=data.id;/endTime",
          "message": "@bind=data.endTime;",
          "description": "The end time for the feature."
        },
        {
          "topic": "state/features/@bind=data.id;/type",
          "message": "@bind=data.type;",
          "description": "The type of feature we are dealing with."
        },
        {
          "topic": "state/features/@bind=data.id;/showInFeatures",
          "message": "@bind=data.showInFeatures;",
          "description": "Indicates whether the item should show in features."
        },
        {
          "topic": "state/features/@bind=data.id;/endTime",
          "message": "@bind=data.endTime;",
          "description": "Indicates end time for a features (when it will turn off)."
        }
      ]
    },
    {
      "name": "lightGroup",
      "description": "Populate the lightGroup topic",
      "topics": [
        {
          "topic": "state/lightGroups/@bind=data.id;/name",
          "message": "@bind=data.name;",
          "description": "Bind name to the state topic."
        },
        {
          "topic": "state/lightGroups/@bind=data.id;/isOn",
          "message": "@bind=data.isOn;",
          "description": "Bind the on/off status to the topic."
        },
        {
          "topic": "state/lightGroups/@bind=data.id;/action",
          "message": "@bind=data.action;"
        },
        {
          "topic": "state/lightGroups/@bind=data.id;/lightingTheme",
          "message": "@bind=data.lightingTheme;"
        },
        {
          "topic": "state/lightGroups/@bind=data.id;/type",
          "message": "@bind=data.type;"
        },
        {
          "topic": "state/lightGroups/@bind=data.id;/endTime",
          "message": "@bind=data.endTime;"
        }
      ]
    },
    {
      "name": "circuitGroup",
      "description": "Populate the circuitGroup topic",
      "topics": [
        {
          "topic": "state/circuitGroups/@bind=data.id;/name",
          "message": "@bind=data.name;",
          "description": "Bind name to the state topic."
        },
        {
          "topic": "state/circuitGroups/@bind=data.id;/isOn",
          "message": "@bind=data.isOn;",
          "description": "Bind the on/off status to the topic."
        },
        {
          "topic": "state/circuitGroups/@bind=data.id;/type",
          "message": "@bind=data.type;"
        },
        {
          "topic": "state/circuitGroups/@bind=data.id;/showInFeatures",
          "message": "@bind=data.showInFeatures;",
          "description": "Indicates whether the item should show in features."
        },
        {
          "topic": "state/circuitGroups/@bind=data.id;/endTime",
          "message": "@bind=data.showInFeatures;",
          "description": "Indicates end time for the circuitGroup (when it will turn off)."
        }

      ]
    },
    {
      "name": "virtualCircuit",
      "description": "Populate the virtual circuits topics",
      "topics": [
        {
          "topic": "state/virtualCircuits/@bind=data.id;/name",
          "message": "@bind=data.name;",
          "description": "Bind the name."
        },
        {
          "topic": "state/virtualCircuits/@bind=data.id;/isOn",
          "message": "@bind=data.isOn;",
          "description": "Bind the on/off status to the topic."
        },
        {
          "topic": "state/virtualCircuits/@bind=data.id;/type",
          "message": "@bind=data.type;",
          "description": "The type of circuit we are dealing with."
        }
      ]
    },
    {
      "name": "valve",
      "description": "Populate the valve topics",
      "topics": [
        {
          "topic": "state/valves/@bind=data.id;",
          "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.",
          "enabled": false
        },
        {
          "topic": "state/valves/@bind=data.id;/name",
          "message": "@bind=data.name;",
          "description": "The name of the valve"
        },
        {
          "topic": "state/valves/@bind=data.id;/type",
          "message": "@bind=data.type;",
          "description": "The type of valve we are dealing with."
        },
        {
          "topic": "state/valves/@bind=data.id;/isDiverted",
          "message": "@bind=data.isDiverted;",
          "description": "Indicates whether the valve is diverted"
        },
        {
          "topic": "state/valves/@bind=data.id;/isVirtual",
          "message": "@bind=data.isVirtual;",
          "description": "Indicates whether the valve is virtual"
        },
        {
          "topic": "state/valves/@bind=data.id;/isIntake",
          "message": "@bind=data.isIntake ? true : false;",
          "description": "Indicates whether the valve is for the intake in a shared system"
        },
        {
          "topic": "state/valves/@bind=data.id;/isReturn",
          "message": "@bind=data.isReturn ? true : false;",
          "description": "Indicates whether the valve is for the return in a shared system"
        },
        {
          "topic": "state/valves/@bind=data.id;/pinId",
          "message": "@bind=data.pinId;",
          "description": "The pin id that is set on the valve",
          "filter": "@bind=data.isVirtual === true;"
        }
      ]
    },
    {
      "name": "temps",
      "description": "Populate the temps topics",
      "topics": [
        {
          "topic": "state/temps/air",
          "message": "@bind=data.air;",
          "description": "Air temp."
        },
        {
          "topic": "state/temps/solar",
          "message": "@bind=data.solar;",
          "description": "Solar temp",
          "filter": "@bind=typeof data.solar !== 'undefined';"
        },
        {
          "topic": "state/temps/solarSensor2",
          "message": "@bind=data.solarSensor2;",
          "description": "Solar temp",
          "filter": "@bind=typeof data.solarSensor2 !== 'undefined';"
        },
        {
          "topic": "state/temps/solarSensor3",
          "message": "@bind=data.solarSensor3;",
          "description": "Solar temp",
          "filter": "@bind=typeof data.solarSensor3 !== 'undefined';"
        },
        {
          "topic": "state/temps/solarSensor4",
          "message": "@bind=data.solarSensor4;",
          "description": "Solar temp",
          "filter": "@bind=typeof data.solarSensor4 !== 'undefined';"
        },
        {
          "topic": "state/temps/waterSensor1",
          "message": "@bind=data.waterSensor1;",
          "description": "Water temp sensor 1",
          "filter": "@bind=typeof data.waterSensor1 !== 'undefined';"
        },
        {
          "topic": "state/temps/waterSensor2",
          "message": "@bind=data.waterSensor2;",
          "description": "Water temp sensor 2",
          "filter": "@bind=typeof data.waterSensor2 !== 'undefined';"
        },
        {
          "topic": "state/temps/waterSensor3",
          "message": "@bind=data.waterSensor3;",
          "description": "Water temp sensor 3",
          "filter": "@bind=typeof data.waterSensor3 !== 'undefined';"
        },
        {
          "topic": "state/temps/waterSensor4",
          "message": "@bind=data.waterSensor4;",
          "description": "Water temp sensor 4",
          "filter": "@bind=typeof data.waterSensor4 !== 'undefined';"
        },
        {
          "topic": "state/temps/units",
          "message": "@bind=data.units;"
        }
      ]
    },
    {
      "name": "body",
      "description": "Populate the body topic",
      "filter": "@bind=data.isActive;",
      "topics": [
        {
          "topic": "state/temps/bodies/@bind=data.id;/name",
          "message": "@bind=data.name;",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/type",
          "message": "@bind=data.type;",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/isOn",
          "message": "@bind=data.isOn;",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/circuit",
          "message": "@bind=data.circuit;",
          "description": "Bind the associated circuit."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/heatMode",
          "message": "@bind=data.heatMode;",
          "description": "Heat mode."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/heatStatus",
          "message": "@bind=data.heatStatus;",
          "description": "Heat status."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/setPoint",
          "message": "@bind=data.setPoint;",
          "description": "Setpoint."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/heatSetpoint",
          "message": "@bind=data.setPoint;",
          "description": "Heat setpoint."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/coolSetpoint",
          "message": "@bind=data.coolSetpoint;",
          "description": "Cool setpoint."
        },
        {
          "topic": "state/temps/bodies/@bind=data.id;/temp",
          "message": "@bind=data.temp;",
          "description": "Body Temp."
        }
      ]
    },
    {
      "name": "chlorinator",
      "description": "Populate the chlorinator topic",
      "topics": [
        {
          "topic": "state/chlorinators/@bind=data.id;/name",
          "message": "@bind=data.name;",
          "description": "Bind the name topic."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/isOn",
          "message": "@bind=data.currentOutput > 0;",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/currentOutput",
          "message": "@bind=data.currentOutput;",
          "description": "Send current output."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/poolSetpoint",
          "message": "@bind=data.poolSetpoint;",
          "description": "Send pool setpoint."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/spaSetpoint",
          "message": "@bind=data.spaSetpoint;",
          "description": "Send set point."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/status",
          "message": "@bind=data.status;",
          "description": "Send status."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/superChlor",
          "message": "@bind=data.superChlor;",
          "description": "Send superChlor."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/superChlorHours",
          "message": "@bind=data.superChlorHours;",
          "description": "Send superChlorHours."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/saltLevel",
          "message": "@bind=data.saltLevel;",
          "description": "Send salt level."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltTarget",
          "message": "@bind=data.saltTarget;",
          "description": "Send the target salt level."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/@bind=data.name;/saltRequired",
          "message": "@bind=data.saltRequired;",
          "description": "Send the calculated salt requirement."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/type",
          "message": "@bind=data.type;",
          "description": "Send type."
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/model",
          "message": "@bind=data.model;",
          "description": "Send Model"
        },
        {
          "topic": "state/chlorinators/@bind=data.id;/targetOutput",
          "message": "@bind=data.targetOutput;",
          "description": "Send targetOutput."
        }
      ]
    },
    {
      "name": "pump",
      "description": "Populate the pumps topic",
      "topics": [
        {
          "topic": "state/pumps/@bind=data.id;/name",
          "message": "@bind=data.name;",
          "description": "Bind name to the state topic."
        },
        {
          "topic": "state/pumps/@bind=data.id;/isOn",
          "message": "@bind=(data.rpm + data.flow > 0)?true:false;"
        },
        {
          "topic": "state/pumps/@bind=data.id;/rpm",
          "message": "@bind=data.rpm;"
        },
        {
          "topic": "state/pumps/@bind=data.id;/flow",
          "message": "@bind=data.flow;"
        },
        {
          "topic": "state/pumps/@bind=data.id;/watts",
          "message": "@bind=data.watts;"
        },
        {
          "topic": "state/pumps/@bind=data.id;/status",
          "message": "@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;/name",
          "message": "@bind=data.name;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/ph/tankLevel",
          "message": "@bind=data.ph.tank.level;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/ph/setpoint",
          "message": "@bind=data.ph.setpoint;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/ph/level",
          "message": "@bind=data.ph.level;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/ph/doseTime",
          "message": "@bind=data.ph.doseTime;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/ph/doseVolume",
          "message": "@bind=data.ph.doseVolume;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/orp/tankLevel",
          "message": "@bind=data.orp.tank.level;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/orp/setpoint",
          "message": "@bind=data.orp.setpoint;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/orp/level",
          "message": "@bind=data.orp.level;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/orp/doseTime",
          "message": "@bind=data.orp.doseTime;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/orp/doseVolume",
          "message": "@bind=data.orp.doseVolume;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/orp/saltLevel",
          "message": "@bind=data.orp.saltLevel;",
          "enabled": true
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/saturationIndex",
          "message": "@bind=data.saturationIndex;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/status",
          "message": "@bind=data.status;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/type",
          "message": "@bind=data.type;"
        },
        {
          "topic": "config/chemControllers/@bind=data.id;/alkalinity",
          "message": "@bind=vars.cfg.alkalinity;"
        },
        {
          "topic": "config/chemControllers/@bind=data.id;/calciumHardness",
          "message": "@bind=vars.cfg.calciumHardness;"
        },
        {
          "topic": "config/chemControllers/@bind=data.id;/cyanuricAcid",
          "message": "@bind=vars.cfg.cyanuricAcid;"
        },
        {
          "topic": "config/chemControllers/@bind=data.id;/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;/alarms/flow",
          "message": "@bind=data.alarms.flow;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/alarms/ph",
          "message": "@bind=data.alarms.pH;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/alarms/orp",
          "message": "@bind=data.alarms.orp;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/alarms/phTank",
          "message": "@bind=data.alarms.pHTank;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/alarms/orpTank",
          "message": "@bind=data.alarms.orpTank;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/alarms/orpProbeFault",
          "message": "@bind=data.alarms.orpProbeFault;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/alarms/pHProbeFault",
          "message": "@bind=data.alarms.pHProbeFault;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/warnings/waterChemistry",
          "message": "@bind=data.warnings.waterChemistry;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/warnings/pHLockout",
          "message": "@bind=data.warnings.pHLockout;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/warnings/pHDailyLimitReached",
          "message": "@bind=data.warnings.pHDailyLimitReached;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/warnings/orpDailyLimitReached",
          "message": "@bind=data.warnings.orpDailyLimitReached;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/warnings/invalidSetup",
          "message": "@bind=data.warnings.invalidSetup;"
        },
        {
          "topic": "state/chemControllers/@bind=data.id;/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;/name",
          "message": "@bind=data.name;",
          "description": "Bind the name topic."
        },
        {
          "topic": "state/filters/@bind=data.id;/isOn",
          "message": "@bind=data.currentOutput > 0;",
          "description": "Bind 'on'/'off' as a message to the state topic."
        },
        {
          "topic": "state/filters/@bind=data.id;/body",
          "message": "@bind=data.body.desc;",
          "description": "Send body description."
        },
        {
          "topic": "state/filters/@bind=data.id;/cleanPercentage",
          "message": "@bind=data.cleanPercentage;",
          "description": "Send clean percentage."
        },
        {
          "topic": "state/filters/@bind=data.id;/filterType",
          "message": "@bind=data.filterType.desc;",
          "description": "Send filter type."
        },
        {
          "topic": "state/filters/@bind=data.id;/pressure",
          "message": "@bind=data.pressure;",
          "description": "Send pressure."
        },
        {
          "topic": "state/filters/@bind=data.id;/pressureUnits",
          "message": "@bind=data.pressureUnits.desc;",
          "description": "Send pressure units."
        },
        {
          "topic": "state/filters/@bind=data.id;/refPressure",
          "message": "@bind=data.refPressure;",
          "description": "Send reference pressure."
        }
      ]
    },
    {
      "name": "cover",
      "description": "Populate the cover topic",
      "topics": [
        {
          "topic": "state/covers/@bind=data.id;/name",
          "message": "@bind=data.name;",
          "description": "Bind the name topic."
        },
        {
          "topic": "state/covers/@bind=data.id;/isClosed",
          "message": "@bind=data.isClosed;",
          "description": "Bind isClosed as a message to the state topic."
        }
      ]
    },
    {
      "name": "*",
      "description": "DEFAULT: Sends the entire emitted response.",
      "body": "@bind=data;",
      "enabled": false
    }
  ]
}