AlarmDecoder AD2Pi Network Appliance

Here are the changes I made to the device_type.groovy: (Line numbers from original before adding additional code)

I got a little fancy and added the names of my zones right at the beginning, so here is line 18-24 for mine:

/*** Sensors ***/

def getSensorMap() {
    return ['10':'Front Door', '11':'Dining Room S.G.D', '12':'Garage Entry Door', '13':'Laundry Rm Bath Window', '14':'Kitchen Window', '15':'Kitchen Nook Window', '16':'Family Rm Door','17':'Master Bd Rm Window 1', '18':'Master Bd Rm Window 2', '19':'Master Bath Door', '20':'Hall Bathroom Window', '21':'Bedroom 2 Window', '22':'Bedroom 3 Window', '23':'Bedroom 4 Window','24':'Bedroom 5 Window', '25':'Motion - Hallway', '49':'Off', '50':'Away', '51':'Stay'];
}

def sensorMap = getSensorMap();

Then, I added my custom zones to the preferences section (Lines 25-32):

input("zonetracker1zone", "number", title: "10: " + sensorMap['10'], description: "Zone number to associate with this contact sensor.")
input("zonetracker2zone", "number", title: "11: " + sensorMap['11'], description: "Zone number to associate with this contact sensor.")
input("zonetracker3zone", "number", title: "12: " + sensorMap['12'], description: "Zone number to associate with this contact sensor.")
input("zonetracker4zone", "number", title: "13: " + sensorMap['13'], description: "Zone number to associate with this contact sensor.")
input("zonetracker5zone", "number", title: "14: " + sensorMap['14'], description: "Zone number to associate with this contact sensor.")
input("zonetracker6zone", "number", title: "15: " + sensorMap['15'], description: "Zone number to associate with this contact sensor.")
input("zonetracker7zone", "number", title: "16: " + sensorMap['16'], description: "Zone number to associate with this contact sensor.")
input("zonetracker8zone", "number", title: "17: " + sensorMap['17'], description: "Zone number to associate with this contact sensor.")
input("zonetracker9zone", "number", title: "18: " + sensorMap['18'], description: "Zone number to associate with this contact sensor.")
input("zonetracker10zone", "number", title: "19: " + sensorMap['19'], description: "Zone number to associate with this contact sensor.")
input("zonetracker11zone", "number", title: "20: " + sensorMap['20'], description: "Zone number to associate with this contact sensor.")
input("zonetracker12zone", "number", title: "21: " + sensorMap['21'], description: "Zone number to associate with this contact sensor.")
input("zonetracker13zone", "number", title: "22: " + sensorMap['22'], description: "Zone number to associate with this contact sensor.")
input("zonetracker14zone", "number", title: "23: " + sensorMap['23'], description: "Zone number to associate with this contact sensor.")
input("zonetracker15zone", "number", title: "24: " + sensorMap['24'], description: "Zone number to associate with this contact sensor.")
input("zonetracker16zone", "number", title: "25: " + sensorMap['25'], description: "Zone number to associate with this contact sensor.")
input("zonetracker17zone", "number", title: "49: " + sensorMap['49'], description: "Zone number to associate with this contact sensor.")
input("zonetracker18zone", "number", title: "50: " + sensorMap['50'], description: "Zone number to associate with this contact sensor.")
input("zonetracker19zone", "number", title: "51: " + sensorMap['51'], description: "Zone number to associate with this contact sensor.")																																

After line 58, I added the rest of my zones to the attribute list:

    attribute "zoneStatus13", "number"
    attribute "zoneStatus14", "number"
    attribute "zoneStatus15", "number"
    attribute "zoneStatus16", "number"
    attribute "zoneStatus17", "number"
    attribute "zoneStatus18", "number"
    attribute "zoneStatus19", "number"

After line 197, I added the additional ValueTiles for my additional zones:

valueTile("zoneStatus13", "device.zoneStatus13", inactiveLabel: false, width: 1, height: 1) {
    state "default", icon:"", label: '${currentValue}', backgroundColors: [
        [value: 0, color: "#ffffff"],
        [value: 1, color: "#ff0000"],
        [value: 99, color: "#ff0000"]
    ]
}

valueTile("zoneStatus14", "device.zoneStatus14", inactiveLabel: false, width: 1, height: 1) {
    state "default", icon:"", label: '${currentValue}', backgroundColors: [
        [value: 0, color: "#ffffff"],
        [value: 1, color: "#ff0000"],
        [value: 99, color: "#ff0000"]
    ]
}

valueTile("zoneStatus15", "device.zoneStatus15", inactiveLabel: false, width: 1, height: 1) {
    state "default", icon:"", label: '${currentValue}', backgroundColors: [
        [value: 0, color: "#ffffff"],
        [value: 1, color: "#ff0000"],
        [value: 99, color: "#ff0000"]
    ]
}

valueTile("zoneStatus16", "device.zoneStatus16", inactiveLabel: false, width: 1, height: 1) {
    state "default", icon:"", label: '${currentValue}', backgroundColors: [
        [value: 0, color: "#ffffff"],
        [value: 1, color: "#ff0000"],
        [value: 99, color: "#ff0000"]
    ]
}

valueTile("zoneStatus17", "device.zoneStatus17", inactiveLabel: false, width: 1, height: 1) {
    state "default", icon:"", label: '${currentValue}', backgroundColors: [
        [value: 0, color: "#ffffff"],
        [value: 1, color: "#ff0000"],
        [value: 99, color: "#ff0000"]
    ]
}

valueTile("zoneStatus18", "device.zoneStatus18", inactiveLabel: false, width: 1, height: 1) {
    state "default", icon:"", label: '${currentValue}', backgroundColors: [
        [value: 0, color: "#ffffff"],
        [value: 1, color: "#ff0000"],
        [value: 99, color: "#ff0000"]
    ]
}

valueTile("zoneStatus19", "device.zoneStatus19", inactiveLabel: false, width: 1, height: 1) {
    state "default", icon:"", label: '${currentValue}', backgroundColors: [
        [value: 1, color: "#ff0000"],
        [value: 99, color: "#ff0000"]
    ]
}

Update line 204:

    details(["status", "arm_disarm", "stay_disarm", "panic", "zoneStatus1", "zoneStatus2", "zoneStatus3", "zoneStatus4", "zoneStatus5", "zoneStatus6", "zoneStatus7", "zoneStatus8", "zoneStatus9", "zoneStatus10", "zoneStatus11", "zoneStatus12", "zoneStatus13", "zoneStatus14", "zoneStatus15", "zoneStatus16", "zoneStatus17", "zoneStatus18", "zoneStatus19", "refresh", "teststuff"])

Update the loops to have the correct number:
Line 211 and 225:

for (def i = 1; i <= sensorMap.size(); i++)

line 495:

	def sensorMap = getSensorMap();
    for (def i = 1; i <= sensorMap.size(); i++) {

Line 518-522

	def sensorMap = getSensorMap();
    // Iterate through the zone tracker settings.  If the zone number matches,
    // trigger an event for the service manager to use to flip the virtual
    // switches.
    for (def i = 1; i <= sensorMap.size(); i++) {

And in the service_manager.groovy:

Lines 365-381 become:

  			/*** Sensors ***/
  		def sensorMap = ['10':'Front Door', '11':'Dining Room S.G.D', '12':'Garage Entry Door', '13':'Laundry Rm Bath Window', '14':'Kitchen Window', '15':'Kitchen Nook Window', '16':'Family Rm Door','17':'Master Bd Rm Window 1', '18':'Master Bd Rm Window 2', '19':'Master Bath Door', '20':'Hall Bathroom Window', '21':'Bedroom 2 Window', '22':'Bedroom 3 Window', '23':'Bedroom 4 Window','24':'Bedroom 5 Window', '25':'Motion - Hallway', '49':'Off', '50':'Away', '51':'Stay'];
  		def sensorKeys = sensorMap.keySet() as String[]; 
// Add virtual zone contact sensors.
for (def i = 0; i < sensorMap.size(); i++)
{
  def currentSensorKey = sensorKeys[i];	
	def currentSensorValue = sensorMap[currentSensorKey];									  
  																								 
    def newSwitch = state.devices.find { k, v -> k == "${state.ip}:${state.port}:switch${i+1}" }
    if (!newSwitch)
    {
        def zone_switch = addChildDevice("alarmdecoder", "VirtualContactSensor", "${state.ip}:${state.port}:switch${i+1}", state.hub, [name: "${state.ip}:${state.port}:switch${i+1}", label: "${currentSensorKey}: ${currentSensorValue}", completedSetup: true])