DBX ZonePro RS232

50 views
Skip to first unread message

Fiasco

unread,
Mar 19, 2024, 5:24:35 PMMar 19
to CommandFusion Software


Some time ago I wrote a module to control the ZonePro via RS232 (57600 8N1) and, for the life of me, I can not get it working again.  It generates the commands and parses the feedback.

I have the ZonePro string calculator which allows you to generate the proper command strings.  It also lets you test the strings against your zone pro.   When using this software and connected to the Zonepro via a USB->RS232 adapter the commands work fine.  Sending commands this way also works with the GUI Designer.

I am trying to control it with CommandFusion through a Moxa NPort (IP to RS232).

To dumb it all down I just created a system that connects to the appropriate port on the NPort and created a couple test commands.  I'm just trying to mute/unmute zone 1.   I get feedback from the zonepro with regex (.*)\xFF.   Because I can't send command to the unit All I'm getting are the resync requests from the unit (A series of \xFF and \xF0's)

I created two buttons and two commands
Mute
\xF0\x64\x00\x01\x00\x00\x00\x1B\x00\x33\x01\x05\x00\x14\x00\x8A\x01\x05\x00\x14\x01\x00\x00\x00\x00\x01\x00\x02\x01\x01\x81
Unmute
\xF0\x64\x00\x01\x00\x00\x00\x1B\x00\x33\x01\x05\x00\x14\x00\x8A\x01\x05\x00\x14\x01\x00\x00\x00\x00\x01\x00\x02\x01\x00\xDF

I can not, for the life of me, figure out what I'm doing wrong.   I've tested the pinout on the cable.   I know it's correct.

Fiasco

unread,
Mar 19, 2024, 8:12:30 PMMar 19
to CommandFusion Software
Bad 232 cable.  I tested fine with a tone test on a meter but the resistance in the TX wire was way off.

Fiasco

unread,
Mar 21, 2024, 6:27:47 PMMar 21
to CommandFusion Software
OMG, the zonepro engineer responsible for writing the protocol and providing absolutely minimum documentation of it must jerk off every time he things of someone trying to integrate it.

From the protocol document

"The dbx ZonePRO is designed for 1-way control from a 3rd party controller. We do not offer a full-duplex protocol guide to our end users. The only exception to this rule is if the user downloads and uses the AMX and Crestron modules from our website www.dbxpro.com . We have worked with these two manufacturers to provide reliable full-duplex (2-way) controllers for our customers.
"
So just sitting around for hours capturing strings across the com port and comparing them and making minor adjustments to the unit to see what changed.   Got the RTE's done today (which is all anyone would probably care about unless trying to build a full control interface).

var ZonePro = function() {
var module = {
system : "",
model : "",
join : -1,
feedback     : "",
debug : 1,
disco       : ["ff","ff"],
zone1   : ["00","00","00","00"],
zone2   : ["00","00","00","00"],
zone3   : ["00","00","00","00"],
zone4   : ["00","00","00","00"],
buffer : [],
                node : ["8A"],  // 640m default node is 138/8A
                framestart : ["F0", "64"],
                framecount : ["00"],
                version : ["01"],
                address : ["AB", "CD"],  // Pick a hex address to identify yourself to the zonepro    
                recipient : ["FF", "FF"],
                zone1join : 0,
                zone2join : 0,
                zone3join : 0,
                zone4join : 0,
};

// Output 1 Address 20 0 5 1
// Output 2 Address 21 1 5 1
// Output 3 Address 22 2 5 1
// Output 4 Address 23 3 5 1
// zonepro node address 48
// router 1 id 27 b0 16 b1 0 b2 5 b3 1 posb0 0 posb1 5
// router 2 id 27 b0 17 b1 1 b2 5 b3 1 posb0 1 posb1 5
// router 3 id 27 b0 18 b1 2 b2 5 b3 1 posb0 2 posb1 5
// router 4 id 27 b0 19 b1 3 b2 5 b3 1 posb0 3 posb1 5
// msgid 0113 subscribeall
// msgid 0114 unsubscribeall
// msgid 9001 recall scene
// msgid 0100 multisvset
// msgid 0000 disco
// msgid 0004 info
// msgid 0103 get message
// msgid 011e get object list
// flags bit 0 reqack
// flags bit 1 ack
// flags bit 2 info
// flags bit 3 error
// flags bit 4 event
// flags bit 8-15 hop count


//Frame Start UBYTE 0x64
//Frame Count UBYTE 0x00
//VERSION UBYTE 0x01
//LEN ULONG Length of entire packet (not including FS FC, CS)
//SRC UWORD:ULONG [Device : Object]
//DEST UWORD:ULONG [Device : Object]
//MSG_ID UWORD Specific type of command issued
//FLAGS UWORD (there is no guaranteed bit)
//(Payload)
//Checksum UBYTE CCITT-8 (over FS, FC, Header, Payload)
// [FRAMESTART] [FRAMECOUNT] [VERSION] [LEN] [SRC.RTE] [NODE] [DEST.RTE] [MSGID] [FLAGS] [PAYLOAD] [CHECKSUM]
// F0 64 00 01 00,00,00,1B 00,33 01,05,00,15 00,8A 01,05,00,15 01,00,00,00,00,01,00,02,01 01 7B


module.setup = function(system, feedback, node, debug) {
    module.system = system;
    module.feedback = feedback;
    module.node = node.toString(16);
    module.node = "8A";
    module.debug = debug;
module.log("Setup System " + system + " Feedback " + feedback + " DBXNode " + node + " Debug " + debug );  

};


// in zone pro designer, select the RTE and hit ctrl+shift+o to get the 4 address numbers (b0, b1, b2, b3) and call the RTE functions to assign them.
module.setupRTE = function( rte, array ) {
// create the base join number for GUI elements
var joinnumber = "";
for ( var i = 0; i < array.length; i++ ) {
joinnumber = joinnumber + array[i];
}
module.log("RTE" + rte + " " + "Mute Join Number " + joinnumber);

// convert address to hex
for ( var i = 0; i < array.length; i++ ) {
array[i] = array[i].toString(16);
// pad hex value with leading 0 if necessary
if ( array[i].length < 2 ) {
array[i] = "0" + array[i];
}
}
// assign it to the zones

switch (rte) {
case 1:
module.zone1 = array.reverse();
module.log("Setup RTE1 " + module.zone1 );
module.zone1join = joinnumber;
break;
case 2:
module.zone2 = array.reverse();
module.log("Setup RTE2 " + module.zone2 );
module.zone2join = joinnumber;
break;
case 3:
module.zone3 = array.reverse();
module.log("Setup RTE3 " + module.zone3 );
module.zone3join = joinnumber;
break;
case 4:
module.zone4 = array.reverse();
module.log("Setup RTE4 " + module.zone4 );
module.zone4join = joinnumber;
break;
default:
module.log("ERROR - invalid RTE number should be 1-4");
break;
}
}

module.initialize = function() {
module.log("Start watching freedback on " + module.system + " " + module.feedback);
CF.watch(CF.FeedbackMatchedEvent, module.system, module.feedback, module.ProcessFeedback);
module.requestAddress();
module.sendDisco();
setInterval(function(){ module.sendHeartbeat();}, 1000);
setInterval(function(){ module.sendDisco();} , 10000);
module.log("Initialized...\n");
};

module.requestAddress = function() {
var framestart = module.framestart;
var framecount = module.framecount;
var version = module.version;
var length = ["00", "00", "00", "2F"];
var source = [module.address[0], module.address[1], "00", "00", "00", "00"];
var destination = ["ff", "ff", "00", "00", "00", "00"];
var messageid = ["00", "00"];
var flags = ["05", "00"];
var payload = [module.address[0], module.address[1], "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00"];
var commandarray =  [];
commandarray = commandarray.concat( framestart, framecount, version, length, source, destination, messageid, flags, payload);  
commandarray.push(module.checksum(commandarray));
module.sendCommand(commandarray, "Request Address: ", 0);
}

module.sendDisco = function() {
var framestart = module.framestart;
var framecount = module.framecount;
var version = module.version;
var length = ["00", "00", "00", "2F"];
var source = [module.address[0], module.address[1], "00", "00", "00", "00"];
var destination = ["ff", "ff", "00", "00", "00", "00"];
var messageid = ["00", "00"];
var flags = ["05", "00"];
var payload = [module.address[0], module.address[1], "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00", "00"];
var commandarray = [];
commandarray = commandarray.concat( framestart, framecount, version, length, source, destination, messageid, flags, payload);  
commandarray.push(module.checksum(commandarray));
module.sendCommand(commandarray, "Send Disco: ", 0);
};


module.subscribe = function( zone ) {
var framestart = module.framestart;
var framecount = module.framecount;
var version = module.version;
var length = ["00", "00", "00", "20"];
var source = [module.address[0], module.address[1], zone[0], zone[1], zone[2], zone[3]];
var destination = ["00", module.node, zone[0], zone[1], zone[2], zone[3]];
var messageid = ["01", "13"];
var flags = ["00", "00"];
var payload = [module.address[0], module.address[1], zone[0], zone[1], zone[2], zone[3], "01", "00", "00", "00", "01"];
var commandarray = [];
commandarray = commandarray.concat( framestart, framecount, version, length, source, destination, messageid, flags, payload);  
commandarray.push(module.checksum(commandarray));
module.sendCommand(commandarray, "Subscribe to Zone: ", 0);
};
module.getVDList = function() {
var framestart = module.framestart;
var framecount = module.framecount;
var version = module.version;
var length = ["00", "00", "00", "19"];
var source = [module.address[0], module.address[1], "00", "00", "00", "00"];
var destination = ["00", module.node, "00", "00", "00", "00"];
var messageid = ["01", "1a"];
var flags = ["05", "00"];
var payload = ["00", "02", "00", "00"];
var commandarray = [];
commandarray = commandarray.concat( framestart, framecount, version, length, source, destination, messageid, flags, payload);  
commandarray.push(module.checksum(commandarray));
module.sendCommand(commandarray, "Get VD List: ", 1);
}
module.describeVD = function() {
var framestart = module.framestart;
var framecount = module.framecount;
var version = module.version;
var length = ["00", "00", "00", "15"];
var source = [module.address[0], module.address[1], module.zone1[0], module.zone1[1], module.zone1[2], module.zone1[3]];
var destination = ["00", module.node, module.zone1[0], module.zone1[1], module.zone1[2], module.zone1[3]];
var messageid = ["01", "19"];
var flags = ["00", "01"];
var commandarray = [];
module.log(module.zone1 + " " + module.zone1[3]);
commandarray = commandarray.concat( framestart, framecount, version, length, source, destination, messageid, flags);  
commandarray.push(module.checksum(commandarray));
module.sendCommand(commandarray, "Describe VD: ", 1);
}





///////////////////////////////
// VOLUME FUNCTIONS          //
///////////////////////////////
module.setVolume = function(zone, volume) {
var commandarray = ["F0","64","00","01","00","00","00","1C","00","33"];
var nodearray  = ["00", module.node];
var msgidarray  = ["01","00","00","00","00","01","00","01","03","00"];
var target = "";
switch (zone) {
case 1:
target = module.zone1;
break;
case 2:
target = module.zone2;
break;
case 3:
target = module.zone3;
break;
case 4:
target = module.zone4;
break;
}
commandarray = commandarray.concat(target, nodearray, target, msgidarray);
commandarray.push(volume);
commandarray.push(module.checksum(commandarray));
module.sendCommand(commandarray, "zone " + zone + " volume " + volume );
};

module.muteZone = function(zone, join) {
CF.getJoin(join, function(join,value) {
if ( value == 1 ) {
value = 0;
} else {
value = 1;
}
// zone 1 mute     F0 64 00 01 00 00 00 1B 00 33 01 05 00 14 00 8A 01 05 00 14 01 00 00 00 00 01 00 02 01 01 81
// zone 2 unmute   F0 64 00 01 00 00 00 1B 00 33 01 05 00 14 00 8A 01 05 00 14 01 00 00 00 00 01 00 02 01 00 DF
module.log("Zone " + zone + " mute " + value );
var commandarray = ["F0","64","00","01","00","00","00","1B","00","33"];
var nodearray  = ["00", module.node];
var msgidarray  = ["01","00","00","00","00","01","00","02","01"];
var target = "";
switch (zone) {
case 1:
target = module.zone1;
break;
case 2:
target = module.zone2;
break;
case 3:
target = module.zone3;
break;
case 4:
target = module.zone4;
break;
}
commandarray = commandarray.concat(target, nodearray, target, msgidarray);
commandarray.push("0" + value);
commandarray.push(module.checksum(commandarray));
module.sendCommand(commandarray, "zone " + zone + " mute " + value );
});
};

module.setInput = function(zone, input) {
var commandarray = ["F0","64","00","01","00","00","00","1B","00","33"];
var nodearray  = ["00", module.node];
var msgidarray  = ["01","00","00","00","00","01","00","00","01"];
var target = "";
switch (zone) {
case 1:
target = module.zone1;
break;
case 2:
target = module.zone2;
break;
case 3:
target = module.zone3;
break;
case 4:
target = module.zone4;
break;
}
commandarray = commandarray.concat(target, nodearray, target, msgidarray);
commandarray.push("0" + input);
commandarray.push(module.checksum(commandarray));
module.sendCommand(commandarray, "zone " + zone + " input " + input + " - ");
}






// current receiving from disco 64 - 0 - 1 - 0 0 0 2f - 0 8a - 0 0 0 0 - 1c 30 0 0 0 0 0 0 0 4 0 8a 5 0 10 0 0 0 0 0 0 0 0 0 0 0 f d7 1 5 8a 10 0 0 0 e8
// [FRAMESTART] [FRAMECOUNT] [VERSION] [LEN] [SRC.RTE] [NODE] [DEST.RTE] [MSGID] [FLAGS] [PAYLOAD] [CHECKSUM]
// F0 64 00 01 00,00,00,1B 00,33 01,05,00,15 00,8A 01,05,00,15 01,00,00,00,00,01,00,02,01 01 7B
// 4 10 17 26 37 45
// send disco no address
// 01 00 00 00 2f 30 1c 00 00 00 00 ff ff 00 00 00 00 00 00 05 00 1c 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
// send disco w/ address
// 01 00 00 00 2f 30 1c 00 00 00 00 00 30 00 00 00 00 00 00 05 04 1c 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
// rec disco no address
// 01 00 00 00 2f 00 30 00 00 00 00 ff ff 00 00 00 00 00 00 00 04 00 30 37 00 10 00 00 00 00 00 00 00 00 00 00 00 0f d7 02 20 51 10 00 00 00 04
// rec disco w/ address
// 01 00 00 00 2f 00 30 00 00 00 00 30 1c 00 00 00 00 00 00 00 04 00 30 70 00 10 00 00 00 00 00 00 00 00 00 00 00 0f d7 02 20 51 10 00 00 00 04
///////////////////////////////
// FEEDBACK                  //
///////////////////////////////
module.ProcessFeedback = function(feedbackname, feedbackstring) {

// put the feedback string in the buffer
var text = feedbackstring.split("");
for ( var i = 0; i < text.length; i++ ) {
var digit = text[i].charCodeAt(0);
var hexy = digit.toString(16);
// ignore resync requests
if ( hexy === "f0" && i == 0) { return; }
if ( hexy === "ff" && i == 0) { return; }
module.buffer.push(hexy);
}
//module.log("Buffer " + module.buffer);
// The first part of the buffer is the frame start
// we want to get go the length marker and cut that chunk from the buffer and process it

// find the first index of a frame start "64"
var index = module.buffer.indexOf("64");
// remove everything that precedes it
if ( index > 0 ) {
var waste = module.buffer.splice(0, index);
//module.log("Waste " + waste);
// reset the 64 index incase waste happened

index = module.buffer.indexOf("64");

}

var framelength = 0;
if ( module.buffer.length > 7 ) {
framelength = parseInt(module.buffer[6], 16);
// module.log("Frame Length: " + framelength);
// if we have accumulated the whole frame in the buffer splice it out
var response = "";
if ( index > -1 && module.buffer.length >= framelength + 3 ) {
response = module.buffer.splice(0, framelength + 3);
// module.log("\nResponse: " + response + "\n");
module.parseCommand(response);
}
}
//module.log("Buffer " + module.buffer );







/// OLD
return;




var text = feedbackstring.split("");
var hexstr = "fb>";
var hexstring = "HS";
for ( var i = 0; i < text.length; i++ ) {
var digit = text[i].charCodeAt(0);
var hexy = digit.toString(16);
if ( hexy === "f0" && i == 0) { return; }
if ( hexy === "ff" && i == 0) { return; }
module.buffer.push(hexy);
hexstring = hexstring + digit + " ";
hexstr = hexstr + hexy + " ";
}
module.log( "FEEDBACK " + hexstr );


for ( var i = 0; i < module.buffer.length; i++ ) {
if ( module.buffer[i] === "8c" ) {
// Ping
module.log("Ping");
module.buffer.splice(i, 1);
i--;
} else
if ( module.buffer[i] === "64" ) {

// Command - Get Frame Count
var framecount = "";
for ( var j = i+3; j < i + 7; j++ ) {
framecount +=  module.buffer[j];
}
framecount = parseInt(framecount, 16);
var cmd = module.buffer.splice(i, 1 + framecount + 2);
i--;
module.parseCommand( cmd );
} else
if ( module.buffer[i] === "ff" ) {
// Check for FF flush
var ffcount = 0;
var start = 0;
for ( var j = i; j < module.buffer.length; j++ ) {
if ( module.buffer[j] === "ff" ) {
if ( start == 0 ) { start = i; }
ffcount++;
}
if ( module.buffer[j] !== "ff" ) { break; }
}
if ( ffcount > 4 ) {
// module.log("FF FLUSH");
module.buffer.splice(i, ffcount);
i--;
return;
}
} else
if ( module.buffer[i] === "f0" ) {
// Check for FO flush
var ffcount = 0;
var start = 0;
for ( var j = i; j < module.buffer.length; j++ ) {
if ( module.buffer[j] === "f0" ) {
if ( start == 0 ) { start = i; }
ffcount++;
}
if ( module.buffer[j] !== "f0" ) { break; }
}
if ( ffcount > 4 ) {
//module.log("F0 FLUSH");
module.buffer.splice(i, ffcount);
i--;
return;
}
}
// module.log( "FEEDBACK " + hexstr );
if ( module.buffer.length > 0 ) {
module.log("BUFFER> " + module.buffer);
}
}
};


///////////////////////////////
// INTERNAL HELPER FUNCTIONS //
///////////////////////////////

module.parseCommand = function(command) {
module.log("parse");
module.ack();

var framestart = command.splice(0,1);
var framecount  = command.splice(0,1);
var version = command.splice(0,1);
var framelength = command.splice(0,4);
var src = command.splice(0,6);
var dest = command.splice(0,6);
var msgid = command.splice(0,2);
var flags = command.splice(0,2);
var payload = command.splice(0,command.length-1);
var checksum = command.splice(0,1);
var length = "";

  for ( var i = 0; i < 4; i++ ) {
length +=  framelength[i];
}
// DISCO MESSAGE
if ( module.compareArrays(msgid, [0,0]) && module.compareArrays(flags,[0,4]) ) {
module.log("Disco Recieved");
// if the disco ever fails the src[0] won't match, resubscribe
if ( module.disco[0] !== src[0] ) {
module.getVDList();
module.subscribe(module.zone1);
module.subscribe(module.zone2);
module.subscribe(module.zone3);
module.subscribe(module.zone4);

};
module.disco[0] = src[0];
module.disco[1] = src[1];
return;
}
// RTE/SV STATE INFORMATION
if ( module.compareArrays(msgid, [1,0]) && module.compareArrays(flags,[8,0]) ) {
var foundzonejoin = 0;
if ( module.compareArrays([src[2],src[3],src[4],src[5]], module.zone1 )) { foundzonejoin = module.zone1join; } else
if ( module.compareArrays([src[2],src[3],src[4],src[5]], module.zone2 )) { foundzonejoin = module.zone2join; } else
if ( module.compareArrays([src[2],src[3],src[4],src[5]], module.zone3 )) { foundzonejoin = module.zone3join; } else
if ( module.compareArrays([src[2],src[3],src[4],src[5]], module.zone4 )) { foundzonejoin = module.zone4join; } else { module.log("Zone Not Found"); return; }

// MUTE
if ( module.compareArrays([payload[0],payload[1],payload[2],payload[3]], [0,3,0,2] )) {
//module.log("MUTE");
//module.log( "Trying to set Join d" + foundzonejoin + payload[3] + " to " + payload[5] );
CF.setJoin("d" + foundzonejoin + payload[3], payload[5]);
}
// VOLUME
if ( module.compareArrays([payload[0],payload[1],payload[2],payload[3]], [0,3,0,1] )) {
//module.log("VOLUME");
//module.log( "Trying to set Join a" + foundzonejoin + payload[3] + " to " + payload[6] );
// convert volume to a decimal  00 min DD max (0 - 221);
var volume = parseInt(payload[6], 16);
var volinc = parseInt(65535 / 75); // 105 min 180 max (set for my house)  75 = 180-105
var volset = (volume - 105) * volinc;
CF.setJoin("a" + foundzonejoin + payload[3], volset );
}
// INPUT
if ( module.compareArrays([payload[0],payload[1],payload[2],payload[3]], [0,3,0,0] )) {
//module.log("INPUT");
//module.log( "Trying to set Join d" + module.zone1join + payload[3] + payload[1] );
for (var i = 0; i <= 6; i++ ) {
CF.setJoin("d" + foundzonejoin + payload[3] + i, 0);
}
CF.setJoin("d" + foundzonejoin + payload[3] + payload[5], 1);
}
}
// if ( module.compareArrays( [src[2],src[3],src[4],src[5]], module.zone1 ) ) {
module.log( "Feedback: FS " + framestart + " FC " + framecount + " FL " + framelength + " SRC " + src + " DEST " + dest + " MSGID " + msgid + " FLAGS " + flags + " PAYLOAD " + payload + " CHK " + checksum );
// }

if ( module.compareArrays(msgid, [1,"1a"])  ) {
module.log("Get VD List Response " + payload);
module.describeVD();
}
if ( module.compareArrays(msgid, [1,"1e"])  ) {
//module.log("Unkown Response");
var numsv = payload.splice(0,2);
var sv_id = payload.splice(0,2);
var type  = payload.splice(0,1);
var sv_val = payload
     //   module.log("NumSV " + numsv + " sv_id " + sv_id + " type " + type  + " svval " + sv_val );
}


if ( module.compareArrays(msgid, [1,19])  ) {
module.log("Describe VD Response SRC " + src + " DEST " + dest );
var numsv = payload.splice(0,2);
var sv_id = payload.splice(0,2);
var type  = payload.splice(0,1);
var sv_val = payload
        module.log("NumSV " + numsv + " sv_id " + sv_id + " type " + type  + " svval " + sv_val );
}
if ( module.compareArrays(msgid, [1,3]) ) {
var foundzonejoin = 0;
if ( module.compareArrays([src[2],src[3],src[4],src[5]], module.zone1 )) { foundzonejoin = module.zone1join; } else
if ( module.compareArrays([src[2],src[3],src[4],src[5]], module.zone2 )) { foundzonejoin = module.zone2join; } else
if ( module.compareArrays([src[2],src[3],src[4],src[5]], module.zone3 )) { foundzonejoin = module.zone3join; } else
if ( module.compareArrays([src[2],src[3],src[4],src[5]], module.zone4 )) { foundzonejoin = module.zone4join; } else { module.log("Zone Not Found"); return; }

//              2   INPUT 6     VOLUME 11  MUTE  15   PAGE 19        23        27        31        35  PAGE VOL 40               PAGE DUCKING                               68      PRVOL 73 PRTHRESH 77PRATTACK 81  PRHOLD 85PRRELEASE 89 PRDEPTH 93           RADIO
// PAYLOAD 0,18,[0,0,1,6],[0,1,3,0,9c],[0,2,1,1],[0,3,1,0],[0,4,1,0],[0,5,1,0],[0,6,1,0],[0,7,1,0],[0,8,3,0,b5],[0,9,1,28,0,a,1,9,0,b,1,0,0,c,1,12,0,d,1,0,0,e,1,3,0,f,1,0],[0,10,3,0,b5],[0,11,1,28],[0,12,1,9],[0,13,1,0],[0,14,1,12],[0,15,1,0],[0,16,1,3],[0,17,1,0]


var input = payload[5];  //
var vol = payload[10]; //
var mute = payload[14]; //
var page = payload[18]; //
var pagevol = payload[39]; //
var pgthreshold = payload[43]; //
var pgattack = payload[47]; //
var pghold = payload[51]; //
var pgrelease = payload[55]; //
var pgdepth = payload[59]; //
var priority = payload[67]; //
var priorityvol = payload[72]; //
var prthreshold = payload[76]; //
var prattack = payload[80]; //
var prhold = payload[84]; //
var prrelease = payload[88]; //
var prdepth = payload[92]; //
var masterradio = payload[100];//

// set mute button
CF.setJoin("d" + foundzonejoin + payload[12], mute);

// set input buttons
for (var i = 0; i <= 6; i++ ) {
CF.setJoin("d" + foundzonejoin + payload[3] + i, 0);
}
CF.setJoin("d" + foundzonejoin + 0 + payload[5], 1);

// set volume sliders
var volume = parseInt(vol, 16);
var volinc = parseInt(65535 / 75); // 105 min 180 max (set for my house)  75 = 180-105
var volset = (volume - 105) * volinc;
CF.setJoin("a" + foundzonejoin + 1, volset );
}
payload = payload.splice(41,27);
return;

};
module.resync = function() {
module.log("resync");
var resyncrequest = [];
for ( var i = 0; i < 16; i++ ) {
resyncrequest.push("FF");
};
module.sendCommand(resyncrequest);
var resyncack = [];
for ( var i = 0; i < 261; i++ ) {
resyncack.push("F0");
}
module.sendCommand(resyncack, "resync", 1);
};



module.ack = function() {
module.sendCommand(["A5"], "ack", 0);
};

module.compareArrays = function( array1, array2 ) {
var equal = 1;
//module.log( "COMPARE " + array1 +  " " + array2 );
if (array1.length != array2.length ) { equal = 0; }
for ( var i = 0; i < array1.length; i++ ) {
if ( parseInt(array1[i],16) != parseInt(array2[i],16) ) {  equal = 0; }
}
return equal;

};

module.sendHeartbeat = function() {
// ever second
// Heartbeat F0 8C
module.sendCommand(["F0","8C"], "ping", 0);
};

module.hexify = function( array ) {
var string = "";
var tstring = "";
for ( var i = 0; i < array.length; i++) {
string = string + String.fromCharCode(parseInt(array[i],16));
tstring = tstring + " " + parseInt(array[i],16);

}
// module.log(tstring);
return string;
};

        module.checksum = function(dbx) {
                var ccit = ["5E","BC","E2","61","3F","DD","83","C2","9C","7E","20","A3","FD","1F","41","9D","C3","21","7F","FC","A2","40","1E","5F","01","E3","BD","3E","60","82","DC","23","7D","9F","C1","42","1C","FE","A0","E1","BF","5D","03","80","DE","3C","62","BE","E0","02","5C","DF","81","63","3D","7C","22","C0","9E","1D","43","A1","FF","46","18","FA","A4","27","79","9B","C5","84","DA","38","66","E5","BB","59","07","DB","85","67","39","BA","E4","06","58","19","47","A5","FB","78","26","C4","9A","65","3B","D9","87","04","5A","B8","E6","A7","F9","1B","45","C6","98","7A","24","F8","A6","44","1A","99","C7","25","7B","3A","64","86","D8","5B","05","E7","B9","8C","D2","30","6E","ED","B3","51","0F","4E","10","F2","AC","2F","71","93","CD","11","4F","AD","F3","70","2E","CC","92","D3","8D","6F","31","B2","EC","0E","50","AF","F1","13","4D","CE","90","72","2C","6D","33","D1","8F","0C","52","B0","EE","32","6C","8E","D0","53","0D","EF","B1","F0","AE","4C","12","91","CF","2D","73","CA","94","76","28","AB","F5","17","49","08","56","B4","EA","69","37","D5","8B","57","09","EB","B5","36","68","8A","D4","95","CB","29","77","F4","AA","48","16","E9","B7","55","0B","88","D6","34","6A","2B","75","97","C9","4A","14","F6","A8","74","2A","C8","96","15","4B","A9","F7","B6","E8","0A","54","D7","89","6B","35"];
                var bcc = "FF";
                for (var i = 1; i < dbx.length; i++ ) {
                    var dbx1 = parseInt(dbx[i],16);
                    var bcc1 = parseInt(bcc,16);
                   var bcc = ccit[(bcc1^dbx1)-1];
                }
                return bcc;
        };

module.sendCommand = function (command, descrip, debug) {
if (debug) { module.log("send command: " + descrip + " " + command); }
command = module.hexify(command);
// module.log("sent command: " + command);
CF.send("Moxa_ZonePro", command);
};

// Only allow logging calls when CF is in debug mode - better performance in release mode this way
module.log = function(msg) {
if (CF.debug && module.debug) {
CF.log("ZonePro: " + msg);
}
};  





return module;
};

CF.modules.push({
name: "ZonePro",
object: ZonePro,
version: 1.0
});

Fiasco

unread,
Mar 24, 2024, 3:14:53 AMMar 24
to CommandFusion Software
Getting pretty farIMG_2391.PNG

Fiasco

unread,
Mar 27, 2024, 6:09:10 PMMar 27
to CommandFusion Software
Getting really far along on my javascript ZonePro Modules.    I can control every aspect of a zone pro and all of it's zones with feedback.   There are approximatley 320 different settings in a 4 zone zonepro (640/640m).   I don't have a 1200 series to test (six zone controller) so I'll stop with the 640.

Now I'm refining/simplifying the code and breaking it down into seperate modules that work together for the various functions. to make configuring it as easy as possible.

This is all it takes to configure the zonepro in the commandfusion setup/start script.   If you turn debugging in the command fusion app and set the "Debug" entry in ZonePro.setup() to 1 the debugger will spit out all join numbers it will assign the various functions to.

try {
ZonePro = new ZonePro();
// system name, system feedback, node address, debug,
// get the node address from the zonepro GUI Designer screen
ZonePro.setup( "Moxa_ZonePro", "Moxa_ZonePro_Feedback", 138, 1 );
// enter zone addresses backwards
// first array entry is the base number join you want to use for that section of the zonepro
// The modules will auto assign join numbers and spit them out in the commandfusion debugger browser window
// to get the section addresses, select the section in the zone pro gui designer software window and hit CTRL+SHIFT+O
// ZonePro.setupXXX ( base join number, [address b3, address b2, address b1, address b0]
ZonePro.setupRTE (800, ['01', '05', '00', '20']);
ZonePro.setupRTEEQ (600, ['01', '08', '00', '32']);
ZonePro.setupIN (200, ['01', '01', '00', '00']);
ZonePro.setupINS1 (300, ['01', '03', '00', '12']);
ZonePro.setupINS2 (400, ['01', '04', '00', '16']);
ZonePro.setupAW (500, ['01', '06', '00', '24']);
ZonePro.setupBPF (600, ['01', '07', '00', '28']);
ZonePro.setupINS3 (700, ['01', '09', '00', '36']);
ZonePro.setupDLY (1000, [ '01', '10', '00', '40']);
ZonePro.setupOUT (1100, ['01', '11', '00', '44']);
} catch ( err ) {
CF.log("ZonePro Setup Error " + err.message );
}

IMG_2403.PNG
Reply all
Reply to author
Forward
0 new messages