Java connection to a C-Bus device without C-Gate?

Discussion in 'C-Gate Developers' started by Jats, Nov 11, 2011.

  1. Jats

    Jats

    Joined:
    Nov 11, 2011
    Messages:
    3
    Likes Received:
    0
    Location:
    Adelaide, Australia
    Hi,

    I have a Clipsal C-Bus device that has a network interface (5500CN, it seems). So the device has an ip address and a port and I can connect with it with Putty and hyperterminal and send it commands to switch it on and off and whatever. It works great.

    Now I want to write my own Java program to control the device. I've used a Java socket to connect to the device and sent the commands to initialise the PCI, as specified in the "C-Bus Quick Start Guide" but I don't get any response from the device. Even though they worked in both Putty and in hyperterminal. So what am I missing?

    From my understanding, C-Gate acts as an interface to a C-Bus device. I am not using C-Gate, and I would prefer not to. I don't want to install and run a program from the multiple computers that I want to run my Java program from.

    How can I communicate directly through Java to my one C-Bus device? Is it possible without C-Gate?

    Thanks
     
    Jats, Nov 11, 2011
    #1
    1. Advertisements

  2. Jats

    ashields

    Joined:
    Feb 2, 2011
    Messages:
    20
    Likes Received:
    1
    Location:
    Nottinghamshire,UK
    If you are able to get it to work from putty you've obviously read the protocol documents from

    http://training.clipsal.com/downloads/OpenCBus/OpenCBusProtocolDownloads.html

    which would suggest a problem in your code, can you post it?

    One advantage of C-Gate is that it will accept multiple inbound connections whereas the CNI will only accept one at a time.

    If you have a single machine that's always on you could just run c-gate on that, then connect to it from multiple machines.

    Cheers
     
    ashields, Nov 11, 2011
    #2
    1. Advertisements

  3. Jats

    ievolve

    Joined:
    Mar 20, 2010
    Messages:
    112
    Likes Received:
    1
    Location:
    Idaho
    I know if you do not properly disconnect from a CNI after connecting to it that it can become in a locked state, in which case only a power cycle will cure (at least this has been my experience) you may want to make sure you havent improperly disconnected and left yourself in that state.
     
    ievolve, Nov 12, 2011
    #3
  4. Jats

    Jats

    Joined:
    Nov 11, 2011
    Messages:
    3
    Likes Received:
    0
    Location:
    Adelaide, Australia
    Sure have, particularly the "C-Bus Quick Start Guide". But I have also gone through the "C-Bus Interface Requirements" document and a couple more.

    Note that, within the "C-Bus Interface Requirements" document, page 14 shows different PCI initialisation commands than the "C-Bus Quick Start Guide" does. I've used the "C-Bus Quick Start Guide" initialisation commands below, but I've tried with both different sets of commands and I get the same result - works in Putty, not in Java.

    Yeah, I'm aware of this, and it's not happening - I have been closing the putty connection before attempting to connect through my Java program. I've even tried cycling the power and then just trying to send the commands with my Java program, not using any other connection at all. By the way, do you (or does someone else) know if there's a disconnect command that I can send when I'm finished connecting to the device and sending commands? I couldn't find one. I've also found that the only way to get out of that locked state is with a power cycle. If someone knows another more graceful way, please let me know.

    Here's what I've been doing:

    If can connect to the device in Putty and send these commands:
    ~~~ <press enter>
    A3210038g <press enter>
    A3420002g <press enter>
    A3300059g <press enter>
    \05380079004Ag <press enter>

    The first four commands initialise the PCI, and the final command is one that I have calculated to power on the device. This sequence of commands works in Putty when I do a "raw connection" to the device. The device is powered on after using these commands. That's all I want to do!

    So, I thought I could just translate this over to Java Sockets. Here's the kind of thing I've been trying in Java:
    Code:
    public void setPowerOn ()
    {
        try 
        {
          Socket sock = null;
          PrintWriter out = null;
          
          sock = new Socket ("xxx.xxx.xxx.xxx", 10001);
          out = new PrintWriter(sock.getOutputStream(), true);
          
          char carriageReturn = (char) 13;
          
          out.write("~~~" + carriageReturn);
          Thread.sleep(500);
          
          out.write("A3210038g" + carriageReturn);
          Thread.sleep(500);
          
          out.write("A3420002g" + carriageReturn);
          Thread.sleep(500);
          
          out.write("A3300059g" + carriageReturn);
          Thread.sleep(500);
          
          out.write("\05380079004Ag" + carriageReturn);
          Thread.sleep(500);
          
          sock.close();
        }
        catch (Exception e) 
        {
          //TODO
          System.out.println("an exception occured when sending the on command.");
        }
    }
    Where xxx.xxx.xxx.xxx is obviously substituted for the valid IP address that I've set in the webpage for the device. I'm using port 10001 of the device, which was also set from the webpage. When calling this method, it doesn't power on the device as I think it should! I put the sleeps in just to not bombard the device with commands, but it doesn't work with them removed, either.

    Note that if I connect to the device with Putty, and then initialise and turn on MMI reports, like this:
    ~~~ <press enter>
    A3210038g <press enter>
    A3420002g <press enter>
    A3300079g <press enter>

    Then I can read the MMI reports in Java, using a BufferedReader. It appears to me that I just can't initialise the PCI and send commands properly in Java. For some unknown reason.

    Any suggestions? Have I made a silly mistake somewhere or is it simply not possible to send commands via a direct connection to the device in Java without using C-Gate?
     
    Last edited by a moderator: Nov 14, 2011
    Jats, Nov 14, 2011
    #4
  5. Jats

    ashields

    Joined:
    Feb 2, 2011
    Messages:
    20
    Likes Received:
    1
    Location:
    Nottinghamshire,UK
    I'll try it myself when I get a chance but it will be a couple of days at least.

    In the meantime I would suggest getting rid of the PrintWriter and writing directly to the socket's OutputStream and maybe also try calling flush after each write.

    Cheers
    Alan
     
    ashields, Nov 15, 2011
    #5
  6. Jats

    ashields

    Joined:
    Feb 2, 2011
    Messages:
    20
    Likes Received:
    1
    Location:
    Nottinghamshire,UK
    This version works for me:

    public void setPowerOn ()
    {
    try
    {
    Socket sock = null;
    OutputStream out = null;

    sock = new Socket ("xxx.xxx.xxx.xxx", 10001);
    out = sock.getOutputStream();

    char carriageReturn = (char) 13;

    out.write(("~~~" + carriageReturn).getBytes());
    Thread.sleep(500);

    out.write(("A3210038g" + carriageReturn).getBytes());
    Thread.sleep(500);

    out.write(("A3420002g" + carriageReturn).getBytes());
    Thread.sleep(500);

    out.write(("A3300059g" + carriageReturn).getBytes());
    Thread.sleep(500);

    out.write(("\\053800791A30g" + carriageReturn).getBytes());
    Thread.sleep(500);

    sock.close();
    }
    catch (Exception e)
    {
    //TODO
    System.out.println("an exception occured when sending the on command.");
    }
    }

    1) The backslash character needs to appear twice in a java string as it's the escape character

    2) I'm writing straight to the output stream rather than using a print writer.

    3) I've changed the last line of output as I'm switching a different group address

    Good luck
    Alan
     
    ashields, Nov 17, 2011
    #6
  7. Jats

    ashields

    Joined:
    Feb 2, 2011
    Messages:
    20
    Likes Received:
    1
    Location:
    Nottinghamshire,UK
    By the way if you haven't already got something to work out the check digit

    public String checkSum(String message) {
    long sum=0;
    int len=message.length();
    for(int i1=0;i1<len;i1=i1+2) {
    String bt=message.substring(i1,i1+2);
    int ibt=Integer.parseInt(bt, 16);
    sum=sum+ibt;
    }
    int m=(byte)(sum % 256);
    int check=256+((~m)+1);
    String cs="0"+Integer.toHexString(check).toUpperCase();
    return cs.substring(cs.length()-2);
    }

    This is a little inelegant but seems to work for the few samples that I've tried.
     
    ashields, Nov 17, 2011
    #7
  8. Jats

    Jats

    Joined:
    Nov 11, 2011
    Messages:
    3
    Likes Received:
    0
    Location:
    Adelaide, Australia
    Thanks so much Alan!

    I can't believe I didn't remember the backslash for the escape character! *doh*

    Cheers
     
    Jats, Nov 18, 2011
    #8
  9. Jats

    ievolve

    Joined:
    Mar 20, 2010
    Messages:
    112
    Likes Received:
    1
    Location:
    Idaho
    ievolve, Dec 24, 2011
    #9
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.