First working platformio version

This commit is contained in:
Dmitry Borisenko
2020-06-18 23:43:06 +02:00
parent c16b61c82b
commit 86e18f1e99
45 changed files with 511 additions and 856 deletions

View File

@@ -1,17 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

View File

@@ -1,215 +0,0 @@
/*
Copyright (c) 2016 TheThings.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Original Maker: Mateo Velez - Metavix for TheThings Inc
Modified and Maintened by: Jose Garcia - TheThings Inc
*/
#include "TheThingsMQTT.h"
TheThings::TheThings(char* token){
initialize(token, NULL);
}
TheThings::TheThings(char* token, char* clientName) {
initialize(token, clientName);
}
void TheThings::begin(void (*callback)(char*,uint8_t*,unsigned int)) {
this->callback = callback;
_client.setServer(_server, MQTT_PORT);
_client.setCallback(callback);
}
bool TheThings::add(char* variableLabel, float value) {
return add(variableLabel, value, "NULL", "NULL");
}
bool TheThings::add(char* variableLabel, float value, char *context) {
return add(variableLabel, value, context, "NULL");
}
bool TheThings::add(char* variableLabel, float value, char *context, char *timestamp) {
(val+currentValue)->_variableLabel = variableLabel;
(val+currentValue)->_value = value;
(val+currentValue)->_context = context;
(val+currentValue)->_timestamp = timestamp;
currentValue++;
if (currentValue > MAX_VALUES) {
Serial.println(F("You are sending more than the maximum of consecutive variables"));
currentValue = MAX_VALUES;
}
return true;
}
bool TheThings::connected(){
return _client.connected();
}
char* TheThings::getMac(){
// Obtains the MAC of the device
Serial.println("entra");
byte mac[6];
WiFi.macAddress(mac);
char macAddr[18];
sprintf(macAddr, "%2X%2X%2X%2X%2X%2X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
return macAddr;
}
void TheThings::initialize(char* token, char* clientName){
_server = SERVER;
_token = token;
currentValue = 0;
val = (Value *)malloc(MAX_VALUES*sizeof(Value));
if(clientName!=NULL){
_clientName = clientName;
}
}
bool TheThings::loop() {
if (!_client.connected()) {
reconnect();
}
return _client.loop();
}
void TheThings::reconnect() {
while (!_client.connected()) {
Serial.print("Attempting MQTT connection...");
if (_client.connect(_clientName, _token, NULL)) {
Serial.println("connected");
break;
} else {
Serial.print("failed, rc=");
Serial.print(_client.state());
Serial.println(" try again in 3 seconds");
delay(3000);
}
}
}
void TheThings::setDebug(bool debug){
_debug = debug;
}
void TheThings:: setBroker(char* broker){
if (_debug){
Serial.println("Broker set for Business Account");
}
_server = broker;
}
bool TheThings::subscribe() {
char topic[150];
sprintf(topic, "%s%s", FIRST_PART_TOPIC, _token);
if (!_client.connected()) {
reconnect();
}
if (_debug){
Serial.println("Subscribed to: ");
Serial.println(topic);
}
return _client.subscribe(topic);
}
bool TheThings::publish() {
char topic[150];
char payload[500];
String str;
sprintf(topic, "%s%s", FIRST_PART_TOPIC, _token);
sprintf(payload, "[");
for (int i = 0; i <= currentValue; ) {
str = String((val+i)->_value, 1);
sprintf(payload,"%s{\"key\":\"%s\",\"value\":%s",payload,(val+i)->_variableLabel, str.c_str());
if ((val+i)->_timestamp != "NULL") {
sprintf(payload, "%s, \"timestamp\": %s", payload, (val+i)->_timestamp);
}
if ((val+i)->_context != "NULL") {
sprintf(payload, "%s, \"context\": {%s}", payload, (val+i)->_context);
}
i++;
if (i >= currentValue) {
sprintf(payload, "%s}]", payload);
break;
} else {
sprintf(payload, "%s},", payload);
}
}
if (_debug){
Serial.println("publishing to TOPIC: ");
Serial.println(topic);
Serial.print("JSON dict: ");
Serial.println(payload);
}
currentValue = 0;
return _client.publish(topic, payload, 512);
}
bool TheThings::wifiConnection(char* ssid, char* pass) {
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(F("WiFi connected"));
Serial.println(F("IP address: "));
Serial.println(WiFi.localIP());
if(_clientName==NULL){
_clientName = getMac();
}
}
bool TheThings::wifiConnection2() {
WiFiManager wifiManager;
wifiManager.setTimeout(180);
//if(!wifiManager.autoConnect("AutoConnectAP")) {
if(!wifiManager.autoConnect()) {
Serial.println("failed to connect and hit timeout");
delay(3000);
ESP.reset();
delay(5000);
}
}
int TheThings::state() {
return _client.state();
}

View File

@@ -1,58 +0,0 @@
#ifndef TheThingsMQTT_H
#define TheThingsMQTT_H
//#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiManager.h>
#define MQTT_PORT 1883
#define SERVER "mqtt.thethings.io"
#define MAX_VALUES 5
#define FIRST_PART_TOPIC "v2/things/"
#define META_DEBUG Serial
typedef struct Value {
char* _variableLabel;
float _value;
char* _context;
char* _timestamp;
} Value;
class TheThings {
private:
void (*callback)(char*, uint8_t*, unsigned int);
char* getMac();
void initialize(char* token, char* clientName);
WiFiClient espClient;
PubSubClient _client = PubSubClient(espClient);
WiFiManager wifiManager;
char* _clientName = NULL;
bool _debug = false;
uint8_t currentValue;
char* _password;
char* _server;
char* _ssid;
char* _token;
Value* val;
public:
TheThings(char* token);
TheThings(char* token, char* clientName);
bool add(char* variableLabel, float value);
bool add(char* variableLabel, float value, char* context);
bool add(char* variableLabel, float value, char* context, char* timestamp);
void begin(void (*callback)(char*, uint8_t*, unsigned int));
bool connected();
bool loop();
bool subscribe();
bool publish();
void setBroker(char* broker);
void reconnect();
void setDebug(bool debug);
bool wifiConnection(char* ssid, char* pass);
bool wifiConnection2();
int state();
};
#endif

View File

@@ -1,79 +0,0 @@
#pragma once
#include <arduino.h>
#include <stdint.h>
class Ticker {
typedef void (*ticker_callback_t)(bool *);
private:
bool is_attached = false;
uint32_t period = 0;
uint32_t last_tick = 0;
ticker_callback_t callback;
bool *callback_argument;
public:
void Tick() {
if (is_attached && millis() - last_tick >= period) {
callback(callback_argument);
last_tick = millis();
}
}
void detach() {
this->is_attached = true;
}
template <typename TArg>
void attach_ms(uint32_t milliseconds, void (*callback)(TArg), TArg arg) {
this->period = milliseconds;
this->callback = callback;
this->callback_argument = arg;
this->is_attached = true;
}
};
#ifdef ARDUINO_ARCH_ESP8266
#include <Ticker.h>
#include <functional>
#endif
void tickerFlagHandle(volatile bool *flag);
#ifdef _GLIBCXX_FUNCTIONAL
typedef std::function<void(void *)> tscallback_t;
#else
typedef void (*tscallback_t)(void *);
#endif
struct TickerSchedulerItem {
Ticker t;
volatile bool flag = false;
tscallback_t cb;
void *cb_arg;
uint32_t period;
volatile bool is_used = false;
};
class TickerScheduler {
private:
uint8_t size;
TickerSchedulerItem *items = NULL;
void handleTicker(tscallback_t, void *, volatile bool *flag);
static void handleTickerFlag(volatile bool *flag);
public:
TickerScheduler(uint8_t size);
~TickerScheduler();
bool add(uint8_t i, uint32_t period, tscallback_t, void *, boolean shouldFireNow = false);
bool remove(uint8_t i);
bool enable(uint8_t i);
bool disable(uint8_t i);
void enableAll();
void disableAll();
void update();
};

View File

@@ -1,182 +0,0 @@
/****************************************
* Include Libraries
****************************************/
#include "TheThingsMQTT.h"
#include "TickerScheduler.h"
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
/****************************************
* Define Constants
****************************************/
#define TOKEN "" // Your TheThings TOKEN
#define WIFINAME "" //Your SSID
#define WIFIPASS "" // Your Wifi Pass
TheThings client(TOKEN);
#define DHTPIN 14 // Pin which is cosnnected to the DHT sensor.
// Uncomment the type of sensor in use:
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
DHT_Unified dht(DHTPIN, DHTTYPE);
uint32_t delayMS;
#define TRIGGER_PIN 0
#define FRECUENCY 2000
char *AP="TEST_BQ";
String prefix="rel";
const char WiFiAPPSK[] = "prueba";
WiFiManager wifiManager;
#define RELAY1 12
#define RELAY2 13
#define MEASUREMENT_TIME 30000 // Time in milisecons
float Temperature,Humidity;
TickerScheduler ts(1);
/****************************************
* Auxiliar Functions
****************************************/
//void configWiFi(){
// wifiManager.resetSettings();
// if(!wifiManager.autoConnect(AP,WiFiAPPSK)) {
// Serial.println("Reconfiguration called");
// delay(3000);
// //reset and try again, or maybe put it to deep sleep
// ESP.reset();
// delay(15000);
// }
//}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived");
// handle message arrived
String text = "";
for (int i = 0; i < length; i++)
text.concat((char)payload[i]);
Serial.println(text);
text.replace(" ", "");
text.toUpperCase();
if (text.indexOf("\"KEY\":\"REL1\"") >= 0) {
if (text.indexOf("\"VALUE\":\"ON\"") >= 0) digitalWrite(RELAY1,HIGH);
else if (text.indexOf("\"VALUE\":\"OFF\"") >= 0) digitalWrite(RELAY1,LOW);
}
else if (text.indexOf("\"KEY\":\"REL2\"") >= 0) {
if (text.indexOf("\"VALUE\":\"ON\"") >= 0) digitalWrite(RELAY2,HIGH);
else if (text.indexOf("\"VALUE\":\"OFF\"") >= 0) digitalWrite(RELAY2,LOW);
}
}
float temperatureMeasurement(sensors_event_t event, DHT_Unified dht){
// Get temperature event and print its value.
dht.temperature().getEvent(&event);
if (isnan(event.temperature)) {
Serial.println("Error reading temperature!");
}
else {
Serial.print("Temperature: ");
Serial.print(event.temperature);
Serial.println(" *C");
return event.temperature;
}
}
float humidityMeasurement(sensors_event_t event, DHT_Unified dht){
// Get humidity event and print its value.
dht.humidity().getEvent(&event);
if (isnan(event.relative_humidity)) {
Serial.println("Error reading humidity!");
}
else {
Serial.print("Humidity: ");
Serial.print(event.relative_humidity);
Serial.println("%");
return event.relative_humidity;
}
}
void measureAndSend(){
sensors_event_t event;
Temperature=temperatureMeasurement(event,dht);
Humidity=humidityMeasurement(event,dht);
client.add("Temperature", Temperature);
client.add("Humidity", Humidity);
client.publish();
}
/****************************************
* Main Functions
****************************************/
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(100);
pinMode(RELAY1,OUTPUT);
pinMode(RELAY2,OUTPUT);
dht.begin();
sensor_t sensor;
// pinMode(TRIGGER_PIN, INPUT);
// attachInterrupt(digitalPinToInterrupt(TRIGGER_PIN), configWiFi, RISING);
//
// //sets timeout until configuration portal gets turned off
// //useful to make it all retry or go to sleep
// //in seconds
// wifiManager.setTimeout(280);
//
// //fetches ssid and pass and tries to connect
// //if it does not connect it starts an access point with the specified name
// //here "AutoConnectAP"
// //and goes into a blocking loop awaiting configuration
// if(!wifiManager.autoConnect(AP,WiFiAPPSK)) {
// Serial.println("failed to connect and hit timeout");
// delay(3000);
// //reset and try again, or maybe put it to deep sleep
// //ESP.reset();
// delay(FRECUENCY);
// }
// //if you get here you have connected to the WiFi
// Serial.println("connected...yeey :)");
client.wifiConnection(WIFINAME, WIFIPASS);
//client.wifiConnection2();
client.begin(callback);
client.subscribe(); //Insert the dataSource and Variable's Labels
ts.add(0, MEASUREMENT_TIME, [&](void*) { measureAndSend(); }, nullptr, false);
ts.enableAll();
}
void loop() {
// put your main code here, to run repeatedly:
ts.update();
if(!client.connected()){
client.reconnect();
client.subscribe(); //Insert the dataSource and Variable's Labels
}
client.loop();
}

View File

@@ -0,0 +1,81 @@
# TickerScheduler
Simple scheduler for ESP8266 Arduino based on Ticker
### Initialization
`TickerScheduler(uint size);`
| Param | Description |
| --- | --- |
| size | Amount of task Tickers to initialize |
**Example**:
`TickerScheduler ts(5)`
### Add task
`boolean add(uint i, uint32_t period, tscallback_t f, boolean shouldFireNow = false); `
| Param | Description |
| --- | --- |
| i | Task ID |
| period | Task execution period in ms |
| f | Task callback |
| shouldFireNow| `true` if you want to execute task right after first scheduler update or wait next scheduled start |
**Returns**:
`true` - task added sucessfully
`false` - task was not added
**Example**:
`ts.add(0, 3000, sendData)`
### Execute scheduler in `loop()`
`ts.update()`
### Remove task
`boolean remove(uint i)`
**Returns**:
`true` - task removed sucessfully
`false` - task was not removed
| Param | Description |
| --- | --- |
| i | Task ID |
### Enable/Disable task
`boolean enable(uint i)`
`boolean disable(uint i)`
**Returns**:
`true` - task enabled/disabled sucessfully
`false` - task was not enabled/disabled
| Param | Description |
| --- | --- |
| i | Task ID |
### Enable / disable all tasks
`void enableAll()`
`void disableAll()`
### TODO
* Task callback parameters support
* ...

View File

@@ -19,13 +19,13 @@ TickerScheduler::~TickerScheduler()
this->size = 0;
}
void TickerScheduler::handleTickerFlag(volatile bool * flag)
void TickerScheduler::handleTickerFlag(bool * flag)
{
if (!*flag)
*flag = true;
}
void TickerScheduler::handleTicker(tscallback_t f, void * arg, volatile bool * flag)
void TickerScheduler::handleTicker(tscallback_t f, void * arg, bool * flag)
{
if (*flag)
{
@@ -81,7 +81,7 @@ bool TickerScheduler::enable(uint8_t i)
if (i >= this->size || !this->items[i].is_used)
return false;
volatile bool * flag = &this->items[i].flag;
bool * flag = &this->items[i].flag;
this->items[i].t.attach_ms(this->items[i].period, TickerScheduler::handleTickerFlag, flag);
return true;

View File

@@ -0,0 +1,91 @@
#ifndef TICKERSCHEDULER_H
#define TICKERSCHEDULER_H
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#endif
#include <stdint.h>
#ifdef ARDUINO_ARCH_AVR
class Ticker
{
typedef void(*ticker_callback_t)(bool*);
private:
bool is_attached = false;
uint32_t period = 0;
uint32_t last_tick = 0;
ticker_callback_t callback;
bool *callback_argument;
public:
void Tick()
{
if (is_attached && millis() - last_tick >= period)
{
callback(callback_argument);
last_tick = millis();
}
}
void detach()
{
this->is_attached = true;
}
template<typename TArg> void attach_ms(uint32_t milliseconds, void(*callback)(TArg), TArg arg)
{
this->period = milliseconds;
this->callback = callback;
this->callback_argument = arg;
this->is_attached = true;
}
};
#endif
//#ifdef ARDUINO_ARCH_ESP8266
#include <Ticker.h>
#include <functional>
//#endif
void tickerFlagHandle(volatile bool * flag);
#ifdef _GLIBCXX_FUNCTIONAL
typedef std::function<void(void*)> tscallback_t;
#else
typedef void(*tscallback_t)(void*);
#endif
struct TickerSchedulerItem
{
Ticker t;
bool flag = false;
tscallback_t cb;
void * cb_arg;
uint32_t period;
volatile bool is_used = false;
};
class TickerScheduler
{
private:
uint8_t size;
TickerSchedulerItem *items = NULL;
void handleTicker(tscallback_t, void *, bool * flag);
static void handleTickerFlag(bool * flag);
public:
TickerScheduler(uint8_t size);
~TickerScheduler();
bool add(uint8_t i, uint32_t period, tscallback_t, void *, boolean shouldFireNow = false);
bool remove(uint8_t i);
bool enable(uint8_t i);
bool disable(uint8_t i);
void enableAll();
void disableAll();
void update();
};
#endif

View File

@@ -0,0 +1,29 @@
#include <TickerScheduler.h>
#define LED1 4
#define LED2 5
TickerScheduler ts(2);
void blink1() {
digitalWrite(LED1, !digitalRead(LED1));
}
void blink2() {
digitalWrite(LED2, !digitalRead(LED2));
}
void setup() {
pinMode(LED1, OUTPUT);
digitalWrite(LED1, LOW);
pinMode(LED2, OUTPUT);
digitalWrite(LED2, LOW);
ts.add(0, 1000, [&](void *) { blink1(); }, nullptr, true);
ts.add(1, 3000, [&](void *) { blink2(); }, nullptr, true);
}
void loop() {
ts.update();
}