1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-07-30 16:24:09 +03:00

SpacebrewYun library to the 1.5 format

This commit is contained in:
Fede85
2013-09-06 18:25:03 +02:00
parent fa22bc358e
commit c35d4dc131
4 changed files with 12 additions and 2 deletions

View File

@ -0,0 +1,15 @@
SpacebrewYun KEYWORD3
addPublish KEYWORD2
addSubscribe KEYWORD2
connect KEYWORD2
verbose KEYWORD2
monitor KEYWORD2
onMessage KEYWORD2
send KEYWORD2
onRangeMessage KEYWORD2
onStringMessage KEYWORD2
onBooleanMessage KEYWORD2
onCustomMessage KEYWORD2
onOpen KEYWORD2
onClose KEYWORD2
onError KEYWORD2

View File

@ -0,0 +1,10 @@
name=SpacebrewYun
author=
email=
sentence=
paragraph=
url=
architectures=avr
version=1.0
dependencies=
core-dependencies=arduino (>=1.5.0)

View File

@ -0,0 +1,459 @@
#include "SpacebrewYun.h"
SpacebrewYun::SpacebrewYun(const String& _name, const String& _description) {
name = _name;
description = _description;
subscribers = NULL;
publishers = NULL;
server = "sandbox.spacebrew.cc";
port = 9000;
_connected = false;
_verbose = false;
_error_msg = false;
sub_name = "";
sub_msg = "";
sub_type = "";
read_name = false;
read_msg = false;
for ( int i = 0; i < pidLength; i++ ) {
pid [i] = '\0';
}
for ( int i = 0; i < sbPidsLen; i++ ) {
sbPids [i] = '\0';
}
Console.buffer(64);
}
int SpacebrewYun::sub_msg_int_max = 6;
int SpacebrewYun::sub_msg_bool_max = 5;
int SpacebrewYun::sub_msg_str_max = 50;
int SpacebrewYun::sub_name_max = 20;
SpacebrewYun::OnBooleanMessage SpacebrewYun::_onBooleanMessage = NULL;
SpacebrewYun::OnRangeMessage SpacebrewYun::_onRangeMessage = NULL;
SpacebrewYun::OnStringMessage SpacebrewYun::_onStringMessage = NULL;
SpacebrewYun::OnCustomMessage SpacebrewYun::_onCustomMessage = NULL;
SpacebrewYun::OnSBOpen SpacebrewYun::_onOpen = NULL;
SpacebrewYun::OnSBClose SpacebrewYun::_onClose = NULL;
SpacebrewYun::OnSBError SpacebrewYun::_onError = NULL;
void SpacebrewYun::onOpen(OnSBOpen function){
_onOpen = function;
}
void SpacebrewYun::onClose(OnSBClose function){
_onClose = function;
}
void SpacebrewYun::onRangeMessage(OnRangeMessage function){
_onRangeMessage = function;
}
void SpacebrewYun::onStringMessage(OnStringMessage function){
_onStringMessage = function;
}
void SpacebrewYun::onBooleanMessage(OnBooleanMessage function){
_onBooleanMessage = function;
}
void SpacebrewYun::onCustomMessage(OnCustomMessage function){
_onCustomMessage = function;
}
void SpacebrewYun::onError(OnSBError function){
_onError = function;
}
void SpacebrewYun::addPublish(const String& name, const String& type) {
struct Publisher *p = new Publisher();
p->name = createString(name.length() + 1);
p->type = createString(type.length() + 1);
p->confirmed = false;
p->time = 0;
if (type == "range") {
p->lastMsg = createString(sub_msg_int_max);
emptyString(p->lastMsg, sub_msg_int_max);
}
else if (type == "boolean") {
p->lastMsg = createString(sub_msg_bool_max);
emptyString(p->lastMsg, sub_msg_bool_max);
}
else {
p->lastMsg = createString(sub_msg_str_max);
emptyString(p->lastMsg, sub_msg_str_max);
}
name.toCharArray(p->name, name.length() + 1);
type.toCharArray(p->type, type.length() + 1);
if (publishers == NULL){
publishers = p;
}
else {
struct Publisher *curr = publishers;
int counter = 1;
while(curr->next != NULL){
curr = curr->next;
counter++;
}
curr->next = p;
}
p->next = NULL;
}
void SpacebrewYun::addSubscribe(const String& name, const String& type) {
Subscriber *s = new Subscriber();
s->name = createString(name.length() + 1);
s->type = createString(type.length() + 1);
name.toCharArray(s->name, name.length() + 1);
type.toCharArray(s->type, type.length() + 1);
if (subscribers == NULL){
subscribers = s;
}
else {
struct Subscriber *curr = subscribers;
while(curr->next != NULL){
curr = curr->next;
}
curr->next = s;
}
}
void SpacebrewYun::connect(String _server, int _port) {
server = _server;
port = _port;
killPids();
brew.begin("run-spacebrew"); // Process should launch the "curl" command
// brew.begin("python"); // Process should launch the "curl" command
// brew.addParameter("/usr/lib/python2.7/spacebrew/spacebrew.py"); // Process should launch the "curl" command
brew.addParameter("--server");
brew.addParameter(server);
brew.addParameter("--port");
brew.addParameter(String(port));
brew.addParameter("-n");
brew.addParameter(name);
brew.addParameter("-d");
brew.addParameter(description);
if (subscribers != NULL) {
struct Subscriber *curr = subscribers;
while(curr != NULL){
if (_verbose) {
Serial.print(F("Creating subscribers: "));
Serial.print(curr->name);
Serial.print(F(" of type: "));
Serial.println(curr->type);
}
brew.addParameter("-s"); // Add the URL parameter to "curl"
brew.addParameter(curr->name); // Add the URL parameter to "curl"
brew.addParameter(","); // Add the URL parameter to "curl"
brew.addParameter(curr->type); // Add the URL parameter to "curl"
// if (curr->next == NULL) curr = NULL;
// else curr = curr->next;
curr = curr->next;
}
}
if (publishers != NULL) {
struct Publisher *curr = publishers;
while(curr != NULL){
if (_verbose) {
Serial.print(F("Creating publishers: "));
Serial.print(curr->name);
Serial.print(F(" of type: "));
Serial.println(curr->type);
}
brew.addParameter("-p"); // Add the URL parameter to "curl"
brew.addParameter(curr->name); // Add the URL parameter to "curl"
brew.addParameter(","); // Add the URL parameter to "curl"
brew.addParameter(curr->type); // Add the URL parameter to "curl"
curr = curr->next;
}
}
Console.begin();
if (_verbose) {
Serial.println(F("Console started "));
}
brew.runAsynchronously();
if (_verbose) {
Serial.println(F("Brew started "));
}
while (!Console) { ; }
}
void SpacebrewYun::monitor() {
while (Console.available() > 0) {
char c = Console.read();
if (c == char(CONNECTION_START) && !_connected) {
if (_verbose) {
Serial.print(F("Connected to spacebrew server at: "));
Serial.println(server);
Serial.print(F("Application name set to: "));
Serial.println(name);
}
if (_onOpen != NULL){
_onOpen();
}
_connected = true;
}
else if (c == char(CONNECTION_END) && _connected) {
_connected = false;
if (_verbose) {
Serial.print(F("Disconnected from spacebrew server at: "));
Serial.println(server);
}
if (_onClose != NULL){
_onClose();
}
}
if (_verbose) {
if (c == char(CONNECTION_ERROR)) {
_error_msg = true;
Serial.println(F("ERROR :: with Spacebrew.py Connection ::"));
}
else if (_error_msg && c == char(MSG_END)) {
_error_msg = false;
Serial.println();
}
if (_error_msg) {
Serial.print(c);
}
}
if (_connected) {
if (c == char(MSG_START)) {
read_name = true;
} else if (c == char(MSG_DIV) || sub_name.length() > sub_name_max) {
read_name = false;
read_msg = true;
} else if (c == char(MSG_END) || sub_msg.length() > sub_msg_str_max) {
if (read_msg == true) {
read_msg = false;
onMessage();
// delay(2);
}
if (read_confirm == true) {
read_confirm = false;
onConfirm();
delay(2);
}
} else if (c == char(MSG_CONFIRM)) {
read_confirm = true;
} else {
if (read_name == true) {
sub_name += c;
} else if (read_confirm == true) {
sub_name += c;
} else if (read_msg == true) {
sub_msg += c;
}
else if (_verbose) {
Serial.print(c);
}
}
}
}
if (publishers != NULL) {
struct Publisher *curr = publishers;
while((curr != NULL)){
if ( (curr->confirmed == 0) && ((millis() - curr->time) > 50) ) {
if (_verbose) {
Serial.print(F("resending msg: "));
Serial.println(curr->name);
}
send(curr->name, curr->lastMsg);
}
curr = curr->next;
}
}
}
void SpacebrewYun::onConfirm() {
if (publishers != NULL) {
struct Publisher *curr = publishers;
while((curr != NULL)){
if (sub_name.equals(curr->name) == true) {
curr->confirmed = true;
// if (_verbose) {
// Serial.print(F("confirmed "));
// Serial.println(curr->name);
// }
break;
}
curr = curr->next;
}
}
sub_name = "";
sub_msg = "";
sub_type = "";
}
boolean SpacebrewYun::connected() {
return SpacebrewYun::_connected;
}
void SpacebrewYun::verbose(boolean verbose = true) {
_verbose = verbose;
}
void SpacebrewYun::onMessage() {
if (subscribers != NULL) {
struct Subscriber *curr = subscribers;
while((curr != NULL) && (sub_type == "")){
if (sub_name.equals(curr->name) == true) {
sub_type = curr->type;
}
curr = curr->next;
}
}
if ( sub_type.equals("range") ) {
if (_onRangeMessage != NULL) {
_onRangeMessage( sub_name, int(sub_msg.toInt()) );
} else {
Serial.println(F("ERROR :: Range message received, no callback method is registered"));
}
} else if ( sub_type.equals("boolean") ) {
if (_onBooleanMessage != NULL) {
_onBooleanMessage( sub_name, ( sub_msg.equals("false") ? false : true ) );
} else {
Serial.println(F("ERROR :: Boolean message received, no callback method is registered"));
}
} else if ( sub_type.equals("string") ) {
if (_onStringMessage != NULL) {
_onStringMessage( sub_name, sub_msg );
} else {
Serial.println(F("ERROR :: String message received, no callback method is registered"));
}
} else {
if (_onCustomMessage != NULL) {
_onCustomMessage( sub_name, sub_msg, sub_type );
} else {
Serial.println(F("ERROR :: Custom message received, no callback method is registered"));
}
}
sub_name = "";
sub_msg = "";
sub_type = "";
}
void SpacebrewYun::send(const String& name, const String& value){
if (publishers != NULL) {
Console.print(char(29));
Console.print(name);
Console.print(char(30));
Console.print(value);
Console.print(char(31));
Console.flush();
struct Publisher *curr = publishers;
while(curr != NULL){
if (name.equals(curr->name) == true) {
int msg_len = 0;
if (curr->type == "range") msg_len = sub_msg_int_max;
else if (curr->type == "boolean") msg_len = sub_msg_bool_max;
else msg_len = sub_msg_str_max;
if (value.length() < msg_len) msg_len = value.length() + 1;
value.toCharArray(curr->lastMsg, msg_len);
curr->confirmed = false;
curr->time = millis();
}
curr = curr->next;
}
}
}
/**
* method that gets the pid of all spacebrew.py instances running on the linino.
*/
void SpacebrewYun::getPids() {
// request the pid of all python processes
// brew.begin("run-getsbpids"); // Process should launch the "curl" command
pids.begin("python");
pids.addParameter("/usr/lib/python2.7/spacebrew/getprocpid.py"); // Process should launch the "curl" command
pids.run();
if (_verbose) {
Serial.println(F("Checking if spacebrew process already running"));
}
int sbPidsIndex = 0;
int pidCharIndex = 0;
char c = '\0';
while ( pids.available() > 0 ) {
c = pids.read();
if ( c >= '0' && c <= '9' ) {
pid[pidCharIndex] = c;
pidCharIndex = (pidCharIndex + 1) % pidLength;
}
else if ( (c == ' ' || c == '\n') && pidCharIndex > 0) {
sbPids[sbPidsIndex] = atoi(pid);
if ( sbPidsIndex < (sbPidsLen - 1) ) sbPidsIndex = (sbPidsIndex + 1);
for( int i = 0; i < pidLength; i++ ){
pid[i] = '\0';
pidCharIndex = 0;
}
}
}
}
/**
* method that kills all of the spacebrew.py instances that are running
* on the linino.
*/
void SpacebrewYun::killPids() {
getPids();
delay(400);
for (int i = 0; i < sbPidsLen; i ++) {
if (sbPids[i] > 0) {
char * newPID = itoa(sbPids[i], pid, 10);
if (_verbose) {
Serial.print(F("Stopping existing spacebrew processes with pids: "));
Serial.println(newPID);
}
Process p;
p.begin("kill");
p.addParameter("-9");
p.addParameter(newPID); // Process should launch the "curl" command
p.run(); // Run the process and wait for its termination
delay(400);
}
}
}

View File

@ -0,0 +1,137 @@
#ifndef YUNSPACEBREW_H
#define YUNSPACEBREW_H
#include "Arduino.h"
#include <Bridge.h>
#include <Console.h>
#include <Process.h>
enum SBmsg {
CONNECTION_START = char(28),
CONNECTION_END = char(27),
CONNECTION_ERROR = char(26),
MSG_CONFIRM = char(7),
MSG_START = char(29),
MSG_DIV = char(30),
MSG_END = char(31)
};
struct Publisher {
char *name;
char *type;
char *lastMsg;
Publisher *next;
int confirmed;
long time;
};
struct Subscriber{
char *name;
char *type;
Subscriber *next;
};
int const pidLength = 6;
int const sbPidsLen = 4;
class SpacebrewYun {
public:
SpacebrewYun(const String&, const String&);
void addPublish(const String&, const String&);
void addSubscribe(const String&, const String&);
void connect(String, int);
void connect() { connect(server, port); };
void connect(String _server) { connect(String(_server), port); };
void monitor();
void onMessage();
void onConfirm();
boolean connected();
void send(const String&, const String&);
void send(const String& name, char * value) { send(name, String(value)); }
void send(const String& name, bool value){ send(name, (value ? String("true") : String("false"))); };
void send(const String& name, int value) { send(name, String(value)); };
void send(const String& name, long value) { send(name, String(value)); };
void send(const String& name, float value) { send(name, String(value)); };
void verbose(boolean);
typedef void (*OnBooleanMessage)(String name, boolean value);
typedef void (*OnRangeMessage)(String name, int value);
typedef void (*OnStringMessage)(String name, String value);
typedef void (*OnCustomMessage)(String name, String value, String type);
typedef void (*OnSBOpen)();
typedef void (*OnSBClose)();
typedef void (*OnSBError)(int code, String message);
void onOpen(OnSBOpen function);
void onClose(OnSBClose function);
void onRangeMessage(OnRangeMessage function);
void onStringMessage(OnStringMessage function);
void onBooleanMessage(OnBooleanMessage function);
void onCustomMessage(OnCustomMessage function);
void onError(OnSBError function);
private:
Process brew;
String name;
String server;
String description;
boolean _connected;
boolean _error_msg;
boolean _verbose;
int port;
/**Output should be at least 5 cells**/
static OnBooleanMessage _onBooleanMessage;
static OnRangeMessage _onRangeMessage;
static OnStringMessage _onStringMessage;
static OnCustomMessage _onCustomMessage;
static OnSBOpen _onOpen;
static OnSBClose _onClose;
static OnSBError _onError;
Subscriber * subscribers;
Publisher * publishers;
String sub_name;
String sub_msg;
String sub_type;
boolean read_name;
boolean read_msg;
boolean read_confirm;
static int sub_name_max;
static int sub_msg_str_max;
static int sub_msg_int_max;
static int sub_msg_bool_max;
// int sub_name_max;
// int sub_msg_str_max;
Process pids;
char pid [6];
int sbPids [4];
void killPids();
void getPids();
static char * createString(int len){
char * out = ( char * ) malloc ( len + 1 );
return out;
}
static void emptyString(char * str, int len){
for (int i = 0; i < len; i++) {
str[i] = '\0';
}
}
};
#endif