Merge pull request #113 from thozza/gateway-refactoring
Add Ethernet Transport driver for Gateway
This commit is contained in:
@@ -74,6 +74,11 @@
|
|||||||
// Enables inclusion-mode button feature on the gateway device
|
// Enables inclusion-mode button feature on the gateway device
|
||||||
#define MY_INCLUSION_BUTTON_FEATURE
|
#define MY_INCLUSION_BUTTON_FEATURE
|
||||||
|
|
||||||
|
// Disable inclusion mode button if inclusion mode feature is not enabled
|
||||||
|
#ifndef MY_INCLUSION_MODE_FEATURE
|
||||||
|
#undef MY_INCLUSION_BUTTON_FEATURE
|
||||||
|
#endif
|
||||||
|
|
||||||
// The default input pin used for the inclusion mode button
|
// The default input pin used for the inclusion mode button
|
||||||
#define MY_INCLUSION_MODE_BUTTON_PIN 3
|
#define MY_INCLUSION_MODE_BUTTON_PIN 3
|
||||||
// Number of seconds (default one minute) inclusion mode should be enabled
|
// Number of seconds (default one minute) inclusion mode should be enabled
|
||||||
@@ -152,6 +157,13 @@
|
|||||||
#define RFM69_ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
|
#define RFM69_ENCRYPTKEY "sampleEncryptKey" //exactly the same 16 characters/bytes on all nodes!
|
||||||
|
|
||||||
|
|
||||||
|
/**************************************
|
||||||
|
* Gateway Transport Ethernet Defaults
|
||||||
|
***************************************/
|
||||||
|
// Enable to use DHCP for getting IP address. If not defined, static IP is expected
|
||||||
|
//#define IP_ADDRESS_DHCP
|
||||||
|
|
||||||
|
// Enable to use UDP instead of plain Ethernet
|
||||||
|
#define USE_UDP
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -73,6 +73,12 @@ void MyGateway::begin(void (*_msgCallback)(const MyMessage &)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// initialize the transport driver
|
||||||
|
if (!transport.begin()) {
|
||||||
|
debug(PSTR("transport driver init fail\n"));
|
||||||
|
while(1); // Nothing more we can do
|
||||||
|
}
|
||||||
|
|
||||||
// Start MySensors in repeater mode
|
// Start MySensors in repeater mode
|
||||||
MySensor::begin(_msgCallback, GATEWAY_ADDRESS, true, GATEWAY_ADDRESS);
|
MySensor::begin(_msgCallback, GATEWAY_ADDRESS, true, GATEWAY_ADDRESS);
|
||||||
|
|
||||||
@@ -92,7 +98,9 @@ boolean MyGateway::sendRoute(MyMessage &message) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean MyGateway::process() {
|
boolean MyGateway::process() {
|
||||||
|
#ifdef MY_INCLUSION_MODE_FEATURE
|
||||||
checkInclusionMode();
|
checkInclusionMode();
|
||||||
|
#endif
|
||||||
bool newMessage = false;
|
bool newMessage = false;
|
||||||
if (transport.available()) {
|
if (transport.available()) {
|
||||||
MyMessage &gmsg = transport.receive();
|
MyMessage &gmsg = transport.receive();
|
||||||
@@ -128,7 +136,15 @@ boolean MyGateway::process() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MySensor::process() || newMessage;
|
|
||||||
|
// new message from sensor node
|
||||||
|
if (MySensor::process()) {
|
||||||
|
MyMessage &msg = MySensor::getLastMessage();
|
||||||
|
newMessage = true;
|
||||||
|
transport.send(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MY_INCLUSION_MODE_FEATURE
|
#ifdef MY_INCLUSION_MODE_FEATURE
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ public:
|
|||||||
// MyProtocol constructor
|
// MyProtocol constructor
|
||||||
MyGatewayTransport(MyProtocol &protocol = *new MyProtocolDefault());
|
MyGatewayTransport(MyProtocol &protocol = *new MyProtocolDefault());
|
||||||
|
|
||||||
|
// initialize the transport driver
|
||||||
|
virtual bool begin() = 0;
|
||||||
|
|
||||||
// Send message to controller
|
// Send message to controller
|
||||||
virtual bool send(MyMessage &message) = 0;
|
virtual bool send(MyMessage &message) = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
/**
|
||||||
|
* 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 Tomas Hozza <thozza@gmail.com>
|
||||||
|
* Copyright (C) 2015 Tomas Hozza
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "MyGatewayTransportEthernet.h"
|
||||||
|
|
||||||
|
MyGatewayTransportEthernet::MyGatewayTransportEthernet(
|
||||||
|
MyProtocol &protocol,
|
||||||
|
uint8_t *gw_mac
|
||||||
|
#ifndef IP_ADDRESS_DHCP
|
||||||
|
, IPAddress gw_ip
|
||||||
|
#endif /* not IP_ADDRESS_DHCP */
|
||||||
|
, uint16_t gw_port
|
||||||
|
#ifdef IP_ADDRESS_DHCP
|
||||||
|
, unsigned long ip_renew_interval
|
||||||
|
#endif /* IP_ADDRESS_DHCP */
|
||||||
|
, IPAddress controller_IP
|
||||||
|
, uint16_t controller_port) :
|
||||||
|
MyGatewayTransport(protocol),
|
||||||
|
gatewayMAC(gw_mac),
|
||||||
|
#ifndef IP_ADDRESS_DHCP
|
||||||
|
gatewayIP(gw_ip),
|
||||||
|
#endif /* not IP_ADDRESS_DHCP */
|
||||||
|
gatewayPort(gw_port),
|
||||||
|
#ifdef IP_ADDRESS_DHCP
|
||||||
|
ip_renewal_period(ip_renew_interval),
|
||||||
|
#endif /* IP_ADDRESS_DHCP */
|
||||||
|
controllerIP(controller_IP),
|
||||||
|
controllerPort(controller_port)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MyGatewayTransportEthernet::begin() {
|
||||||
|
#ifdef IP_ADDRESS_DHCP
|
||||||
|
// Get IP address from DHCP
|
||||||
|
Ethernet.begin(gatewayMAC);
|
||||||
|
#else
|
||||||
|
Ethernet.begin(gatewayMAC, gatewayIP);
|
||||||
|
#endif /* IP_ADDRESS_DHCP */
|
||||||
|
|
||||||
|
// give the Ethernet interface a second to initialize
|
||||||
|
// TODO: use HW delay
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
#ifdef USE_UDP
|
||||||
|
server = new EthernetUDP();
|
||||||
|
server->begin(gatewayPort);
|
||||||
|
#else
|
||||||
|
// we have to use pointers due to the constructor of EthernetServer
|
||||||
|
server = new EthernetServer(gatewayPort);
|
||||||
|
server->begin();
|
||||||
|
#endif /* USE_UDP */
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MyGatewayTransportEthernet::send(MyMessage &message)
|
||||||
|
{
|
||||||
|
char *msg = NULL;
|
||||||
|
|
||||||
|
if (controllerIP == INADDR_NONE) {
|
||||||
|
// no controller IP address set!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg = protocol.format(message);
|
||||||
|
#ifdef USE_UDP
|
||||||
|
server->beginPacket(controllerIP, controllerPort);
|
||||||
|
server->write(msg, strlen(msg));
|
||||||
|
// returns 1 if the packet was sent successfully
|
||||||
|
return server->endPacket();
|
||||||
|
#else
|
||||||
|
EthernetClient client;
|
||||||
|
if (client.connect(controllerIP, controllerPort)) {
|
||||||
|
client.write(msg, strlen(msg));
|
||||||
|
client.stop();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// connecting to the server failed!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif /* USE_UDP */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MyGatewayTransportEthernet::available()
|
||||||
|
{
|
||||||
|
bool available = false;
|
||||||
|
|
||||||
|
#ifdef IP_ADDRESS_DHCP
|
||||||
|
// renew IP address using DHCP
|
||||||
|
renewIP();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_UDP
|
||||||
|
int packet_size = server->parsePacket();
|
||||||
|
|
||||||
|
if (server->available()) {
|
||||||
|
server->read(inputBuffer, MAX_RECEIVE_LENGTH);
|
||||||
|
available = true;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// if an incoming client connects, there will be
|
||||||
|
// bytes available to read via the client object
|
||||||
|
EthernetClient client = server->available();
|
||||||
|
|
||||||
|
if (client) {
|
||||||
|
while (client.available()) {
|
||||||
|
// read the bytes incoming from the client
|
||||||
|
char inChar = client.read();
|
||||||
|
|
||||||
|
if (inputPos < MAX_RECEIVE_LENGTH - 1) {
|
||||||
|
// if newline then command is complete
|
||||||
|
if (inChar == '\n') {
|
||||||
|
inputBuffer[inputPos] = 0;
|
||||||
|
available = true;
|
||||||
|
} else {
|
||||||
|
inputBuffer[inputPos] = inChar;
|
||||||
|
inputPos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inputPos = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (available) {
|
||||||
|
// Parse message and return parse result
|
||||||
|
available = protocol.parse(msg, inputBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
MyMessage& MyGatewayTransportEthernet::receive()
|
||||||
|
{
|
||||||
|
// Return the last parsed message
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MyGatewayTransportEthernet::setControllerIPPort(const IPAddress& addr, const uint16_t port) {
|
||||||
|
controllerIP = addr;
|
||||||
|
|
||||||
|
/* set the port if some legal value passed */
|
||||||
|
if (port > 0)
|
||||||
|
controllerPort = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef IP_ADDRESS_DHCP
|
||||||
|
void MyGatewayTransportEthernet::renewIP()
|
||||||
|
{
|
||||||
|
/* renew/rebind IP address
|
||||||
|
0 - nothing happened
|
||||||
|
1 - renew failed
|
||||||
|
2 - renew success
|
||||||
|
3 - rebinf failed
|
||||||
|
4 - rebind success
|
||||||
|
*/
|
||||||
|
// TODO: Use millis from MyHw ??
|
||||||
|
static unsigned long next_time = millis() + ip_renewal_period;
|
||||||
|
unsigned long now = millis();
|
||||||
|
|
||||||
|
// http://playground.arduino.cc/Code/TimingRollover
|
||||||
|
if ((long)(now - next_time) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Ethernet.maintain() & ~(0x06)) {
|
||||||
|
/* Error occured -> IP was not renewed */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
next_time = now + ip_renewal_period;
|
||||||
|
}
|
||||||
|
#endif /* IP_ADDRESS_DHCP */
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* 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 Tomas Hozza <thozza@gmail.com>
|
||||||
|
* Copyright (C) 2015 Tomas Hozza
|
||||||
|
* 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 MyGatewayTransportEthernet_h
|
||||||
|
#define MyGatewayTransportEthernet_h
|
||||||
|
|
||||||
|
#include "MyConfig.h"
|
||||||
|
#include "MyMessage.h"
|
||||||
|
#include "MyProtocol.h"
|
||||||
|
#include "MyGatewayTransport.h"
|
||||||
|
#include "MyProtocolDefault.h"
|
||||||
|
|
||||||
|
#include <IPAddress.h>
|
||||||
|
|
||||||
|
// Use this if you have attached a Ethernet ENC28J60 shields
|
||||||
|
//#include <UIPEthernet.h>
|
||||||
|
|
||||||
|
// Use this fo WizNET W5100 module and Arduino Ethernet Shield
|
||||||
|
#include <Ethernet.h>
|
||||||
|
|
||||||
|
#ifdef USE_UDP
|
||||||
|
#include <EthernetUdp.h>
|
||||||
|
#endif /* USE_UDP */
|
||||||
|
|
||||||
|
#define CONTROLLER_PORT 5003
|
||||||
|
#define IP_RENEWAL_INTERVAL 60000 // in milliseconds
|
||||||
|
#define MAX_RECEIVE_LENGTH 100 // Maximum message length for messages coming from controller
|
||||||
|
|
||||||
|
|
||||||
|
class MyGatewayTransportEthernet : public MyGatewayTransport
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyGatewayTransportEthernet(MyProtocol &protocol,
|
||||||
|
uint8_t *gw_mac
|
||||||
|
#ifndef IP_ADDRESS_DHCP
|
||||||
|
, IPAddress gw_ip
|
||||||
|
#endif /* not IP_ADDRESS_DHCP */
|
||||||
|
, uint16_t gw_port
|
||||||
|
#ifdef IP_ADDRESS_DHCP
|
||||||
|
, unsigned long ip_renew_interval
|
||||||
|
#endif /* IP_ADDRESS_DHCP */
|
||||||
|
, IPAddress controller_IP
|
||||||
|
, uint16_t controller_port
|
||||||
|
);
|
||||||
|
|
||||||
|
// initialize the driver
|
||||||
|
bool begin();
|
||||||
|
|
||||||
|
// Send message to controller
|
||||||
|
bool send(MyMessage &message);
|
||||||
|
|
||||||
|
// Check if a new message is available from controller
|
||||||
|
bool available();
|
||||||
|
|
||||||
|
// Pick up last message received from controller
|
||||||
|
MyMessage& receive();
|
||||||
|
|
||||||
|
// Set the controller IP and Port
|
||||||
|
void setControllerIPPort(const IPAddress& addr, const uint16_t port);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
IPAddress controllerIP;
|
||||||
|
uint16_t controllerPort;
|
||||||
|
|
||||||
|
#ifdef IP_ADDRESS_DHCP
|
||||||
|
void renewIP();
|
||||||
|
unsigned long ip_renewal_period;
|
||||||
|
#endif /* IP_ADDRESS_DHCP */
|
||||||
|
uint8_t *gatewayMAC;
|
||||||
|
IPAddress gatewayIP;
|
||||||
|
uint16_t gatewayPort;
|
||||||
|
|
||||||
|
#ifndef USE_UDP
|
||||||
|
EthernetServer *server;
|
||||||
|
uint8_t inputPos;
|
||||||
|
#else
|
||||||
|
EthernetUDP *server;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char inputBuffer[MAX_RECEIVE_LENGTH]; // A buffer for incoming commands from serial interface
|
||||||
|
MyMessage msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MyGatewayTransportEthernet_h */
|
||||||
@@ -25,6 +25,10 @@ MyGatewayTransportSerial::MyGatewayTransportSerial(MyProtocol &_protocol) : MyGa
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MyGatewayTransportSerial::begin() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool MyGatewayTransportSerial::send(MyMessage &message) {
|
bool MyGatewayTransportSerial::send(MyMessage &message) {
|
||||||
Serial.print(protocol.format(message));
|
Serial.print(protocol.format(message));
|
||||||
// Serial print is always successful
|
// Serial print is always successful
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ public:
|
|||||||
// MyGateway constructor
|
// MyGateway constructor
|
||||||
MyGatewayTransportSerial(MyProtocol &protocol = *new MyProtocolDefault());
|
MyGatewayTransportSerial(MyProtocol &protocol = *new MyProtocolDefault());
|
||||||
|
|
||||||
|
// initialize the transport driver
|
||||||
|
bool begin();
|
||||||
|
|
||||||
// Send message to controller
|
// Send message to controller
|
||||||
bool send(MyMessage &message);
|
bool send(MyMessage &message);
|
||||||
|
|
||||||
|
|||||||
@@ -20,67 +20,60 @@
|
|||||||
*
|
*
|
||||||
* REVISION HISTORY
|
* REVISION HISTORY
|
||||||
* Version 1.0 - Henrik EKblad
|
* Version 1.0 - Henrik EKblad
|
||||||
* Contribution by a-lurker and Anticimex,
|
* Contribution by a-lurker and Anticimex,
|
||||||
* Contribution by Norbert Truchsess <norbert.truchsess@t-online.de>
|
* Contribution by Norbert Truchsess <norbert.truchsess@t-online.de>
|
||||||
|
* Contribution by Tomas Hozza <thozza@gmail.com>
|
||||||
|
*
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The EthernetGateway sends data received from sensors to the ethernet link.
|
* The EthernetGateway sends data received from sensors to the ethernet link.
|
||||||
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
|
* The gateway also accepts input on ethernet interface, which is then sent out to the radio network.
|
||||||
*
|
*
|
||||||
* The GW code is designed for Arduino 328p / 16MHz. ATmega168 does not have enough memory to run this program.
|
* The GW code is designed for Arduino 328p / 16MHz. ATmega168 does not have enough memory to run this program.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* COMPILING WIZNET (W5100) ETHERNET MODULE
|
* COMPILING WIZNET (W5100) ETHERNET MODULE
|
||||||
* > Edit MyConfig.h in (libraries\MySensors\) to enable softspi (remove // before "#define SOFTSPI").
|
* > Edit MyConfig.h in (libraries\MySensors\) to enable softspi (remove // before "#define SOFTSPI").
|
||||||
*
|
*
|
||||||
* COMPILING ENC28J60 ETHERNET MODULE
|
* COMPILING ENC28J60 ETHERNET MODULE
|
||||||
* > Use Arduino IDE 1.5.7 (or later)
|
* > Use Arduino IDE 1.5.7 (or later)
|
||||||
* > Disable DEBUG in Sensor.h before compiling this sketch. Othervise the sketch will probably not fit in program space when downloading.
|
* > Disable DEBUG in Sensor.h before compiling this sketch. Othervise the sketch will probably not fit in program space when downloading.
|
||||||
* > Remove Ethernet.h include below and include UIPEthernet.h
|
* > Remove Ethernet.h include below and include UIPEthernet.h
|
||||||
* > Remove DigitalIO include
|
* > Remove DigitalIO include
|
||||||
* Note that I had to disable UDP and DHCP support in uipethernet-conf.h to reduce space. (which means you have to choose a static IP for that module)
|
* Note that I had to disable UDP and DHCP support in uipethernet-conf.h to reduce space. (which means you have to choose a static IP for that module)
|
||||||
*
|
*
|
||||||
* VERA CONFIGURATION:
|
* VERA CONFIGURATION:
|
||||||
* Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin.
|
* Enter "ip-number:port" in the ip-field of the Arduino GW device. This will temporarily override any serial configuration for the Vera plugin.
|
||||||
* E.g. If you want to use the defualt values in this sketch enter: 192.168.178.66:5003
|
* E.g. If you want to use the defualt values in this sketch enter: 192.168.178.66:5003
|
||||||
*
|
*
|
||||||
* LED purposes:
|
* LED purposes:
|
||||||
* - To use the feature, uncomment WITH_LEDS_BLINKING in MyConfig.h
|
* - To use the feature, uncomment WITH_LEDS_BLINKING in MyConfig.h
|
||||||
* - RX (green) - blink fast on radio message recieved. In inclusion mode will blink fast only on presentation recieved
|
* - 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
|
* - 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
|
* - ERR (red) - fast blink on error during transmission error or recieve crc error
|
||||||
*
|
*
|
||||||
* See http://www.mysensors.org/build/ethernet_gateway for wiring instructions.
|
* See http://www.mysensors.org/build/ethernet_gateway for wiring instructions.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define NO_PORTB_PINCHANGES
|
|
||||||
|
|
||||||
#include <DigitalIO.h> // This include can be removed when using UIPEthernet module
|
#include <DigitalIO.h> // This include can be removed when using UIPEthernet module
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
#include <MySigningNone.h>
|
#include <MySigningNone.h>
|
||||||
|
#include <MySigningAtsha204.h>
|
||||||
|
#include <MySigningAtsha204Soft.h>
|
||||||
#include <MyTransportRFM69.h>
|
#include <MyTransportRFM69.h>
|
||||||
#include <MyTransportNRF24.h>
|
#include <MyTransportNRF24.h>
|
||||||
#include <MyHwATMega328.h>
|
#include <MyHwATMega328.h>
|
||||||
#include <MySigningAtsha204Soft.h>
|
|
||||||
#include <MySigningAtsha204.h>
|
|
||||||
|
|
||||||
#include <MyProtocolDefault.h>
|
#include <MyGateway.h>
|
||||||
#include <MySensor.h>
|
#include <MyProtocolDefault.h>
|
||||||
#include <stdarg.h>
|
#include <MyGatewayTransportEthernet.h>
|
||||||
#include <PinChangeInt.h>
|
|
||||||
#include "GatewayUtil.h"
|
|
||||||
|
|
||||||
|
// needed due to Arduino IDE
|
||||||
|
#include <Ethernet.h>
|
||||||
|
|
||||||
// Use this if you have attached a Ethernet ENC28J60 shields
|
#define INCLUSION_MODE_TIME 60 // Number of minutes inclusion mode is enabled
|
||||||
// #include <UIPEthernet.h>
|
|
||||||
|
|
||||||
// Use this for WizNET W5100 module and Arduino Ethernet Shield
|
|
||||||
#include <Ethernet.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define INCLUSION_MODE_TIME 1 // Number of minutes inclusion mode is enabled
|
|
||||||
#define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button
|
#define INCLUSION_MODE_PIN 3 // Digital pin used for inclusion mode button
|
||||||
|
|
||||||
#define RADIO_CE_PIN 5 // radio chip enable
|
#define RADIO_CE_PIN 5 // radio chip enable
|
||||||
@@ -90,6 +83,11 @@
|
|||||||
#define RADIO_RX_LED_PIN 8 // Receive led pin
|
#define RADIO_RX_LED_PIN 8 // Receive led pin
|
||||||
#define RADIO_TX_LED_PIN 9 // the PCB, on board LED
|
#define RADIO_TX_LED_PIN 9 // the PCB, on board LED
|
||||||
|
|
||||||
|
#define IP_PORT 5003 // The port you want to open
|
||||||
|
#ifndef IP_ADDRESS_DHCP
|
||||||
|
// Gateway IP address if not using DHCP
|
||||||
|
IPAddress myIp (192, 168, 178, 66); // Configure your static ip-address here COMPILE ERROR HERE? Use Arduino IDE 1.5.7 or later!
|
||||||
|
#endif /* IP_ADDRESS_DHCP */
|
||||||
|
|
||||||
// NRFRF24L01 radio driver (set low transmit power by default)
|
// NRFRF24L01 radio driver (set low transmit power by default)
|
||||||
MyTransportNRF24 transport(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);
|
MyTransportNRF24 transport(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);
|
||||||
@@ -100,117 +98,49 @@ MyTransportNRF24 transport(RF24_CE_PIN, RF24_CS_PIN, RF24_PA_LEVEL_GW);
|
|||||||
//MySigningAtsha204Soft signer;
|
//MySigningAtsha204Soft signer;
|
||||||
//MySigningAtsha204 signer;
|
//MySigningAtsha204 signer;
|
||||||
|
|
||||||
// Hardware profile
|
// Hardware profile
|
||||||
MyHwATMega328 hw;
|
MyHwATMega328 hw;
|
||||||
|
|
||||||
// Construct MySensors library (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h)
|
// Controller protocol
|
||||||
// To use LEDs blinking, uncomment MY_LEDS_BLINKING_FEATURE in MyConfig.h
|
MyProtocolDefault protocol;
|
||||||
#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*/);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define IP_PORT 5003 // The port you want to open
|
|
||||||
IPAddress myIp (192, 168, 178, 66); // Configure your static ip-address here COMPILE ERROR HERE? Use Arduino IDE 1.5.7 or later!
|
|
||||||
|
|
||||||
// The MAC address can be anything you want but should be unique on your network.
|
// 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.
|
// 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.
|
// Note that most of the Ardunio examples use "DEAD BEEF FEED" for the MAC address.
|
||||||
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // DEAD BEEF FEED
|
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // DEAD BEEF FEED
|
||||||
|
|
||||||
// a R/W server on the port
|
// Controller IP
|
||||||
EthernetServer server = EthernetServer(IP_PORT);
|
IPAddress controllerIP = IPAddress(192, 168, 178, 254);
|
||||||
// handle to open connection
|
|
||||||
EthernetClient client = EthernetClient();
|
|
||||||
|
|
||||||
char inputString[MAX_RECEIVE_LENGTH] = ""; // A string to hold incoming commands from serial/ethernet interface
|
// Gateway transport driver
|
||||||
int inputPos = 0;
|
#ifdef IP_ADDRESS_DHCP
|
||||||
bool sentReady = false;
|
MyGatewayTransportEthernet ctrlTransport(protocol, mac, /* gw port */ CONTROLLER_PORT, IP_RENEWAL_INTERVAL, controllerIP, CONTROLLER_PORT);
|
||||||
|
#else
|
||||||
|
MyGatewayTransportEthernet ctrlTransport(protocol, mac, myIp, /* gw port */ CONTROLLER_PORT, controllerIP, CONTROLLER_PORT);
|
||||||
|
#endif
|
||||||
|
|
||||||
void output(const char *fmt, ... ) {
|
|
||||||
va_list args;
|
// Construct MyGateway library (signer needed if MY_SIGNING_FEATURE is turned on in MyConfig.h)
|
||||||
va_start (args, fmt );
|
// To use LEDs blinking, uncomment MY_LEDS_BLINKING_FEATURE in MyConfig.h
|
||||||
vsnprintf_P(serialBuffer, MAX_SEND_LENGTH, fmt, args);
|
#ifdef MY_WITH_LEDS_BLINKING
|
||||||
va_end (args);
|
MyGateway gw(ctrlTransport, transport, hw /*, signer*/, RADIO_RX_LED_PIN, RADIO_TX_LED_PIN, RADIO_ERROR_LED_PIN);
|
||||||
Serial.print(serialBuffer);
|
#else
|
||||||
client.write(serialBuffer);
|
MyGateway gw(ctrlTransport, transport, hw /*, signer*/);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
gw.begin(NULL
|
||||||
|
#ifdef MY_INCLUSION_MODE_FEATURE
|
||||||
|
, INCLUSION_MODE_TIME
|
||||||
|
#ifdef MY_INCLUSION_BUTTON_FEATURE
|
||||||
|
, INCLUSION_MODE_PIN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Ethernet.begin(mac, myIp);
|
|
||||||
|
|
||||||
setupGateway(INCLUSION_MODE_PIN, INCLUSION_MODE_TIME, output);
|
|
||||||
|
|
||||||
// Add interrupt for inclusion button to pin
|
|
||||||
PCintPort::attachInterrupt(pinInclusion, startInclusionInterrupt, RISING);
|
|
||||||
|
|
||||||
// give the Ethernet interface a second to initialize
|
|
||||||
delay(1000);
|
|
||||||
|
|
||||||
// Initialize gateway at maximum PA level, channel 70 and callback for write operations
|
|
||||||
gw.begin(incomingMessage, 0, true, 0);
|
|
||||||
|
|
||||||
|
|
||||||
// start listening for clients
|
|
||||||
server.begin();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
gw.process();
|
gw.process();
|
||||||
|
|
||||||
checkButtonTriggeredInclusion();
|
|
||||||
checkInclusionFinished();
|
|
||||||
|
|
||||||
// if an incoming client connects, there will be
|
|
||||||
// bytes available to read via the client object
|
|
||||||
EthernetClient newclient = server.available();
|
|
||||||
// if a new client connects make sure to dispose any previous existing sockets
|
|
||||||
if (newclient) {
|
|
||||||
if (client != newclient) {
|
|
||||||
client.stop();
|
|
||||||
client = newclient;
|
|
||||||
output(PSTR("0;0;%d;0;%d;Gateway startup complete.\n"), C_INTERNAL, I_GATEWAY_READY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client) {
|
|
||||||
if (!client.connected()) {
|
|
||||||
client.stop();
|
|
||||||
} else if (client.available()) {
|
|
||||||
// read the bytes incoming from the client
|
|
||||||
char inChar = client.read();
|
|
||||||
if (inputPos<MAX_RECEIVE_LENGTH-1) {
|
|
||||||
// if newline then command is complete
|
|
||||||
if (inChar == '\n') {
|
|
||||||
Serial.println("Finished");
|
|
||||||
// a command was issued by the client
|
|
||||||
// we will now try to send it to the actuator
|
|
||||||
inputString[inputPos] = 0;
|
|
||||||
|
|
||||||
// echo the string to the serial port
|
|
||||||
Serial.print(inputString);
|
|
||||||
|
|
||||||
parseAndSend(gw, inputString);
|
|
||||||
|
|
||||||
// clear the string:
|
|
||||||
inputPos = 0;
|
|
||||||
} else {
|
|
||||||
// add it to the inputString:
|
|
||||||
inputString[inputPos] = inChar;
|
|
||||||
inputPos++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Incoming message too long. Throw away
|
|
||||||
inputPos = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
#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 MY_LEDS_BLINKING_FEATURE
|
|
||||||
gw.txBlink(1);
|
|
||||||
#endif
|
|
||||||
ok = gw.sendRoute(msg);
|
|
||||||
if (!ok) {
|
|
||||||
#ifdef MY_LEDS_BLINKING_FEATURE
|
|
||||||
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
|
|
||||||
Reference in New Issue
Block a user