diff --git a/.project b/.project new file mode 100644 index 0000000..1a19211 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + illucat + + + + + + + + diff --git a/data/ircConfig.json b/data/ircConfig.json new file mode 100644 index 0000000..4390db3 --- /dev/null +++ b/data/ircConfig.json @@ -0,0 +1,6 @@ +{ + "ircServer": "chat.freenode.net", + "ircPort": 6665, + "ircNickname": "redcat", + "ircUser": "redcat" +} \ No newline at end of file diff --git a/data/mqttConfig.json b/data/mqttConfig.json index 7b1b6e6..789897d 100644 --- a/data/mqttConfig.json +++ b/data/mqttConfig.json @@ -1,7 +1,6 @@ { - "mqttClientName" : "illucat00", + "mqttClientName" : "illucat", "mqttBrokerHost" : "192.168.1.2", "mqttBrokerPort" : 1883, - "mqttInTopicRoot" : "wirelos/led-in/", - "mqttOutTopicRoot" : "wirelos/led-out/" + "mqttRootTopic" : "wirelos/led/illucat" } \ No newline at end of file diff --git a/data/pixelConfig.json b/data/pixelConfig.json index d45d7b9..8adce06 100644 --- a/data/pixelConfig.json +++ b/data/pixelConfig.json @@ -1,7 +1,7 @@ { "pin": 4, "length": 8, - "brightness": 100, + "brightness": 127, "updateInterval": 100, "defaultColor": 100 } \ No newline at end of file diff --git a/data/www/favicon-32x32.png b/data/www/favicon-32x32.png new file mode 100644 index 0000000..0e5d4f6 Binary files /dev/null and b/data/www/favicon-32x32.png differ diff --git a/data/www/gradients.json b/data/www/gradients.json index 2b8556f..d184f8d 100644 --- a/data/www/gradients.json +++ b/data/www/gradients.json @@ -3,10 +3,6 @@ "text": "None", "value": ["#000000", "#000000"] }, - { - "text": "Stadler", - "value": ["#0B3F75", "#0B3F75"] - }, { "text": "Blu", "value": ["#00416A", "#E4E5E6"] diff --git a/data/www/index.html b/data/www/index.html index c1ee593..69e9946 100644 --- a/data/www/index.html +++ b/data/www/index.html @@ -2,7 +2,7 @@ - ESP Kit + IlluCat @@ -60,6 +60,12 @@ +
+ IlluChat +
+
+
+
Settings
@@ -69,6 +75,8 @@

MQTT

+

IRC

+
diff --git a/data/www/script.js b/data/www/script.js index 15b4f74..b2f0c68 100644 --- a/data/www/script.js +++ b/data/www/script.js @@ -10793,7 +10793,9 @@ __WEBPACK_IMPORTED_MODULE_0_jquery___default()(() => { let app = new __WEBPACK_IMPORTED_MODULE_1__core_App__["a" /* default */](__WEBPACK_IMPORTED_MODULE_0_jquery___default()('body')) .components(__WEBPACK_IMPORTED_MODULE_2__components_exports__) .websocket(new WebSocket(endpoint.indexOf('/') === 0 ? "ws://" + window.location.host + endpoint : endpoint)); - + app.ws.onmessage = (msg) => { + app.mediator.trigger('out/chat/log', {topic: 'out/chat/log', payload: msg.data}); + }; app.mediator.on('pixels/hue', (payload) => { let colors = payload.split(','); let msg = JSON.stringify({ @@ -10814,6 +10816,8 @@ __WEBPACK_IMPORTED_MODULE_0_jquery___default()(() => { app.mediator.trigger('pixels/color2', colors[1]); //console.log('pixels/hue: ' + msg); app.ws.send(msg); + + }); // TODO make components @@ -11045,6 +11049,9 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "ParamSelect", function() { return __WEBPACK_IMPORTED_MODULE_11__ParamSelect__["a"]; }); /* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__LedStripPatternSwitch__ = __webpack_require__(29); /* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "LedStripPatternSwitch", function() { return __WEBPACK_IMPORTED_MODULE_12__LedStripPatternSwitch__["a"]; }); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__Chat_Chat__ = __webpack_require__(30); +/* harmony reexport (binding) */ __webpack_require__.d(__webpack_exports__, "Chat", function() { return __WEBPACK_IMPORTED_MODULE_13__Chat_Chat__["a"]; }); + @@ -12115,10 +12122,10 @@ class ParamWs extends __WEBPACK_IMPORTED_MODULE_1__base_TextInput_TextInput__["a obj[this.config.name] = this.value; //this.store.save(obj); console.log(this.value); - this.ctx.ws.send({ + this.ctx.ws.send(JSON.stringify({ topic: this.config.topic, payload: this.value - }); + })); this.ctx.mediator.trigger(this.config.endpoint, this.value); } @@ -12241,5 +12248,112 @@ class LedStripPatternSwitch extends __WEBPACK_IMPORTED_MODULE_1__base_Switch_Swi /* harmony export (immutable) */ __webpack_exports__["a"] = LedStripPatternSwitch; +/***/ }), +/* 30 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery__ = __webpack_require__(0); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_jquery__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Chat_html__ = __webpack_require__(31); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Chat_html___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1__Chat_html__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__core_Component__ = __webpack_require__(1); + + + + +class Chat extends __WEBPACK_IMPORTED_MODULE_2__core_Component__["a" /* default */] { + + constructor(ctx, node, template) { + super(ctx, node, template || __WEBPACK_IMPORTED_MODULE_1__Chat_html___default.a); + this.render(this.config); + this.ctx.mediator.on(this.config.topic, this.onMessage.bind(this)); + this.ctx.mediator.on("chat/connected", this.connected.bind(this)); + //this.ctx.mediator.on("irc/configValid", this.configValid.bind(this)); + this.node.delegate('input.msg', 'keypress', this.onInput.bind(this)); + this.node.delegate('button.send', 'click', this.send.bind(this)); + this.node.delegate('button.join', 'click', this.join.bind(this)); + } + + templates() { + return { + message: (user, msg) => ` +
  • + ${user} + ${msg} +
  • + `, + serverMessage: (msg) => ` +
  • + ${msg} +
  • + ` + }; + } + + configValid() { + this.node.text("Please configure first"); + } + + join(evt) { + evt.preventDefault(); + let message = JSON.stringify({ + topic: 'irc/join', + payload: this.sanitizeInput(this.node.find('.channel').val()) + }); + this.ctx.ws.send(message); + this.node.find('.controls').show(); + //this.node.find('button.join').hide(); + } + connected() { + this.node.find('.controls').show(); + this.node.find('button.connect').hide(); + } + + onMessage(msg) { + let payload = msg.payload; //.replace(/<.+?>/g, ''); + //console.log('onMsg: ' + msg); + let msgParts = payload.split(':'); + let messages = this.node.find('.messages'); + messages.append( + msgParts.length == 2 ? + this.templates().message(msgParts[0], this.sanitizeInput(msgParts[1])) + : this.templates().serverMessage(this.sanitizeInput(payload)) + ); + this.node.find('.message-container').animate({ + scrollTop: messages[0].scrollHeight + }, 250); + } + sanitizeInput(val) { + return val.replace(/<.+?>/g, ''); + } + send(evt) { + evt.preventDefault(); + let msg = this.node.find('input.msg'); + if (msg.length > 0) { + let message = JSON.stringify({ + topic: this.sanitizeInput(this.config.topic), + payload: this.sanitizeInput(msg.val()) + }); + this.ctx.ws.send(message); + msg.val(''); + } + } + onInput(evt) { + if (evt.keyCode === 13) { + this.send(evt); + } + } + +} +/* harmony export (immutable) */ __webpack_exports__["a"] = Chat; + + +/***/ }), +/* 31 */ +/***/ (function(module, exports) { + +module.exports = "
    \n \n
    \n
      \n
      \n \n
      " + /***/ }) /******/ ]); \ No newline at end of file diff --git a/data/www/styles.css b/data/www/styles.css index fb13cdf..dd04a28 100644 --- a/data/www/styles.css +++ b/data/www/styles.css @@ -31,7 +31,7 @@ .sui label { color: #b3b2b2; } -.sui button, .sui input[type=file] { +.sui button { background: #097479; color: #eeeeee; font-size: 0.9em; @@ -306,3 +306,24 @@ form .form-row input[type="checkbox"] { .sui select option { background: #333333; } +.Chat .message-container { + max-height: 200px; + overflow: auto; +} +.Chat .message-container .messages { + list-style-type: none; +} +.Chat .message-container .messages .user-label { + color: lightblue; +} +.Chat .message-container .messages .user-label:before { + color: #097479; + content: '<'; +} +.Chat .message-container .messages .user-label:after { + color: #097479; + content: '>'; +} +.Chat .message-container .messages .message-text { + font-weight: normal; +} diff --git a/platformio.ini b/platformio.ini index 8699069..7616473 100644 --- a/platformio.ini +++ b/platformio.ini @@ -85,4 +85,21 @@ lib_deps = ${common.lib_deps} https://gitlab.com/wirelos/sprocket-network-wifi.git https://gitlab.com/wirelos/sprocket-plugin-web.git https://gitlab.com/wirelos/sprocket-plugin-mqtt.git - PubSubClient \ No newline at end of file + PubSubClient + +[env:illuchat] +src_filter = +<*> - + +platform = ${common.platform} +board = ${common.board} +upload_speed = ${common.upload_speed} +monitor_baud = ${common.monitor_baud} +framework = ${common.framework} +build_flags = -Wl,-Teagle.flash.4m1m.ld + -DSPROCKET_PRINT=1 +lib_deps = ${common.lib_deps} + https://gitlab.com/wirelos/sprocket-network-wifi.git + https://gitlab.com/wirelos/sprocket-plugin-web.git + https://gitlab.com/wirelos/sprocket-plugin-irc.git + https://gitlab.com/wirelos/sprocket-plugin-mqtt.git + PubSubClient + ArduinoIRC diff --git a/src/var/illuchat/illuchat_config.h b/src/var/illuchat/illuchat_config.h new file mode 100644 index 0000000..41b90b7 --- /dev/null +++ b/src/var/illuchat/illuchat_config.h @@ -0,0 +1,62 @@ +#ifndef __ILLUCHAT_CONFIG__ +#define __ILLUCHAT_CONFIG__ + +// Scheduler config +#define _TASK_SLEEP_ON_IDLE_RUN +#define _TASK_STD_FUNCTION +#define _TASK_PRIORITY + +// Chip config +#define SPROCKET_TYPE "ILLUCAT" +#define SERIAL_BAUD_RATE 115200 +#define STARTUP_DELAY 1000 + +// Network config +#define WIFI_MODE 0 +#define WIFI_CHANNEL 11 +#define AP_SSID "illucat" +#define AP_PASSWORD "illumination" +#define MESH_PREFIX "illucat-mesh" +#define MESH_PASSWORD "th3r31sn0sp00n" +#define STATION_SSID "MyAP" +#define STATION_PASSWORD "th3r31sn0sp00n" +#define HOSTNAME "illucat" +#define CONNECT_TIMEOUT 10000 + +// config files +#define PIXEL_CONFIG_FILE "/pixelConfig.json" +#define MQTT_CONFIG_FILE "/mqttConfig.json" +#define IRC_CONFIG_FILE "/ircConfig.json" + +// NeoPixel +#define LED_STRIP_PIN D2 +#define LED_STRIP_LENGTH 8 +#define LED_STRIP_BRIGHTNESS 48 +#define LED_STRIP_UPDATE_INTERVAL 200 +#define LED_STRIP_DEFAULT_COLOR 100 +#define COLOR_CONNECTED LED_STRIP_DEFAULT_COLOR +#define COLOR_NOT_CONNECTED 255 + +#define IRC_SERVER "chat.freenode.net" +#define IRC_PORT 6665 +#define IRC_NICKNAME "" +#define IRC_USER "" + +// OTA config +#define OTA_PORT 8266 +#define OTA_PASSWORD "" + +// WebServer +#define WEB_CONTEXT_PATH "/" +#define WEB_DOC_ROOT "/www" +#define WEB_DEFAULT_FILE "index.html" +#define WEB_PORT 80 + +// mqtt config +#define MQTT_CLIENT_NAME "illucat" +#define MQTT_HOST "192.168.1.2" +#define MQTT_PORT 1883 +#define MQTT_ROOT_TOPIC "wirelos/led/illucat" + + +#endif \ No newline at end of file diff --git a/src/var/illuchat/main.cpp b/src/var/illuchat/main.cpp new file mode 100644 index 0000000..c6ecb61 --- /dev/null +++ b/src/var/illuchat/main.cpp @@ -0,0 +1,82 @@ +#include "illuchat_config.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +WiFiNet *network; +Sprocket *sprocket; +WebServerPlugin *webServerPlugin; +WebConfigPlugin *webConfigPlugin; +WebApiPlugin *webApiPlugin; +PixelPlugin *pixelPlugin; +IrcPlugin *ircPlugin; +OtaTcpPlugin *otaTcp; +MqttPlugin *mqttPlugin; + +void setup() +{ + const char *chipName = String("Sprocket" + String(ESP.getChipId())).c_str(); + sprocket = new Sprocket({STARTUP_DELAY, SERIAL_BAUD_RATE}); + pixelPlugin = new PixelPlugin({LED_STRIP_PIN, LED_STRIP_LENGTH, LED_STRIP_BRIGHTNESS, LED_STRIP_UPDATE_INTERVAL}); + ircPlugin = new IrcPlugin({IRC_SERVER, IRC_PORT, chipName, chipName}); + mqttPlugin = new MqttPlugin({MQTT_CLIENT_NAME, MQTT_HOST, MQTT_PORT, MQTT_ROOT_TOPIC}); + webServerPlugin = new WebServerPlugin({WEB_CONTEXT_PATH, WEB_DOC_ROOT, WEB_DEFAULT_FILE, WEB_PORT}); + webConfigPlugin = new WebConfigPlugin(webServerPlugin->server); + webApiPlugin = new WebApiPlugin(webServerPlugin->server); + otaTcp = new OtaTcpPlugin({OTA_PORT, OTA_PASSWORD}); + + sprocket->addPlugin(pixelPlugin); + sprocket->addPlugin(webServerPlugin); + sprocket->addPlugin(webConfigPlugin); + sprocket->addPlugin(webApiPlugin); + sprocket->addPlugin(otaTcp); + sprocket->addPlugin(ircPlugin); + sprocket->addPlugin(mqttPlugin); + + network = new WiFiNet( + WIFI_MODE, + STATION_SSID, + STATION_PASSWORD, + AP_SSID, + AP_PASSWORD, + HOSTNAME, + CONNECT_TIMEOUT); + network->connect(); + + webServerPlugin->server->serveStatic(PIXEL_CONFIG_FILE, SPIFFS, "pixelConfig.json"); + webServerPlugin->server->serveStatic(IRC_CONFIG_FILE, SPIFFS, "ircConfig.json"); + webServerPlugin->server->serveStatic(MQTT_CONFIG_FILE, SPIFFS, "mqttConfig.json"); + + sprocket->subscribe("irc/connected", [](String msg) { + if (atoi(msg.c_str())) + { + sprocket->subscribe("irc/log", [](String msg) { + PRINT_MSG(Serial, "CHAT", String("incoming: " + msg).c_str()); + webApiPlugin->ws->textAll(msg); + }); + sprocket->subscribe("out/chat/log", [](String msg) { + PRINT_MSG(Serial, "CHAT", String("outgoing: " + msg).c_str()); + sprocket->publish("irc/sendMessage", msg); + webApiPlugin->ws->textAll("You:"+msg); + }); + sprocket->publish("chat/connected", ""); + } + }); + + sprocket->activate(); + sprocket->publish("irc/connect",""); +} + +void loop() +{ + sprocket->loop(); + yield(); +} \ No newline at end of file diff --git a/src/var/mqcatt/main.cpp b/src/var/mqcatt/main.cpp index ec7d85d..c6f688f 100644 --- a/src/var/mqcatt/main.cpp +++ b/src/var/mqcatt/main.cpp @@ -21,7 +21,7 @@ void setup() { sprocket = new Sprocket({STARTUP_DELAY, SERIAL_BAUD_RATE}); pixelPlugin = new PixelPlugin({LED_STRIP_PIN, LED_STRIP_LENGTH, LED_STRIP_BRIGHTNESS, LED_STRIP_UPDATE_INTERVAL}); - mqttPlugin = new MqttPlugin({MQTT_CLIENT_NAME, MQTT_HOST, MQTT_PORT, MQTT_TOPIC_IN, MQTT_TOPIC_OUT}); + mqttPlugin = new MqttPlugin({MQTT_CLIENT_NAME, MQTT_HOST, MQTT_PORT, MQTT_ROOT_TOPIC}); webServerPlugin = new WebServerPlugin({WEB_CONTEXT_PATH, WEB_DOC_ROOT, WEB_DEFAULT_FILE, WEB_PORT}); webConfigPlugin = new WebConfigPlugin(webServerPlugin->server); webApiPlugin = new WebApiPlugin(webServerPlugin->server); diff --git a/src/var/mqcatt/mqcatt_config.h b/src/var/mqcatt/mqcatt_config.h index 9d5b9fa..00b9bc5 100644 --- a/src/var/mqcatt/mqcatt_config.h +++ b/src/var/mqcatt/mqcatt_config.h @@ -36,17 +36,17 @@ #define COLOR_CONNECTED LED_STRIP_DEFAULT_COLOR #define COLOR_NOT_CONNECTED 255 -// mqtt config -#define MQTT_CLIENT_NAME "illucat" -#define MQTT_HOST "192.168.1.2" -#define MQTT_PORT 1883 -#define MQTT_TOPIC_IN "wirelos/led-in/" -#define MQTT_TOPIC_OUT "wirelos/led-out/" // OTA config #define OTA_PORT 8266 #define OTA_PASSWORD "" +// mqtt config +#define MQTT_CLIENT_NAME "illucat" +#define MQTT_HOST "192.168.1.2" +#define MQTT_PORT 1883 +#define MQTT_ROOT_TOPIC "wirelos/illucat" + // WebServer #define WEB_CONTEXT_PATH "/" #define WEB_DOC_ROOT "/www"