basic irc plugin

This commit is contained in:
2018-11-23 14:38:39 +01:00
commit 90f7af7bdc
15 changed files with 571 additions and 0 deletions

72
.gitignore vendored Normal file
View File

@@ -0,0 +1,72 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# platformio / IDE
.pioenvs
.piolibdeps
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.clang_complete
.gcc-flags.json
.pioenvs
.piolibdeps
data/config.json

14
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,14 @@
image: python:2.7-stretch
stages:
- build
before_script:
- "pip install -U platformio"
examples:
stage: build
image: python:2.7-stretch
script:
- pio run -t clean
- pio run -e basic

67
.travis.yml Normal file
View File

@@ -0,0 +1,67 @@
# Continuous Integration (CI) is the practice, in software
# engineering, of merging all developer working copies with a shared mainline
# several times a day < http://docs.platformio.org/page/ci/index.html >
#
# Documentation:
#
# * Travis CI Embedded Builds with PlatformIO
# < https://docs.travis-ci.com/user/integration/platformio/ >
#
# * PlatformIO integration with Travis CI
# < http://docs.platformio.org/page/ci/travis.html >
#
# * User Guide for `platformio ci` command
# < http://docs.platformio.org/page/userguide/cmd_ci.html >
#
#
# Please choice one of the following templates (proposed below) and uncomment
# it (remove "# " before each line) or use own configuration according to the
# Travis CI documentation (see above).
#
#
# Template #1: General project. Test it using existing `platformio.ini`.
#
# language: python
# python:
# - "2.7"
#
# sudo: false
# cache:
# directories:
# - "~/.platformio"
#
# install:
# - pip install -U platformio
# - platformio update
#
# script:
# - platformio run
#
# Template #2: The project is intended to by used as a library with examples
#
# language: python
# python:
# - "2.7"
#
# sudo: false
# cache:
# directories:
# - "~/.platformio"
#
# env:
# - PLATFORMIO_CI_SRC=path/to/test/file.c
# - PLATFORMIO_CI_SRC=examples/file.ino
# - PLATFORMIO_CI_SRC=path/to/test/directory
#
# install:
# - pip install -U platformio
# - platformio update
#
# script:
# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N

7
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"terminal.integrated.env.linux": {
"PATH": "/home/master/.platformio/penv/bin:/home/master/.platformio/penv:/usr/local/sbin:/usr/local/bin:/usr/bin",
"PLATFORMIO_CALLER": "vscode"
}
}

13
data/config.json Normal file
View File

@@ -0,0 +1,13 @@
{
"stationMode": 1,
"hostname": "sprocket",
"apSSID": "sprocket",
"apPassword": "th3r31sn0Sp00n",
"connectTimeout": 20000,
"stationSSID": "MyAP",
"stationPassword": "th3r31sn0Sp00n",
"meshSSID": "whateverYouLike",
"meshPassword": "somethingSneaky",
"meshPort": 5555,
"channel": 5
}

6
data/ircConfig.json Normal file
View File

@@ -0,0 +1,6 @@
{
"ircServer": "chat.freenode.net",
"ircPort": 6665,
"ircNickname": "sprocket",
"ircUser": "sprocket"
}

41
lib/readme.txt Normal file
View File

@@ -0,0 +1,41 @@
This directory is intended for the project specific (private) libraries.
PlatformIO will compile them to static libraries and link to executable file.
The source code of each library should be placed in separate directory, like
"lib/private_lib/[here are source files]".
For example, see how can be organized `Foo` and `Bar` libraries:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) http://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- readme.txt --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
Then in `src/main.c` you should use:
#include <Foo.h>
#include <Bar.h>
// rest H/C/CPP code
PlatformIO will find your libraries automatically, configure preprocessor's
include paths and build them.
More information about PlatformIO Library Dependency Finder
- http://docs.platformio.org/page/librarymanager/ldf.html

25
library.json Normal file
View File

@@ -0,0 +1,25 @@
{
"name": "sprocket-plugin-mqtt",
"keywords": "sprocket, plugin",
"description": "Plugin for message dispatching a Sprocket and a MQTT queue.",
"authors":
{
"name": "Patrick Balsiger",
"email": "patrick.balsiger@wirelos.net",
"url": "https://gitlab.com/0x1d"
},
"repository":
{
"type": "git",
"url": "https://gitlab.com/wirelos/sprocket-plugin-mqtt"
},
"frameworks": "arduino",
"platforms": "espressif8266, esp32",
"examples": "examples/*",
"export": {
"exclude":
[
"src/examples/"
]
}
}

28
platformio.ini Normal file
View File

@@ -0,0 +1,28 @@
[platformio]
env_default = basic
[common]
framework = arduino
platform = espressif8266
board = esp12e
upload_speed = 921600
monitor_baud = 115200
lib_deps =
Hash
TaskScheduler
SPIFFS
ArduinoJson
ArduinoOTA
https://gitlab.com/wirelos/sprocket-lib.git#develop
https://gitlab.com/wirelos/sprocket-network-wifi.git
[env:basic]
src_filter = +<*> -<examples/> +<examples/basic/>
platform = ${common.platform}
board = ${common.board}
upload_speed = ${common.upload_speed}
monitor_baud = ${common.monitor_baud}
framework = ${common.framework}
lib_deps = ${common.lib_deps}
ESP8266mDNS
ArduinoIRC

44
src/IrcConfig.h Normal file
View File

@@ -0,0 +1,44 @@
#ifndef __IRC_CONFIG__
#define __IRC_CONFIG__
#include <JsonStruct.h>
#define JSON_IRC_SERVER "ircServer"
#define JSON_IRC_PORT "ircPort"
#define JSON_IRC_NICKNAME "ircNickname"
#define JSON_IRC_USER "ircUser"
struct IrcConfig
{
const char *server;
int port;
const char *nickname;
const char *user;
};
struct IrcConfigJson : public IrcConfig, public JsonStruct
{
void mapJsonObject(JsonObject &root)
{
root[JSON_IRC_SERVER] = server;
root[JSON_IRC_PORT] = port;
root[JSON_IRC_NICKNAME] = nickname;
root[JSON_IRC_USER] = user;
}
void fromJsonObject(JsonObject &json)
{
if (!verifyJsonObject(json))
{
Serial.println("ERROR: cannot parse JSON object");
valid = 0;
return;
}
server = getAttr(json, JSON_IRC_SERVER);
port = getIntAttrFromJson(json, JSON_IRC_PORT);
nickname = getAttr(json, JSON_IRC_NICKNAME);
user = getAttr(json, JSON_IRC_USER);
valid = 1;
};
};
#endif

118
src/IrcPlugin.cpp Normal file
View File

@@ -0,0 +1,118 @@
#include "IrcPlugin.h"
IrcPlugin::IrcPlugin(IrcConfig cfg)
{
applyConfig(cfg);
}
void IrcPlugin::applyConfig(IrcConfig cfg)
{
server = String(cfg.server);
port = cfg.port;
nick = String(cfg.nickname);
user = String(cfg.user);
}
void IrcPlugin::applyConfigFromFile(const char *fileName)
{
IrcConfigJson configFile;
configFile.fromFile(fileName);
if (configFile.valid)
{
PRINT_MSG(Serial, "MQTT", "apply config from file");
applyConfig(configFile);
}
}
void IrcPlugin::activate(Scheduler *scheduler)
{
applyConfigFromFile("/ircConfig.json");
client = new IRCClient(server.c_str(), port, wifiClient);
client->setCallback(bind(&IrcPlugin::callback, this, _1));
client->setSentCallback(bind(&IrcPlugin::debugSentCallback, this, _1));
String channel = "#illucat";
subscribe("irc/connect", bind(&IrcPlugin::connect, this));
subscribe("irc/join", bind(&IrcPlugin::join, this, _1));
subscribe("irc/sendMessage", bind(&IrcPlugin::sendMessage, this, channel, _1));
//enableConnectTask(scheduler);
enableProcessTask(scheduler);
PRINT_MSG(Serial, "MQTT", "plugin activated");
}
void IrcPlugin::enableConnectTask(Scheduler *scheduler)
{
connectTask.set(TASK_SECOND * 5, TASK_FOREVER, bind(&IrcPlugin::connect, this));
scheduler->addTask(connectTask);
connectTask.enable();
}
void IrcPlugin::enableProcessTask(Scheduler *scheduler)
{
processTask.set(TASK_MILLISECOND * 5, TASK_FOREVER, bind(&IRCClient::loop, client));
scheduler->addTask(processTask);
processTask.enable();
}
void IrcPlugin::connect()
{
if (!client->connected())
{
PRINT_MSG(Serial, "IRC", String("Attempting connection to " + server).c_str());
if (client->connect(nick.c_str(), user.c_str()))
{
PRINT_MSG(Serial, "IRC", "connected");
}
else
{
PRINT_MSG(Serial, "IRC", "failed... ");
}
return;
}
}
void IrcPlugin::join(String channel)
{
if (client->connected())
{
String joinCmd = "JOIN :" + channel + "\r\n";
wifiClient.print(joinCmd.c_str());
PRINT_MSG(Serial, "IRC", joinCmd.c_str());
}
}
void IrcPlugin::sendMessage(String to, String msg)
{
client->sendMessage(to, msg);
}
void IrcPlugin::callback(IRCMessage ircMessage)
{
String message("<" + ircMessage.nick + "> " + ircMessage.text);
publish("irc/log", message);
PRINT_MSG(Serial, "IRC", message.c_str());
// PRIVMSG ignoring CTCP messages
/* if (ircMessage.command == "PRIVMSG" && ircMessage.text[0] != '\001')
{
String message("<" + ircMessage.nick + "> " + ircMessage.text);
PRINT_MSG(Serial, "IRC", message.c_str());
if (ircMessage.nick == REPLY_TO)
{
client->sendMessage(ircMessage.nick, "Hi " + ircMessage.nick + "! I'm your IRC bot.");
}
return;
} */
PRINT_MSG(Serial, "IRC", ircMessage.original.c_str());
}
void IrcPlugin::debugSentCallback(String data)
{
PRINT_MSG(Serial, "IRC", data.c_str());
}

47
src/IrcPlugin.h Normal file
View File

@@ -0,0 +1,47 @@
#ifndef __IRC_PLUGIN__
#define __IRC_PLUGIN__
#define _TASK_SLEEP_ON_IDLE_RUN
#define _TASK_STD_FUNCTION
#include <IRCClient.h>
#include <WiFiClient.h>
#include <Plugin.h>
#include "utils/print.h"
#include "IrcConfig.h"
using namespace std;
using namespace std::placeholders;
#define REPLY_TO "mentex" // Reply only to this nick
class IrcPlugin : public Plugin
{
public:
IrcPlugin(IrcConfig cfg);
void activate(Scheduler *scheduler);
private:
WiFiClient wifiClient;
IRCClient* client;
Task connectTask;
Task processTask;
String server;
int port;
String nick;
String user;
void applyConfig(IrcConfig cfg);
void applyConfigFromFile(const char *fileName);
void enableConnectTask(Scheduler *scheduler);
void enableProcessTask(Scheduler *scheduler);
virtual void connect();
virtual void callback(IRCMessage ircMessage);
virtual void debugSentCallback(String data);
void join(String channel);
void sendMessage(String to, String msg);
};
#endif

View File

@@ -0,0 +1,38 @@
#ifndef __DEVICE_CONFIG__
#define __DEVICE_CONFIG__
// Scheduler config
#define _TASK_SLEEP_ON_IDLE_RUN
#define _TASK_STD_FUNCTION
#define _TASK_PRIORITY
// Chip config
#define SPROCKET_TYPE "SPROCKET"
#define SERIAL_BAUD_RATE 115200
#define STARTUP_DELAY 1000
// network config
#define SPROCKET_MODE 1
#define WIFI_CHANNEL 11
#define MESH_PORT 5555
#define AP_SSID "sprocket"
#define AP_PASSWORD "th3r31sn0sp00n"
#define MESH_PREFIX "sprocket-mesh"
#define MESH_PASSWORD "th3r31sn0sp00n"
#define STATION_SSID "MyAP"
#define STATION_PASSWORD "th3r31sn0sp00n"
#define HOSTNAME "sprocket"
#define CONNECT_TIMEOUT 10000
#define MESH_DEBUG_TYPES ERROR | STARTUP | CONNECTION
//#define MESH_DEBUG_TYPES ERROR | MESH_STATUS | CONNECTION | SYNC | COMMUNICATION | GENERAL | MSG_TYPES | REMOTE
// WebServer
#define WEB_CONTEXT_PATH "/"
#define WEB_DOC_ROOT "/www"
#define WEB_DEFAULT_FILE "index.html"
#define WEB_PORT 80
#define MQTT_CONFIG_FILE "/mqttConfig.json"
#endif

View File

@@ -0,0 +1,45 @@
//#include <ESP8266WiFi.h>
//#include <IRCClient.h>
#include "config.h"
#include "WiFiNet.h"
#include "Sprocket.h"
#include "IrcPlugin.h"
#define IRC_SERVER "chat.freenode.net"
#define IRC_PORT 6665
#define IRC_NICKNAME "illucat"
#define IRC_USER "illucat"
WiFiNet *network;
Sprocket *sprocket;
IrcPlugin *irc;
void setup()
{
delay(1000);
sprocket = new Sprocket({STARTUP_DELAY, SERIAL_BAUD_RATE});
irc = new IrcPlugin({IRC_SERVER, IRC_PORT, IRC_NICKNAME, IRC_USER});
sprocket->addPlugin(irc);
network = new WiFiNet(
SPROCKET_MODE,
STATION_SSID,
STATION_PASSWORD,
AP_SSID,
AP_PASSWORD,
HOSTNAME,
CONNECT_TIMEOUT);
network->connect();
sprocket->activate();
sprocket->publish("irc/connect", "");
sprocket->publish("irc/join", "#illucat");
sprocket->publish("irc/sendMessage", "hoiii");
}
void loop()
{
sprocket->loop();
yield();
}