We got the ticker to work, so I added ESP Now code for the 8266.
Trouble is, I can’t get the stock data into the ESP Now sender queue, because it’s declared somewhere funky within loop.
quote_msg holds the stock price and changes. I want to use it to send the stock data to the ESP Now receiver, but it’s not declarable.
Please tell me how to get quote_msg into ESP Now at the end of the same loop.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <espnow.h>
#include <ArduinoJson.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
// REPLACE WITH RECEIVER MAC Address
uint8_t broadcastAddress[] = {0x8C, 0xaa, 0xb5, 0x86, 0x1C, 0x94};
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message
{
int id;
float temperature;
float humidity;
float pressure;
int Gas;
int CO;
int smoke;
int altitude;
float moisture;
float stock;
int UV;
int CO2;
int NH3;
int NO2;
int VOC;
int H2;
unsigned int counter;
} struct_message;
// Create a struct_message called myData
struct_message myData;
const String kApiUri = "https://www.alphavantage.co";
const String kApiBaseUri = "https://www.alphavantage.co/query?";
const String kApiStockPrice = "function=GLOBAL_QUOTE&";
const String kApiExchangeRate = "function=CURRENCY_EXCHANGE_RATE&";
const String kApiFromCurrency = "from_currency=BTC&";
// Note: we leave the & off of this one as the last piece is the kApiKey
const String kApiToCurrency = "to_currency=USD";
const String kApiSymbol = "symbol=";
const String kApiKey = "&apikey=QITRTT5A746YIJBI";
// Define additional ticker symbols here
const String kTickerSymbols[] = {
"TSLA", //
"NLY", //
};
// Max document size that we can parse for JSON, resp from AV has about 10 vals
const size_t kMaxJsonDoc = 0x400;
StaticJsonDocument<kMaxJsonDoc> doc;
// Main loop pause
const size_t kDelay = 30000;
// Seconds to wait between POSTs to AlphaVantage
const size_t kStockPause = 15000;
// Blink delay for the lights
const size_t kBlinkDelay = 1000;
// SHA1 fingerprint of the sites certificate
const char *kAlphaVantageFingerprint = "27 F4 DF 78 11 04 1A DB 4B EC 5A 4C D5 0A FE 1F D6 24 CE BF";
// Init the ESP8266 Wifi Module
ESP8266WiFiMulti WiFiMulti;
unsigned long lastTime = 0;
unsigned long timerDelay = 2000; // send readings timer
// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus)
{
Serial.print("Last Packet Send Status: ");
if (sendStatus == 0)
{
Serial.println("Delivery success");
}
else
{
Serial.println("Delivery fail");
}
}
void setup()
{
// Init Serial Monitor
Serial.begin(9600);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != 0)
{
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
// Fetches a string response from a remote API endpoint URI
int getApiResponse(const String &uri, String &resp)
{
Serial.println("Fetching resource from " + uri);
std::unique_ptr<BearSSL::WiFiClientSecure> secure_client(new BearSSL::WiFiClientSecure);
secure_client->setFingerprint(kAlphaVantageFingerprint);
secure_client->setTimeout(3000);
HTTPClient https;
auto ret = https.begin(*secure_client, uri);
if (!ret)
{
Serial.println("Failed to connect to URI with " + String(ret));
return 1;
}
auto status = https.GET();
if (status != HTTP_CODE_OK)
{
Serial.println("HTTPS GET failed with code " + String(status));
return status;
}
resp = https.getString();
return status;
}
void loop()
{
float moisture = map(analogRead(A0), 1, 100, 0, 4095);
float stock = quote_msg;
// We fetch stock values in a loop around the ticker symbols, defined above
for (const auto sym : kTickerSymbols)
{
Serial.println("Fetching price for " + sym);
// Perform the API request
String resp;
String uri = kApiBaseUri + kApiStockPrice + kApiSymbol + sym + kApiKey;
auto ret = getApiResponse(uri, resp);
if (ret == 1)
{
Serial.println("Fetch remote resource failed. Continuing");
delay(kStockPause);
continue;
}
// Parse the response into a JSON object
auto err = deserializeJson(doc, resp);
if (err)
{
Serial.println("Failed to parse response to JSON with " + String(err.c_str()));
delay(kStockPause);
continue;
}
// We display the price
auto quote = doc["Global Quote"];
auto quote_msg = sym + ": " + quote["05. price"].as<String>() + ", " +
quote["09. change"].as<String>() + " (" +
quote["10. change percent"].as<String>() + ")";
Serial.println(quote_msg);
delay(kStockPause);
}
// Lastly, fetch the USD -> BTC exchange rate, for funsies
String resp;
String uri = kApiBaseUri + kApiExchangeRate + kApiFromCurrency +
kApiToCurrency + kApiKey;
auto ret = getApiResponse(uri, resp);
// Parse the response into a JSON object
auto err = deserializeJson(doc, resp);
if (err)
{
Serial.println("Failed to parse response to JSON with " + String(err.c_str()));
}
delay(kDelay);
myData.moisture = moisture;
myData.stock = stock;
// Send message via ESP-NOW
esp_now_send(broadcastAddress, (uint8_t *)&myData, sizeof(myData));
lastTime = millis();
}