Serial Gateway in a working state

This commit is contained in:
Henrik Ekblad
2015-05-12 23:28:49 +02:00
parent 9469188e32
commit 01d13f0ca4
9 changed files with 185 additions and 272 deletions
+19 -5
View File
@@ -49,22 +49,36 @@
* Information LEDs blinking
***********************************/
// This feature enables LEDs blinking on message receive, transmit
// or if some error occured. This was commonly used only in gateways,
// or if some error occurred. This was commonly used only in gateways,
// but now can be used in any sensor node. Also the LEDs can now be
// disabled in the gateway.
// #define WITH_LEDS_BLINKING
// #define MY_LEDS_BLINKING_FEATURE
// default LEDs blinking period in milliseconds
#define MY_DEFAULT_LED_BLINK_PERIOD 300
// The RX LED default pin
#define MY_DEFAULT_RX_LED_PIN 8
#define MY_DEFAULT_RX_LED_PIN 6
// The TX LED default pin
#define MY_DEFAULT_TX_LED_PIN 9
#define MY_DEFAULT_TX_LED_PIN 5
// The Error LED default pin
#define MY_DEFAULT_ERR_LED_PIN 7
#define MY_DEFAULT_ERR_LED_PIN 4
/**********************************************
* Gateway inclusion button/mode configuration
**********************************************/
// Enabled inclusion mode feature
#define MY_INCLUSION_MODE_FEATURE
// Enables inclusion-mode button feature on the gateway device
#define MY_INCLUSION_BUTTON_FEATURE
// The default input pin used for the inclusion mode button
#define MY_INCLUSION_MODE_BUTTON_PIN 3
// Number of seconds (default one minute) inclusion mode should be enabled
#define MY_INCLUSION_MODE_DURATION 60
/**********************************
* Message Signing Settings
***********************************/
+89 -20
View File
@@ -20,33 +20,64 @@
#include "MyGateway.h"
// Inline function and macros
static inline MyMessage& build (MyMessage &msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type, bool enableAck) {
msg.sender = sender;
msg.destination = destination;
msg.sensor = sensor;
static inline MyMessage& build(MyMessage &msg, uint8_t type) {
msg.sender = GATEWAY_ADDRESS;
msg.destination = GATEWAY_ADDRESS;
msg.sensor = 0;
msg.type = type;
mSetCommand(msg,command);
mSetRequestAck(msg,enableAck);
mSetAck(msg,false);
mSetCommand(msg, C_INTERNAL);
mSetRequestAck(msg, false);
mSetAck(msg, false);
return msg;
}
MyGateway::MyGateway(MyGatewayTransport &_transport,MyTransport &_radio, MyHw &_hw
MyGateway::MyGateway(MyGatewayTransport &_transport, MyTransport &_radio,
MyHw &_hw
#ifdef MY_SIGNING_FEATURE
, MySigning &_signer
, MySigning &_signer
#endif
#ifdef WITH_LEDS_BLINKING
, uint8_t _rx, uint8_t _tx, uint8_t _er, unsigned long _blink_period
#ifdef MY_LEDS_BLINKING_FEATURE
, uint8_t _rx, uint8_t _tx, uint8_t _er, unsigned long _blink_period
#endif
) : transport(_transport),MySensor(_radio, _hw
) :
transport(_transport), MySensor(_radio, _hw
#ifdef MY_SIGNING_FEATURE
, _signer
, _signer
#endif
#ifdef WITH_LEDS_BLINKING
, _rx, _tx, _er, _blink_period
#ifdef MY_LEDS_BLINKING_FEATURE
, _rx, _tx, _er, _blink_period
#endif
)
{
#ifdef MY_INCLUSION_MODE_FEATURE
inclusionMode = false;
#endif
}
void MyGateway::begin(void (*_msgCallback)(const MyMessage &)
#ifdef MY_INCLUSION_MODE_FEATURE
, int _inclusionModeDuration
#ifdef MY_INCLUSION_BUTTON_FEATURE
, uint8_t _inclusionModeButtonPin
#endif
#endif
) {
// Setup digital in that triggers inclusion mode
#ifdef MY_INCLUSION_MODE_FEATURE
inclusionDuration = _inclusionModeDuration*1000;
#ifdef MY_INCLUSION_BUTTON_FEATURE
inclusionButtonPin = _inclusionModeButtonPin;
pinMode(inclusionButtonPin, INPUT);
digitalWrite(inclusionButtonPin, HIGH);
#endif
#endif
// Start MySensors in repeater mode
MySensor::begin(_msgCallback, GATEWAY_ADDRESS, true, GATEWAY_ADDRESS);
// Startup complete
transport.send(build(msg, I_GATEWAY_READY).set("Gateway startup complete."));
}
@@ -60,8 +91,8 @@ boolean MyGateway::sendRoute(MyMessage &message) {
}
}
boolean MyGateway::process() {
checkInclusionMode();
bool newMessage = false;
if (transport.available()) {
MyMessage &gmsg = transport.receive();
@@ -70,8 +101,8 @@ boolean MyGateway::process() {
if (mGetRequestAck(gmsg)) {
// Copy message
tmpMsg = gmsg;
mSetRequestAck(tmpMsg,false); // Reply without ack flag (otherwise we would end up in an eternal loop)
mSetAck(tmpMsg,true);
mSetRequestAck(tmpMsg, false); // Reply without ack flag (otherwise we would end up in an eternal loop)
mSetAck(tmpMsg, true);
tmpMsg.sender = nc.nodeId;
tmpMsg.destination = msg.sender;
transport.send(tmpMsg);
@@ -79,10 +110,12 @@ boolean MyGateway::process() {
if (mGetCommand(gmsg) == C_INTERNAL) {
if (msg.type == I_VERSION) {
// Request for version. Create the response
transport.send(build(msg, GATEWAY_ADDRESS, GATEWAY_ADDRESS, GATEWAY_ADDRESS, C_INTERNAL, I_VERSION, false).set(LIBRARY_VERSION));
transport.send(build(msg, I_VERSION).set(LIBRARY_VERSION));
#ifdef MY_INCLUSION_MODE_FEATURE
} else if (msg.type == I_INCLUSION_MODE) {
// Request to change inclusion mode
//setInclusionMode(atoi(msg.data) == 1);
setInclusionMode(atoi(msg.data) == 1);
#endif
} else {
processInternalMessages(gmsg);
}
@@ -97,3 +130,39 @@ boolean MyGateway::process() {
}
return MySensor::process() || newMessage;
}
#ifdef MY_INCLUSION_MODE_FEATURE
void MyGateway::setInclusionMode(boolean newMode) {
if (newMode != inclusionMode) {
inclusionMode = newMode;
// Send back mode change to controller
transport.send(build(msg, I_INCLUSION_MODE).set(inclusionMode?1:0));
if (inclusionMode) {
inclusionStartTime = hw_millis();
Serial.println(inclusionStartTime);
Serial.println(inclusionDuration);
}
}
}
void MyGateway::checkInclusionMode() {
#ifdef MY_INCLUSION_BUTTON_FEATURE
if (!inclusionMode && digitalRead(inclusionButtonPin) == LOW) {
// Start inclusion mode
setInclusionMode(true);
}
#endif
if (inclusionMode && hw_millis()-inclusionStartTime>inclusionDuration) {
// inclusionTimeInMinutes minute(s) has passed.. stop inclusion mode
setInclusionMode(false);
}
}
#endif
+33 -2
View File
@@ -51,7 +51,7 @@ public:
#ifdef MY_SIGNING_FEATURE
, MySigning &signer=*new MySigningNone()
#endif
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
, uint8_t _rx=MY_DEFAULT_RX_LED_PIN
, uint8_t _tx=MY_DEFAULT_TX_LED_PIN
, uint8_t _er=MY_DEFAULT_ERR_LED_PIN
@@ -60,7 +60,24 @@ public:
);
void enableInclusionModeFeature(uint8_t inclusionModeButtonPin, uint8_t inclusionModeDuration);
/**
* Begin operation of the MySensors library
*
* Call this in setup(), before calling any other sensor net library methods.
* @param incomingMessageCallback Callback function for incoming messages from other nodes or controller and request responses. Default is NULL.
* @param inclusionModeDuration Number of milliseconds inclusion mode should be enabled
* @param inclusionModeButtonPin Button pin used for enabling inclusion mode
*/
void begin(void (* msgCallback)(const MyMessage &)=NULL
#ifdef MY_INCLUSION_MODE_FEATURE
, int inclusionModeDuration=MY_INCLUSION_MODE_DURATION
#ifdef MY_INCLUSION_BUTTON_FEATURE
, uint8_t inclusionModeButtonPin=MY_INCLUSION_MODE_BUTTON_PIN
#endif
#endif
);
/**
* See MySensor.h
@@ -77,7 +94,21 @@ public:
boolean process();
private:
MyGatewayTransport &transport;
#ifdef MY_INCLUSION_MODE_FEATURE
void setInclusionMode(bool newMode);
void checkInclusionMode();
unsigned long inclusionStartTime;
bool inclusionMode;
unsigned long inclusionDuration;
#ifdef MY_INCLUSION_BUTTON_FEATURE
uint8_t inclusionButtonPin;
#endif
#endif
};
#endif
+16 -16
View File
@@ -53,7 +53,7 @@ MySensor::MySensor(MyTransport &_radio, MyHw &_hw
#ifdef MY_SIGNING_FEATURE
, MySigning &_signer
#endif
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
, uint8_t _rx, uint8_t _tx, uint8_t _er, unsigned long _blink_period
#endif
)
@@ -62,7 +62,7 @@ MySensor::MySensor(MyTransport &_radio, MyHw &_hw
#ifdef MY_SIGNING_FEATURE
signer(_signer),
#endif
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
pinRx(_rx), pinTx(_tx), pinEr(_er), ledBlinkPeriod(_blink_period),
#endif
#ifdef MY_OTA_FIRMWARE_FEATURE
@@ -96,7 +96,7 @@ bool MySensor::isValidFirmware() {
#endif
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
void MySensor::handleLedsBlinking() {
static unsigned long next_time = hw_millis() + ledBlinkPeriod;
@@ -175,7 +175,7 @@ void MySensor::begin(void (*_msgCallback)(const MyMessage &), uint8_t _nodeId, b
hw_readConfigBlock((void*)doSign, (void*)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS, sizeof(doSign));
#endif
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
// Setup led pins
pinMode(pinRx, OUTPUT);
pinMode(pinTx, OUTPUT);
@@ -327,7 +327,7 @@ boolean MySensor::sendRoute(MyMessage &message) {
// If we still don't have any parent id, re-request and skip this message.
if (nc.parentNodeId == AUTO) {
findParentNode();
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
errBlink(1);
#endif
return false;
@@ -336,7 +336,7 @@ boolean MySensor::sendRoute(MyMessage &message) {
// If we still don't have any node id, re-request and skip this message.
if (nc.nodeId == AUTO) {
requestNodeId();
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
errBlink(1);
#endif
return false;
@@ -375,14 +375,14 @@ boolean MySensor::sendRoute(MyMessage &message) {
}
if (hw_millis() - enter > MY_VERIFICATION_TIMEOUT_MS) {
debug(PSTR("nonce tmo\n"));
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
errBlink(1);
#endif
return false;
}
if (!signOk) {
debug(PSTR("sign fail\n"));
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
errBlink(1);
#endif
return false;
@@ -443,7 +443,7 @@ boolean MySensor::sendRoute(MyMessage &message) {
if (!ok) {
// Failure when sending to parent node. The parent node might be down and we
// need to find another route to gateway.
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
errBlink(1);
#endif
failedTransmissions++;
@@ -460,7 +460,7 @@ boolean MySensor::sendWrite(uint8_t to, MyMessage &message) {
mSetVersion(message, PROTOCOL_VERSION);
uint8_t length = mGetSigned(message) ? MAX_MESSAGE_LENGTH : mGetLength(message);
message.last = nc.nodeId;
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
txBlink(1);
#endif
bool ok = radio.send(to, &message, min(MAX_MESSAGE_LENGTH, HEADER_SIZE + length));
@@ -508,7 +508,7 @@ void MySensor::requestTime(void (* _timeCallback)(unsigned long)) {
boolean MySensor::process() {
hw_watchdogReset();
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
handleLedsBlinking();
#endif
@@ -522,7 +522,7 @@ boolean MySensor::process() {
debug(PSTR("fw upd fail\n"));
// Give up. We have requested MY_OTA_RETRY times without any packet in return.
fwUpdateOngoing = false;
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
errBlink(1);
#endif
return false;
@@ -546,7 +546,7 @@ boolean MySensor::process() {
#endif
uint8_t len = radio.receive((uint8_t *)&msg);
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
rxBlink(1);
#endif
@@ -561,14 +561,14 @@ boolean MySensor::process() {
if (!mGetSigned(msg)) {
// Got unsigned message that should have been signed
debug(PSTR("no sign\n"));
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
errBlink(1);
#endif
return false;
}
else if (!signer.verifyMsg(msg)) {
debug(PSTR("verify fail\n"));
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
errBlink(1);
#endif
return false; // This signed message has been tampered with!
@@ -584,7 +584,7 @@ boolean MySensor::process() {
if(!(mGetVersion(msg) == PROTOCOL_VERSION)) {
debug(PSTR("ver mismatch\n"));
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
errBlink(1);
#endif
return false;
+3 -3
View File
@@ -145,7 +145,7 @@ class MySensor
#ifdef MY_SIGNING_FEATURE
, MySigning &signer=*new MySigningNone()
#endif
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
, uint8_t _rx=MY_DEFAULT_RX_LED_PIN,
uint8_t _tx=MY_DEFAULT_TX_LED_PIN,
uint8_t _er=MY_DEFAULT_ERR_LED_PIN,
@@ -303,7 +303,7 @@ class MySensor
*/
int8_t sleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2, unsigned long ms=0);
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
/**
* Blink with LEDs
* @param cnt how many blink cycles to keep the LED on. Default cycle is 300ms
@@ -339,7 +339,7 @@ class MySensor
MySigning& signer;
#endif
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
uint8_t pinRx; // Rx led pin
uint8_t pinTx; // Tx led pin
uint8_t pinEr; // Err led pin
@@ -104,8 +104,8 @@ MyTransportNRF24 transport(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);
MyHwATMega328 hw;
// Construct MySensors library (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h)
// To use LEDs blinking, uncomment WITH_LEDS_BLINKING in MyConfig.h
#ifdef WITH_LEDS_BLINKING
// To use LEDs blinking, uncomment MY_LEDS_BLINKING_FEATURE in MyConfig.h
#ifdef MY_WITH_LEDS_BLINKING
MySensor gw(transport, hw /*, signer*/, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN);
#else
MySensor gw(transport, hw /*, signer*/);
@@ -92,12 +92,12 @@ void parseAndSend(MySensor &gw, char *commandBuffer) {
setInclusionMode(atoi(msg.data) == 1);
}
} else {
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
gw.txBlink(1);
#endif
ok = gw.sendRoute(msg);
if (!ok) {
#ifdef WITH_LEDS_BLINKING
#ifdef MY_LEDS_BLINKING_FEATURE
gw.errBlink(1);
#endif
}
@@ -1,146 +0,0 @@
/**
* The MySensors Arduino library handles the wireless radio link and protocol
* between your home built sensors/actuators and HA controller of choice.
* The sensors forms a self healing radio network with optional repeaters. Each
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
* network topology allowing messages to be routed to nodes.
*
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
* Copyright (C) 2013-2015 Sensnology AB
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
*
* Documentation: http://www.mysensors.org
* Support Forum: http://forum.mysensors.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
*/
#ifndef __GATEWAYUTIL_H__
#define __GATEWAYUTIL_H__
#include <MyTransport.h>
#ifdef ARDUINO
uint8_t inclusionTime = 1; // Number of minutes inclusion mode is enabled
uint8_t pinInclusion = 3; // Input pin that should trigger inclusion mode
#define MAX_RECEIVE_LENGTH 100 // Max buffersize needed for messages coming from controller
#define MAX_SEND_LENGTH 120 // Max buffersize needed for messages destined for controller
volatile boolean buttonTriggeredInclusion;
boolean inclusionMode; // Keeps track on inclusion mode
void (*serial)(const char *fmt, ... );
MyProtocolDefault protocol;
void setInclusionMode(boolean newMode);
char convBuf[MAX_PAYLOAD*2+1];
char serialBuffer[MAX_SEND_LENGTH]; // Buffer for building string when sending data to vera
unsigned long inclusionStartTime;
void setupGateway(uint8_t _inc, uint8_t _incTime, void (* _serial)(const char *, ... )) {
inclusionMode = 0;
buttonTriggeredInclusion = false;
serial = _serial;
pinInclusion = _inc;
inclusionTime = _incTime;
// Setup digital in that triggers inclusion mode
pinMode(pinInclusion, INPUT);
digitalWrite(pinInclusion, HIGH);
}
void startInclusionInterrupt() {
buttonTriggeredInclusion = true;
}
void incomingMessage(const MyMessage &message) {
// if (mGetCommand(message) == C_PRESENTATION && inclusionMode) {
// gw.rxBlink(3);
// } else {
// gw.rxBlink(1);
// }
// Pass along the message from sensors to serial line
serial(PSTR("%d;%d;%d;%d;%d;%s\n"),message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type, message.getString(convBuf));
}
void checkButtonTriggeredInclusion() {
if (buttonTriggeredInclusion) {
// Ok, someone pressed the inclusion button on the gateway
// start inclusion mode for 1 munute.
#ifdef DEBUG
serial(PSTR("0;0;%d;0;%d;Inclusion started by button.\n"), C_INTERNAL, I_LOG_MESSAGE);
#endif
buttonTriggeredInclusion = false;
setInclusionMode(true);
}
}
void checkInclusionFinished() {
if (inclusionMode && millis()-inclusionStartTime>60000UL*inclusionTime) {
// inclusionTimeInMinutes minute(s) has passed.. stop inclusion mode
setInclusionMode(false);
}
}
void parseAndSend(MySensor &gw, char *commandBuffer) {
boolean ok;
MyMessage &msg = gw.getLastMessage();
if (protocol.parse(msg, commandBuffer)) {
uint8_t command = mGetCommand(msg);
if (msg.destination==GATEWAY_ADDRESS && command==C_INTERNAL) {
// Handle messages directed to gateway
if (msg.type == I_VERSION) {
// Request for version
serial(PSTR("0;0;%d;0;%d;%s\n"), C_INTERNAL, I_VERSION, LIBRARY_VERSION);
} else if (msg.type == I_INCLUSION_MODE) {
// Request to change inclusion mode
setInclusionMode(atoi(msg.data) == 1);
}
} else {
#ifdef WITH_LEDS_BLINKING
gw.txBlink(1);
#endif
ok = gw.sendRoute(msg);
if (!ok) {
#ifdef WITH_LEDS_BLINKING
gw.errBlink(1);
#endif
}
}
}
}
void setInclusionMode(boolean newMode) {
if (newMode != inclusionMode) {
inclusionMode = newMode;
// Send back mode change on serial line to ack command
serial(PSTR("0;0;%d;0;%d;%d\n"), C_INTERNAL, I_INCLUSION_MODE, inclusionMode?1:0);
if (inclusionMode) {
inclusionStartTime = millis();
}
}
}
#else
#error This example is only for use on Arduino.
#endif // ARDUINO
#endif
@@ -29,15 +29,13 @@
* - RX/TX/ERR leds need to be connected between +5V (anode) and digital pin 6/5/4 with resistor 270-330R in a series
*
* LEDs (OPTIONAL):
* - To use the feature, uncomment WITH_LEDS_BLINKING in MyConfig.h
* - To use the feature, uncomment MY_LEDS_BLINKING_FEATURE in MyConfig.h
* - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
* - TX (yellow) - blink fast on radio message transmitted. In inclusion mode will blink slowly
* - ERR (red) - fast blink on error during transmission error or recieve crc error
*
*/
#define NO_PORTB_PINCHANGES
#include <MySigningNone.h>
#include <MyTransportRFM69.h>
#include <MyTransportNRF24.h>
@@ -46,13 +44,11 @@
#include <MySigningAtsha204.h>
#include <SPI.h>
#include <MyGatewayTransportSerial.h>
#include <MyProtocolDefault.h>
#include <MySensor.h>
#include <stdarg.h>
#include <PinChangeInt.h>
#include "GatewayUtil.h"
#include <MyGateway.h>
#define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled
#define INCLUSION_MODE_TIME 60 // Number of seconds inclusion mode is enabled
#define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button
#define RADIO_ERROR_LED_PIN 4 // Error led pin
#define RADIO_RX_LED_PIN 6 // Receive led pin
@@ -70,88 +66,37 @@ MyTransportNRF24 transport(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);
// Hardware profile
MyHwATMega328 hw;
// Controller Transport profile
MyProtocolDefault protocol;
MyGatewayTransportSerial ctrlTransport(protocol);
// Construct MySensors library (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h)
// To use LEDs blinking, uncomment WITH_LEDS_BLINKING in MyConfig.h
#ifdef WITH_LEDS_BLINKING
MySensor gw(transport, hw /*, signer*/, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN);
// To use LEDs blinking, uncomment MY_LEDS_BLINKING_FEATURE in MyConfig.h
#ifdef MY_LEDS_BLINKING_FEATURE
MyGateway gw(ctrlTransport, transport, hw /*, signer*/, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN);
#else
MySensor gw(transport, hw /*, signer*/);
MyGateway gw(ctrlTransport, transport, hw /*, signer*/);
#endif
char inputString[MAX_RECEIVE_LENGTH] = ""; // A string to hold incoming commands from serial/ethernet interface
int inputPos = 0;
boolean commandComplete = false; // whether the string is complete
void parseAndSend(char *commandBuffer);
void output(const char *fmt, ... ) {
va_list args;
va_start (args, fmt );
vsnprintf_P(serialBuffer, MAX_SEND_LENGTH, fmt, args);
va_end (args);
Serial.print(serialBuffer);
}
void setup()
{
gw.begin(incomingMessage, 0, true, 0);
gw.begin(NULL
#ifdef MY_INCLUSION_MODE_FEATURE
, INCLUSION_MODE_TIME
#ifdef MY_INCLUSION_BUTTON_FEATURE
, INCLUSION_MODE_PIN
#endif
#endif
);
setupGateway(INCLUSION_MODE_PIN, INCLUSION_MODE_TIME, output);
// Add interrupt for inclusion button to pin
PCintPort::attachInterrupt(pinInclusion, startInclusionInterrupt, RISING);
// Send startup log message on serial
serial(PSTR("0;0;%d;0;%d;Gateway startup complete.\n"), C_INTERNAL, I_GATEWAY_READY);
}
void loop()
{
gw.process();
checkButtonTriggeredInclusion();
checkInclusionFinished();
if (commandComplete) {
// A command wass issued from serial interface
// We will now try to send it to the actuator
parseAndSend(gw, inputString);
commandComplete = false;
inputPos = 0;
}
}
/*
SerialEvent occurs whenever a new data comes in the
hardware serial RX. This routine is run between each
time loop() runs, so using delay inside loop can delay
response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inputPos<MAX_RECEIVE_LENGTH-1 && !commandComplete) {
if (inChar == '\n') {
inputString[inputPos] = 0;
commandComplete = true;
} else {
// add it to the inputString:
inputString[inputPos] = inChar;
inputPos++;
}
} else {
// Incoming message too long. Throw away
inputPos = 0;
}
}
}