v98x-WiFiMan - same a v98x but set ssid with WiFiManager

master
jameszah 2021-01-06 11:07:42 -07:00 zatwierdzone przez GitHub
rodzic 915af1245d
commit 96ce82ec64
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
7 zmienionych plików z 5241 dodań i 0 usunięć

Plik diff jest za duży Load Diff

Wyświetl plik

@ -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

Wyświetl plik

@ -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("");
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("");
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();
}
}

Wyświetl plik

@ -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 = 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

Wyświetl plik

@ -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

Wyświetl plik

@ -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 = 6; // 10 UXGA, 7 SVGA, 6 VGA, 5 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 = 10; // 10 UXGA, 7 SVGA, 6 VGA, 5 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"