Sep 1, 2021 version 99 for esp32-arduino 1.0.6
rodzic
17456a1ac3
commit
7856f05a52
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,116 @@
|
|||
|
||||
/*
|
||||
* FTP SERVER FOR ESP8266
|
||||
* based on FTP Serveur for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200)
|
||||
* based on Jean-Michel Gallego's work
|
||||
* modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// 2017: modified by @robo8080
|
||||
// 2019: modified by @fa1ke5
|
||||
|
||||
/*******************************************************************************
|
||||
** **
|
||||
** DEFINITIONS FOR FTP SERVER **
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
// Uncomment to print debugging info to console attached to ESP8266
|
||||
//#define FTP_DEBUG
|
||||
|
||||
#ifndef FTP_SERVERESP_H
|
||||
#define FTP_SERVERESP_H
|
||||
|
||||
//#include "Streaming.h"
|
||||
#include "SD_MMC.h"
|
||||
#include <FS.h>
|
||||
#include <WiFiClient.h>
|
||||
|
||||
#define FTP_SERVER_VERSION "FTP-2016-01-14"
|
||||
|
||||
#define FTP_CTRL_PORT 21 // Command port on wich server is listening
|
||||
#define FTP_DATA_PORT_PASV 50009 // Data port in passive mode
|
||||
|
||||
#define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity
|
||||
#define FTP_CMD_SIZE 255 + 8 // max size of a command
|
||||
#define FTP_CWD_SIZE 255 + 8 // max size of a directory name
|
||||
#define FTP_FIL_SIZE 255 // max size of a file name
|
||||
|
||||
//#define FTP_BUF_SIZE 512 //512 // size of file buffer for read/write
|
||||
//#define FTP_BUF_SIZE 2*1460 //512 // size of file buffer for read/write
|
||||
//#define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection.
|
||||
//#define FTP_BUF_SIZE 8192 reduce in v82
|
||||
//#define FTP_BUF_SIZE 2048
|
||||
|
||||
#define FTP_BUF_SIZE 4096
|
||||
|
||||
|
||||
class FtpServer
|
||||
{
|
||||
public:
|
||||
void begin(String uname, String pword);
|
||||
void handleFTP();
|
||||
|
||||
private:
|
||||
bool haveParameter();
|
||||
bool makeExistsPath( char * path, char * param = NULL );
|
||||
void iniVariables();
|
||||
void clientConnected();
|
||||
void disconnectClient();
|
||||
boolean userIdentity();
|
||||
boolean userPassword();
|
||||
boolean processCommand();
|
||||
boolean dataConnect();
|
||||
boolean doRetrieve();
|
||||
boolean doStore();
|
||||
void closeTransfer();
|
||||
void abortTransfer();
|
||||
boolean makePath( char * fullname );
|
||||
boolean makePath( char * fullName, char * param );
|
||||
uint8_t getDateTime( uint16_t * pyear, uint8_t * pmonth, uint8_t * pday,
|
||||
uint8_t * phour, uint8_t * pminute, uint8_t * second );
|
||||
char * makeDateTimeStr( char * tstr, uint16_t date, uint16_t time );
|
||||
int8_t readChar();
|
||||
|
||||
IPAddress dataIp; // IP address of client for data
|
||||
WiFiClient client;
|
||||
WiFiClient data;
|
||||
|
||||
File file;
|
||||
|
||||
boolean dataPassiveConn;
|
||||
uint16_t dataPort;
|
||||
char buf[ FTP_BUF_SIZE ]; // data buffer for transfers
|
||||
char cmdLine[ FTP_CMD_SIZE ]; // where to store incoming char from client
|
||||
char cwdName[ FTP_CWD_SIZE ]; // name of current directory
|
||||
char command[ 5 ]; // command sent by client
|
||||
boolean rnfrCmd; // previous command was RNFR
|
||||
char * parameters; // point to begin of parameters sent by client
|
||||
uint16_t iCL; // pointer to cmdLine next incoming char
|
||||
int8_t cmdStatus, // status of ftp command connexion
|
||||
transferStatus; // status of ftp data transfer
|
||||
uint32_t millisTimeOut, // disconnect after 5 min of inactivity
|
||||
millisDelay,
|
||||
millisEndConnection, //
|
||||
millisBeginTrans, // store time of beginning of a transaction
|
||||
bytesTransfered; //
|
||||
String _FTP_USER;
|
||||
String _FTP_PASS;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // FTP_SERVERESP_H
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,952 @@
|
|||
/*
|
||||
Copyright (c) 2018 Brian Lough. All right reserved.
|
||||
|
||||
UniversalTelegramBot - Library to create your own Telegram Bot using
|
||||
ESP8266 or ESP32 on Arduino IDE.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
**** Note Regarding Client Connection Keeping ****
|
||||
Client connection is established in functions that directly involve use of
|
||||
client, i.e sendGetToTelegram, sendPostToTelegram, and
|
||||
sendMultipartFormDataToTelegram. It is closed at the end of
|
||||
sendMultipartFormDataToTelegram, but not at the end of sendGetToTelegram and
|
||||
sendPostToTelegram as these may need to keep the connection alive for respose
|
||||
/ response checking. Re-establishing a connection then wastes time which is
|
||||
noticeable in user experience. Due to this, it is important that connection
|
||||
be closed manually after calling sendGetToTelegram or sendPostToTelegram by
|
||||
calling closeClient(); Failure to close connection causes memory leakage and
|
||||
SSL errors
|
||||
*/
|
||||
|
||||
// James Zahary June 30, 2020
|
||||
// - small mods to add caption to photos, and slow down transmit to telegram
|
||||
|
||||
#include "UniversalTelegramBot.h"
|
||||
|
||||
UniversalTelegramBot::UniversalTelegramBot(String token, Client &client) {
|
||||
_token = token;
|
||||
#ifdef ARDUINO_ESP8266_RELEASE_2_5_0
|
||||
//client->setInsecure();
|
||||
#endif
|
||||
this->client = &client;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendGetToTelegram(String command) {
|
||||
String mess = "";
|
||||
long now;
|
||||
bool avail;
|
||||
|
||||
// Connect with api.telegram.org if not already connected
|
||||
if (!client->connected()) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("[BOT]Connecting to server"));
|
||||
#endif
|
||||
if (!client->connect(HOST, SSL_PORT)) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("[BOT]Conection error"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (client->connected()) {
|
||||
|
||||
#ifdef _debug
|
||||
Serial.println(F(".... connected to server"));
|
||||
#endif
|
||||
|
||||
String a = "";
|
||||
char c;
|
||||
int ch_count = 0;
|
||||
client->println("GET /" + command);
|
||||
now = millis();
|
||||
avail = false;
|
||||
while (millis() - now < longPoll * 1000 + waitForResponse) {
|
||||
while (client->available()) {
|
||||
char c = client->read();
|
||||
if (ch_count < maxMessageLength) {
|
||||
mess = mess + c;
|
||||
ch_count++;
|
||||
}
|
||||
avail = true;
|
||||
}
|
||||
if (avail) {
|
||||
#ifdef _debug
|
||||
Serial.println();
|
||||
Serial.println(mess);
|
||||
Serial.println();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mess;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendPostToTelegram(String command, JsonObject payload) {
|
||||
|
||||
String body = "";
|
||||
String headers = "";
|
||||
long now;
|
||||
bool responseReceived = false;
|
||||
|
||||
// Connect with api.telegram.org if not already connected
|
||||
if (!client->connected()) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("[BOT Client]Connecting to server"));
|
||||
#endif
|
||||
if (!client->connect(HOST, SSL_PORT)) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("[BOT Client]Conection error"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (client->connected()) {
|
||||
// POST URI
|
||||
client->print("POST /" + command);
|
||||
client->println(F(" HTTP/1.1"));
|
||||
delay(jzdelay);
|
||||
// Host header
|
||||
client->print(F("Host:"));
|
||||
client->println(HOST);
|
||||
delay(jzdelay);
|
||||
// JSON content type
|
||||
client->println(F("Content-Type: application/json"));
|
||||
delay(jzdelay);
|
||||
|
||||
// Content length
|
||||
int length = measureJson(payload);
|
||||
client->print(F("Content-Length:"));
|
||||
client->println(length);
|
||||
delay(jzdelay);
|
||||
// End of headers
|
||||
client->println();
|
||||
// POST message body
|
||||
String out;
|
||||
serializeJson(payload, out);
|
||||
|
||||
client->println(out);
|
||||
delay(jzdelay);
|
||||
|
||||
int ch_count = 0;
|
||||
now = millis();
|
||||
bool finishedHeaders = false;
|
||||
bool currentLineIsBlank = true;
|
||||
while (millis() - now < waitForResponse) {
|
||||
while (client->available()) {
|
||||
char c = client->read();
|
||||
responseReceived = true;
|
||||
|
||||
if (!finishedHeaders) {
|
||||
if (currentLineIsBlank && c == '\n') {
|
||||
finishedHeaders = true;
|
||||
} else {
|
||||
headers = headers + c;
|
||||
}
|
||||
} else {
|
||||
if (ch_count < maxMessageLength) {
|
||||
body = body + c;
|
||||
ch_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\n') currentLineIsBlank = true;
|
||||
else if (c != '\r') currentLineIsBlank = false;
|
||||
|
||||
}
|
||||
|
||||
if (responseReceived && ch_count > 5) { //jz
|
||||
#ifdef _debug
|
||||
Serial.println();
|
||||
Serial.println(body);
|
||||
Serial.println();
|
||||
#endif
|
||||
//Serial.print(millis() - now); Serial.println(" sendPostToTelegram - breaking");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendMultipartFormDataToTelegram(
|
||||
String command, String binaryProperyName, String fileName,
|
||||
String contentType, String chat_id, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback) {
|
||||
|
||||
String body = "";
|
||||
String headers = "";
|
||||
long now;
|
||||
bool responseReceived = false;
|
||||
bool finishedHeaders = false;
|
||||
bool currentLineIsBlank = true;
|
||||
|
||||
String boundry = F("------------------------b8f610217e83e29b");
|
||||
|
||||
// Connect with api.telegram.org if not already connected
|
||||
if (!client->connected()) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("[BOT Client]Connecting to server"));
|
||||
#endif
|
||||
if (!client->connect(HOST, SSL_PORT)) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("[BOT Client]Conection error"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (client->connected()) {
|
||||
|
||||
String start_request = "";
|
||||
String end_request = "";
|
||||
|
||||
start_request = start_request + "--" + boundry + "\r\n";
|
||||
start_request = start_request + "content-disposition: form-data; name=\"chat_id\"" + "\r\n";
|
||||
start_request = start_request + "\r\n";
|
||||
start_request = start_request + chat_id + "\r\n";
|
||||
|
||||
start_request = start_request + "--" + boundry + "\r\n";
|
||||
start_request = start_request + "content-disposition: form-data; name=\"caption\"" + "\r\n";
|
||||
start_request = start_request + "\r\n";
|
||||
start_request = start_request + "caption here!" + "\r\n";
|
||||
|
||||
start_request = start_request + "--" + boundry + "\r\n";
|
||||
start_request = start_request + "content-disposition: form-data; name=\"" + binaryProperyName + "\"; filename=\"" + fileName + "\"" + "\r\n";
|
||||
|
||||
start_request = start_request + "Content-Type: " + contentType + "\r\n";
|
||||
start_request = start_request + "\r\n";
|
||||
|
||||
end_request = end_request + "\r\n";
|
||||
end_request = end_request + "--" + boundry + "--" + "\r\n";
|
||||
|
||||
client->print("POST /bot" + _token + "/" + command);
|
||||
client->println(F(" HTTP/1.1"));
|
||||
// Host header
|
||||
client->print(F("Host: "));
|
||||
client->println(HOST);
|
||||
client->println(F("User-Agent: arduino/1.0"));
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
client->println(F("Accept: */*"));
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
|
||||
int contentLength = fileSize + start_request.length() + end_request.length();
|
||||
#ifdef _debug
|
||||
Serial.println("Content-Length: " + String(contentLength));
|
||||
#endif
|
||||
client->print("Content-Length: ");
|
||||
client->println(String(contentLength));
|
||||
client->println("Content-Type: multipart/form-data; boundary=" + boundry);
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
client->println(); //v99 - ssl not happy
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
client->print(start_request);
|
||||
Serial.print("Start request: " + start_request);
|
||||
#ifdef _debug
|
||||
Serial.print("Start request: " + start_request);
|
||||
#endif
|
||||
|
||||
if (getNextByteCallback == nullptr) {
|
||||
while (moreDataAvailableCallback()) {
|
||||
client->write((const uint8_t *)getNextBufferCallback(), getNextBufferLenCallback());
|
||||
#ifdef _debug
|
||||
Serial.println(F("Sending photo from buffer"));
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#ifdef _debug
|
||||
Serial.println(F("Sending photo by binary"));
|
||||
#endif
|
||||
byte buffer[jzblocksize]; //jz 512
|
||||
int count = 0;
|
||||
char ch;
|
||||
while (moreDataAvailableCallback()) {
|
||||
buffer[count] = getNextByteCallback();
|
||||
count++;
|
||||
if (count == jzblocksize) { //jz 512
|
||||
// yield();
|
||||
#ifdef _debug
|
||||
//Serial.println(F("Sending binary photo full buffer"));
|
||||
#endif
|
||||
client->write((const uint8_t *)buffer, jzblocksize); //jz 512
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("Sending binary photo remaining buffer"));
|
||||
#endif
|
||||
client->write((const uint8_t *)buffer, count);
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
}
|
||||
}
|
||||
|
||||
client->print(end_request);
|
||||
//#ifdef _debug
|
||||
Serial.print("End request: " + end_request);
|
||||
//#endif
|
||||
|
||||
Serial.print("... Done Sending. Client.Available = "); Serial.println(client->available());
|
||||
delay(2000);
|
||||
Serial.print("... 2 secs later. Client.Available = "); Serial.println(client->available());
|
||||
|
||||
int ch_count = 0;
|
||||
now = millis();
|
||||
|
||||
while (millis() - now < waitForResponse) {
|
||||
while (client->available()) {
|
||||
char c = client->read();
|
||||
responseReceived = true;
|
||||
|
||||
if (!finishedHeaders) {
|
||||
if (currentLineIsBlank && c == '\n') {
|
||||
finishedHeaders = true;
|
||||
} else {
|
||||
headers = headers + c;
|
||||
}
|
||||
} else {
|
||||
if (ch_count < maxMessageLength) {
|
||||
body = body + c;
|
||||
ch_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\n') currentLineIsBlank = true;
|
||||
else if (c != '\r') currentLineIsBlank = false;
|
||||
}
|
||||
|
||||
if (responseReceived && ch_count > 5) { //jz && ch_count > 5
|
||||
#ifdef _debug
|
||||
Serial.println();
|
||||
Serial.println(body);
|
||||
Serial.println();
|
||||
#endif
|
||||
//Serial.print(millis() - now); Serial.println(" sendMultipartFormDataToTelegram - breaking");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return body;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendMultipartFormDataToTelegramWithCaption(
|
||||
String command, String binaryProperyName, String fileName,
|
||||
String contentType, String caption, String chat_id, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback) {
|
||||
|
||||
String body = "";
|
||||
String headers = "";
|
||||
long now;
|
||||
bool responseReceived = false;
|
||||
bool finishedHeaders = false;
|
||||
bool currentLineIsBlank = true;
|
||||
|
||||
String boundry = F("------------------------b8f610217e83e29b");
|
||||
|
||||
// Connect with api.telegram.org if not already connected
|
||||
if (!client->connected()) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("[BOT Client]Connecting to server"));
|
||||
#endif
|
||||
if (!client->connect(HOST, SSL_PORT)) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("[BOT Client]Conection error"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (client->connected()) {
|
||||
|
||||
String start_request = "";
|
||||
String end_request = "";
|
||||
|
||||
|
||||
//Serial.print("Start: "); Serial.println(ESP.getFreeHeap());
|
||||
|
||||
start_request = start_request + "--" + boundry + "\r\n";
|
||||
start_request = start_request + "content-disposition: form-data; name=\"chat_id\"" + "\r\n";
|
||||
start_request = start_request + "\r\n";
|
||||
start_request = start_request + chat_id + "\r\n";
|
||||
|
||||
start_request = start_request + "--" + boundry + "\r\n"; //jz caption stuff
|
||||
start_request = start_request + "content-disposition: form-data; name=\"caption\"" + "\r\n";
|
||||
start_request = start_request + "\r\n";
|
||||
start_request = start_request + caption + "\r\n";
|
||||
|
||||
start_request = start_request + "--" + boundry + "\r\n";
|
||||
start_request = start_request + "content-disposition: form-data; name=\"" + binaryProperyName + "\"; filename=\"" + fileName + "\"" + "\r\n";
|
||||
|
||||
start_request = start_request + "Content-Type: " + contentType + "\r\n";
|
||||
start_request = start_request + "\r\n";
|
||||
|
||||
end_request = end_request + "\r\n";
|
||||
end_request = end_request + "--" + boundry + "--" + "\r\n";
|
||||
|
||||
client->print("POST /bot" + _token + "/" + command);
|
||||
client->println(F(" HTTP/1.1"));
|
||||
// Host header
|
||||
client->print(F("Host: "));
|
||||
client->println(HOST);
|
||||
client->println(F("User-Agent: arduino/1.0"));
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
client->println(F("Accept: */*"));
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
|
||||
int contentLength = fileSize + start_request.length() + end_request.length();
|
||||
#ifdef _debug
|
||||
Serial.println("Content-Length: " + String(contentLength));
|
||||
#endif
|
||||
client->print("Content-Length: ");
|
||||
client->println(String(contentLength));
|
||||
client->println("Content-Type: multipart/form-data; boundary=" + boundry);
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
client->println(); //v99
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
client->print(start_request);
|
||||
|
||||
#ifdef _debug
|
||||
Serial.print("Start request: " + start_request);
|
||||
#endif
|
||||
|
||||
//Serial.print("End: "); Serial.println(ESP.getFreeHeap());
|
||||
|
||||
if (getNextByteCallback == nullptr) {
|
||||
while (moreDataAvailableCallback()) {
|
||||
client->write((const uint8_t *)getNextBufferCallback(), getNextBufferLenCallback());
|
||||
#ifdef _debug
|
||||
Serial.println(F("Sending photo from buffer"));
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#ifdef _debug
|
||||
Serial.println(F("Sending photo by binary"));
|
||||
#endif
|
||||
byte buffer[jzblocksize];
|
||||
int count = 0;
|
||||
char ch;
|
||||
while (moreDataAvailableCallback()) {
|
||||
buffer[count] = getNextByteCallback();
|
||||
count++;
|
||||
if (count == jzblocksize) {
|
||||
// yield();
|
||||
#ifdef _debug
|
||||
//Serial.println(F("Sending binary photo full buffer"));
|
||||
#endif
|
||||
client->write((const uint8_t *)buffer, jzblocksize);
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("Sending binary photo remaining buffer"));
|
||||
#endif
|
||||
client->write((const uint8_t *)buffer, count);
|
||||
Serial.print("*") ; delay(jzdelay); //jz
|
||||
}
|
||||
}
|
||||
|
||||
client->print(end_request);
|
||||
#ifdef _debug
|
||||
Serial.print("End request: " + end_request);
|
||||
|
||||
Serial.print("... Done Sending. Client.Available = "); Serial.println(client->available());
|
||||
delay(2000);
|
||||
Serial.print("... 2 secs later. Client.Available = "); Serial.println(client->available());
|
||||
#endif
|
||||
|
||||
int ch_count = 0;
|
||||
now = millis();
|
||||
|
||||
while (millis() - now < waitForResponse) {
|
||||
while (client->available()) {
|
||||
char c = client->read();
|
||||
responseReceived = true;
|
||||
|
||||
if (!finishedHeaders) {
|
||||
if (currentLineIsBlank && c == '\n') {
|
||||
finishedHeaders = true;
|
||||
} else {
|
||||
headers = headers + c;
|
||||
}
|
||||
} else {
|
||||
if (ch_count < maxMessageLength) {
|
||||
body = body + c;
|
||||
ch_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\n') currentLineIsBlank = true;
|
||||
else if (c != '\r') currentLineIsBlank = false;
|
||||
}
|
||||
|
||||
if (responseReceived && ch_count > 5) { //jz && ch_count > 5
|
||||
#ifdef _debug
|
||||
Serial.println();
|
||||
Serial.println(body);
|
||||
Serial.println();
|
||||
#endif
|
||||
//Serial.print(millis() - now); Serial.println(" sendMultipartFormDataToTelegram - breaking");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return body;
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::getMe() {
|
||||
String command = "bot" + _token + "/getMe";
|
||||
String response = sendGetToTelegram(command); // receive reply from telegram.org
|
||||
DynamicJsonDocument doc(maxMessageLength);
|
||||
DeserializationError error = deserializeJson(doc, response);
|
||||
JsonObject obj = doc.as<JsonObject>(); //there is nothing better right now to use obj.containsKey("result")
|
||||
closeClient();
|
||||
|
||||
if (!error) {
|
||||
if (obj.containsKey("result")) {
|
||||
String _name = doc["result"]["first_name"];
|
||||
String _username = doc["result"]["username"];
|
||||
name = _name;
|
||||
userName = _username;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
GetUpdates - function to receive messages from telegram
|
||||
(Argument to pass: the last+1 message to read)
|
||||
Returns the number of new messages
|
||||
***************************************************************/
|
||||
int UniversalTelegramBot::getUpdates(long offset) {
|
||||
|
||||
#ifdef _debug
|
||||
Serial.println(F("GET Update Messages"));
|
||||
#endif
|
||||
String command = "bot" + _token + "/getUpdates?offset=" + String(offset) + "&limit=" + String(HANDLE_MESSAGES);
|
||||
if (longPoll > 0) {
|
||||
command = command + "&timeout=" + String(longPoll);
|
||||
}
|
||||
String response = sendGetToTelegram(command); // receive reply from telegram.org
|
||||
|
||||
if (response == "") {
|
||||
#ifdef _debug
|
||||
Serial.println(F("Received empty string in response!"));
|
||||
#endif
|
||||
// close the client as there's nothing to do with an empty string
|
||||
closeClient();
|
||||
return 0;
|
||||
} else {
|
||||
#ifdef _debug
|
||||
Serial.print(F("incoming message length "));
|
||||
Serial.println(response.length());
|
||||
Serial.println(F("Creating DynamicJsonBuffer"));
|
||||
#endif
|
||||
|
||||
// Parse response into Json object
|
||||
DynamicJsonDocument doc(maxMessageLength);
|
||||
DeserializationError error = deserializeJson(doc, response);
|
||||
#ifdef _debug
|
||||
Serial.print(F("GetUpdates parsed jsonDoc: "));
|
||||
serializeJson(doc, Serial);
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
JsonObject obj = doc.as<JsonObject>(); //there is nothing better right now
|
||||
if (!error) {
|
||||
#ifdef _debug
|
||||
Serial.print(F("GetUpdates parsed jsonObj: "));
|
||||
serializeJson(obj, Serial);
|
||||
Serial.println();
|
||||
#endif
|
||||
if (obj.containsKey("result")) {
|
||||
int resultArrayLength = doc["result"].size();
|
||||
if (resultArrayLength > 0) {
|
||||
int newMessageIndex = 0;
|
||||
// Step through all results
|
||||
for (int i = 0; i < resultArrayLength; i++) {
|
||||
JsonObject result = doc["result"][i];
|
||||
if (processResult(result, newMessageIndex)) newMessageIndex++;
|
||||
}
|
||||
// We will keep the client open because there may be a response to be
|
||||
// given
|
||||
return newMessageIndex;
|
||||
} else {
|
||||
#ifdef _debug
|
||||
Serial.println(F("no new messages"));
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#ifdef _debug
|
||||
Serial.println(F("Response contained no 'result'"));
|
||||
#endif
|
||||
}
|
||||
} else { // Parsing failed
|
||||
if (response.length() < 2) { // Too short a message. Maybe a connection issue
|
||||
#ifdef _debug
|
||||
Serial.println(F("Parsing error: Message too short"));
|
||||
#endif
|
||||
} else {
|
||||
// Buffer may not be big enough, increase buffer or reduce max number of
|
||||
// messages
|
||||
#ifdef _debug
|
||||
Serial.print(F("Failed to parse update, the message could be too "
|
||||
"big for the buffer. Error code: "));
|
||||
Serial.println(error.c_str()); // debug print of parsing error
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// Close the client as no response is to be given
|
||||
closeClient();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::processResult(JsonObject result, int messageIndex) {
|
||||
int update_id = result["update_id"];
|
||||
// Check have we already dealt with this message (this shouldn't happen!)
|
||||
if (last_message_received != update_id) {
|
||||
last_message_received = update_id;
|
||||
messages[messageIndex].update_id = update_id;
|
||||
messages[messageIndex].text = F("");
|
||||
messages[messageIndex].from_id = F("");
|
||||
messages[messageIndex].from_name = F("");
|
||||
messages[messageIndex].longitude = 0;
|
||||
messages[messageIndex].latitude = 0;
|
||||
|
||||
if (result.containsKey("message")) {
|
||||
JsonObject message = result["message"];
|
||||
messages[messageIndex].type = F("message");
|
||||
messages[messageIndex].from_id = message["from"]["id"].as<String>();
|
||||
messages[messageIndex].from_name = message["from"]["first_name"].as<String>();
|
||||
messages[messageIndex].date = message["date"].as<String>();
|
||||
messages[messageIndex].chat_id = message["chat"]["id"].as<String>();
|
||||
messages[messageIndex].chat_title = message["chat"]["title"].as<String>();
|
||||
|
||||
if (message.containsKey("text")) {
|
||||
messages[messageIndex].text = message["text"].as<String>();
|
||||
|
||||
} else if (message.containsKey("location")) {
|
||||
messages[messageIndex].longitude = message["location"]["longitude"].as<float>();
|
||||
messages[messageIndex].latitude = message["location"]["latitude"].as<float>();
|
||||
}
|
||||
} else if (result.containsKey("channel_post")) {
|
||||
JsonObject message = result["channel_post"];
|
||||
messages[messageIndex].type = F("channel_post");
|
||||
messages[messageIndex].text = message["text"].as<String>();
|
||||
messages[messageIndex].date = message["date"].as<String>();
|
||||
messages[messageIndex].chat_id = message["chat"]["id"].as<String>();
|
||||
messages[messageIndex].chat_title = message["chat"]["title"].as<String>();
|
||||
|
||||
} else if (result.containsKey("callback_query")) {
|
||||
JsonObject message = result["callback_query"];
|
||||
messages[messageIndex].type = F("callback_query");
|
||||
messages[messageIndex].from_id = message["from"]["id"].as<String>();
|
||||
messages[messageIndex].from_name = message["from"]["first_name"].as<String>();
|
||||
messages[messageIndex].text = message["data"].as<String>();
|
||||
messages[messageIndex].date = message["date"].as<String>();
|
||||
messages[messageIndex].chat_id = message["message"]["chat"]["id"].as<String>();
|
||||
messages[messageIndex].chat_title = F("");
|
||||
|
||||
} else if (result.containsKey("edited_message")) {
|
||||
JsonObject message = result["edited_message"];
|
||||
messages[messageIndex].type = F("edited_message");
|
||||
messages[messageIndex].from_id = message["from"]["id"].as<String>();
|
||||
messages[messageIndex].from_name = message["from"]["first_name"].as<String>();
|
||||
messages[messageIndex].date = message["date"].as<String>();
|
||||
messages[messageIndex].chat_id = message["chat"]["id"].as<String>();
|
||||
messages[messageIndex].chat_title = message["chat"]["title"].as<String>();
|
||||
|
||||
if (message.containsKey("text")) {
|
||||
messages[messageIndex].text = message["text"].as<String>();
|
||||
|
||||
} else if (message.containsKey("location")) {
|
||||
messages[messageIndex].longitude = message["location"]["longitude"].as<float>();
|
||||
messages[messageIndex].latitude = message["location"]["latitude"].as<float>();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
SendMessage - function to send message to telegram
|
||||
(Arguments to pass: chat_id, text to transmit and markup(optional))
|
||||
***********************************************************************/
|
||||
bool UniversalTelegramBot::sendSimpleMessage(String chat_id, String text,
|
||||
String parse_mode) {
|
||||
|
||||
bool sent = false;
|
||||
#ifdef _debug
|
||||
Serial.println(F("sendSimpleMessage: SEND Simple Message"));
|
||||
#endif
|
||||
long sttime = millis();
|
||||
|
||||
if (text != "") {
|
||||
while (millis() < sttime + 8000) { // loop for a while to send the message
|
||||
String command = "bot" + _token + "/sendMessage?chat_id=" + chat_id +
|
||||
"&text=" + text + "&parse_mode=" + parse_mode;
|
||||
String response = sendGetToTelegram(command);
|
||||
#ifdef _debug
|
||||
Serial.println(response);
|
||||
#endif
|
||||
sent = checkForOkResponse(response);
|
||||
if (sent) break;
|
||||
}
|
||||
}
|
||||
closeClient();
|
||||
return sent;
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::sendMessage(String chat_id, String text,
|
||||
String parse_mode) {
|
||||
|
||||
DynamicJsonDocument payload(maxMessageLength);
|
||||
payload["chat_id"] = chat_id;
|
||||
payload["text"] = text;
|
||||
|
||||
if (parse_mode != "")
|
||||
payload["parse_mode"] = parse_mode;
|
||||
|
||||
return sendPostMessage(payload.as<JsonObject>());
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::sendMessageWithReplyKeyboard(
|
||||
String chat_id, String text, String parse_mode, String keyboard,
|
||||
bool resize, bool oneTime, bool selective) {
|
||||
|
||||
DynamicJsonDocument payload(maxMessageLength);
|
||||
payload["chat_id"] = chat_id;
|
||||
payload["text"] = text;
|
||||
|
||||
if (parse_mode != "")
|
||||
payload["parse_mode"] = parse_mode;
|
||||
|
||||
JsonObject replyMarkup = payload.createNestedObject("reply_markup");
|
||||
|
||||
// Reply keyboard is an array of arrays.
|
||||
// Outer array represents rows
|
||||
// Inner arrays represents columns
|
||||
// This example "ledon" and "ledoff" are two buttons on the top row
|
||||
// and "status is a single button on the next row"
|
||||
DynamicJsonDocument keyboardBuffer(maxMessageLength); // creating a buffer enough to keep keyboard string
|
||||
deserializeJson(keyboardBuffer, keyboard);
|
||||
replyMarkup["keyboard"] = keyboardBuffer.as<JsonArray>();
|
||||
|
||||
// Telegram defaults these values to false, so to decrease the size of the
|
||||
// payload we will only send them if needed
|
||||
if (resize)
|
||||
replyMarkup["resize_keyboard"] = resize;
|
||||
|
||||
if (oneTime)
|
||||
replyMarkup["one_time_keyboard"] = oneTime;
|
||||
|
||||
if (selective)
|
||||
replyMarkup["selective"] = selective;
|
||||
|
||||
return sendPostMessage(payload.as<JsonObject>());
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::sendMessageWithInlineKeyboard(String chat_id,
|
||||
String text,
|
||||
String parse_mode,
|
||||
String keyboard) {
|
||||
|
||||
DynamicJsonDocument payload(maxMessageLength);
|
||||
payload["chat_id"] = chat_id;
|
||||
payload["text"] = text;
|
||||
|
||||
if (parse_mode != "")
|
||||
payload["parse_mode"] = parse_mode;
|
||||
|
||||
JsonObject replyMarkup = payload.createNestedObject("reply_markup");
|
||||
DynamicJsonDocument keyboardBuffer(maxMessageLength); // assuming keyboard buffer will alwas be limited to 1024 bytes
|
||||
deserializeJson(keyboardBuffer, keyboard);
|
||||
replyMarkup["inline_keyboard"] = keyboardBuffer.as<JsonArray>();
|
||||
return sendPostMessage(payload.as<JsonObject>());
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
SendPostMessage - function to send message to telegram
|
||||
(Arguments to pass: chat_id, text to transmit and markup(optional))
|
||||
***********************************************************************/
|
||||
bool UniversalTelegramBot::sendPostMessage(JsonObject payload) {
|
||||
|
||||
bool sent = false;
|
||||
#ifdef _debug
|
||||
Serial.print(F("sendPostMessage: SEND Post Message: "));
|
||||
serializeJson(payload, Serial);
|
||||
Serial.println();
|
||||
#endif
|
||||
long sttime = millis();
|
||||
|
||||
if (payload.containsKey("text")) {
|
||||
while (millis() < sttime + 8000) { // loop for a while to send the message
|
||||
String command = "bot" + _token + "/sendMessage";
|
||||
String response = sendPostToTelegram(command, payload);
|
||||
#ifdef _debug
|
||||
Serial.println(response);
|
||||
#endif
|
||||
sent = checkForOkResponse(response);
|
||||
if (sent) break;
|
||||
}
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return sent;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendPostPhoto(JsonObject payload) {
|
||||
|
||||
bool sent = false;
|
||||
String response = "";
|
||||
#ifdef _debug
|
||||
Serial.println(F("sendPostPhoto: SEND Post Photo"));
|
||||
#endif
|
||||
long sttime = millis();
|
||||
|
||||
if (payload.containsKey("photo")) {
|
||||
while (millis() < sttime + 8000) { // loop for a while to send the message
|
||||
String command = "bot" + _token + "/sendPhoto";
|
||||
response = sendPostToTelegram(command, payload);
|
||||
#ifdef _debug
|
||||
Serial.println(response);
|
||||
#endif
|
||||
sent = checkForOkResponse(response);
|
||||
if (sent) break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return response;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendPhotoByBinary(
|
||||
String chat_id, String contentType, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback, GetNextBuffer getNextBufferCallback, GetNextBufferLen getNextBufferLenCallback) {
|
||||
|
||||
#ifdef _debug
|
||||
Serial.println(F("sendPhotoByBinary: SEND Photo"));
|
||||
#endif
|
||||
|
||||
String response = sendMultipartFormDataToTelegram("sendPhoto", "photo", "img.jpg",
|
||||
contentType, chat_id, fileSize,
|
||||
moreDataAvailableCallback, getNextByteCallback, getNextBufferCallback, getNextBufferLenCallback);
|
||||
|
||||
#ifdef _debug
|
||||
Serial.println(response);
|
||||
#endif
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
|
||||
String UniversalTelegramBot::sendPhoto(String chat_id, String photo,
|
||||
String caption,
|
||||
bool disable_notification,
|
||||
int reply_to_message_id,
|
||||
String keyboard) {
|
||||
|
||||
DynamicJsonDocument payload(maxMessageLength);
|
||||
payload["chat_id"] = chat_id;
|
||||
payload["photo"] = photo;
|
||||
|
||||
if (caption)
|
||||
payload["caption"] = caption;
|
||||
|
||||
if (disable_notification)
|
||||
payload["disable_notification"] = disable_notification;
|
||||
|
||||
if (reply_to_message_id && reply_to_message_id != 0)
|
||||
payload["reply_to_message_id"] = reply_to_message_id;
|
||||
|
||||
if (keyboard) {
|
||||
JsonObject replyMarkup = payload.createNestedObject("reply_markup");
|
||||
DynamicJsonDocument keyboardBuffer(maxMessageLength); // assuming keyboard buffer will alwas be limited to 1024 bytes
|
||||
deserializeJson(keyboardBuffer, keyboard);
|
||||
replyMarkup["keyboard"] = keyboardBuffer.as<JsonArray>();
|
||||
}
|
||||
|
||||
return sendPostPhoto(payload.as<JsonObject>());
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::checkForOkResponse(String response) {
|
||||
int responseLength = response.length();
|
||||
|
||||
for (int m = 5; m < responseLength + 1; m++) {
|
||||
if (response.substring(m - 10, m) ==
|
||||
"{\"ok\":true") { // Chek if message has been properly sent
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::sendChatAction(String chat_id, String text) {
|
||||
|
||||
bool sent = false;
|
||||
#ifdef _debug
|
||||
Serial.println(F("SEND Chat Action Message"));
|
||||
#endif
|
||||
long sttime = millis();
|
||||
|
||||
if (text != "") {
|
||||
while (millis() < sttime + 8000) { // loop for a while to send the message
|
||||
String command = "bot" + _token + "/sendChatAction?chat_id=" + chat_id +
|
||||
"&action=" + text;
|
||||
String response = sendGetToTelegram(command);
|
||||
|
||||
#ifdef _debug
|
||||
Serial.println(response);
|
||||
#endif
|
||||
sent = checkForOkResponse(response);
|
||||
|
||||
if (sent) break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return sent;
|
||||
}
|
||||
|
||||
void UniversalTelegramBot::closeClient() {
|
||||
if (client->connected()) {
|
||||
#ifdef _debug
|
||||
Serial.println(F("Closing client"));
|
||||
#endif
|
||||
client->stop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
Copyright (c) 2018 Brian Lough. All right reserved.
|
||||
|
||||
UniversalTelegramBot - Library to create your own Telegram Bot using
|
||||
ESP8266 or ESP32 on Arduino IDE.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef UniversalTelegramBot_h
|
||||
#define UniversalTelegramBot_h
|
||||
|
||||
#define ARDUINOJSON_DECODE_UNICODE 1
|
||||
#define ARDUINOJSON_USE_LONG_LONG 1
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <Client.h>
|
||||
#include <core_version.h>
|
||||
|
||||
#define HOST "api.telegram.org"
|
||||
#define SSL_PORT 443
|
||||
#define HANDLE_MESSAGES 1
|
||||
|
||||
//unmark following line to enable debug mode
|
||||
//#define _debug
|
||||
|
||||
typedef bool (*MoreDataAvailable)();
|
||||
typedef byte (*GetNextByte)();
|
||||
typedef byte* (*GetNextBuffer)();
|
||||
typedef int (GetNextBufferLen)();
|
||||
|
||||
struct telegramMessage {
|
||||
String text;
|
||||
String chat_id;
|
||||
String chat_title;
|
||||
String from_id;
|
||||
String from_name;
|
||||
String date;
|
||||
String type;
|
||||
float longitude;
|
||||
float latitude;
|
||||
int update_id;
|
||||
};
|
||||
|
||||
class UniversalTelegramBot {
|
||||
public:
|
||||
UniversalTelegramBot(String token, Client &client);
|
||||
String sendGetToTelegram(String command);
|
||||
String sendPostToTelegram(String command, JsonObject payload);
|
||||
String
|
||||
sendMultipartFormDataToTelegram(String command, String binaryProperyName,
|
||||
String fileName, String contentType,
|
||||
String chat_id, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback);
|
||||
|
||||
String
|
||||
sendMultipartFormDataToTelegramWithCaption(String command, String binaryProperyName,
|
||||
String fileName, String contentType,
|
||||
String caption, String chat_id, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback);
|
||||
|
||||
|
||||
bool getMe();
|
||||
|
||||
bool sendSimpleMessage(String chat_id, String text, String parse_mode);
|
||||
bool sendMessage(String chat_id, String text, String parse_mode = "");
|
||||
bool sendMessageWithReplyKeyboard(String chat_id, String text,
|
||||
String parse_mode, String keyboard,
|
||||
bool resize = false, bool oneTime = false,
|
||||
bool selective = false);
|
||||
bool sendMessageWithInlineKeyboard(String chat_id, String text,
|
||||
String parse_mode, String keyboard);
|
||||
|
||||
bool sendChatAction(String chat_id, String text);
|
||||
|
||||
bool sendPostMessage(JsonObject payload);
|
||||
String sendPostPhoto(JsonObject payload);
|
||||
String sendPhotoByBinary(String chat_id, String contentType, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback);
|
||||
String sendPhoto(String chat_id, String photo, String caption = "",
|
||||
bool disable_notification = false,
|
||||
int reply_to_message_id = 0, String keyboard = "");
|
||||
|
||||
int getUpdates(long offset);
|
||||
bool checkForOkResponse(String response);
|
||||
telegramMessage messages[HANDLE_MESSAGES];
|
||||
long last_message_received;
|
||||
String name;
|
||||
String userName;
|
||||
int longPoll = 0;
|
||||
int waitForResponse = 5000; //jz = 1500;
|
||||
int jzdelay = 10; //60; // delay between multipart blocks
|
||||
int jzblocksize = 2 * 1024; // multipart block size
|
||||
|
||||
private:
|
||||
// JsonObject * parseUpdates(String response);
|
||||
String _token;
|
||||
Client *client;
|
||||
void closeClient();
|
||||
const int maxMessageLength = 1500; //was 1500
|
||||
bool processResult(JsonObject result, int messageIndex);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,64 @@
|
|||
// ... pending inclusion in the new esp32 distribution - jz
|
||||
|
||||
// You may have to edit rtc_cntl.h ... according to this link -- doesn't seem to be included in esp32 libraries as of Jun 2020 ... or I'll just put it here
|
||||
// https://github.com/espressif/esp-idf/commit/17bd6e8faba15812780d21e6e3db08fb26dd7033#diff-5e22dcf9fc6087d1585c7b2e434c0932
|
||||
// https://github.com/espressif/esp-idf/pull/4532
|
||||
// C:\Users\James\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\driver\driver -- approximate path
|
||||
|
||||
|
||||
// Copyright 2016-2017 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Register a handler for specific RTC_CNTL interrupts
|
||||
*
|
||||
* Multiple handlers can be registered using this function. Whenever an
|
||||
* RTC interrupt happens, all handlers with matching rtc_intr_mask values
|
||||
* will be called.
|
||||
*
|
||||
* @param handler handler function to call
|
||||
* @param handler_arg argument to be passed to the handler
|
||||
* @param rtc_intr_mask combination of RTC_CNTL_*_INT_ENA bits indicating the
|
||||
* sources to call the handler for
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NO_MEM not enough memory to allocate handler structure
|
||||
* - other errors returned by esp_intr_alloc
|
||||
*/
|
||||
esp_err_t rtc_isr_register(intr_handler_t handler, void* handler_arg,
|
||||
uint32_t rtc_intr_mask);
|
||||
/**
|
||||
* @brief Deregister the handler previously registered using rtc_isr_register
|
||||
* @param handler handler function to call (as passed to rtc_isr_register)
|
||||
* @param handler_arg argument of the handler (as passed to rtc_isr_register)
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_STATE if a handler matching both handler and
|
||||
* handler_arg isn't registered
|
||||
*/
|
||||
esp_err_t rtc_isr_deregister(intr_handler_t handler, void* handler_arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,66 @@
|
|||
static const char devname[] = "desklens"; // name of your camera for mDNS, Router, and filenames
|
||||
|
||||
#define include_telegram
|
||||
//#define include_pir_and_touch
|
||||
#define include_ftp
|
||||
#define include_streaming
|
||||
#define get_rid_of_touch
|
||||
|
||||
int delete_old_files = 1; // set to 1 and it will delete your oldest day of files so you SD is always 10% empty
|
||||
|
||||
// https://sites.google.com/a/usapiens.com/opnode/time-zones -- find your timezone here
|
||||
#define TIMEZONE "GMT0BST,M3.5.0/01,M10.5.0/02" // your timezone - this is GMT
|
||||
//#define TIMEZONE "MST7MDT,M3.2.0/2:00:00,M11.1.0/2:00:00" // mountain time
|
||||
|
||||
// 1 for blink red led with every sd card write, at your frame rate
|
||||
// 0 for blink only for skipping frames and SOS if camera or sd is broken
|
||||
#define BlinkWithWrite 1
|
||||
|
||||
// EDIT ssid and password **** with Version 98x-WiFiMan, you are using WiFiManager to set ssid and password, so these are redundant
|
||||
const char* ssid = "jzjzjz";
|
||||
const char* password = "jzjzjz";
|
||||
|
||||
// reboot startup parameters here
|
||||
|
||||
int Internet_Enabled = 1; // set to 0 to shut off all internet activities - wifi, time, http, ftp, telegram
|
||||
int DeepSleepPir = 0; // set to 1 to deepsleep between pir videos
|
||||
int record_on_reboot = 1; // set to 1 to record, or 0 to NOT record on reboot
|
||||
int PIRpin = 13; // for active high pir or microwave etc
|
||||
int PIRenabled = 0; // 1 is PIR is enable on reboot, will only work if you are not recording
|
||||
|
||||
int MagicNumber = 011; // change this if you are re-compiling and you dont want to use the ESPROM settings
|
||||
int stream_interval = 333; // milliseconds between frames delivered during the live stream - 333 is 3 fps
|
||||
|
||||
// here are 2 sets of startup parameters -- more down in the stop and restart webpage
|
||||
|
||||
// VGA 10 fps for 30 minutes, and repeat, play at real time
|
||||
|
||||
int framesize = 8; // 13 UXGA, 11 HD, 9 SVGA, 8 VGA, 6 CIF
|
||||
int repeat_config = 100; // repaeat same movie this many times
|
||||
int xspeed = 1; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frame ( 30 fps / 0.1 fps )
|
||||
int gray = 0; // not gray
|
||||
int quality = 12; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping
|
||||
int capture_interval = 100; // milli-seconds between frames
|
||||
volatile int total_frames_config = 18000; // how many frames - length of movie in ms is total_frames x capture_interval
|
||||
|
||||
|
||||
// UXGA 1 frame every 10 seconds for 60 minutes, and repeat, play at 30 fps or 300 times speed
|
||||
/*
|
||||
int framesize = 13; // 13 UXGA, 11 HD, 9 SVGA, 8 VGA, 6 CIF
|
||||
int repeat_config = 300; // repaeat same movie this many times
|
||||
int xspeed = 300; // playback speed - realtime is 1, or 300 means playpack 30 fps of frames at 10 second per frames ( 30 fps / 0.1 fps )
|
||||
int gray = 0; // not gray
|
||||
int quality = 6; // quality on the 10..50 subscale - 10 is good, 20 is grainy and smaller files, 12 is better in bright sunshine due to clipping
|
||||
int capture_interval = 10000; // milli-seconds between frames
|
||||
volatile int total_frames_config = 360; // how many frames - length of movie is total_frames x capture_interval
|
||||
*/
|
||||
|
||||
// enable the www.telegram.org BOT - it sends a text and and snapshot to you every time it starts a video
|
||||
// https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot
|
||||
// I'm using the branch v1.2 from June 2020 - new master introduced late june, but not working for picture and captions, so my v1.2 mods included here
|
||||
// You need to create a bot, and get its number BOTtoken, and then get your telegram number -- all free at telegram.org
|
||||
// detailed instructions here https://randomnerdtutorials.com/telegram-control-esp32-esp8266-nodemcu-outputs/
|
||||
|
||||
RTC_DATA_ATTR int EnableBOT = 0;
|
||||
#define BOTtoken "9876543210:qwertyuiopasdfghjklzxcvbnmqwertyuio" // get your own bot and id at telegram.org
|
||||
#define BOTme "1234567890"
|
Ładowanie…
Reference in New Issue