Найти тему
Project A.L.T.

Получение данных о доходе РСЯ через API на ESP8266

Если Вы зарабатываете в РСЯ (Рекламная сеть Яндекса), то наверняка озадачивались вопросом удобного способа получения информации о заработанных средствах. Разумеется, прочитать баланс на счету можно в личном кабинете (авторизовавшись). Но если вам просто хочется быстро просмотреть статистику без лишних телодвижений, типа включения компьютера, запуска браузера, перехода на сайт РСЯ и ввода учетных данных, то вам на помощь придет ESP8266.
В данной статье вы узнаете как собрать компактное устройство, которое в реальном времени будет получать статистику от РСЯ через и выводить её на oled экран.

Получаем доход от РСЯ по API

Яндекс упрощает нам получение информации о текущем доходе в РСЯ, поскольку у Рекламной сети Яндекса имеется API — можно получить подробную статистику о работе с Яндексом для последующей обработки данных, анализа доходов и т.д.

Мы воспользуемся сегодня такой возможностью что-бы сделать простое устройство, информирующее о доходах вебмастера за текущий день, вчерашний день, позавчерашний и текущий месяц в РСЯ.

Вы спросите зачем? Ну а какому вебмастеру не интересно, сколько денег он заработал сегодня? Правильно, никакому

Регистрация приложения

Для взаимодействия с API нам нужно получить токен (специальный ключ). Процедура следующая:

Авторизуемся в Яндексе, идем по ссылке «Создание приложение» — https://oauth.yandex.ru/client/new

Заполняем поля. Названиедоход от сайта https://projectalt.ru (произвольно), Описаниеполучение дохода от сайта https://projectalt.ru (произвольно), в разделе Какие данные вам нужны? выбираем: Партнерский интерфейс Яндекса, ставим галочку — «Использование API партнерского интерфейса Яндекса«. У вас должно получиться примерно следующая картина:

-2
-3

Пролистываем страницу в самый низ и жмем Создать приложение

-4

На следующей странице вам предоставят Client ID и Пароль приложения

-5

Получение токена

Перейдите по ссылке вида https://oauth.yandex.ru/authorize?response_type=token&client_id=xxxxxxxxxxxxxxxx. Где xxxxxxxxxxxxxxxx значение вашего Client ID, полученное на предыдущем шаге. Откроется стандартное окно авторизации в сервисах Яндекс

-6

Заходим в свой аккаунт и откроется окно с текстовым сообщением вида y0_AgAAAAAAxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx. Это и есть ваш токен. Запишите его где-нибудь и на этом настройки на стороне яндекса закончены

Создание устройства для получения информации о доходах в РСЯ

API РСЯ работает просто: вы посылаете специальный запрос на специальный адрес, в ответ получаете необходимые вам данные (что запросили, то вам и выслали). Ответы могут приходить в JSON и XML. Какие запросы можно посылать и как их оформлять — я не буду детально на этом останавливаться, все описано в документации к API.

Необходимые компоненты

Для создания устройства нам понадобятся следующие компоненты

  • Плата на базе ESP8266(Wemos D1 mini, NodeMCU и др.)
  • OLED дисплей 0.96 128х64 I2C
  • Провода для соединения компонентов
  • USB кабель для прошивки

И, пожалуй, понадобится еще макетная плата для тестирования и отладки.

Схема устройства

Соединяем все компоненты по схеме

-7

Код программы

Открываем ArduinoIDE и копируем следующий код

#include <SPI.h> #include <Wire.h> #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <WiFiClientSecure.h> #include <ArduinoJson.h> #include <Adafruit_GFX.h> // Подключение библиотеки Adafruit_GFX #include <Adafruit_SSD1306.h> // Подключение библиотеки Adafruit_SSD1306 #define OLED_RESET -1 #define SCL 5 // D1 #define SDA 4
#define SCREEN_WIDTH 128 // OLED дисплей ширина в пикселях #define SCREEN_HEIGHT 64 // OLED дисплей высота в пикселях const char* ssid = "ssid";
const char* password = "pass";
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Соединяемся с сервером раз в 10 секунд unsigned long lastTime = 0;
// Устанавливаем таймер на 10 секунд (10000) unsigned long timerDelay = 10000;

void setup() {
Serial.begin(115200);
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Указываем адрес дисплея display.clearDisplay(); // Очищаем дисплей display.setTextSize(1); // Устанавливаем размер шрифта display.setTextColor(WHITE); // Цвет фона WiFi.begin(ssid, password);
Serial.println("Connecting");
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi network with IP Address: ");
Serial.println(WiFi.localIP());

Serial.println("Timer set to 10 seconds (timerDelay variable), it will take 10 seconds before publishing the first reading.");
}

void loop() {
// Send an HTTP GET request if ((millis() - lastTime) > timerDelay) {
// Check WiFi connection status if(WiFi.status()== WL_CONNECTED){
String serverPath = "https://partner2.yandex.ru/api/statistics2/get.json?lang=ru&pretty=1&dimension_field=date|day&period=thismonth&field=partner_wo_nds";

WiFiClientSecure client;
HTTPClient https;
client.setInsecure();
https.begin(client,serverPath);
https.addHeader("Authorization","OAuth xxxxxxxxxxxxxxxxxxxxxxxxxxx");
int httpCode = https.GET();
if (httpCode > 0) {

String response = https.getString();

//Serial.println (response); DynamicJsonDocument doc(10000);

DeserializationError error = deserializeJson(doc, response);

if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}

JsonObject data = doc["data"];

const char* data_periods_0_0 = data["periods"][0][0];
const char* data_periods_0_1 = data["periods"][0][1];
int data_total_rows = data["total_rows"];
float vals[data_total_rows];
int i=0;
for (JsonObject data_point : data["points"].as()) {
vals[i] = data_point["measures"][0]["partner_wo_nds"];
Serial.println(vals[i]);
i++;
}
float data_totals_2_0_partner_wo_nds = data["totals"]["2"][0]["partner_wo_nds"];

i=data_total_rows-1;
display.clearDisplay();
display.setCursor(0,0);
display.print("Total reward: ");
display.println(data_totals_2_0_partner_wo_nds);
display.print("2 days ago: ");
display.println(vals[i-2]);
display.print("Yesterday: ");
display.println(vals[i-1]);
display.print("Today: ");
display.println(vals[i]);
display.display();
Serial.println(data_totals_2_0_partner_wo_nds);
Serial.print("Вознаграждение позавчера: ");
Serial.println(vals[i-2]);
Serial.print("Вознаграждение вчера: ");
Serial.println(vals[i-1]);
Serial.print("Вознаграждение сегодня: ");
Serial.println(vals[i]);

const char* result = doc["result"]; // "ok" } else{
Serial.println("http.GET() == 0");
}

https.end(); //Close connection

}
else {
Serial.println("WiFi Disconnected");
}
lastTime = millis();
}
}

Делать полный разбор кода особого смысла нет. Остановлюсь лишь на некоторых моментах

Так как обращение к API Яндекса происходит по защищенному https протоколу, то стандартная библиотека WiFiClient нам не подойдет. Так как она не умеет работать с такими данными. Поэтом будем использовать её модифицированную версию WiFiClientSecure

#include <WiFiClientSecure.h>

Здесь как всегда меняем учетные данные для подключения к Wifi на свои

const char* ssid = "ssid";
const char* password = "pass";

Если изображение на дисплее отсутсвует или появляются артефакты, то пробуем изменить адрес 0x3C на 0x3D

display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Указываем адрес дисплея

Здесь формируется строка для запроса к API Яндекса

String serverPath = "https://partner2.yandex.ru/api/statistics2/get.json?lang=ru&pretty=1&dimension_field=date|day&period=thismonth&field=partner_wo_nds";СКОПИРОВАТЬ КОД

значение всех параметров вы можете узнать в документации к API. В данном же случаем мы указываем, что get.json - хотим получить результат в виде json. lang=ru - на русском языке. pretty=1 - в форматированном виде. dimension_field=date|day - с сортировкой по дате. period=thismonth - за текущий месяц. field=partner_wo_nds" - поле с доходом за выбранный период

Далее подставляем вместо xxxxxxxxxxxxxxxxxxxxxxxxxxx код токена полученный на предыдущем шаге

https.addHeader("Authorization","OAuth xxxxxxxxxxxxxxxxxxxxxxxxxxx");

В следующем коде идет разбор полученного JSON, запись данных в массив vals[] и вывод результатов на экран

JsonObject data = doc["data"];

const char* data_periods_0_0 = data["periods"][0][0];
const char* data_periods_0_1 = data["periods"][0][1];
int data_total_rows = data["total_rows"]; // 22 float vals[data_total_rows];
int i=0;
for (JsonObject data_point : data["points"].as()) {
vals[i] = data_point["measures"][0]["partner_wo_nds"];
Serial.println(vals[i]);
i++;
}
float data_totals_2_0_partner_wo_nds = data["totals"]["2"][0]["partner_wo_nds"];

i=data_total_rows-1;
display.clearDisplay();
display.setCursor(0,0);
display.print("Total reward: ");
display.println(data_totals_2_0_partner_wo_nds);
display.print("2 days ago: ");
display.println(vals[i-2]);
display.print("Yesterday: ");
display.println(vals[i-1]);
display.print("Today: ");
display.println(vals[i]);
display.display();
Serial.println(data_totals_2_0_partner_wo_nds);
Serial.print("Вознаграждение позавчера: ");
Serial.println(vals[i-2]);
Serial.print("Вознаграждение вчера: ");
Serial.println(vals[i-1]);
Serial.print("Вознаграждение сегодня: ");
Serial.println(vals[i]);

В массиве vals[] хранятся данные о ежедневных выплатах за текущий месяц. Так как адресация в массиве начинается с 0, то из значения интересующего вас числа нужно вычесть 1. То есть если вам нужа информация, например, о размере выплат за 3 число текущего месяца, то она хранится в ячейке 2. И получить его можно обратившись к массиву по адресу vals[2].

Результат работы

Результат работы программы вы можете увидеть на скриншоте ниже

-8

Разумеется это всего лишь прототип для демонстрации работы и о какой либо оптимизации и красоте говорить не приходится. Но как основа для будущих более сложных проектов подойдет как нельзя кстати.

Например вот так реализован данный код в моем старом проекте
Монитор параметров ПК + Метеостанция.

-9

Данная статья также доступна на сайте Project A.L.T. Записки разработчика