Peer2Peer

Dario Di Maio edited this page Aug 18, 2017 · 16 revisions
Clone this wiki locally

Peer 2 Peer Communication

The Souliss network is based on peer-to-peer communication using event-based protocol in order to have a very fast response time and a very low footprint. Once a network has been setup, while adding nodes in your architecture a communication channel is automatically build between the Gateway and Peer nodes, this communication channels are generally used by the user interfaces like SoulissApp.

You can build user defined communication in order to execute logic across multiple nodes.

User defined Publish / Subscribe

The user defined publish / subscribe is a broadcast or multicast communication, the node that publish notify a topic to all the other in the network; nodes that subscribe the topic act based on an user sketch. The publish / subscribe is completely peer-to-peer and doesn't relay on any central node.

The following code is used to publish and subscribe the Alarm topic.

// Sender
if(...)	pblsh(Alarm);
// Receiver
if(sbscrb(Alarm))
{
   // If you are here is because the Alarm topic has been recognized
}

At your option you can carry a payload using

// Sender
uint8_t mypayload[10];

if(...)	pblshdata(Alarm, mypayload, 10);
// Receiver
uint8_t mypayload_len;
uint8_t mypayload[10];
if(sbscrbdata(Alarm, mypayload, &mypayload_len))
{
   // If you are here is because the Alarm topic has been recognized
   // in the mypayload you will found the data send from the publisher node
   // in the mypayload_len the length of the data.
}

The Publish/Subscribe use a dedicate queue, so the maximum payload length is restricted byMaCaco_QUEUELEN. The queue contains also the header of the MaCaco frame (5 bytes) so for each message stored the payload is reduced.

Multicast Publish

As option you can multicast a publish message, consider that is a vNet multicast based on the broadcast of the communication media, so the use of multicast doesn't reduce the network load but has lower impact on MCU processing load.

Similar to the previous case, you just need to specify a multicast address.

m_pblsh(maddress, Alarm);
m_pblshdata(maddress, Alarm, mypayload, 10);

The receiver node shall listen the relevant multicast address using vNet_SetMulticastGroup, the Addressing page list valid multicast addresses.

void vNet_SetMulticastGroup(U16 multicastgroup, U8 multicastnumber);

Available and Custom Topics

A topic is defined by a couple of two numbers and below table list the default topics

  • A 16-bit Topic Number: Define the topic itself
  • A 8-bit Topic Variant : Define a variant for the topic
Topic Name Topic Number Topic Variant
GeneralEvent 0xF001 0x01
Alarm 0x0001 0x01
Alarm_Fire 0x0001 0x02
Alarm_WaterLeak 0x0001 0x03
Alarm_GasLeak 0x0001 0x04
DoorClosed 0x0002 0x01
DoorOpen 0x0003 0x01
Sunny 0x0004 0x01
Raining 0x0004 0x02
Cloudy 0x0004 0x03

You are free to define new topics just using at top of your sketch

#define	YourTopicName TopicCode,TopicVariant

as example

#define	GeneralEvent 0xF001,0x01

Remote I/O

The remote I/O is a set of digital input functions that act on a different node inside the Souliss network, those include an on-change logic and prevents network flooding, so user should not care about. Can be use as well as local I/O and are listed in Souliss API.

An example of remote I/O is

U8 RemoteDigIn(U8 pin, U8 value, U16 addr, U8 slot);

This transfer value when pin is activated into the node addr into the assigned slot.

Send and SendData

The send and senddata are peer-to-peer unicast communication, used to force a logic into a remote node in the Souliss network. Doesn't include any network flooding protection and user code shall care about (see Network Usage).

if(...) Send(addr, slot, command);
if(...) SendData(addr, slot, command, commandsize);

In case of SendData command is a pointer to an array of command that has commadsize as lenght. Note that Send and SendData was previously referred as RemoteInput and RemoteInputs, as legacy option you can still use the old names.

PullData

The Send and SendData is used when the node that owns the data have to send those to another node, rather reading data from the another node in the network can be done via PullData

PullData(addr, slot, remote_slot, remote_numbof)

Where addr is the vNet address of the node from where data shall be read, slot is the input slot where data will be placed, remote_slot is the starting node from where data should be read a number of remote_numof bytes will be read. Consider that PullData reads the output state from a node in the network and place the result in the input slot, so you may need to manipulate data before use it.

As example, a Lamp/T11 has the following input and outputs values:

Input values: 
-  1(hex) as command, toggle the output 
-  2(hex) as command, the output move to ON
-  4(hex) as command, the output move to OFF
- >30(hex) as command, time the output to ON
-  0(hex) as command, no action

Output values:
-  0(hex) for output OFF,
-  1(hex) for output ON.

As result, reading a T11 the output values will be available as 0 for lamp OFF and 1 for lamp ON. These values cannot be used directly as command into another T11 as this doesn't reflect the input values. So just after PullData use an if, else statement to convert the values.

Network Usage

A special care in the user sketch should be used in order to avoid communication flood, as rule of thumb the number of frames per second should never be greater than 1 per second. Have always in mind that Souliss communication is event-based and all user code shall always publish or send commands on event basis.

So for example, if you connect SendData or publish to a pushbutton, ensure that only on first press data are sent and avoid to send data for all long time while the button is press.

A tricky way to avoid network flooding and ensure multiple transmission (to ensure communication) is to roll an 8 bit counter like in the below example

uint8_t multiple_send=0;

// Transmit 3 times
if((...) && !multiple_send) multiple_send=-3;

if(multiple_send) {
	pblsh(Alarm);
        multiple_send++;
}