Skip to content

SoulissAPI

sdurnev edited this page Mar 27, 2022 · 18 revisions

Introduction

Souliss APIs let you program your Souliss nodes with different logics and communication paradigms in order to harvest sensor values and issue commands to actuators. The methods can be divided as follows:

  • Setup/Init functions
  • Read/receive functions
  • Write/send functions

All logics are based on a common concept, there is an input area that is used to read the command. Whoever write on that area (a pushbutton connected to the board or to another board, an user interface, another node, ...) trigger an action, this is stored in the output area. The inputs are cleared once the action is executed.

To the user interface (like Android) only the outputs are available as feedback. All logics are grouped by type, 1n are lights and share (as much as possible) same commands values. For example, Typical 11 and 12 are lights, the 12 has AUTO mode to be used with a PIR sensor. The 14 is a pulsed output, to be used with electric gate (that needs only a pulse to open).

Souliss nodes, programmatically speaking, are Arduino sketches that run a loop() function. Inside the loop, a simple interval mechanism is provided, so that you can call API functions at pre-determined intervals:

Souliss Scheduler

In order to share the load on the microcontroller and avoid energy waste a simple scheduler is used in Souliss, this is build over two phases (slow and fast) that execute part of the code at regular time bases.

All the code included in the schedule at 50 ms will be executed at this rate, without preemption.

FAST_50ms() {
  ...
}

You can create multiple execution with the same periodic rate but with a different shift in time, use any value in the 0-255 range to select different shift to balance load between different phases. The SHIFT can be used only in the FAST group.

SHIFT_50ms(shift) {
  ...
}

Souliss APIs List

The Application Programming Interface are the methods used into an user sketch, those are grouped based on their scope and are defined as C Macro in the SpeakEasy:

  • Network Setup
  • Communication
  • Publish/Subscribe
  • Local I/O

Network Setup

SetAddress

Set the vNet network configuration parameters, in case of devices with multiple interfaces shall be multiple times, is not allowed the change of the network parameters out of the setup()

SetAddress(U16 addr, U16 subnetmask, U16 mysupernode);

SetAsGateway

Define the vNet address relevant to device, this is not included in Souliss_SetAddress because only one address can be declared as Local also in case of boards with multiple interfaces.

If thi is missed, the board will not answer correctly to a Database Structure Request from Android or any other MaCaco interface.

SetAsGateway(U16 address);

SetAsPeerNode

Define the vNet address of other nodes in the network that shall be monitored using this board as gateway, the address defined here will be used while building an event-based channel with other boards.

All nodes reported as remote will be available at Android or any other MaCaco interface. The node parameter shall be between 1 and the maximum number of nodes allowed in your configuration setup .

SetAsPeerNode(U16 address, U8 index);

SetIPAddress

Define an IP address and relevant subnetmask and IP gateway, this set automatically also the vNet address of the node using the last byte of the IP address.

SetIPAddress(U8* ip_address, U8* subnet_mask, U8* ip_gateway);

SetAddressingServer

Is used in a network without fixed addresses in the Souliss network, shall be used with a Gateway and let it assign an address to peers. It doesn't set the IP address of the Gateway node, that must be set before the use of this method.

SetAddressingServer();

SetDynamicAddressing

Is used in a network without fixed addresses in the Souliss network, shall be used with Peer nodes to assign a temporary address while getting from the Gateway a final address to be stored in the EEPROM.

SetDynamicAddressing();

GetAddress

It follows the SetDynamicAddressing(); and start the process to get an address from the Gateway.

GetAddress();

FAST_GatewayComms

Process all the communication relevant for a Gateway, this include also the process of communication channels defined with SetAsPeerNode and the retrieve of Typicals for the user interfaces.

Is a composite macro and doesn't need to be placed inside a PHASE.

FAST_GatewayComms();

FAST_BridgeComms

Process the communication and data routing/bridging in case of nodes with multiple communication interface.

Is a composite macro and doesn't need to be placed inside a PHASE.

FAST_BridgeComms();

FAST_PeerComms

Process the communication for a standard Peer node.

Is a composite macro and doesn't need to be placed inside a PHASE.

FAST_PeerComms();

START_PeerJoin

Broadcast periodically the node addressing details till it get a subscription from a Gateway. Is also used to build dynamically the communication path between nodes.

Is a composite macro and doesn't need to be placed inside a PHASE.

START_PeerJoin()

SLOW_PeerJoin

Broadcast periodically the node addressing details and is unrelated with the subscription state, useful to rebuild the subscription and communication paths in case of reboot of nodes.

Is a composite macro and doesn't need to be placed inside a PHASE, shall be located into the SLOW group.

SLOW_PeerJoin()

Communication

RemoteInput

Let a node act as a remote input for another node, it simply force a command into a peer node. It can be used to transfer a pushbutton from a node to a peer one.

RemoteInput(U16 addr, U8 slot, U8 command);

RemoteInputs

As previous one, but transfer an array of commands and not a single one.

RemoteInputs(U16 addr, U8 firstslot, U8 *commands, U8 numberof);

Watchdog

Build a network watchdog as a virtual chain of nodes, a token is passed from each node to the next one. If one node goes off, the next in the chain didn't receive the token and goes in alarm. If the node is in alarm, Watchdog returns the alarm_command. Each node in the chain can go returns the alarm state and shall then send that to another node that has a sounder or any other external notification.

Is mandatory that all nodes in the chain share the same value for chain_slot.

Watchdog(U16 chain_address, U8 chain_slot, U8 alarm_command);

Publish/Subscribe

Using this methods gives a communication path that is free from the SLOT and TYPICAL relation, more details in peer to peer communication.

Publish

Broadcast (a multicast option is available) a topic to other nodes, optionally data can be send together with a specific topic.

pblsh(topic);

Subscribe

Is a trigger for any user code relevant to specific topic

sbscrb(topic);

Local I/O

DigIn

Read a value from a digital input pin and assign the value into the slot, is used to define the action (example Turn On Light) to a digital input.

The action is triggered on the HIGH value of the input pin, so is suggested to use a pull-down resistor in order to avoid false reading. This function, like all others input ones, act on the edge of the signal.

U8 DigIn(U8 pin, U8 value, U8 slot);

LowDigIn

As DigIn but acts on LOW value and needs a pull-up value.

U8 LowDigIn(U8 pin, U8 value, U8 slot);

DigIn2State

Detect the steady state of an input (like a pushbutton) with two different action (values) for HIGH and LOW state. Wiring shall force the input to HIGH or LOW and cannot be floating or pulled-down/up.

Can be used to convert a bistable push-button into an ON/OFF command.

U8 DigIn2State(U8 pin, U8 value_state_on, U8 value_state_off, U8 slot);

DigInHold

Detect the edge of the signal on the HIGH value or if the inputs is forced HIGH for more than some seconds (see the code for details), a single pushbutton has two different actions based on single press or long press.

The pull-down resistor must be applied and tuned properly, too high resistor values may drive a false long press.

U8 DigInHold(U8 pin, U8 value_state1, U8 value_state2, U8 slot);

This method recognize a single short and long press, keeping pressed the button will give just one execution of the value_state2, if you need to detect long press multiple time use:

U8 DigKeepHold(U8 pin, U8 value_state1, U8 value_state2, U8 slot);

DigInHold2

Similar to DigInHold, but controls two different slots.

Single press -> value_state1 -> slot1

Long press -> value_state2 -> slot2

U8 DigInHold2(U8 pin, U8 value_state1, U8 value_state2, U8 slot1, U8 slot2);

LowDigInHold

As LowDigInHold but active on LOW input values. With single long press detection

U8 LowDigInHold(U8 pin, U8 value_state1, U8 value_state2, U8 slot);

and multiple long press detection,

U8 LowDigKeepHold(U8 pin, U8 value_state1, U8 value_state2, U8 slot);

LowDigInHold2

Similar to DigInHold2, but active on LOW input values.

U8 LowDigInHold2(U8 pin, U8 value_state1, U8 value_state2, U8 slot1, U8 slot2);

DigOut

Force to HIGH value a digital output pin if a slot match a value, is used to assign an output pin to a logic.

DigOut(U8 pin, U8 value, U8 slot);

nDigOut

Force to HIGH value a digital output pin if a slot match a value as bit-wise AND boolean operation, is used for a pin that needs to be activated for multiple value states.

nDigOut(U8 pin, U8 value, U8 slot);

LowDigOut

As DigOut, but drives the pin LOW when activated. In normal condition the output pin is at HIGH value, to avoid spurius activation at first boot you have to force the output register to an HIGH value before set the pin as output.

LowDigOut(U8 pin, U8 value, U8 slot);
setup()
{
  ...
  digitalWrite(pin, HIGH);
  pinMode(pin, OUTPUT);
}

nLowDigOut

As nDigOut, but drives the pin LOW when activated. In normal condition the output pin is at HIGH value.

nLowDigOut(U8 pin, U8 value, U8 slot);

DigOutToggle

While the slot match the value the digital output pin will toggle once per execution cycle of the method. Can be used to flashing light or similar cases.

DigOutToggle(U8 pin, U8 value, U8 slot);

Remote I/O

These are same as Local I/O but doesn't act on the node itself, but on another node into the network. Compared with the relevant Local I/O ones require the address of the target node as parameter.

RemoteDigIn

Read a value from a digital input pin and assign the value into the slot of the addr node, is used to define the action (example Turn On Light) to a digital input.

The action is triggered on the HIGH value of the input pin, so is suggested to use a pull-down resistor in order to avoid false reading. This function, like all others input ones, act on the edge of the signal. This is equivalent to DigIn but acts on a different node of the network.

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

RemoteLowDigIn

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

RemoteDigIn2State

U8 RemoteDigIn2State(U8 pin, U8 value_state_on, U8 value_state_off, U16 addr, U8 slot);

RemoteLowDigIn2State

U8 RemoteLowDigIn2State(U8 pin, U8 value_state_on, U8 value_state_off, U16 addr, U8 slot);

RemoteDigInHold

U8 RemoteDigInHold(U8 pin, U8 value, U8 value_hold, U16 addr, U8 slot);

RemoteLowDigInHold

U8 RemoteLowDigInHold(U8 pin, U8 value, U8 value_hold, U16 addr, U8 slot);

Read the Memory Area

You can have direct access at the memory area using mInput(slot), mOutput(slot), mOutputAsFloat(slot) and mTypical(slot) this allow direct handling of data and interaction with typicals. If you are using a persistance use pOutput(node,slot) , pOutputAsFloat(node,slot) and pTypical(node,slot).

Clone this wiki locally