How to combine hex bytes from variables in javascript

1,827 views
Skip to first unread message

JohanJ

unread,
Apr 23, 2012, 4:32:21 PM4/23/12
to comman...@googlegroups.com
I'm trying to communicate with a Pronto RFX9600 extender over UDP. I have defined the UDP system in CF and It works fine when sending complete strings of the hex bytes in Javascript, e.g. the string below close relay 1.
"\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x63\x00\x00\x06\x00\x01\x00\x00"

But how can I construct these string from variables? For example the three first hex bytes is a number that should be increased each time a command is sent. 
I know that I can NOT write:
var index = 1;
var hexString = "\x"+index;

Any suggestions?

Johan

Barry Gordon

unread,
Apr 23, 2012, 5:03:10 PM4/23/12
to comman...@googlegroups.com

look up in a JS reference  number.toString(base) as in

 

 n=17; hex="0x"+n.toString(16) yields the string "0x11"

 

Also look at my Serial Comm reference on  my web site.  I believe it illustrates your question with several answers

 

It also explains the bigger picture in that if you want to place an integer of value let's say 17 into a string there is no need to go to hex.  JS on seeing a string of the form "\xnn" where nn is a hex number (00-FF) converts it to an integer (0-255) to place in the appropriate byte, the issue there is packing as numbers in memory hold two bytes (16 bits)

--
You received this message because you are subscribed to the Google Groups "CommandFusion Software" group.
To view this discussion on the web visit https://groups.google.com/d/msg/commandfusion/-/6L5jCd8tD6YJ.
To post to this group, send email to comman...@googlegroups.com.
To unsubscribe from this group, send email to commandfusio...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/commandfusion?hl=en.

Jarrod Bell

unread,
Apr 24, 2012, 8:29:26 PM4/24/12
to comman...@googlegroups.com
String.fromCharCode(17)

This would result in a hex byte such as \x17

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/fromCharCode

Jarrod

Barry Gordon

unread,
Apr 24, 2012, 10:29:43 PM4/24/12
to comman...@googlegroups.com

Hate to disagree, but IIRC string.fromCharCode assumes the argument is the ascii index for the character so it is a decimal 17 this would result in the byte being of type string with the decimal value of 17. "\x17" will produce the byte whose ascii index (decimal value) is 23

Jarrod Bell

unread,
Apr 24, 2012, 10:33:38 PM4/24/12
to comman...@googlegroups.com
Ah yes, sorry about that (misreading again!)

So instead it would be:
String.fromCharCode(23)

Jarrod

Barry Gordon

unread,
Apr 25, 2012, 12:16:51 AM4/25/12
to comman...@googlegroups.com

I spent a lot of time on the pronto forum trying to explain the difference between representations and the contents of a byte.  The contents of a byte which is always a number in the range of 0-255 can be represented in many different bases and using several different notations, however when push comes to shove the byte will contain a number in the range of 0-255 decimal.  Because HEX is such a convenient representation for things that come in sizes of 4 bits (0-15 decimal)  many like hex. Ergo two hex bytes are a convenient and easily decoded way of representing 8 bit binary quantities.

 

When I started programming in the early 60's  the machine I worked on had a 24 bit memory cell and 24 bit registers.  We represented everything in octal which is similar to the utility of HEX with three bit quantities.

 

The bottom line however is just getting the memory to contain the correct numbers no matter how you choose to represent them, ASCII, HEX, Octal, decimal  etc.

 

In Javascript the notation "\x21" and string.fromcharCode(33) and "!" are all the exact same quantity in memory.  Just a different way of representing them on paper with JS doing the conversion

Nahshon Williams

unread,
Apr 26, 2012, 1:40:29 AM4/26/12
to comman...@googlegroups.com
We need the relentless explanations Barry. . .you are dealing with a phobia first. . . The brain just switches off . . .many years ago (in the 90s) when I studied a module in digital electronics. . . The test marks took priority. . . So we just studied enough to pass. . . (hoping not to be confused by someone else's logic before the exam). . . Wish we had CF for labs at the time . . and u conducting them. :-)

Nahshon 

JohanJ

unread,
Apr 26, 2012, 2:05:38 AM4/26/12
to comman...@googlegroups.com
Hi Barry, thanks for your answers. I have now read your primer and will do some tests later on. Yes, it gave me answers to a lot of my questions.

It's too bad that I do not have the time to play with this all the time.... Day time work, family and house takes most of my time.

Thanks again,

Johan

JohanJ

unread,
Apr 28, 2012, 2:48:19 AM4/28/12
to comman...@googlegroups.com
I managed to get full control of the RFX9600 relays, now IR and RS232 left.  




self.relay = function(id, type) {
      var index = self.RFXSendIndex;
      self.RFXSendIndex++;
//The first three hex bytes correspond to the message id:     
var b1 = Math.floor(index/256);
      var b2 = Math.floor((index-b1*256)/16);
      var b3 = index-b1*256-b2*16;
      var messageId = String.fromCharCode(b1,b2,b3);
     
      var typeHex, openCloseHex;
      if (type == "open" || type == "close"){
         typeHex = "\x63";
      } else if(type == "toggle"){
         typeHex = "\x64";
      } else if(type == "query"){
         typeHex = "\x65";
      }

      if (type == "open" || type == "toggle" || type == "query"){
         openCloseHex = "\x00";
      } else if(type == "close"){
         openCloseHex = "\x01";
      }

      var datalengthHex;
      if (type == "open" || type == "close") {
         datalengthHex = "\x06";
      } else if (type == "toggle" || type == "query") {
         datalengthHex = "\x05";
      }
      var portIdHex = String.fromCharCode(id-1);
      self.sendRFX(messageId +                      //Id - Three bytes
                   "\x00" +                         //Status
                   "\x00" +                         //Repeatcount
                   "\x00\x00\x00\x00\x00\x00\x00" + //7 reserved bytes
                   typeHex +                        //Type of message - 1 byte
                   "\x00\x00" +                     //?? ?? 2 Byte
                   datalengthHex +                  // data length
                   portIdHex +                      //Port id (0-3) 1 byte
                   openCloseHex  +                  //(open-00 close-01)1 byte
                   "\x00\x00");                     // End of data two bytes
   }

   self.sendRFX = function(string) {
      CF.log("\n  Send data:" + self.showHEX(string));
      for (var j = 0 ; j < 1 ; j++) {
         CF.send("RFX9600",string);
      }

   }

I also used Barrys function for logging the hex bytes that are sent:
self.showHEX = function(a){
      var b="";
      var ch="";
      for(var i=0; i<a.length; i++) {
         ch=a.charCodeAt(i);
         ch = (ch < 16 ? "0" + ch.toString(16) : ch.toString(16) );
         b+=ch.toUpperCase()+ " ";
      }
      return b;
   }

I first tried wireshark for sniffing the packages but couldn't see the traffic between remote/extender. It seems that one need a switch that can duplicate a specific port and I do not have that kind of switch. Instead I tried sudppipe for sniffing the traffic, it's a UDP proxy. One direct all traffic through a pc, the program can produce a cap file that wireshark can read. This solution worked fine for me.

Thanks for the help,

Johanu

Barry Gordon

unread,
Apr 28, 2012, 7:34:57 AM4/28/12
to comman...@googlegroups.com
When trying to see things with wireshark a hub should be used to connect the devices being investigated. A hub sends to all its ports, while a switch is smart and only sends to the port that has the device with the desired address

Sent from my iPad
--
You received this message because you are subscribed to the Google Groups "CommandFusion Software" group.
To view this discussion on the web visit https://groups.google.com/d/msg/commandfusion/-/aHDAvQKuessJ.

JohanJ

unread,
Apr 28, 2012, 9:05:44 AM4/28/12
to comman...@googlegroups.com
Thanks, I know that a hub also would be sufficient but I do not have that either. Can one still buy such a device? I do not see the point with them, apart for sniffing packages. 

sudppipe seems to be perfect for my current needs.

Johan
To unsubscribe from this group, send email to commandfusion+unsubscribe@googlegroups.com.

Barry Gordon

unread,
Apr 28, 2012, 10:54:18 AM4/28/12
to comman...@googlegroups.com

That is exactly why I keep a 5 port linksys hub in my toolbox.  yes they are still available.  A google or yahoo search will find one

 

From: comman...@googlegroups.com [mailto:comman...@googlegroups.com] On Behalf Of JohanJ
Sent: Saturday, April 28, 2012 9:06 AM
To: comman...@googlegroups.com
Subject: Re: How to combine hex bytes from variables in javascript

 

Thanks, I know that a hub also would be sufficient but I do not have that either. Can one still buy such a device? I do not see the point with them, apart for sniffing packages. 

To unsubscribe from this group, send email to commandfusio...@googlegroups.com.


For more options, visit this group at http://groups.google.com/group/commandfusion?hl=en.

--

You received this message because you are subscribed to the Google Groups "CommandFusion Software" group.

To view this discussion on the web visit https://groups.google.com/d/msg/commandfusion/-/caFh8KoFKTEJ.


To post to this group, send email to comman...@googlegroups.com.

To unsubscribe from this group, send email to commandfusio...@googlegroups.com.

Jarrod Bell

unread,
Apr 28, 2012, 9:44:10 PM4/28/12
to comman...@googlegroups.com
Congrats Johan! Please do continue to share your experiences with the
RFX9600 as I'm sure there are quite a few of those sitting around that
people would love to be able to make use of with their iOS/Android devices.

Jarrod
> --
> You received this message because you are subscribed to the Google
> Groups "CommandFusion Software" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/commandfusion/-/aHDAvQKuessJ.

JohanJ

unread,
Apr 30, 2012, 2:14:37 AM4/30/12
to comman...@googlegroups.com
Thanks Jarrod. I should although not take the credit, sWORDs in the RemoteCentral forum posted some information regarding their protocol in 2010. I just redid what he did and wrote the javascript functions to get it working in CommandFusion. According to his posts it should be possible to control RS232 and learned IR codes(not Philips database ones). sWORDs stopped posting in the forum and the protocol is still incomplete. There are for example some communication back and fourth the remote and extender after a command is sent, some of the data can be understood but not all. It works however fine to just send a command. It's although enough info in the response to know if the message was accepted/failed/finished. 

I will try with some IR codes later on and will continue to post my finding.

My CF system:
UDP
ip:192.168.1.5
port: 65442
Accept incoming connections is  ticked.

CPadilha

unread,
May 14, 2012, 1:21:05 PM5/14/12
to CommandFusion Software
Hi Johan, I have a little knowledge about RFX9600 communication
protocol. Today I can communicate, via iViewer-javascript, with
RFX9600. send IR codes, RS-232 codes, close/open/togle relays, read
relay-status, imput-status. I reached this level of knowledge with the
use of prontronic software. If you want to know how do it, feel free
and ask me.
Carlos

JohanJ

unread,
May 14, 2012, 1:50:41 PM5/14/12
to comman...@googlegroups.com
Hi CPadilha

That sounds great! Do you have gui/js file that you are willing to share? Me, and I guess a lot of other people in the same position, would be appreciate it a lot.

If not, I would be really grateful for getting answers to my questions regarding how to implement.

I haven't spend any time on this since my last post. I bought an RS232 cable ago for my new amp a couple of weeks but haven't connected it yet. My next step is to try some ir codes for the projector.

Cheers,

Johan

CPadilha

unread,
May 15, 2012, 11:31:45 PM5/15/12
to CommandFusion Software
Johan,
I love to do reverse engeneering, so I was able to discover the
RFX9600 communication protocol. My last work was to discover Samsung
Air-Conditioner IR protocol and then, control by iViewer, if anyone
has interest...,
So, Below is my RFX9600 application:

Sorry about remarks on brazilian-portuguese, but I think it is not
difficult to understand.

To send commands: CX.rfxTxRx(cmd, porta, texto, special), where:
cmd: command (0:relay open, 1:relay close, 2:relay togle, 3:input read
status, 4:IR send, 5:serial send, 6:relay status)
porta: RFX port (1 to 4)
texto: text to send (IR, RS232)
special: used in Samsung air conditioned protocol

To read relay status: CX.leEntStat(index), where:
index: index of RFX buffer commands

To read input ports: CX.leEnt(entrada), where:
entrada: input port (1 to 4)


var ackTime, ackTime1, rfxInput, indexAck, rfxAckId=35, timerID;
var rfxEnt = new Array(256); // array de respostas de entrada
enfileiradas
function onProcessAck(feedbackItem, txtAck) {
CF.setJoin("s500"+(indexAck++), CP.charToHex(txtAck));
if (txtAck.charCodeAt(3)==64) { // 4º byte = 40 (resposta)?
if (txtAck.charCodeAt(4)==0){ // 5º byte = 00 (2ª sequência)?
rfxAckId=txtAck.charCodeAt(2); // armazene 3º byte, id ack do
RFX9600
rfxEnt[rfxAckId]=rfxInput=txtAck.charCodeAt(12)==1 ? true :
false; // status da entrada/rele, true=ON, false=OFF
var today2=new Date();ackTime=today2.getTime()-ackTime1
}
if (txtAck.charCodeAt(4)==2) sendRFX9600(); // 5º byte = 02 (6ª
sequência)? se sim, verifique buffer de comandos
} else if (!((txtAck.charCodeAt(3)==32)|(txtAck.charCodeAt(3)==34)))
CP.msgStart("** Erro de Comunicacao com RFX9600 **");
}
CF.watch(CF.FeedbackMatchedEvent, "RFX9600_1", "RFX9600_feedback",
onProcessAck);

var cntCode=34, cntCodeH, cntCodeL;
function countCode() { // contador (3 bytes)
cntCodeH=cntCode/256; cntCodeL=cntCode++%256;
CF.setJoin("s5678", "00 "+CP.charToHex(String.fromCharCode(cntCodeH))
+CP.charToHex(String.fromCharCode(cntCodeL)));
return("\x00"+String.fromCharCode(cntCodeH)
+String.fromCharCode(cntCodeL));
}

var rfxCodeArray = new Array(256);
function sendRFX9600(){ // envia comando, do buffer, ao
RFX9600
var rfxIdxDif=cntCodeL-rfxAckId; // (id de envio) - (id de ack/
recebimento)
if ((rfxIdxDif<0 ? rfxIdxDif+256 : rfxIdxDif)==0) return; // buffer
vazio, saia
indexAck=1; // resseta índice da tabela ack
CF.send("RFX9600_1", rfxCodeArray[rfxAckId<255 ? rfxAckId+1 : 0]); //
envia pacote UDP para o TSU9600
var today1=new Date();ackTime1=today1.getTime(); // para cálculo
do "ack Time" do RFX9600
clearTimeout(timerID);timerID=setTimeout(ackTimeout, 2000); //
verifique Timeout na resposta do RFX9600
}

function ackTimeout(){
if (cntCodeL==rfxAckId) return // id envidado = id recebido,
houve resposta, saia
// CF.log("cntCodeL: "+cntCodeL+" rfxAckId: "+rfxAckId);
CP.msgStart ("*** RFX9600 Timeout ***");
CP.msgErr ("*** RFX9600 Timeout ***");
rfxAckId=rfxAckId<255 ? ++rfxAckId : 0; // próximo ack (próximo
dado do buffer)
sendRFX9600(); // leia próximo comando do buffer
}
//-----------------------------------------------------------------------

var CX = {
// cmd: 0=relé_abrir(63) 1=relé_fechar(63) 2=relé_togle(64)
3=ler_entrada(60) 4=IR(40)
// 5=serial(50) 6=relé_status(65) 7=request_status(30)
8=repeat_frame(31) 9=testes(?)
// porta: de 1 a 4
// texto: dados de IR ou RS232

rfxTxRx: function(cmd, porta, texto, special) {

var statusCode ="\x08"; // (00=Request 08=? 20=Ok 24=Failed
40=Finished)
var rptcntCode ="\x00"; // repeatcount: 1º envio=(00), 2º
envio=(01)
var verCode ="\x02"; // versão ???
var lenHCode =0; // 8 bits mais significativo do datalength
var lenLCode =6; // 8 bits menos significativo do datalength
(from action to end data)
var reserveCode ="\x00\x00\x00\x00\x00\x00\x00";
var onOffCode ="\x00"; // ON/OFF relé, nulo em togle, RS232 flags
var endCode ="\x00\x00"; // Duration in ms (01 ea = 1ea = 490ms = .
49s)
var teste =String.fromCharCode(5);
var portaCode =porta-1;

if (cmd=="0") { // abrir relé
var actionCode= "\x63"; // (00=Completed 30=RequestStatus 40=IR
50=RS232 63=setRelay 64=togleRelay 65=getRelay)
}
if (cmd=="1") { // fechar relé
var actionCode ="\x63"; // (63=setRelay)
onOffCode ="\x01"; // fecha relé
}
if (cmd=="2") { // abrir/fechar relé
var actionCode ="\x64"; // (64=togleRelay)
}
if (cmd=="3") { // ler entrada
var actionCode ="\x60"; // (60=le entrada)
lenLCode =5;
}
if (cmd=="4") { // enviar IR
statusCode ="\x00"; // (00=Request 08=? 20=Ok 24=Failed
40=Finished)
var actionCode ="\x40"; // IR
verCode ="\x00";
var dado="", j=0;
for (var i=0; i<texto.length; i++) {
if (texto.charAt(i)!="x") {
var a=CP.hexToDec(texto.charAt(i)); i++; a <<= 4;
var b=CP.hexToDec(texto.charAt(i)); i++; b=a|b;
dado+=String.fromCharCode(b); j++
} else {i=i+2; j++}
}
var lenTxt =14+j; // datalength (from action to end data)
if (lenTxt>255) {lenHCode=lenTxt/256; lenLCode=lenTxt%256}
else lenLCode=lenTxt;
if (special) specialCode="\x05\xDC"
else specialCode="\x00\x00";
endCode +="\x00\x00"+specialCode+"\x00\x00\x00"+"\x00"+dado; //
specialCode + 1 (IR repeatcount) + texto;
}
if (cmd=="5") { // RS232
var actionCode ="\x50"; // (50=RS232)
lenLCode =16+texto.length; // datalength (from action to end data)
portaCode <<=4; // shift left 4 vezes
portaCode |=4; // 2=2400 3=4800 4=9600 5=14400 6=19200
7=28800....\11=115200
onOffCode ="\xC0"; // 1 stopbit, no parity, 8 databits (veja
tabela abaixo)
endCode +="\x00\x00\x00\x00\x00\x00\x00"+"\x01"+texto; // 7
(reserved) + 1 (RS232 repeatcount) + texto;
}
/* onOffCode: stopbits: parity: databits:
1 = 00 none = 00 5 = 00
1.5 = 02 even = 08 6 = 40
2 = 04 odd = 10 7 = 80
mark = 18 8 = C0
space = 20 */
if (cmd=="6") { // ler status de relé
var actionCode ="\x65"; // (65=GetStatusRelay)
lenLCode =5;
}
if (cmd=="7") { // ler status do RFX9600
var actionCode ="\x30"; // (30=request status)
lenLCode =5;
}
if (cmd=="8") { // repita último comando
var actionCode ="\x31"; // (31=repeat last frame)
lenLCode =8;
}
if (cmd=="9") { // teste
var actionCode ="\x62";
lenLCode =5;
}

portaCode=String.fromCharCode(portaCode);
lenHCode =String.fromCharCode(lenHCode);
lenLCode =String.fromCharCode(lenLCode);
var code=countCode()+statusCode+rptcntCode+reserveCode+actionCode
+verCode+lenHCode+lenLCode+portaCode+onOffCode+endCode;
rfxCodeArray[cntCodeL]=code; // armazena no buffer (FIFO) os
comandos para o RFX9600
var rfxIdxDif=cntCodeL-rfxAckId; // (id de envio) - (id de ack/
recebimento)
if ((rfxIdxDif<0 ? rfxIdxDif+256 : rfxIdxDif)==1) sendRFX9600(); //
1º comando no buffer, envie dado para o RFX9600
},
leInput: function() {return rfxInput},
leEnt: function(entrada) {CX.rfxTxRx(3,entrada); index=cntCodeL;
rfxEnt[index]=null;/* CF.log("idi: "+index);*/ return index},
leRele: function(rele) {CX.rfxTxRx(6,rele); index=cntCodeL;
rfxEnt[index]=null;/* CF.log("idi: "+index);*/ return index},
leEntStat: function(index) {/*CF.log("rfxEnt: "+rfxEnt[index]);
CF.log("ido: "+index); */ return rfxEnt[index]}

Jarrod Bell

unread,
May 15, 2012, 11:33:27 PM5/15/12
to comman...@googlegroups.com
Please don't litter the group with source code. Instead create a gist at
gist.github.com and share the link.
Much nicer way to share code, but thanks for sharing!

Jarrod

On 16/05/12 1:31 PM, CPadilha wrote:
> Johan,
> I love to do reverse engeneering, so I was able to discover the
> RFX9600 communication protocol. My last work was to discover Samsung
> Air-Conditioner IR protocol and then, control by iViewer, if anyone
> has interest...,
> So, Below is my RFX9600 application:
>
> Sorry about remarks on brazilian-portuguese, but I think it is not
> difficult to understand.
>
> To send commands: CX.rfxTxRx(cmd, porta, texto, special), where:
> cmd: command (0:relay open, 1:relay close, 2:relay togle, 3:input read
> status, 4:IR send, 5:serial send, 6:relay status)
> porta: RFX port (1 to 4)
> texto: text to send (IR, RS232)
> special: used in Samsung air conditioned protocol
>
> To read relay status: CX.leEntStat(index), where:
> index: index of RFX buffer commands
>
> To read input ports: CX.leEnt(entrada), where:
> entrada: input port (1 to 4)
>
>
> var ackTime, ackTime1, rfxInput, indexAck, rfxAckId=35, timerID;
> var rfxEnt = new Array(256); // array de respostas de entrada
> enfileiradas
> function onProcessAck(feedbackItem, txtAck) {
> CF.setJoin("s500"+(indexAck++), CP.charToHex(txtAck));
> if (txtAck.charCodeAt(3)==64) { // 4� byte = 40 (resposta)?
> if (txtAck.charCodeAt(4)==0){ // 5� byte = 00 (2� sequ�ncia)?
> rfxAckId=txtAck.charCodeAt(2); // armazene 3� byte, id ack do
> RFX9600
> rfxEnt[rfxAckId]=rfxInput=txtAck.charCodeAt(12)==1 ? true :
> false; // status da entrada/rele, true=ON, false=OFF
> var today2=new Date();ackTime=today2.getTime()-ackTime1
> }
> if (txtAck.charCodeAt(4)==2) sendRFX9600(); // 5� byte = 02 (6�
> sequ�ncia)? se sim, verifique buffer de comandos
> } else if (!((txtAck.charCodeAt(3)==32)|(txtAck.charCodeAt(3)==34)))
> CP.msgStart("** Erro de Comunicacao com RFX9600 **");
> }
> CF.watch(CF.FeedbackMatchedEvent, "RFX9600_1", "RFX9600_feedback",
> onProcessAck);
>
> var cntCode=34, cntCodeH, cntCodeL;
> function countCode() { // contador (3 bytes)
> cntCodeH=cntCode/256; cntCodeL=cntCode++%256;
> CF.setJoin("s5678", "00 "+CP.charToHex(String.fromCharCode(cntCodeH))
> +CP.charToHex(String.fromCharCode(cntCodeL)));
> return("\x00"+String.fromCharCode(cntCodeH)
> +String.fromCharCode(cntCodeL));
> }
>
> var rfxCodeArray = new Array(256);
> function sendRFX9600(){ // envia comando, do buffer, ao
> RFX9600
> var rfxIdxDif=cntCodeL-rfxAckId; // (id de envio) - (id de ack/
> recebimento)
> if ((rfxIdxDif<0 ? rfxIdxDif+256 : rfxIdxDif)==0) return; // buffer
> vazio, saia
> indexAck=1; // resseta �ndice da tabela ack
> CF.send("RFX9600_1", rfxCodeArray[rfxAckId<255 ? rfxAckId+1 : 0]); //
> envia pacote UDP para o TSU9600
> var today1=new Date();ackTime1=today1.getTime(); // para c�lculo
> do "ack Time" do RFX9600
> clearTimeout(timerID);timerID=setTimeout(ackTimeout, 2000); //
> verifique Timeout na resposta do RFX9600
> }
>
> function ackTimeout(){
> if (cntCodeL==rfxAckId) return // id envidado = id recebido,
> houve resposta, saia
> // CF.log("cntCodeL: "+cntCodeL+" rfxAckId: "+rfxAckId);
> CP.msgStart ("*** RFX9600 Timeout ***");
> CP.msgErr ("*** RFX9600 Timeout ***");
> rfxAckId=rfxAckId<255 ? ++rfxAckId : 0; // pr�ximo ack (pr�ximo
> dado do buffer)
> sendRFX9600(); // leia pr�ximo comando do buffer
> }
> //-----------------------------------------------------------------------
>
> var CX = {
> // cmd: 0=rel�_abrir(63) 1=rel�_fechar(63) 2=rel�_togle(64)
> 3=ler_entrada(60) 4=IR(40)
> // 5=serial(50) 6=rel�_status(65) 7=request_status(30)
> 8=repeat_frame(31) 9=testes(?)
> // porta: de 1 a 4
> // texto: dados de IR ou RS232
>
> rfxTxRx: function(cmd, porta, texto, special) {
>
> var statusCode ="\x08"; // (00=Request 08=? 20=Ok 24=Failed
> 40=Finished)
> var rptcntCode ="\x00"; // repeatcount: 1� envio=(00), 2�
> envio=(01)
> var verCode ="\x02"; // vers�o ???
> var lenHCode =0; // 8 bits mais significativo do datalength
> var lenLCode =6; // 8 bits menos significativo do datalength
> (from action to end data)
> var reserveCode ="\x00\x00\x00\x00\x00\x00\x00";
> var onOffCode ="\x00"; // ON/OFF rel�, nulo em togle, RS232 flags
> var endCode ="\x00\x00"; // Duration in ms (01 ea = 1ea = 490ms = .
> 49s)
> var teste =String.fromCharCode(5);
> var portaCode =porta-1;
>
> if (cmd=="0") { // abrir rel�
> var actionCode= "\x63"; // (00=Completed 30=RequestStatus 40=IR
> 50=RS232 63=setRelay 64=togleRelay 65=getRelay)
> }
> if (cmd=="1") { // fechar rel�
> var actionCode ="\x63"; // (63=setRelay)
> onOffCode ="\x01"; // fecha rel�
> }
> if (cmd=="2") { // abrir/fechar rel�
> if (cmd=="6") { // ler status de rel�
> var actionCode ="\x65"; // (65=GetStatusRelay)
> lenLCode =5;
> }
> if (cmd=="7") { // ler status do RFX9600
> var actionCode ="\x30"; // (30=request status)
> lenLCode =5;
> }
> if (cmd=="8") { // repita �ltimo comando
> var actionCode ="\x31"; // (31=repeat last frame)
> lenLCode =8;
> }
> if (cmd=="9") { // teste
> var actionCode ="\x62";
> lenLCode =5;
> }
>
> portaCode=String.fromCharCode(portaCode);
> lenHCode =String.fromCharCode(lenHCode);
> lenLCode =String.fromCharCode(lenLCode);
> var code=countCode()+statusCode+rptcntCode+reserveCode+actionCode
> +verCode+lenHCode+lenLCode+portaCode+onOffCode+endCode;
> rfxCodeArray[cntCodeL]=code; // armazena no buffer (FIFO) os
> comandos para o RFX9600
> var rfxIdxDif=cntCodeL-rfxAckId; // (id de envio) - (id de ack/
> recebimento)
> if ((rfxIdxDif<0 ? rfxIdxDif+256 : rfxIdxDif)==1) sendRFX9600(); //
> 1� comando no buffer, envie dado para o RFX9600
> },
> leInput: function() {return rfxInput},
> leEnt: function(entrada) {CX.rfxTxRx(3,entrada); index=cntCodeL;
> rfxEnt[index]=null;/* CF.log("idi: "+index);*/ return index},
> leRele: function(rele) {CX.rfxTxRx(6,rele); index=cntCodeL;
> rfxEnt[index]=null;/* CF.log("idi: "+index);*/ return index},
> leEntStat: function(index) {/*CF.log("rfxEnt: "+rfxEnt[index]);
> CF.log("ido: "+index); */ return rfxEnt[index]}
>
>
>
> On 14 maio, 14:50, JohanJ<johanjeppsso...@gmail.com> wrote:
>> Hi CPadilha
>>
>> That sounds great! Do you have gui/js file that you are willing to share?
>> Me, and I guess a lot of other people in the same position, would be
>> appreciate it a lot.
>>
>> If not, I would be really grateful for getting answers to my questions
>> regarding how to implement.
>>
>> I haven't spend any time on this since my last post. I bought an RS232
>> cable ago for my new amp a couple of weeks but haven't connected it yet. My
>> next step is to try some ir codes for the projector.
>>
>> Cheers,
>>
>> Johan
>>

Jordan

unread,
May 16, 2012, 11:29:01 AM5/16/12
to comman...@googlegroups.com
Hi CPadilha, looks like a great work. I have checked your code and was trying to send IR to a RFX9400 (they share firmware so I assume their communication protocol is the same).
As a quick test I have assembled a IR code command and sent it to the 65442 UDP port of the RFX. As feedback I am receiving #@, which from your code I understand are respectively the ack character and the IR command character. I however can't get it to work through an IR blaster. Can you confirm the feedback is correct?

My problem might be the IR code format. I used an hex code built from RC5 System and Command codes, as it yelds shorter codes. I have also tried with a learned code, still no joy. Any thoughts?

Thanks again for sharing your work!

CPadilha

unread,
May 16, 2012, 6:18:17 PM5/16/12
to CommandFusion Software
Hi Jordan,
First at all, you must download the Prontonic Application (http://
www.plane9.com/creations/prontonic), then you must configure the
extender IP on TSU9600 using ProntoEdit Professional to point to
computer IP where Prontonic is installed, download to TSU. After that,
run Prontonic and configure IP of remote control and IP of extender.
Send IR code from TSU9600/9400 to extender and you will see the codes
to and from extender. Copy the code sent by TSU9xxx from "FF
FF.......". It looks like:
"FF FF 01 3E 01 00 00 08 0A .....", and put it in "texto" on
CX.rfxTxRx(4,1,texto,false).
The complete code sent to RFX9600 is:
00 00 05 00 00 00 00 00 00 00 00 00 40 00 01 4E 00 00 00 00 00 00 05
DC 00 00 00 00 FF FF 01 3E 01 00 00 08 0A ....

I hope to have helped you.

Carlos

You can create a button named "Vol +" and call the function
"CX.rfxTxRx(
> ...
>
> mais »

CPadilha

unread,
May 17, 2012, 9:08:12 AM5/17/12
to CommandFusion Software
I must say that this method is somewhat laborious, but I'm working on
a way to convert the RC5 protocol to RXF, and it is almost done, when
this is finalized I'll let you know. However, the Prontonic
application is very useful for communication debugging between the
iPad and RFX.

On 16 maio, 19:18, CPadilha <carlos.l.padi...@terra.com.br> wrote:
> Hi Jordan,
> First at all, you must download the Prontonic Application (http://www.plane9.com/creations/prontonic), then you must configure the
> > >RFX9600communication protocol. My last work was to discover Samsung
> > > CP.msgStart("** Erro de Comunicacao comRFX9600**");
> > >         CP.msgErr        ("***RFX9600Timeout ***");
> ...
>
> mais »- Ocultar texto das mensagens anteriores -
>
> - Mostrar texto das mensagens anteriores -

JohanJ

unread,
May 17, 2012, 9:10:25 AM5/17/12
to comman...@googlegroups.com
Hi

Thanks for the code, I will try as soon I get a moment.

Is it not possible to use the learned IR code directly? I was hoping that I could just learn the needed codes with the pronto remote and then copy/paste them.

Johan

Jordan

unread,
May 17, 2012, 9:10:35 AM5/17/12
to comman...@googlegroups.com
Thanks, and I'm looking forward to see more of this from you. I do not have a TSU9x00 remote available to test, as the RFX9400 is a leftover and I was thinking to put it to use somewhere with CF. If I can get a hold of a remote it'll probably make things easier.

CPadilha

unread,
May 17, 2012, 12:45:11 PM5/17/12
to CommandFusion Software
Johan and Jordan,
The RFX9x00 protocol is particularly unique and very different of RC5.
Since April I have worked on this protocol and discovered 95% of its
funcionality. I decided to develop this function because to send IR
codes to air conditioner is complex, and to use learned codes is
almost impossible.

for example: below is RC5 IR code learned for "Onkyo - volume up":0000
006D 0000 0022 0156 00AB 0016 0015 0016 0040 0016 0015 0016 0015 0016
0040 0016 0015 0016 0040 0016 0040 0016 0040 0016 0015 0016 0040 0016
0040 0016 0015 0016 0040 0016 0040 0016 0015 0016 0040 0016 0040 0016
0015 0016 0015 0016 0015 0016 0015 0016 0015 0016 0015 0016 0015 0016
0015 0016 0040 0016 0040 0016 0040 0016 0040 0016 0040 0016 0040 0016
05C6

The RFX9x00 is:00 00 1B 00 00 00 00 00 00 00 00 00 40 00 00 EE 00 00
00 00 00 00 05 DC 00 00 00 00 FF FF 00 DE 01 00 00 08 0A 05 21 66 DA
16 43 6D F2 60 70 D6 40 6B DE 60 70 D6 41 48 60 60 70 D6 40 6B DE 60
70 D6 40 6B DE 60 70 D6 41 48 60 60 70 D6 40 6B DE 60 70 D6 41 48 60
60 70 D6 41 48 60 60 70 D6 41 48 60 60 70 D6 40 6B DE 60 70 D6 41 48
60 60 70 D6 41 48 60 60 70 D6 40 6B DE 60 70 D6 41 48 60 60 70 D6 41
48 60 60 70 D6 40 6B DE 60 70 D6 40 6B DE 60 70 D6 41 48 60 60 70 D6
40 6B DE 60 70 D6 40 6B DE 60 70 D6 40 6B DE 60 70 D6 40 6B DE 60 70
D6 40 6B DE 60 70 D6 40 6B DE 60 70 D6 41 48 60 60 70 D6 40 6B DE 60
70 D6 41 48 60 60 70 D6 41 48 60 60 70 D6 41 48 60 60 70 D6 41 48 60
60 70 D6 41 48 60 60 70 D6 41 48 60 60 70 D6 50 76 7D 40 00 02 C3 00
00 00 00 00

sarneel

unread,
Aug 3, 2012, 3:49:41 AM8/3/12
to comman...@googlegroups.com
Hi all, 

Just a check on how far this is going. 
As far as i can see, i would be able to use this script to send commands to the RFX9000?
Codes for in CF needs to be extracted with prontonic.. 

Is it stable to use? Is there anyway to use feedback from rs232 ?

Ben

unread,
Nov 4, 2012, 5:13:31 PM11/4/12
to comman...@googlegroups.com
Hi CPadilha

First of all, thanks for the code, i was waiting for somthing like this for a long time.

I tryed it to control my RFX9600. the relays work fine, but i have some trouble with
the infrared functions. When i send them with my TSU, the status light on the RFX
is flashing brightly, and the comand gets executet. but when i send it with the iPad,
the status light is flashing only short and weak, and there gets no command executed.

The only things i changed on your code is that i took out your CP. functions, and also
took out your special section for the air conditioner in the IR part.

I compared the messages with prontonic, and the ones from TSU are identivaly to the ones from the iPad.

i also allways get a timeout from the RFX when i execute the relay function, even when these are working fine.

Any Ideas what i did wrong?
And how have you set up the RFX in the GuiDesigner?

Thanks for any answer

Ben

CPadilha

unread,
Nov 5, 2012, 7:16:17 PM11/5/12
to comman...@googlegroups.com
Hi Ben
It happens when the IR code is not complete, one or two bytes is missing.
Take this simple test:
Send the IR code via iPad and watch at Prontonic Software, then send the same code via TSU. The both codes must be similar.
Pay special attention on code length.
If you want, send me the TSU RC5-code via email, then I will check what's wrong.

MarcoB

unread,
Jan 8, 2013, 9:21:13 AM1/8/13
to comman...@googlegroups.com
Hi Carlos,

Thanks for this great tool!
I have a RFX9600 and a TSU9800. They both work great but the time has come to move on to a new system.
I would like to keep the RFX9600 if I can. I have a Denon AVC-A1HDA, a Denon POA-3012CI, Pioneer TV an d a velodyne dd12 subwoofer controlled through the RFX.
Did you get any further in converting an ASCII code into a command the RFX understands for rs232?

I only have 1 IR device I control. In Belgium the digital TV provider DVR doesn't have discrete ON/OFF commands. So I use 1 input to see if it's on or off through the scart connector. 
I can bare extracting the IR codes to control the box but if there is an easier way that would be great!

So any update you can share on your RFX module?

Kind regards

Marco

Barry Gordon

unread,
Jan 8, 2013, 10:12:25 AM1/8/13
to comman...@googlegroups.com

Speaking as one fairly expert on both the Pronto PRO and the CF systems, May I strongly recommend that you drop the RFX and go with a Global Cache or similar device.  You will save yourself hours of frustration.  If you need a lot of RS232 outputs then there should be  available several devices that will go from TCP/IP to serial. Most of them however only supply a single serial connection. I have used the one port xetaserver for $65 and I am sure the 2 port unit for $95 will work as well.

 

From: comman...@googlegroups.com [mailto:comman...@googlegroups.com] On Behalf Of MarcoB
Sent: Tuesday, January 08, 2013 9:21 AM
To: comman...@googlegroups.com
Subject: Re: How to combine hex bytes from variables in javascript

 

Hi Carlos,

--

You received this message because you are subscribed to the Google Groups "CommandFusion Software" group.

To view this discussion on the web visit https://groups.google.com/d/msg/commandfusion/-/mZg6QoBqcn4J.

MarcoB

unread,
Jan 8, 2013, 11:11:23 AM1/8/13
to comman...@googlegroups.com
Hi Barry,

You've always been a great help and good support on the remote central forum. 
And you seem to be very active with CF as well. Many thanks.

I do have a MOXA nport 5410. This works actually very well. It's a 4 port RS232 device server. 
I bought this because of the reason you mention. 
Also I have a KNX home automation system and the server has problems with TCP connections so I use UDP. The Moxa talks through UDP/RS232 with my audio/video equipment.
The only problem I have is that i need an input sensor to see if my digital cable DVR is ON or OFF.  I use 2 pins on the scart to sense if it's on or off, for this i still use the RFX. This device can only be controlled by IR.

I could by a GC but don't want to get to many devices where I only use half their functionality. 
I've never worked with GC equipment so I don't know there functionality. need to read up on it.

Regards

Marco

Barry Gordon

unread,
Jan 8, 2013, 2:51:21 PM1/8/13
to comman...@googlegroups.com

A single GC iTach should do what you need for IR.  I just do not recall if an IR port can be set as a sensor input on an iTach.  It can on a GC-100.  The GC-100 has 2 RS232 modules and 6 individually controlled IR ports.  I use both in my home.

To view this discussion on the web visit https://groups.google.com/d/msg/commandfusion/-/zDd9S_ekDegJ.

Scott Ahlers

unread,
Jan 8, 2013, 3:22:11 PM1/8/13
to comman...@googlegroups.com

I believe the GC-100 only support one connection at a time, where iTach’s support 8. Just fyi…

husa550

unread,
Jan 8, 2013, 3:30:30 PM1/8/13
to comman...@googlegroups.com
Here you can se what an iTach wifi2ir have can be configurated to do!
Skärmavbild 2013-01-08 kl. 21.26.28.png
Reply all
Reply to author
Forward
0 new messages