SerialGateway fixed and verified

This commit is contained in:
Henrik Ekblad
2015-09-30 22:30:32 +02:00
parent 415aa29b34
commit adc3f664fc
12 changed files with 252 additions and 410 deletions
+24 -1
View File
@@ -44,6 +44,7 @@
#define MY_BAUD_RATE 115200
#endif
/**********************************
* Radio selection and node config
***********************************/
@@ -87,6 +88,28 @@
#define MY_OTA_FLASH_JDECID 0x1F65
#endif
/**********************************
* Gateway config
***********************************/
// Max buffersize needed for messages coming from controller
#ifndef MY_GATEWAY_MAX_RECEIVE_LENGTH
#define MY_GATEWAY_MAX_RECEIVE_LENGTH 100
#endif
// Max buffer size when sending messages
#ifndef MY_GATEWAY_MAX_SEND_LENGTH
#define MY_GATEWAY_MAX_SEND_LENGTH 120
#endif
// Max number of parallel clients (sever mode)
#ifndef MY_GATEWAY_MAX_CLIENTS
#define MY_GATEWAY_MAX_CLIENTS 1
#endif
/**********************************
* Information LEDs blinking
***********************************/
@@ -98,7 +121,7 @@
//#define MY_LEDS_BLINKING_FEATURE
// The following setting allows you to inverse the blinking feature MY_LEDS_BLINKING_FEATURE
// When WITH_LEDS_BLINKING_INVERSE is enabled LEDSs are normally turned on and switches
// When MY_WITH_LEDS_BLINKING_INVERSE is enabled LEDSs are normally turned on and switches
// off when blinking
//#define MY_WITH_LEDS_BLINKING_INVERSE
+16 -5
View File
@@ -26,6 +26,7 @@
#include "MyConfig.h"
#include "core/MySensorCore.h"
// Detect node type
#if defined(MY_GATEWAY_SERIAL) || defined(MY_GATEWAY_W5100) || defined(MY_GATEWAY_ENC28J60) || defined(ARDUINO_ARCH_ESP8266)
#define MY_GATEWAY_FEATURE
#define MY_IS_GATEWAY (true)
@@ -36,13 +37,18 @@
#define MY_NODE_TYPE "sensor"
#endif
// Enable radio "feature" if one of the radio types was enabled
#if defined(MY_RADIO_NRF24) || defined(MY_RADIO_RFM69)
#define MY_RADIO_FEATURE
#endif
// HARDWARE
#if defined(ARDUINO_ARCH_ESP8266)
#include "drivers/ESP8266/SPI/SPI.cpp"
#undef PSTR
#define PSTR(x) (x)
#include "drivers/ESP8266/EEPROM/EEPROM.cpp"
#include "drivers/ESP8266/SPI/SPI.cpp"
#include "core/MyHwESP8266.cpp"
// For ESP8266, we always enable gateway feature
#define MY_GATEWAY_ESP8266
#elif defined(ARDUINO_ARCH_AVR)
@@ -118,14 +124,20 @@
// #include "drivers/ESP8266/ESP8266WiFi/src/WifiClient.cpp"
// #include "drivers/ESP8266/ESP8266WiFi/src/WifiServer.cpp"
// #include "drivers/ESP8266/ESP8266WiFi/src/WifiUdp.cpp"
#if !defined(USE_UDP)
#endif
#include "core/MyGatewayTransportEthernet.cpp"
#elif defined(MY_GATEWAY_W5100)
// GATEWAY - W5100
#include "drivers/AVR/Ethernet_W5100/utility/socket.cpp"
/*#include "drivers/AVR/Ethernet_W5100/utility/socket.cpp"
#include "drivers/AVR/Ethernet_W5100/utility/w5100.cpp"
#include "drivers/AVR/Ethernet_W5100/DNS.cpp"
#include "drivers/AVR/Ethernet_W5100/Ethernet.cpp"
#include "drivers/AVR/Ethernet_W5100/EthernetUdp.cpp"
#include "drivers/AVR/Ethernet_W5100/IPAddress.cpp"
#include "drivers/AVR/Ethernet_W5100/IPAddress.cpp"*/
#if !defined(USE_UDP)
#include "drivers/AVR/Ethernet_W5100/EthernetServer.cpp"
@@ -166,7 +178,6 @@
// RADIO
#if defined(MY_RADIO_NRF24) || defined(MY_RADIO_RFM69)
#define MY_RADIO_FEATURE
// SOFTSPI
#ifdef MY_SOFTSPI
#if defined(ARDUINO_ARCH_ESP8266)
@@ -19,8 +19,11 @@
#include "MyGatewayTransport.h"
extern boolean transportSendRoute(MyMessage &message);
inline void gatewayTransportProcess() {
if (gatewayTransportAvailable()) {
MyMessage &_msg = gatewayTransportReceive();
if (_msg.destination == GATEWAY_ADDRESS) {
// Check if sender requests an ack back.
@@ -51,6 +54,10 @@ inline void gatewayTransportProcess() {
receive(_msg);
}
}
} else {
#if defined(MY_RADIO_FEATURE)
transportSendRoute(_msg);
#endif
}
}
}
@@ -17,25 +17,59 @@
* version 2 as published by the Free Software Foundation.
*/
#include "MyGatewayTransportEthernet.h"
#include "MyGatewayTransport.h"
IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS);
IPAddress _ethernetGatewayIP(MY_IP_ADDRESS);
#if defined(MY_CONTROLLER_IP_ADDRESS)
IPAddress _ethernetControllerIP(MY_CONTROLLER_IP_ADDRESS);
#endif
#if defined(MY_IP_ADDRESS)
IPAddress _ethernetGatewayIP(MY_IP_ADDRESS);
#endif
byte _ethernetGatewayMAC[] = { MY_MAC_ADDRESS };
uint16_t _ethernetGatewayPort = MY_PORT;
char _ethernetInputBuffer[MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface
MyMessage _ethernetMsg;
#ifdef MY_USE_UDP
EthernetUDP _ethernetServer;
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
// gatewayTransportSend(buildGw(_msg, I_GATEWAY_READY).set("Gateway startup complete."));
typedef struct
{
char string[MY_GATEWAY_MAX_RECEIVE_LENGTH];
uint8_t idx;
} inputBuffer;
#if defined(MY_GATEWAY_ESP8266)
// Some re-defines to make code more readable below
#define EthernetServer WiFiServer
#define EthernetClient WiFiClient
#if defined(MY_IP_ADDRESS)
IPAddress gateway(MY_IP_GATEWAY_ADDRESS);
IPAddress subnet(MY_IP_SUBNET_ADDRESS);
#endif
#endif
#if defined(MY_USE_UDP)
#if defined(MY_GATEWAY_ESP8266)
WiFiUDP _ethernetServer;
#else
EthernetUDP _ethernetServer;
#endif
#else
// we have to use pointers due to the constructor of EthernetServer
EthernetServer _ethernetServer(_ethernetGatewayPort);
uint8_t _ethernetInputPos;
#endif /* USE_UDP */
#define MAX_RECEIVE_LENGTH 100 // Maximum message length for messages coming from controller
static EthernetClient clients[MY_GATEWAY_MAX_CLIENTS];
static bool clientsConnected[MY_GATEWAY_MAX_CLIENTS];
static inputBuffer inputString[MY_GATEWAY_MAX_CLIENTS];
#ifndef MY_IP_ADDRESS
void gatewayTransportRenewIP();
@@ -43,102 +77,136 @@ MyMessage _ethernetMsg;
bool gatewayTransportInit() {
#ifdef MY_IP_ADDRESS
Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP);
#else
// Get IP address from DHCP
Ethernet.begin(_ethernetGatewayMAC);
#endif /* IP_ADDRESS_DHCP */
#if defined(MY_GATEWAY_ESP8266)
(void)WiFi.begin(MY_ESP8266_SSID, MY_ESP8266_PASSWORD);
#ifdef MY_IP_ADDRESS
WiFi.config(_ethernetGatewayIP, gateway, subnet);
#endif
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(PSTR("Connected to AP!"));
Serial.print(PSTR("IP: "));
Serial.println(WiFi.localIP());
// give the Ethernet interface a second to initialize
// TODO: use HW delay
delay(1000);
#else
#ifdef MY_IP_ADDRESS
Ethernet.begin(_ethernetGatewayMAC, _ethernetGatewayIP);
#else
// Get IP address from DHCP
Ethernet.begin(_ethernetGatewayMAC);
#endif /* IP_ADDRESS_DHCP */
// give the Ethernet interface a second to initialize
// TODO: use HW delay
delay(1000);
#endif
#ifdef MY_USE_UDP
_ethernetServer.begin(_ethernetGatewayPort);
#else
// we have to use pointers due to the constructor of EthernetServer
_ethernetServer.begin();
#endif /* USE_UDP */
#ifdef MY_USE_UDP
_ethernetServer.begin(_ethernetGatewayPort);
#else
// we have to use pointers due to the constructor of EthernetServer
_ethernetServer.begin();
#if defined(MY_GATEWAY_ESP8266)
_ethernetServer.setNoDelay(true);
#endif
#endif /* USE_UDP */
}
bool gatewayTransportSend(MyMessage &message)
{
char *_ethernetMsg = NULL;
char *_ethernetMsg = protocolFormat(message);
if (_ethernetControllerIP == INADDR_NONE) {
// no controller IP address set!
return false;
}
else {
_ethernetMsg = protocolFormat(message);
#ifdef MY_USE_UDP
_ethernetServer.beginPacket(_ethernetControllerIP, MY_PORT);
_ethernetServer.write(_ethernetMsg, strlen(_ethernetMsg));
// returns 1 if the packet was sent successfully
return _ethernetServer.endPacket();
#else
EthernetClient client;
if (client.connect(_ethernetControllerIP, MY_PORT)) {
client.write(_ethernetMsg, strlen(_ethernetMsg));
client.stop();
return true;
}
else {
// connecting to the server failed!
return false;
}
#endif /* USE_UDP */
}
#if defined(MY_CONTROLLER_IP_ADDRESS)
#if defined(MY_USE_UDP)
_ethernetServer.beginPacket(_ethernetControllerIP, MY_PORT);
_ethernetServer.write(_ethernetMsg, strlen(_ethernetMsg));
// returns 1 if the packet was sent successfully
return _ethernetServer.endPacket();
#else
EthernetClient client;
if (client.connect(_ethernetControllerIP, MY_PORT)) {
client.write(_ethernetMsg, strlen(_ethernetMsg));
client.stop();
return true;
}
else {
// connecting to the server failed!
return false;
}
#endif
#else
// Send to connected clients
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++)
{
if (clients[i] && clients[i].connected())
{
clients[i].write((uint8_t*)_ethernetMsg, strlen(_ethernetMsg));
}
}
// TODO: What do we return here?
return true;
#endif
}
bool gatewayTransportAvailable()
{
bool available = false;
#ifndef MY_IP_ADDRESS
// renew IP address using DHCP
gatewayTransportRenewIP();
#endif
#if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266)
// renew IP address using DHCP
gatewayTransportRenewIP();
#endif
#ifdef MY_USE_UDP
int packet_size = _ethernetServer.parsePacket();
#ifdef MY_USE_UDP
int packet_size = _ethernetServer.parsePacket();
if (_ethernetServer.available()) {
_ethernetServer.read(_ethernetInputBuffer, MAX_RECEIVE_LENGTH);
available = true;
}
#else
// if an incoming client connects, there will be
// bytes available to read via the client object
EthernetClient client = _ethernetServer.available();
if (_ethernetServer.available()) {
_ethernetServer.read(inputString[0], MY_GATEWAY_MAX_RECEIVE_LENGTH);
return protocolParse(_ethernetMsg, inputString[0]);
}
#else
// Loop over clients connect and read available data
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++) {
while (clients[i].connected() && clients[i].available()) {
char inChar = clients[i].read();
if (inputString[i].idx < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1) {
// if newline then command is complete
if (inChar == '\n') {
// a command was issued by the client
// we will now try to send it to the actuator
inputString[i].string[inputString[i].idx] = 0;
if (client) {
while (client.available()) {
// read the bytes incoming from the client
char inChar = client.read();
// echo the string to the serial port
Serial.print(PSTR("Client "));
Serial.print(i);
Serial.print(": ");
Serial.println(inputString[i].string);
if (_ethernetInputPos < MAX_RECEIVE_LENGTH - 1) {
// if newline then command is complete
if (inChar == '\n') {
_ethernetInputBuffer[_ethernetInputPos] = 0;
available = true;
// clear the string:
inputString[i].idx = 0;
return protocolParse(_ethernetMsg, inputString[i].string);
} else {
// add it to the inputString:
inputString[i].string[inputString[i].idx++] = inChar;
}
} else {
_ethernetInputBuffer[_ethernetInputPos] = inChar;
_ethernetInputPos++;
// Incoming message too long. Throw away
Serial.print(PSTR("Client "));
Serial.print(i);
Serial.println(PSTR(": Message too long"));
inputString[i].idx = 0;
// Finished with this client's message. Next loop() we'll see if there's more to read.
break;
}
}
}
}
_ethernetInputPos = 0;
#endif
if (available) {
// Parse message and return parse result
available = protocolParse(_ethernetMsg, _ethernetInputBuffer);
}
return available;
#endif
return false;
}
MyMessage& gatewayTransportReceive()
@@ -148,7 +216,7 @@ MyMessage& gatewayTransportReceive()
}
#ifndef MY_IP_ADDRES
#if !defined(MY_IP_ADDRESS) && !defined(MY_GATEWAY_ESP8266)
void gatewayTransportRenewIP()
{
/* renew/rebind IP address
@@ -19,20 +19,16 @@
#include "MyConfig.h"
#include "MyProtocolMySensors.h"
#include "MyProtocol.h"
#include "MyGatewayTransport.h"
#include "MyMessage.h"
#include "MyProtocol.h"
#define MAX_RECEIVE_LENGTH 100 // Maximum message length for messages coming from controller
char _serialInputString[MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface
char _serialInputString[MY_GATEWAY_MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface
int _serialInputPos;
MyMessage _serialMsg;
bool gatewayTransportInit() {
return true;
}
bool gatewayTransportSend(MyMessage &message) {
Serial.print(protocolFormat(message));
@@ -40,14 +36,21 @@ bool gatewayTransportSend(MyMessage &message) {
return true;
}
bool gatewayTransportInit() {
gatewayTransportSend(buildGw(_msg, I_GATEWAY_READY).set("Gateway startup complete."));
return true;
}
bool gatewayTransportAvailable() {
bool available = false;
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 (_serialInputPos < MAX_RECEIVE_LENGTH - 1 && !available) {
if (_serialInputPos < MY_GATEWAY_MAX_RECEIVE_LENGTH - 1 && !available) {
if (inChar == '\n') {
_serialInputString[_serialInputPos] = 0;
available = true;
+2
View File
@@ -20,8 +20,10 @@
#ifndef MyProtocol_h
#define MyProtocol_h
#include "MyConfig.h"
#include "MyMessage.h"
// parse(message, inputString)
// parse a string into a message element
// returns true if successfully parsed the input string
@@ -21,11 +21,9 @@
#include "MyTransport.h"
#include "MyProtocol.h"
#define MAX_FORMAT_BUFFER_LENGTH 120 // Max buffersize when formatting messages
uint8_t protocolH2i(char c);
char _fmtBuffer[MAX_FORMAT_BUFFER_LENGTH];
char _fmtBuffer[MY_GATEWAY_MAX_SEND_LENGTH];
char _convBuffer[MAX_PAYLOAD*2+1];
bool protocolParse(MyMessage &message, char *inputString) {
@@ -95,7 +93,7 @@ bool protocolParse(MyMessage &message, char *inputString) {
}
char * protocolFormat(MyMessage &message) {
snprintf_P(_fmtBuffer, MAX_FORMAT_BUFFER_LENGTH, PSTR("%d;%d;%d;%d;%d;%s\n"), message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type, message.getString(_convBuffer));
snprintf_P(_fmtBuffer, MY_GATEWAY_MAX_SEND_LENGTH, PSTR("%d;%d;%d;%d;%d;%s\n"), message.sender, message.sensor, mGetCommand(message), mGetAck(message), message.type, message.getString(_convBuffer));
return _fmtBuffer;
}
@@ -86,7 +86,6 @@ void _begin() {
while(1); // Nothing more we can do
}
gatewayTransportSend(buildGw(_msg, I_GATEWAY_READY).set("Gateway startup complete."));
#endif
+6 -2
View File
@@ -122,7 +122,6 @@ inline void transportProcess() {
uint8_t sender = _msg.sender;
uint8_t last = _msg.last;
uint8_t destination = _msg.destination;
if (destination == _nc.nodeId) {
// This message is addressed to this node
@@ -285,6 +284,10 @@ inline void transportProcess() {
}
#endif
#if defined(MY_GATEWAY_FEATURE)
// Hand over message to controller
gatewayTransportSend(_msg);
#endif
// Call incoming message callback if available
if (receive) {
receive(_msg);
@@ -356,6 +359,7 @@ boolean transportSendRoute(MyMessage &message) {
uint8_t last = message.last;
bool ok;
// If we still don't have any parent id, re-request and skip this message.
if (_nc.parentNodeId == AUTO) {
transportFindParentNode();
@@ -412,7 +416,6 @@ boolean transportSendRoute(MyMessage &message) {
}
#endif
#if !defined(MY_REPEATER_FEATURE)
// None repeating node... We can only send to our parent
ok = transportSendWrite(_nc.parentNodeId, message);
@@ -448,6 +451,7 @@ boolean transportSendRoute(MyMessage &message) {
#if defined (MY_GATEWAY_FEATURE)
// Destination isn't in our routing table and isn't a broadcast address
// Nothing to do here
debug(PSTR("Destination %d unknown\n"), dest);
return false;
# else
// A message comes from a child node and we have no
@@ -64,8 +64,8 @@
*
* Make sure to fill in your ssid and WiFi password below for ssid & pass.
*/
#include <ESP8266WiFi.h>
#include <stdarg.h>
// Enable debug prints to serial monitor
#define MY_DEBUG
@@ -74,26 +74,27 @@
#define MY_RADIO_NRF24
//#define MY_RADIO_RFM69
// Gateway always enabled for ESP8266 by default
//#define MY_GATEWAY_ESP8266
// Gateway mode always enabled for ESP8266
#define MY_GATEWAY_ESP8266
// Enable to use UDP
#define MY_USE_UDP
#define MY_ESP8266_SSID "MySSID"
#define MY_ESP8266_PASSWORD "MyVerySecretPassword"
#define MY_IP_ADDRESS 192,168,178,66 // If this is disabled, DHCP is used to retrieve address
// Renewal period if using DHCP
//#define MY_IP_RENEWAL_INTERVAL 60000
// The port to keep open on node server mode / or port to contact in client mode
// Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP)
// #define MY_IP_ADDRESS 192,168,178,66
// If using static ip you need to define Gateway and Subnet address as well
#define MY_IP_GATEWAY_ADDRESS 192,168,0,1
#define MY_IP_SUBNET_ADDRESS 255,255,255,0
// The port to keep open on node server mode
#define MY_PORT 5003
// Controller ip address (enables client mode). Undefine this to act as sever.
#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 254
// The MAC address can be anything you want but should be unique on your network.
// Newer boards have a MAC address printed on the underside of the PCB, which you can (optionally) use.
// Note that most of the Ardunio examples use "DEAD BEEF FEED" for the MAC address.
#define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
// How many clients should be able to connect to this gateway (default 1)
#define MY_GATEWAY_MAX_CLIENTS 5
// Controller ip address (enables client mode). Undefine this to act as sever.
//#define MY_CONTROLLER_IP_ADDRESS 192, 168, 178, 254
// Flash leds on rx/tx/err
#define MY_LEDS_BLINKING_FEATURE
// Set blinking period
@@ -108,170 +109,24 @@
// Digital pin used for inclusion mode button
#define MY_INCLUSION_MODE_BUTTON_PIN 3
#define MY_DEFAULT_ERR_LED_PIN 7 // Error led pin
#define MY_DEFAULT_RX_LED_PIN 8 // Receive led pin
#define MY_DEFAULT_TX_LED_PIN 9 // the PCB, on board LED
#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin
#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin
#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED
// NEW
#define MY_ESP8266_MAX_CLIENTS 5 // how many clients should be able to telnet to this ESP8266
#define MY_ESP8266_SSID "MySSID"
#define MY_ESP8266_PASSWORD "MyVerySecretPassword"
#include <MySensor.h>
#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
typedef struct
{
char string[MAX_RECEIVE_LENGTH];
uint8_t idx;
} inputBuffer;
#include <MySensor.h>
//#include <stdarg.h>
const char *ssid = "MySSID"; // cannot be longer than 32 characters!
const char *pass = "MyVerySecretPassword"; //
#define IP_PORT 5003 // The port you want to open
#define MAX_SRV_CLIENTS 5 // how many clients should be able to telnet to this ESP8266
// a R/W server on the port
static WiFiServer server(IP_PORT);
static WiFiClient clients[MAX_SRV_CLIENTS];
static bool clientsConnected[MAX_SRV_CLIENTS];
static inputBuffer inputString[MAX_SRV_CLIENTS];
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
void output(const char *fmt, ... )
{
char serialBuffer[MAX_SEND_LENGTH];
va_list args;
va_start (args, fmt );
vsnprintf_P(serialBuffer, MAX_SEND_LENGTH, fmt, args);
va_end (args);
Serial.print(serialBuffer);
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++)
{
if (clients[i] && clients[i].connected())
{
// Serial.print("Client "); Serial.print(i); Serial.println(" write");
clients[i].write((uint8_t*)serialBuffer, strlen(serialBuffer));
}
}
void setup() {
}
void setup()
{
/* // Setup console
hw_init();
Serial.println(); Serial.println();
Serial.println("ESP8266 MySensors Gateway");
Serial.print("Connecting to "); Serial.println(ssid);
(void)WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("Connected!");
Serial.print("IP: "); Serial.println(WiFi.localIP());
Serial.flush();
setupGateway(INCLUSION_MODE_PIN, INCLUSION_MODE_TIME, output);
// Initialize gateway at maximum PA level, channel 70 and callback for write operations
begin(incomingMessage, 0, true, 0);
// start listening for clients
server.begin();
server.setNoDelay(true); */
void presentation() {
// Present locally attached sensors here
}
void loop() {
/*
checkButtonTriggeredInclusion();
checkInclusionFinished();
// Go over list of clients and stop any that are no longer connected.
// If the server has a new client connection it will be assigned to a free slot.
bool allSlotsOccupied = true;
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++)
{
if (!clients[i].connected())
{
if (clientsConnected[i])
{
Serial.print("Client "); Serial.print(i); Serial.println(" disconnected");
clients[i].stop();
}
//check if there are any new clients
if (server.hasClient())
{
clients[i] = server.available();
inputString[i].idx = 0;
Serial.print("Client "); Serial.print(i); Serial.println(" connected");
output(PSTR("0;0;%d;0;%d;Gateway startup complete.\n"), C_INTERNAL, I_GATEWAY_READY);
}
}
bool connected = clients[i].connected();
clientsConnected[i] = connected;
allSlotsOccupied &= connected;
}
if (allSlotsOccupied && server.hasClient())
{
//no free/disconnected spot so reject
Serial.println("No free slot available");
WiFiClient c = server.available();
c.stop();
}
// Loop over clients connect and read available data
for (uint8_t i = 0; i < ARRAY_SIZE(clients); i++)
{
while(clients[i].connected() && clients[i].available())
{
char inChar = clients[i].read();
if ( inputString[i].idx < MAX_RECEIVE_LENGTH - 1 )
{
// if newline then command is complete
if (inChar == '\n')
{
// a command was issued by the client
// we will now try to send it to the actuator
inputString[i].string[inputString[i].idx] = 0;
// echo the string to the serial port
Serial.print("Client "); Serial.print(i); Serial.print(": "); Serial.println(inputString[i].string);
parseAndSend(gw, inputString[i].string);
// clear the string:
inputString[i].idx = 0;
// Finished with this client's message. Next loop() we'll see if there's more to read.
break;
} else {
// add it to the inputString:
inputString[i].string[inputString[i].idx++] = inChar;
}
} else {
// Incoming message too long. Throw away
Serial.print("Client "); Serial.print(i); Serial.println(": Message too long");
inputString[i].idx = 0;
// Finished with this client's message. Next loop() we'll see if there's more to read.
break;
}
}
}*/
}
@@ -1,136 +0,0 @@
#ifndef __GATEWAYUTIL_H__
#define __GATEWAYUTIL_H__
#ifdef ARDUINO
static uint8_t inclusionTime = 1; // Number of minutes inclusion mode is enabled
static 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
typedef struct
{
char string[MAX_RECEIVE_LENGTH];
uint8_t idx;
} inputBuffer;
static volatile boolean buttonTriggeredInclusion;
static boolean inclusionMode; // Keeps track on inclusion mode
bool inclusionButtonSupported = false;
void (*serial)(const char *fmt, ... );
MyParserSerial parser;
void setInclusionMode(boolean newMode);
char convBuf[MAX_PAYLOAD*2+1];
unsigned long inclusionStartTime;
void startInclusionInterrupt() {
buttonTriggeredInclusion = true;
}
void setupGateway(uint8_t _inc, uint8_t _incTime, void (* _serial)(const char *, ... )) {
inclusionMode = 0;
buttonTriggeredInclusion = false;
serial = _serial;
inclusionTime = _incTime;
inclusionButtonSupported = (_inc != 255);
if (inclusionButtonSupported)
{
pinInclusion = _inc;
// Setup digital in that triggers inclusion mode
pinMode(pinInclusion, INPUT_PULLUP);
// Add interrupt for inclusion button to pin
attachInterrupt(pinInclusion, startInclusionInterrupt, FALLING);
}
}
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 (inclusionButtonSupported)
{
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 (parser.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
+9 -1
View File
@@ -40,7 +40,7 @@ MY_OTA_FIRMWARE_FEATURE LITERAL1
MY_OTA_FLASH_SS LITERAL1
MY_OTA_FLASH_JDECID LITERAL1
MY_LEDS_BLINKING_FEATURE LITERAL1
WITH_LEDS_BLINKING_INVERSE LITERAL1
MY_WITH_LEDS_BLINKING_INVERSE LITERAL1
MY_DEFAULT_LED_BLINK_PERIOD LITERAL1
MY_WITH_LEDS_BLINKING_INVERSE LITERAL1
MY_DEFAULT_RX_LED_PIN LITERAL1
@@ -78,6 +78,7 @@ MY_RF69_IRQ_PIN LITERAL1
MY_RF69_SPI_CS LITERAL1
MY_RF69_IRQ_NUM LITERAL1
MY_RFM69_ENCRYPTKEY LITERAL1
MY_GATEWAY_SERIAL LITERAL1
MY_GATEWAY_W5100 LITERAL1
MY_GATEWAY_ENC28J60 LITERAL1
MY_GATEWAY_ESP8266 LITERAL1
@@ -87,3 +88,10 @@ MY_USE_UDP LITERAL1
MY_IP_RENEWAL_INTERVAL LITERAL1
MY_MAC_ADDRESS LITERAL1
MY_CONTROLLER_IP_ADDRESS LITERAL1
MY_GATEWAY_MAX_CLIENTS LITERAL1
MY_GATEWAY_MAX_SEND_LENGTH LITERAL1
MY_GATEWAY_MAX_RECEIVE_LENGTH LITERAL1
MY_ESP8266_SSID LITERAL1
MY_ESP8266_PASSWORD LITERAL1
MY_IP_GATEWAY_ADDRESS LITERAL1
MY_IP_SUBNET_ADDRESS LITERAL1