A VelBus server-mode tool

dansaertd,

When you use your Velbus-server are you able to use it to scan the complete bus?
Because when I use it, connect VelbusLink8 to it and do a full scan I only get the answer from the first module on the bus.
When I use VelbusLink6 in servermode I get answers for all modules.

Any pointers to start troubleshooting?

Edit 1:
I fiddled with your code a bit and my send/receive test app works if I set the receive buffer of your Server app to 14 bytes (lenght of a velbus packet).
Velbuslink8 however only get replies from about every other 5 modules so i’m missing a lot… (Still better than in the beginning, I only got the answwer from the first module)
The next thing I’ll try is sending the packets to the connected clients with 60ms delays, like Velleman does to not overload the bus.
I’ll keep you guys posted.

Edit 2:
Velleman: As mentioned before my scantool works as expected with a receive buffer on the server side of 14 bytes.
A full scan with VelbusLink8 however makes the server throw Out of range exceptions in the bus.Send(packet) call.
Error: base {System.ArgumentException} = {“Specified argument was out of the range of valid values.\r\nParameter name: Packet does not contain a command byte.”}

Anyone cares to troubleshoot with me? THANKS!

Occurs when you try to set the Command property of the Packet class when the number of databytes has not been set yet.

About troubleshooting your problem, be sure to check the following:

  1. A delay of 60ms must be present between each packet sent to the Velbus interface modules
    a) VelbusLink 8 does not add this delay for a TCP/IP connection, it expects the server to add this delay.
    b) VelbusLink 6 in server mode adds this delay, since it is considered the server
  2. VelbusLink 8 with a TCP/IP connection will send its scan packets as fast as it can (see 1a); the server buffers the packets, adds a delay, and sends them out; thus VelbusLink 8 may have stopped scanning, even though the server is still busy sending out the packets

I’m guessing your problem might be °1…

VEL488,

Dansaerts VelbusServer uses folowing function:

private void VelBusSend(byte] data)
		{
			try
			{
				Packet packet = new Packet();
				packet.rawPacket = data;
				packet.Pack();
				
				m_Bus.Send(packet);
				
			} catch (Exception e) {
				Console.WriteLine(e.ToString());
			}
		}

The Send() procedure of the Serialbus Class does implement the 60ms delay I presume, the SendBlocking does not as I understand. So this should not be a problem.

As you can see VelBusSend procedure uses a Byte array to generate the VelBus packet using rawpacket/Pack.
I’ll try to skip the conversion from/to a Byte array and see if this fixes things.

Indeed, that looks a bit fishy :-/

Ok, I fixed it.
I changed the following:

		private void OnDataReceived(IAsyncResult asyn)
		{
			SocketPacket socketData = (SocketPacket)asyn.AsyncState ;
			try
			{
				int iRx  = 0 ;
				// Complete the BeginReceive() asynchronous call by EndReceive() method
				// which will return the number of characters written to the stream 
				// by the client
				iRx = socketData.m_currentSocket.EndReceive(asyn);
				
				//check existence of client:
				if((socketData.m_currentSocket.Poll(1, SelectMode.SelectRead) && socketData.m_currentSocket.Available == 0))
				{
					string msg = "Client #" + socketData.m_clientNumber + " disconnected.";
					Console.WriteLine(msg);
					m_workerSocketList[socketData.m_clientNumber - 1] = null;
				} else {				
					//Passing the packet trough to the VelBus-code
                    pp.Feed(socketData.dataBuffer, iRx);
                    Packet packet = pp.Next();

                    while (packet != null) // did we succeed in parsing a packet?
                    {
                        ReceivedPacketArgs ra = new ReceivedPacketArgs(packet);

                        VelBusSend(ra);

                         packet = pp.Next();
                    }
					// Continue the waiting for data on the Socket
					WaitForData( socketData.m_currentSocket, socketData.m_clientNumber );	
				}
			}
			catch (ObjectDisposedException )
			{
				System.Diagnostics.Debugger.Log(0,"1","\nOnDataReceived: Socket has been closed\n");
			}
			catch(SocketException se)
			{
					Console.WriteLine(se.Message );
			}
		}
        private void VelBusSend(ReceivedPacketArgs data)
		{
            try
            {
				
				
				m_Bus.Send(data.packet);
				
            } catch (Exception e) {
                Console.WriteLine(e.ToString());
            }
		}

I’ll clean up my code and post a new Velbus-Server version in a couple of days.

I first had that problem to with mt version of the server (linux). I solved this with a big receiving buffer (to have as much as data in at once) and than cut the bulk data back into the right packets (you can count the bytes because there’s a number of bytes in the packet) with a delay in between.

In the other direction (interface -> network) I send as soon there’s data available.
I 'd never problems since the change, even a full backup of the complete system works perfectly.

Yeah, I should have mentioned that I tweaked the rest of the code a bit to. I’m planning to make it into a windows service controled by a form application to set the hostname and port, I’ll make it available on the forum as soon it is finished.
At the moment I use a 1024 byte buffer. The packets are carved out of the buffer by the Velbus PacketParser, nothing to code there. :stuck_out_tongue:

Edit:
Upped the receive buffer to 2k, a buffer of 1k would overflow with 2 clients scanning the bus at the same time crashing the server.
Tried different sizes, 8k would crash on the first packet received (what’s the max size the PacketParser can handle by the way?) 2k seems rock solid.

I’ve been busy last night :arrow_right: LinkServ Velbus server

Minimizes to the system tray

Brilliant!
Have bombed it with packets, no problem!
Would be nice if it could run as a service, not under a user account…
And would be even nicer if it remembered te COM and TCP ports.
:wink:

Have tried this without result… but it seems so close :exclamation: :stuck_out_tongue:

C:\Program Files\Velleman\LinkServ>LinkServ COM4 8443

[size=200]Thanks a lot Vel448 ![/size]

I’ll make those changes, but I’m doing this after work so I can’t say when I’ll have an update :slight_smile:

@ Cantryn,

hi,

i’ve use your velbusconnector usercontrol but i can’t receive any reply from velbus. Seems that the ReceivedPacketArgs event isn’t raised. Can you look into that bit of code?

thx,

Stis

Stis,

Did you add an event handler to handle the packetReceived event in your code behind?

this is the code i’m using

private void velbusConnector1_PacketReceived(VelbusConnector.ReceivedPacketArgs packetInfo)
{
//ParsePacket(packetInfo.packet);

 WriteLog(String.Format("Packet receivedfrom address {0,0}", packetInfo.packet.Address));
 if (packetInfo.packet.Address == 0x32 && packetInfo.packet.Command == 0xFB)// && packetInfo.packet[1] == 2 && packetInfo.packet[3] == 2)
 {
         if (Keukentafel.InvokeRequired)
                Keukentafel.BeginInvoke(new MethodInvoker(delegate() { Keukentafel.BackColor = Color.Green; }));
        else
               Keukentafel.BackColor = Color.Green;
  }
  if (packetInfo.packet.Address == 0x32 && packetInfo.packet.Command == 0xFB && packetInfo.packet[1] == 2 && packetInfo.packet[3] == 0)
  {
          WriteLog(String.Format("Packet received from address {0,0}", packetInfo.packet.Address, packetInfo.packet.Command));
          if (Keukentafel.InvokeRequired)
                Keukentafel.BeginInvoke(new MethodInvoker(delegate() { Keukentafel.BackColor = Color.Red; }));
          else
                Keukentafel.BackColor = Color.Red;
    }

}

I have put a break in your code OnDataReceived(IasyncResult res) after PacketReceived(ra); // raise event

at runtime this breakpoint is never reached.
can you check your code?

Thanks

Stis

Stis,

At the moment you need to add an event handler to call the procedure you posted. I’m not at home at the moment but I’ll post an example tomorow.

Cantryn,

thx for the quick reply

Stis

Stis,

As promised a little elaboration.

If you want to use my control on a forms application and use the PacketReceived in your code behind, you’ll have to add an event handler like this:

 public Form1()
        {
            InitializeComponent();
            velbusConnector1.PacketReceived += new VBConnector.PacketReceivedHandler(velbusConnector1_PacketReceived);
        }

I myself use usercontrols with a VelbusConnector property for every Velbus function and I handle the PacketReceived event in these controls so I don’t need the event handler in the main form.

[quote=“VEL448”]I’ve been busy last night :arrow_right: LinkServ Velbus server

Minimizes to the system tray

http://www.velleman.eu/images/tmp/LinkServTray.png[/quote]

Has this project followed, VEL448 ?

No sorry, I haven’t been able to find the time to update it yet

Hi VEL448,

I’m using your LinkServ from time to time, but as some other people already said before it would be nice to make it possible to run with arguments

C:\Program Files\Velleman\LinkServ>LinkServ COM12 3788

Or the option to automatically start te server with previous settings would even be better.

Those options are really needed because a server is almost always used in automation. So no GUI input …

If you don’t have the time to do this why not share your code at Google Code or Github, so the community can add it?
Would be awesome!

Btw, why not use your real names instead of “VEL448”?