quick mod to add the raduprv sensor control
rodzic
8d31841db8
commit
b9df4519c2
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,963 @@
|
|||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
#include "UniversalTelegramBot.h"
|
||||
|
||||
#define ZERO_COPY(STR) ((char*)STR.c_str())
|
||||
#define BOT_CMD(STR) buildCommand(F(STR))
|
||||
|
||||
UniversalTelegramBot::UniversalTelegramBot(const String& token, Client &client) {
|
||||
updateToken(token);
|
||||
this->client = &client;
|
||||
}
|
||||
|
||||
void UniversalTelegramBot::updateToken(const String& token) {
|
||||
_token = token;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::getToken() {
|
||||
return _token;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::buildCommand(const String& cmd) {
|
||||
String command;
|
||||
|
||||
command += F("bot");
|
||||
command += _token;
|
||||
command += F("/");
|
||||
command += cmd;
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendGetToTelegram(const String& command) {
|
||||
String body, headers;
|
||||
bool avail;
|
||||
|
||||
// Connect with api.telegram.org if not already connected
|
||||
if (!client->connected()) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("[BOT]Connecting to server"));
|
||||
#endif
|
||||
if (!client->connect(TELEGRAM_HOST, TELEGRAM_SSL_PORT)) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("[BOT]Conection error"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (client->connected()) {
|
||||
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println("sending: " + command);
|
||||
#endif
|
||||
|
||||
client->print(F("GET /"));
|
||||
client->print(command);
|
||||
client->println(F(" HTTP/1.1"));
|
||||
client->println(F("Host:" TELEGRAM_HOST));
|
||||
client->println(F("Accept: application/json"));
|
||||
client->println(F("Cache-Control: no-cache"));
|
||||
client->println();
|
||||
|
||||
readHTTPAnswer(body, headers);
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::readHTTPAnswer(String &body, String &headers) {
|
||||
int ch_count = 0;
|
||||
long now = millis();
|
||||
bool finishedHeaders = false;
|
||||
bool currentLineIsBlank = true;
|
||||
bool responseReceived = false;
|
||||
|
||||
while (millis() - now < longPoll * 1000 + waitForResponse) {
|
||||
while (client->available()) {
|
||||
char c = client->read();
|
||||
responseReceived = true;
|
||||
|
||||
if (!finishedHeaders) {
|
||||
if (currentLineIsBlank && c == '\n') {
|
||||
finishedHeaders = true;
|
||||
} else {
|
||||
headers += c;
|
||||
}
|
||||
} else {
|
||||
if (ch_count < maxMessageLength) {
|
||||
body += c;
|
||||
ch_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '\n') currentLineIsBlank = true;
|
||||
else if (c != '\r') currentLineIsBlank = false;
|
||||
}
|
||||
|
||||
if (responseReceived && ch_count > 5) { //jz
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.print(">");
|
||||
Serial.print(body);
|
||||
Serial.println("<");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
return responseReceived;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendPostToTelegram(const String& command, JsonObject payload) {
|
||||
|
||||
String body;
|
||||
String headers;
|
||||
|
||||
// Connect with api.telegram.org if not already connected
|
||||
if (!client->connected()) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("[BOT Client]Connecting to server"));
|
||||
#endif
|
||||
if (!client->connect(TELEGRAM_HOST, TELEGRAM_SSL_PORT)) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("[BOT Client]Conection error"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (client->connected()) {
|
||||
// POST URI
|
||||
client->print(F("POST /"));
|
||||
client->print(command);
|
||||
client->println(F(" HTTP/1.1"));
|
||||
// Host header
|
||||
client->println(F("Host:" TELEGRAM_HOST));
|
||||
// JSON content type
|
||||
client->println(F("Content-Type: application/json"));
|
||||
|
||||
// Content length
|
||||
int length = measureJson(payload);
|
||||
client->print(F("Content-Length:"));
|
||||
client->println(length);
|
||||
// End of headers
|
||||
client->println();
|
||||
// POST message body
|
||||
String out;
|
||||
serializeJson(payload, out);
|
||||
|
||||
client->println(out);
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(String("Posting:") + out);
|
||||
#endif
|
||||
|
||||
readHTTPAnswer(body, headers);
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendMultipartFormDataToTelegram(
|
||||
const String& command, const String& binaryPropertyName, const String& fileName,
|
||||
const String& contentType, const String& chat_id, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback) {
|
||||
|
||||
String body;
|
||||
String headers;
|
||||
|
||||
const String boundary = F("------------------------b8f610217e83e29b");
|
||||
|
||||
// Connect with api.telegram.org if not already connected
|
||||
if (!client->connected()) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("[BOT Client]Connecting to server"));
|
||||
#endif
|
||||
if (!client->connect(TELEGRAM_HOST, TELEGRAM_SSL_PORT)) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("[BOT Client]Conection error"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (client->connected()) {
|
||||
String start_request = "";
|
||||
String end_request = "";
|
||||
|
||||
start_request += F("--");
|
||||
start_request += boundary;
|
||||
start_request += F("\r\ncontent-disposition: form-data; name=\"chat_id\"\r\n\r\n");
|
||||
start_request += chat_id;
|
||||
start_request += F("\r\n" "--");
|
||||
start_request += boundary;
|
||||
start_request += F("\r\ncontent-disposition: form-data; name=\"");
|
||||
start_request += binaryPropertyName;
|
||||
start_request += F("\"; filename=\"");
|
||||
start_request += fileName;
|
||||
start_request += F("\"\r\n" "Content-Type: ");
|
||||
start_request += contentType;
|
||||
start_request += F("\r\n" "\r\n");
|
||||
|
||||
end_request += F("\r\n" "--");
|
||||
end_request += boundary;
|
||||
end_request += F("--" "\r\n");
|
||||
|
||||
client->print(F("POST /"));
|
||||
client->print(buildCommand(command));
|
||||
client->println(F(" HTTP/1.1"));
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
|
||||
// Host header
|
||||
client->println(F("Host: " TELEGRAM_HOST)); //jz <<<<<<<<<<<<<<<<<<<<< println !!!!!!!! >>>>>>>>>>>>>>>>>>>>
|
||||
client->println(F("User-Agent: arduino/1.0"));
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
client->println(F("Accept: */*"));
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
|
||||
int contentLength = fileSize + start_request.length() + end_request.length();
|
||||
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println("Content-Length: " + String(contentLength));
|
||||
#endif
|
||||
client->print(F("Content-Length: "));
|
||||
client->println(String(contentLength));
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
client->print(F("Content-Type: multipart/form-data; boundary="));
|
||||
client->println(boundary);
|
||||
//Serial.print(" --- bef ---") ; delay(jzdelay);
|
||||
client->println(); // client->println(F"");
|
||||
//Serial.print(" --- aft ---") ; delay(jzdelay);
|
||||
client->print(start_request);
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.print("Start request: " + start_request);
|
||||
#endif
|
||||
|
||||
if (getNextByteCallback == nullptr) {
|
||||
while (moreDataAvailableCallback()) {
|
||||
client->write((const uint8_t *)getNextBufferCallback(), getNextBufferLenCallback());
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("Sending photo from buffer"));
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#ifdef TELEGRAM_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 TELEGRAM_DEBUG
|
||||
//jz Serial.println(F("Sending binary photo full buffer"));
|
||||
#endif
|
||||
client->write((const uint8_t *)buffer, jzblocksize);
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("Sending binary photo remaining buffer"));
|
||||
#endif
|
||||
client->write((const uint8_t *)buffer, count);
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
}
|
||||
}
|
||||
|
||||
client->print(end_request);
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
|
||||
#ifdef TELEGRAM_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());
|
||||
readHTTPAnswer(body, headers);
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return body;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendMultipartFormDataToTelegramWithCaption(
|
||||
const String& command, const String& binaryPropertyName, const String& fileName,
|
||||
const String& contentType, const String& caption, const String& chat_id, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback) {
|
||||
|
||||
String body;
|
||||
String headers;
|
||||
|
||||
const String boundary = F("------------------------b8f610217e83e29b");
|
||||
|
||||
// Connect with api.telegram.org if not already connected
|
||||
if (!client->connected()) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("[BOT Client]Connecting to server"));
|
||||
#endif
|
||||
if (!client->connect(TELEGRAM_HOST, TELEGRAM_SSL_PORT)) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("[BOT Client]Conection error"));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (client->connected()) {
|
||||
String start_request = "";
|
||||
String end_request = "";
|
||||
|
||||
start_request += F("--");
|
||||
start_request += boundary;
|
||||
start_request += F("\r\ncontent-disposition: form-data; name=\"chat_id\"\r\n\r\n");
|
||||
start_request += chat_id;
|
||||
start_request += F("\r\n" "--");
|
||||
|
||||
// jz caption start
|
||||
start_request += boundary;
|
||||
start_request += F("\r\ncontent-disposition: form-data; name=\"caption\"\r\n\r\n");
|
||||
start_request += caption;
|
||||
start_request += F("\r\n" "--");
|
||||
// jz caption end
|
||||
|
||||
start_request += boundary;
|
||||
start_request += F("\r\ncontent-disposition: form-data; name=\"");
|
||||
start_request += binaryPropertyName;
|
||||
start_request += F("\"; filename=\"");
|
||||
start_request += fileName;
|
||||
start_request += F("\"\r\n" "Content-Type: ");
|
||||
start_request += contentType;
|
||||
start_request += F("\r\n" "\r\n");
|
||||
|
||||
end_request += F("\r\n" "--");
|
||||
end_request += boundary;
|
||||
end_request += F("--" "\r\n");
|
||||
|
||||
client->print(F("POST /"));
|
||||
client->print(buildCommand(command));
|
||||
client->println(F(" HTTP/1.1"));
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
|
||||
// Host header
|
||||
client->println(F("Host: " TELEGRAM_HOST)); //jz <<<<<<<<<<<<<<<<<<<<< println !!!!!!!! >>>>>>>>>>>>>>>>>>>>
|
||||
client->println(F("User-Agent: arduino/1.0"));
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
client->println(F("Accept: */*"));
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
|
||||
int contentLength = fileSize + start_request.length() + end_request.length();
|
||||
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println("Content-Length: " + String(contentLength));
|
||||
#endif
|
||||
client->print(F("Content-Length: "));
|
||||
client->println(String(contentLength));
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
client->print(F("Content-Type: multipart/form-data; boundary="));
|
||||
client->println(boundary);
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
client->println(); // client->println(F("")); <--- jz 1.05 bug
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
client->print(start_request);
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.print("Start request: " + start_request);
|
||||
#endif
|
||||
|
||||
if (getNextByteCallback == nullptr) {
|
||||
while (moreDataAvailableCallback()) {
|
||||
client->write((const uint8_t *)getNextBufferCallback(), getNextBufferLenCallback());
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("Sending photo from buffer"));
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#ifdef TELEGRAM_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 TELEGRAM_DEBUG
|
||||
//jz Serial.println(F("Sending binary photo full buffer"));
|
||||
#endif
|
||||
client->write((const uint8_t *)buffer, jzblocksize);
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("Sending binary photo remaining buffer"));
|
||||
#endif
|
||||
client->write((const uint8_t *)buffer, count);
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
}
|
||||
}
|
||||
|
||||
client->print(end_request);
|
||||
Serial.print("*") ; delay(jzdelay);
|
||||
|
||||
#ifdef TELEGRAM_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());
|
||||
readHTTPAnswer(body, headers);
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return body;
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::getMe() {
|
||||
String response = sendGetToTelegram(BOT_CMD("getMe")); // receive reply from telegram.org
|
||||
DynamicJsonDocument doc(maxMessageLength);
|
||||
DeserializationError error = deserializeJson(doc, ZERO_COPY(response));
|
||||
closeClient();
|
||||
|
||||
if (!error) {
|
||||
if (doc.containsKey("result")) {
|
||||
name = doc["result"]["first_name"].as<String>();
|
||||
userName = doc["result"]["username"].as<String>();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*********************************************************************************
|
||||
* SetMyCommands - Update the command list of the bot on the telegram server *
|
||||
* (Argument to pass: Serialied array of BotCommand) *
|
||||
* CAUTION: All commands must be lower-case *
|
||||
* Returns true, if the command list was updated successfully *
|
||||
********************************************************************************/
|
||||
bool UniversalTelegramBot::setMyCommands(const String& commandArray) {
|
||||
DynamicJsonDocument payload(maxMessageLength);
|
||||
payload["commands"] = serialized(commandArray);
|
||||
bool sent = false;
|
||||
String response = "";
|
||||
#if defined(_debug)
|
||||
Serial.println(F("sendSetMyCommands: SEND Post /setMyCommands"));
|
||||
#endif // defined(_debug)
|
||||
unsigned long sttime = millis();
|
||||
|
||||
while (millis() < sttime + 8000ul) { // loop for a while to send the message
|
||||
response = sendPostToTelegram(BOT_CMD("setMyCommands"), payload.as<JsonObject>());
|
||||
#ifdef _debug
|
||||
Serial.println("setMyCommands response" + response);
|
||||
#endif
|
||||
sent = checkForOkResponse(response);
|
||||
if (sent) break;
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return sent;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* 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 TELEGRAM_DEBUG
|
||||
Serial.println(F("GET Update Messages"));
|
||||
#endif
|
||||
String command = BOT_CMD("getUpdates?offset=");
|
||||
command += offset;
|
||||
command += F("&limit=");
|
||||
command += HANDLE_MESSAGES;
|
||||
|
||||
if (longPoll > 0) {
|
||||
command += F("&timeout=");
|
||||
command += String(longPoll);
|
||||
}
|
||||
String response = sendGetToTelegram(command); // receive reply from telegram.org
|
||||
|
||||
if (response == "") {
|
||||
#ifdef TELEGRAM_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 TELEGRAM_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, ZERO_COPY(response));
|
||||
|
||||
if (!error) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.print(F("GetUpdates parsed jsonObj: "));
|
||||
serializeJson(doc, Serial);
|
||||
Serial.println();
|
||||
#endif
|
||||
if (doc.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 TELEGRAM_DEBUG
|
||||
Serial.println(F("no new messages"));
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#ifdef TELEGRAM_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 TELEGRAM_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 TELEGRAM_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;
|
||||
messages[messageIndex].reply_to_message_id = 0;
|
||||
messages[messageIndex].reply_to_text = F("");
|
||||
messages[messageIndex].query_id = F("");
|
||||
|
||||
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>();
|
||||
messages[messageIndex].hasDocument = false;
|
||||
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 (message.containsKey("document")) {
|
||||
String file_id = message["document"]["file_id"].as<String>();
|
||||
messages[messageIndex].file_caption = message["caption"].as<String>();
|
||||
messages[messageIndex].file_name = message["document"]["file_name"].as<String>();
|
||||
if (getFile(messages[messageIndex].file_path, messages[messageIndex].file_size, file_id) == true)
|
||||
messages[messageIndex].hasDocument = true;
|
||||
else
|
||||
messages[messageIndex].hasDocument = false;
|
||||
}
|
||||
if (message.containsKey("reply_to_message")) {
|
||||
messages[messageIndex].reply_to_message_id = message["reply_to_message"]["message_id"];
|
||||
// no need to check if containsKey["text"]. If it doesn't, it default to null
|
||||
messages[messageIndex].reply_to_text = message["reply_to_message"]["text"].as<String>();
|
||||
}
|
||||
} 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].reply_to_text = message["message"]["text"].as<String>();
|
||||
messages[messageIndex].chat_title = F("");
|
||||
messages[messageIndex].query_id = message["id"].as<String>();
|
||||
} 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(const String& chat_id, const String& text,
|
||||
const String& parse_mode) {
|
||||
|
||||
bool sent = false;
|
||||
#ifdef TELEGRAM_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_CMD("sendMessage?chat_id=");
|
||||
command += chat_id;
|
||||
command += F("&text=");
|
||||
command += text;
|
||||
command += F("&parse_mode=");
|
||||
command += parse_mode;
|
||||
String response = sendGetToTelegram(command);
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(response);
|
||||
#endif
|
||||
sent = checkForOkResponse(response);
|
||||
if (sent) break;
|
||||
}
|
||||
}
|
||||
closeClient();
|
||||
return sent;
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::sendMessage(const String& chat_id, const String& text,
|
||||
const 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(
|
||||
const String& chat_id, const String& text, const String& parse_mode, const 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");
|
||||
|
||||
replyMarkup["keyboard"] = serialized(keyboard);
|
||||
|
||||
// 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(const String& chat_id,
|
||||
const String& text,
|
||||
const String& parse_mode,
|
||||
const 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");
|
||||
replyMarkup["inline_keyboard"] = serialized(keyboard);
|
||||
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 TELEGRAM_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 response = sendPostToTelegram(BOT_CMD("sendMessage"), payload);
|
||||
#ifdef TELEGRAM_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 TELEGRAM_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
|
||||
response = sendPostToTelegram(BOT_CMD("sendPhoto"), payload);
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(response);
|
||||
#endif
|
||||
sent = checkForOkResponse(response);
|
||||
if (sent) break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return response;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendPhotoByBinary(
|
||||
const String& chat_id, const String& contentType, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback, GetNextBuffer getNextBufferCallback, GetNextBufferLen getNextBufferLenCallback) {
|
||||
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("sendPhotoByBinary: SEND Photo"));
|
||||
#endif
|
||||
|
||||
String response = sendMultipartFormDataToTelegram("sendPhoto", "photo", "img.jpg",
|
||||
contentType, chat_id, fileSize,
|
||||
moreDataAvailableCallback, getNextByteCallback, getNextBufferCallback, getNextBufferLenCallback);
|
||||
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(response);
|
||||
#endif
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
String UniversalTelegramBot::sendPhoto(const String& chat_id, const String& photo,
|
||||
const String& caption,
|
||||
bool disable_notification,
|
||||
int reply_to_message_id,
|
||||
const String& keyboard) {
|
||||
|
||||
DynamicJsonDocument payload(maxMessageLength);
|
||||
payload["chat_id"] = chat_id;
|
||||
payload["photo"] = photo;
|
||||
|
||||
if (caption.length() > 0)
|
||||
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.length() > 0) {
|
||||
JsonObject replyMarkup = payload.createNestedObject("reply_markup");
|
||||
replyMarkup["keyboard"] = serialized(keyboard);
|
||||
}
|
||||
|
||||
return sendPostPhoto(payload.as<JsonObject>());
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::checkForOkResponse(const String& response) {
|
||||
int last_id;
|
||||
DynamicJsonDocument doc(response.length());
|
||||
deserializeJson(doc, response);
|
||||
|
||||
// Save last sent message_id
|
||||
last_id = doc["result"]["message_id"];
|
||||
if (last_id > 0) last_sent_message_id = last_id;
|
||||
|
||||
return doc["ok"] | false; // default is false, but this is more explicit and clear
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::sendChatAction(const String& chat_id, const String& text) {
|
||||
|
||||
bool sent = false;
|
||||
#ifdef TELEGRAM_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_CMD("sendChatAction?chat_id=");
|
||||
command += chat_id;
|
||||
command += F("&action=");
|
||||
command += text;
|
||||
|
||||
String response = sendGetToTelegram(command);
|
||||
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(response);
|
||||
#endif
|
||||
sent = checkForOkResponse(response);
|
||||
|
||||
if (sent) break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
closeClient();
|
||||
return sent;
|
||||
}
|
||||
|
||||
void UniversalTelegramBot::closeClient() {
|
||||
if (client->connected()) {
|
||||
#ifdef TELEGRAM_DEBUG
|
||||
Serial.println(F("Closing client"));
|
||||
#endif
|
||||
client->stop();
|
||||
}
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::getFile(String& file_path, long& file_size, const String& file_id)
|
||||
{
|
||||
String command = BOT_CMD("getFile?file_id=");
|
||||
command += file_id;
|
||||
String response = sendGetToTelegram(command); // receive reply from telegram.org
|
||||
DynamicJsonDocument doc(maxMessageLength);
|
||||
DeserializationError error = deserializeJson(doc, ZERO_COPY(response));
|
||||
closeClient();
|
||||
|
||||
if (!error) {
|
||||
if (doc.containsKey("result")) {
|
||||
file_path = F("https://api.telegram.org/file/");
|
||||
file_path += buildCommand(doc["result"]["file_path"]);
|
||||
file_size = doc["result"]["file_size"].as<long>();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UniversalTelegramBot::answerCallbackQuery(const String &query_id, const String &text, bool show_alert, const String &url, int cache_time) {
|
||||
DynamicJsonDocument payload(maxMessageLength);
|
||||
|
||||
payload["callback_query_id"] = query_id;
|
||||
payload["show_alert"] = show_alert;
|
||||
payload["cache_time"] = cache_time;
|
||||
|
||||
if (text.length() > 0) payload["text"] = text;
|
||||
if (url.length() > 0) payload["url"] = url;
|
||||
|
||||
String response = sendPostToTelegram(BOT_CMD("answerCallbackQuery"), payload.as<JsonObject>());
|
||||
#ifdef _debug
|
||||
Serial.print(F("answerCallbackQuery response:"));
|
||||
Serial.println(response);
|
||||
#endif
|
||||
bool answer = checkForOkResponse(response);
|
||||
closeClient();
|
||||
return answer;
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
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 TELEGRAM_DEBUG 0 //jz
|
||||
#define ARDUINOJSON_DECODE_UNICODE 1
|
||||
#define ARDUINOJSON_USE_LONG_LONG 1
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <Client.h>
|
||||
|
||||
#define TELEGRAM_HOST "api.telegram.org"
|
||||
#define TELEGRAM_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;
|
||||
String file_caption;
|
||||
String file_path;
|
||||
String file_name;
|
||||
bool hasDocument;
|
||||
long file_size;
|
||||
float longitude;
|
||||
float latitude;
|
||||
int update_id;
|
||||
|
||||
int reply_to_message_id;
|
||||
String reply_to_text;
|
||||
String query_id;
|
||||
};
|
||||
|
||||
class UniversalTelegramBot {
|
||||
public:
|
||||
UniversalTelegramBot(const String& token, Client &client);
|
||||
void updateToken(const String& token);
|
||||
String getToken();
|
||||
String sendGetToTelegram(const String& command);
|
||||
String sendPostToTelegram(const String& command, JsonObject payload);
|
||||
String
|
||||
sendMultipartFormDataToTelegram(const String& command, const String& binaryPropertyName,
|
||||
const String& fileName, const String& contentType,
|
||||
const String& chat_id, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback);
|
||||
|
||||
//jz caption
|
||||
String
|
||||
sendMultipartFormDataToTelegramWithCaption(const String& command, const String& binaryPropertyName,
|
||||
const String& fileName, const String& contentType,
|
||||
const String& caption,
|
||||
const String& chat_id, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback);
|
||||
|
||||
|
||||
bool readHTTPAnswer(String &body, String &headers);
|
||||
bool getMe();
|
||||
|
||||
bool sendSimpleMessage(const String& chat_id, const String& text, const String& parse_mode);
|
||||
bool sendMessage(const String& chat_id, const String& text, const String& parse_mode = "");
|
||||
bool sendMessageWithReplyKeyboard(const String& chat_id, const String& text,
|
||||
const String& parse_mode, const String& keyboard,
|
||||
bool resize = false, bool oneTime = false,
|
||||
bool selective = false);
|
||||
bool sendMessageWithInlineKeyboard(const String& chat_id, const String& text,
|
||||
const String& parse_mode, const String& keyboard);
|
||||
|
||||
bool sendChatAction(const String& chat_id, const String& text);
|
||||
|
||||
bool sendPostMessage(JsonObject payload);
|
||||
String sendPostPhoto(JsonObject payload);
|
||||
String sendPhotoByBinary(const String& chat_id, const String& contentType, int fileSize,
|
||||
MoreDataAvailable moreDataAvailableCallback,
|
||||
GetNextByte getNextByteCallback,
|
||||
GetNextBuffer getNextBufferCallback,
|
||||
GetNextBufferLen getNextBufferLenCallback);
|
||||
String sendPhoto(const String& chat_id, const String& photo, const String& caption = "",
|
||||
bool disable_notification = false,
|
||||
int reply_to_message_id = 0, const String& keyboard = "");
|
||||
|
||||
bool answerCallbackQuery(const String &query_id,
|
||||
const String &text = "",
|
||||
bool show_alert = false,
|
||||
const String &url = "",
|
||||
int cache_time = 0);
|
||||
|
||||
bool setMyCommands(const String& commandArray);
|
||||
|
||||
String buildCommand(const String& cmd);
|
||||
|
||||
int getUpdates(long offset);
|
||||
bool checkForOkResponse(const String& response);
|
||||
telegramMessage messages[HANDLE_MESSAGES];
|
||||
long last_message_received;
|
||||
String name;
|
||||
String userName;
|
||||
int longPoll = 0;
|
||||
int waitForResponse = 1500;
|
||||
int _lastError;
|
||||
int last_sent_message_id = 0;
|
||||
int maxMessageLength = 1500;
|
||||
int jzdelay = 0; // delay between multipart blocks
|
||||
//int jzblocksize = 32 * 512;
|
||||
#define jzblocksize 32 * 512
|
||||
byte buffer[jzblocksize];
|
||||
|
||||
private:
|
||||
// JsonObject * parseUpdates(String response);
|
||||
String _token;
|
||||
Client *client;
|
||||
void closeClient();
|
||||
bool getFile(String& file_path, long& file_size, const String& file_id);
|
||||
bool processResult(JsonObject result, int messageIndex);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,443 @@
|
|||
#include "esp_camera.h"
|
||||
#include <Arduino.h>
|
||||
/*
|
||||
|
||||
Code from raduprv at github for low-light use of the ov2640 sensor
|
||||
copied Oct 27, 2022
|
||||
|
||||
It configured the registers of the camera to keep the sensor active
|
||||
or the shutter open, for much longer time to collect light and display
|
||||
a nearly dark image -- the time to take the picture goes from 80 ms (HD)
|
||||
to 500 or 5000 ms for a very dark scene.
|
||||
|
||||
https://github.com/raduprv/esp32-cam_ov2640-timelapse
|
||||
https://github.com/raduprv/esp32-cam_ov2640-timelapse/blob/main/LICENSE
|
||||
|
||||
The exposure is done manually based on the light level, and the image
|
||||
quality is far better than the default settings.
|
||||
|
||||
*/
|
||||
|
||||
extern int framesize;
|
||||
|
||||
void radu() {
|
||||
|
||||
camera_fb_t * fb = NULL;
|
||||
sensor_t * s = esp_camera_sensor_get();
|
||||
int light = 0;
|
||||
int day_switch_value = 140;
|
||||
|
||||
int y;
|
||||
|
||||
Serial.println("Before the radu");
|
||||
y = millis();
|
||||
fb = esp_camera_fb_get();
|
||||
esp_camera_fb_return(fb);
|
||||
Serial.printf("Get took %d ms\n",millis()-y);
|
||||
|
||||
y = millis();
|
||||
fb = esp_camera_fb_get();
|
||||
esp_camera_fb_return(fb);
|
||||
Serial.printf("Get took %d ms\n",millis()-y);
|
||||
|
||||
y = millis();
|
||||
fb = esp_camera_fb_get();
|
||||
esp_camera_fb_return(fb);
|
||||
Serial.printf("Get took %d ms\n",millis()-y);
|
||||
|
||||
y = millis();
|
||||
fb = esp_camera_fb_get();
|
||||
esp_camera_fb_return(fb);
|
||||
Serial.printf("Get took %d ms\n",millis()-y);
|
||||
|
||||
|
||||
s->set_whitebal(s, 1); // 0 = disable , 1 = enable
|
||||
s->set_awb_gain(s, 1); // 0 = disable , 1 = enable
|
||||
s->set_wb_mode(s, 2); // 0 to 4 - if awb_gain enabled (0 - Auto, 1 - Sunny, 2 - Cloudy, 3 - Office, 4 - Home)
|
||||
// s->set_exposure_ctrl(s, 1); // 0 = disable , 1 = enable
|
||||
// s->set_aec2(s, 0); // 0 = disable , 1 = enable
|
||||
//s->set_ae_level(s, 2); // -2 to 2
|
||||
//s->set_aec_value(s, 1200); // 0 to 1200
|
||||
s->set_gain_ctrl(s, 0); // 0 = disable , 1 = enable
|
||||
s->set_agc_gain(s, 0); // 0 to 30
|
||||
s->set_gainceiling(s, (gainceiling_t)6); // 0 to 6
|
||||
s->set_bpc(s, 1); // 0 = disable , 1 = enable
|
||||
s->set_wpc(s, 1); // 0 = disable , 1 = enable
|
||||
s->set_raw_gma(s, 1); // 0 = disable , 1 = enable
|
||||
s->set_lenc(s, 0); // 0 = disable , 1 = enable
|
||||
s->set_hmirror(s, 0); // 0 = disable , 1 = enable
|
||||
s->set_vflip(s, 0); // 0 = disable , 1 = enable
|
||||
s->set_dcw(s, 0); // 0 = disable , 1 = enable
|
||||
s->set_colorbar(s, 0); // 0 = disable , 1 = enable
|
||||
s->set_framesize(s, (framesize_t)framesize); // framesize gets reset somewhere
|
||||
|
||||
s->set_reg(s, 0xff, 0xff, 0x01); //banksel
|
||||
|
||||
light = s->get_reg(s, 0x2f, 0xff);
|
||||
Serial.print("First light is ");
|
||||
Serial.println(light);
|
||||
Serial.print("Old 0x0 value is ");
|
||||
Serial.println(s->get_reg(s, 0x0, 0xff));
|
||||
|
||||
//light=120+cur_pic*10;
|
||||
//light=0+cur_pic*5;
|
||||
|
||||
if (light < day_switch_value)
|
||||
{
|
||||
//here we are in night mode
|
||||
if (light < 45)s->set_reg(s, 0x11, 0xff, 1); //frame rate (1 means longer exposure)
|
||||
s->set_reg(s, 0x13, 0xff, 0); //manual everything
|
||||
s->set_reg(s, 0x0c, 0x6, 0x8); //manual banding
|
||||
|
||||
s->set_reg(s, 0x45, 0x3f, 0x3f); //really long exposure (but it doesn't really work)
|
||||
}
|
||||
else
|
||||
{
|
||||
//here we are in daylight mode
|
||||
|
||||
s->set_reg(s, 0x2d, 0xff, 0x0); //extra lines
|
||||
s->set_reg(s, 0x2e, 0xff, 0x0); //extra lines
|
||||
|
||||
s->set_reg(s, 0x47, 0xff, 0x0); //Frame Length Adjustment MSBs
|
||||
|
||||
if (light < 150)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0xd0); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0xff); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0xff); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 160)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0xc0); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0xb0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x10); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 170)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0xb0); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x80); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x10); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 180)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0xa8); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x80); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x10); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 190)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0xa6); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x80); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x90); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 200)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0xa4); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x80); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x10); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 210)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0x98); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x60); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x10); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 220)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0x80); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x20); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x10); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 230)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0x70); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x20); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x10); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 240)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0x60); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x20); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0x80); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x10); //exposure (doesn't seem to work)
|
||||
}
|
||||
else if (light < 253)
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0x10); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0x40); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x10); //exposure (doesn't seem to work)
|
||||
}
|
||||
else
|
||||
{
|
||||
s->set_reg(s, 0x46, 0xff, 0x0); //Frame Length Adjustment LSBs
|
||||
s->set_reg(s, 0x2a, 0xff, 0x0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0x0); //line adjust
|
||||
s->set_reg(s, 0x45, 0xff, 0x0); //exposure (doesn't seem to work)
|
||||
s->set_reg(s, 0x10, 0xff, 0x0); //exposure (doesn't seem to work)
|
||||
}
|
||||
|
||||
s->set_reg(s, 0x0f, 0xff, 0x4b); //no idea
|
||||
s->set_reg(s, 0x03, 0xff, 0xcf); //no idea
|
||||
s->set_reg(s, 0x3d, 0xff, 0x34); //changes the exposure somehow, has to do with frame rate
|
||||
|
||||
s->set_reg(s, 0x11, 0xff, 0x0); //frame rate
|
||||
s->set_reg(s, 0x43, 0xff, 0x11); //11 is the default value
|
||||
}
|
||||
|
||||
//Serial.println("Getting first frame at");
|
||||
//Serial.println(millis());
|
||||
|
||||
Serial.println("mid radu");
|
||||
y = millis();
|
||||
fb = esp_camera_fb_get();
|
||||
//skip_frame();
|
||||
Serial.printf("Get took %d ms\n",millis()-y);
|
||||
esp_camera_fb_return(fb);
|
||||
|
||||
//Serial.println("Got first frame at");
|
||||
//Serial.println(millis());
|
||||
|
||||
if (light == 0)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x40); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0xf0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 1)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x40); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0xd0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 2)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x40); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0xb0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 3)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x40); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x70); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 4)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x40); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x40); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 5)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x20); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x80); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 6)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x20); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x40); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 7)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x20); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x30); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 8)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x20); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x20); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 9)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x20); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x10); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light == 10)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x10); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x70); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light <= 12)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x10); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x60); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light <= 14)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x10); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x40); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light <= 18)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x08); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0xb0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light <= 20)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x08); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x80); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light <= 23)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x08); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x60); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light <= 27)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x04); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0xd0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light <= 31)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x04); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x80); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light <= 35)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x04); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x60); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light <= 40)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x02); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x70); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light < 45)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x02); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x40); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
//after this the frame rate is higher, so we need to compensate
|
||||
else if (light < 50)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x04); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0xa0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light < 55)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x04); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x70); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light < 65)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x04); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x30); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light < 75)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x02); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x80); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xff); //line adjust
|
||||
}
|
||||
else if (light < 90)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x02); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x50); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0xbf); //line adjust
|
||||
}
|
||||
else if (light < 100)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x02); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x20); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0x8f); //line adjust
|
||||
}
|
||||
else if (light < 110)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x02); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x10); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0x7f); //line adjust
|
||||
}
|
||||
else if (light < 120)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x01); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x10); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0x5f); //line adjust
|
||||
}
|
||||
else if (light < 130)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x00); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0x2f); //line adjust
|
||||
}
|
||||
else if (light < 140)
|
||||
{
|
||||
s->set_reg(s, 0x47, 0xff, 0x00); //Frame Length Adjustment MSBs
|
||||
s->set_reg(s, 0x2a, 0xf0, 0x0); //line adjust MSB
|
||||
s->set_reg(s, 0x2b, 0xff, 0x0); //line adjust
|
||||
}
|
||||
|
||||
if (light < day_switch_value)s->set_reg(s, 0x43, 0xff, 0x40); //magic value to give us the frame faster (bit 6 must be 1)
|
||||
|
||||
//fb = esp_camera_fb_get();
|
||||
|
||||
s->set_reg(s, 0xff, 0xff, 0x00); //banksel
|
||||
s->set_reg(s, 0xd3, 0xff, 0x8); //clock
|
||||
|
||||
s->set_reg(s, 0x42, 0xff, 0x2f); //image quality (lower is bad)
|
||||
s->set_reg(s, 0x44, 0xff, 3); //quality
|
||||
|
||||
//s->set_reg(s,0x96,0xff,0x10);//bit 4, disable saturation
|
||||
|
||||
|
||||
//s->set_reg(s,0xbc,0xff,0xff);//red channel adjustment, 0-0xff (the higher the brighter)
|
||||
//s->set_reg(s,0xbd,0xff,0xff);//green channel adjustment, 0-0xff (the higher the brighter)
|
||||
//s->set_reg(s,0xbe,0xff,0xff);//blue channel adjustment, 0-0xff (the higher the brighter)
|
||||
|
||||
//s->set_reg(s,0xbf,0xff,128);//if the last bit is not set, the image is dim. All other bits don't seem to do anything but ocasionally crash the camera
|
||||
|
||||
//s->set_reg(s,0xa5,0xff,0);//contrast 0 is none, 0xff is very high. Not really useful over 20 or so at most.
|
||||
|
||||
//s->set_reg(s,0x8e,0xff,0x30);//bits 5 and 4, if set make the image darker, not very useful
|
||||
//s->set_reg(s,0x91,0xff,0x67);//really weird stuff in the last 4 bits, can also crash the camera
|
||||
|
||||
//no sharpening
|
||||
s->set_reg(s, 0x92, 0xff, 0x1);
|
||||
s->set_reg(s, 0x93, 0xff, 0x0);
|
||||
|
||||
Serial.println("After the radu");
|
||||
|
||||
y = millis();
|
||||
fb = esp_camera_fb_get();
|
||||
Serial.printf("Get took %d ms\n",millis()-y);
|
||||
esp_camera_fb_return(fb);
|
||||
|
||||
y = millis();
|
||||
fb = esp_camera_fb_get();
|
||||
esp_camera_fb_return(fb);
|
||||
Serial.printf("Get took %d ms\n",millis()-y);
|
||||
|
||||
y = millis();
|
||||
fb = esp_camera_fb_get();
|
||||
esp_camera_fb_return(fb);
|
||||
Serial.printf("Get took %d ms\n",millis()-y);
|
||||
|
||||
}
|
Ładowanie…
Reference in New Issue