Skip to content

Latest commit

 

History

History
705 lines (507 loc) · 44.7 KB

4.md

File metadata and controls

705 lines (507 loc) · 44.7 KB

Лабораторні

ЛАБОРАТОРНА РОБОТА № 4. Створення розподіленого застосунку

Тривалість: 4 акад. години (2 пари).

Мета: Навчитися створювати розподілені застосунки на базі REST API з використанням різноманітних пристроїв

Лабораторна установка

Необхідне апаратне забезпечення.

Для проведення лабораторних робіт необхідно мати комп’ютер з наступною мінімальною апаратною конфігурацією:

  • CPU Intel/AMD 1 ГГц / RAM 2 ГБ / HDD 10 ГБ (вільних)
  • смартфон або планшет з ОС Андроїд

Необхідне програмне забезпечення.

  • На комп’ютері повинна бути встановлена одна з операційних систем, підтримуваних віртуальною машиною VirtualBox та налаштована відповідно до вимог минулої лабораторної роботи.
  • Повинен бути встановлений VirtualBox
  • Повинна бути встановлена віртуальна машина з Mikrotik з минулих лабораторних робіт
  • інше програмне забезпечення встановлюється по ходу виконання лабораторних робіт

Загальна постановка задачі.

Цілі роботи:

  1. навчитися створювати розподілені застосунки на базі REST API
  2. навчитися використовувати Google Apps Scripts для створення WEB-застосунків
  3. навчитися використовувати утиліти тестування HTTP API

Лабораторна робота розроблена з урахуванням самостійного виконання без наявності реального обладнання окрім ПК та смартфону.

У даній лабораторній роботі необхідно розробити розподілений застосунок, який повинен виконувати кілька функцій:

  • фіксувати повідомлення від пристроїв, що підключені через REST API до серверу, з вказівкою дати та часу повідомлення, та властивостей, які передаються в ньому; серед пристроїв в лабораторній роботі будуть:
    • маршрутизатор Mikrotik (вірніше його віртуальна машина), який відправляє на сервер час роботи з періодичністю 5 хв
    • смартфон, який за ініціюванням користувача відправляє на сервер координати розміщення (геолокацію) з вказівкою примітки
  • відправляти повідомлення на Telegram про те, що маршрутизатор з'явився в мережі і про те, що він зник

Послідовність виконання роботи

1. Створення документу Google Sheet з розширенням Google Apps Scripts (GAS)

Google Sheet - це хмарний застосунок від Google для роботи з електронними таблицями. За функціональністю і принципами роботи він схожий на Microsoft Excel. Усі створені таблиці зберігаються на Гугл Диску (Google Drive). У даному рішенні електронна таблиця буде виконувати роль простої бази даних куди буде накопичуватися різноманітна інформація з різних пристроїв. Взаємодія з базою даних відбуватиметься через розгорнутий Web Applications на базі сервісів Google Apps Scripts, надалі вживатиметься термін GAS. У цьому пункті необхідно:

  • створити таблицю Google Sheet

  • створити розширення на Google Apps Scripts

  • реалізувати функцію в GAS, яка буде записувати значення у вказані комірки вказаного листа з фіксацією часу

  • Якщо у Вас немає облікового запису Google - створіть його на сайті. Це безкоштовно, потребується тільки поштова скринька і номер телефону.

  • Зайдіть на головну сторінку Google і зайдіть в застосунок Google Sheet(Таблиці)

рис.4.1. Створення таблиці Google Sheet

Альтернативно можна відразу перейти на сторінку

  • У новому вікні натисніть кнопку "+" (створити) щоб створити нову електронну таблицю

  • Змініть назву документу на якусь більш прийнятну, наприклад WebAppLaba4

  • Створіть розширення на Apps Script

image-20221206172807635

рис.4.2. Створення розширення на Apps Script

  • Новостворений проект перейменуйте у WebAppYourName, де YourName ваше ім'я та прізвище

2. Створення функції Google Apps Scripts для запису полів у вказаний лист

  • Проаналізуйте та впишіть наступний код
//тестовий запис
let smplrecord = {
  device: 'testdevice',
  field1: Math.random(),
  field2: 'this is a text',
  field3: {text: 'this is JSON', n: Math.random()*100.0}
}
//тестування виклику
let result = LogToSheet (smplrecord);
console.log (result);

function LogToSheet (record) {
  if (!record) return 
  let devicename = record.device;
  // якщо імя пристрою не вказане, завершити виконання функції і
  // і повернути відповідний текст 
  if (typeof devicename !== 'string') {
    return 'There is no device field';
  } 
  
  // доступ до активного документу Google Sheet
  let ss = SpreadsheetApp.getActive();
  // доступ до листа - журналу пристрою  
  let sheet = ss.getSheetByName(devicename);
  // якщо такого листа немає - створити
  if (!sheet) {
    sheet = ss.insertSheet(devicename);
  }
  // спочатку вставляємо новий запис в 2-гу позицію
  // усі старі записи зміщуються вниз
  sheet.insertRowBefore(2);
  // доступаємося до перших 2-х клітин в 1-му рядку
  let r = sheet.getRange (1,1,1,2);
  // пишемо назви колонок
  r.setValues ([['TS','DT']]);
  // доступаємося до перших 2-х клітин в 2-му рядку  
  r = sheet.getRange (2,1,1,2);
  // пишемо TS - відмітку часу, DT - дату та часу
  let date = new Date();
  r.setValues ([[date.valueOf() , date.toLocaleDateString('uk-UA') + ' ' + date.toLocaleTimeString('uk-UA')]])
  i=3; // починаємо з 3-го стовпчика
  // перебираємо усі поля
  for (let propname in record){
    // device використовується для назив листа
    if (propname !='device') {
      // виділяємо область i-ї ствопця, 1 та 2 рядки
      r = sheet.getRange(1,i,2,1);
      // у 1-му рядку - назва, у 2-му - значення 
      r.setValues ([[propname],[record[propname]]])
      i++;
    } 
  }
  return (i-3 + ' parameters are recorded')
}
  • Збережіть та запустіть на виконання. Перший раз повинно з'явитися повідомлення про необхідність надання доступу застосунку до Google Sheet. Автентифікуйте себе, та надайте дозвіл на доступ.

image-20221206182104694

рис.4.3. Дозвіл на доступ застосунку до Google Sheet

  • Після успішного виконання у вікні консолі повинно з'явитися повідомлення:

    `Інформація 3 parameters are recorded`
    
  • Перевірте в документі Google Sheet створилася вкладка testdevice з відповідним записом.

image-20221206182744389

рис.4.4. Відображення запису

  • Запустіть ще кілька раз скрипт, щоб створилося кілька записів в баблиці.

3. Створення та перше розгортання Web Application на базі GAS

У даному пункті необхідно реалізувати HTTP API інтерфейс для доступу до даних для читання. Читання даних передбачатиме доступ до записів в конкретних листів, відповідного device з використанням методу GET за шаблоном:

GET baseurl/device

Де baseurl - базова частина URL-шляху, яка вказується Google при публікації або тестуванні інетрфейсу Якщо device не вказується, тобто:

GET baseurl

то виклик методу повинен повинен повертати перелік листів. В обидвох випадках дані повинні повертатися у форматі JSON.

У даній частині лабораторної роботи не проводиметься захист даних і не вимагатиметься автентифікація при доступі до інтерфейсу, а доступ до даних в Google Sheet відбуватиметься через автентифікацію від імені власника застосунку.

  • Допишіть функцію doGet(e) яка повертає зміст вказаного листа або перелік листів, якщо лист не заданий.
// доступ до даних
function doGet(e) {
  // все що йде після базової частини URL, 
  // тобто праворуч від /dev або /exec
  let path = e.pathInfo;
  // запис для журналу для налагодження
  let record = {device : "APIGET", path: path};
  LogToSheet (record); // закоментувати за відсутності налагодження
  let ss = SpreadsheetApp.getActive();  
  let sheets = ss.getSheets();
  let retob = ['Not Found']; // якщо щось пішло не так
  if (typeof path == 'string') { // якщо параметр є 
    try { // ловимо помилку
      // доступ до вказаного листа 
      let sheet = ss.getSheetByName(path);
      // отримати всі  дані
      retob = sheet.getDataRange().getValues();
    } catch (error) { // якщо зловили помилку
      retob = [error + ' ' + path];
    }
  } else { // якщо без параметрів, тільки базоий URL
    try {
      retob = []; // масив з переліком назв листів
      for (let sheet of sheets){ //перебираємо листи
        retob.push (sheet.getName()) //добавляємо назви в масив 
     }
    } catch (error) {
      retob = [error + ' ' + path];
    }
  }
  // формуємо вихід як JSON 
  return ContentService.createTextOutput(JSON.stringify(retob)).setMimeType(ContentService.MimeType.JSON);
}
  • Збережіть проект
  • Опублікуйте скрипт як Веб-застосунок (рис.4.5).

image-20221206223810030

рис.4.5. Публікація скрипту як Веб-застосунку

Після публікації застосунку його базовий URL матиме вигляд:

https://script.google.com/macros/s/AKfyVOWxGcR9A/exec

Зауважте що кожна зміна коду буде приводити до необхідності публікації нового застосунку. Стара адреса буде використовуватися зі старим кодом. Так забезпечується версійність, коли старі застосунки залишаються робочими при зміні реалізації.

Також варто відзначити, що Google Apps Scripts пропонує два інтерфейси:

  • для виконання, URL якого завершується /exec і постійно змінюється при публікації
  • для налагодження, URL якого завершується /dev і не змінюється при публікації, є постійною що спрощує налагодження але доступний тільки розробникам. Приклад такого URL:
https://script.google.com/macros/s/AKfycbzES1LxLzsgWPDm/dev

Таким чином налагоджувати веб-застосунок простіше з URL, що завершується на /dev

4. Тестування Web Application з використанням тестової утиліти

Для тестування API можна скористатися різними безкоштовними утилітами. У даній лабораторній роботі пропонується скористатися доповненням до браузерів FireFox або Chrome з назвою RESTED.

image-20221206225524279

рис.4.6. Отримання посилання на інтерфейс режиму розроблення

  • Запустіть розширення RESTED, як правило іконка на панелі інструментів браузера image-20221206230211518

  • У полі URL впишіть скопійовану адресу і натисніть Send Request

image-20221206232645522

рис.4.7. Перевірка роботи запиту GET для доступу до переліку листів.

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

  • Подивіться Google Sheet. Там повинна з'явитися лист APIGET з даними по запитам.

Увага! Лист APIGET призначений в даному розроблювальному застосунку тільки для тестування, варто закоментувати частину коду з викликом запису в даний лист, якщо налагодження не потребується, щоб не збільшувати даремно об'єм файлу.

  • Передивіться журнал виконання, в якому містяться результати виконання, повідомлення та помилки.

image-20221206233321195

рис.4.8. Перегляд журналу виконання

  • Повторіть запит з вказівкою назви листа, тобто в кінці URL вкажіть назву листа через косу, наприклад /testdevice, щоб URL закінчувався на:
.../dev/testdevice
  • У відповідь повинен прийти зміст листа в форматі JSON.
  • У RESTED збережіть запит в колекцію (кнопка +)

5. Реалізація та перевірка методу POST для запису

У даному пункті необхідно реалізувати HTTP API інтерфейс для доступу до даних для запису. Запис даних передбачатиме відправку методу POST на базовий URL тобто за шаблоном:

POST baseurl

у якому в якості корисного навантаження передаються дані в форматі JSON в форматі:

{"device": "devicename", "field1": "fieldvalue1", ... "fieldn": "fieldvaluen"}

де:

  • devicename - ідентифікатор пристрою, для якого буде створена окрема вкладка

  • field1 .. fieldn - назва параметрів, для яких відбуватиметься запис

  • fieldvalue1 .. fieldvaluen - значення параметрів, для яких відбуватиметься запис

  • Проаналізуйте та допишіть в програму шматок коду, що реалізує обробник методу POST:

// запис даних
function doPost(e) {
 // корисне навантаження 
 let contents = e.postData.contents;
 let retob = {contents: contents};
  try {
    // перетворюємо на об'єкт
    let payload = JSON.parse(contents);
    // якщо є властивість device
    if (payload.device) {
      LogToSheet (payload);
      retob.msg = 'logged succefull'
    } else {
      retob.error = 'device field not found'
    }
  } catch (error) {
    retob.error = error;
  }
 return ContentService.createTextOutput(JSON.stringify(retob)).setMimeType(ContentService.MimeType.JSON);
}
  • Збережіть проект
  • Використовуючи RESTED перевірте роботу інтерфейсу
    • виберіть метод POST
    • у якості URL використайте базовий адрес, що зкінчується на /dev
    • тип корисного навантаження виберіть JSON
    • добавте поля: device зі значенням testdevice та кілька інших полів зі значеннями
    • натисніть `Send requestі перевірте, що:
      • відповідь прийшла позитивна
      • запис добавився на лист testdevice у Google Sheet

image-20221207125150736

рис.4.9. Перегляд методу POST за допомогою RESTED

  • Збережіть запит в колекцію

6. Перевірка роботи через опублікований API

У попередніх пунктах використовувався API режиму розробника, URL якого не змінюється під час зміни проекту та новій публікації. У цьому пункті необхідно протестувати API режиму виконання, URL якого змінюється при кожній публікації нового серверу.

  • Опублікуйте змінений застосунок, при публікації скопіюйте URL-адесу.

image-20221207130922173

рис.4.10. Публікація нової версії застосунку

Цю адресу можна також буде знайти у будь який момент часу у пункті "Керування введенням в дію"

  • Протестуйте роботу методів GET і POST з скопійованим URL.

7. Перевірка роботи клієнта Web Application через curl

cURL — назва проєкту і крос-платформового програмного засобу, що служить для передачі даних через HTTP. Його можна використовувати як для тестування так і для реалізації обміну по HTTP через командний рядок.

У даному пункті cURL буде використовуватися як тестова утиліта. Але так само її можна запускати на різноманітних пристроях з ОС, наприклад для запису якихось значень з планувальника.

  • Завантажте cURL для Вашої ОС https://curl.se/download.html. Завантажуйте архіви з приміткою binary !
  • Розархівуйте папку у зручне для Вас місце, наприклад C:/temp
  • Запустіть командний рядок. Перейдіть у папку bin розархівованої папки. Для Windows це матиме приблизно такий вигляд:
cd C:\temp\curl-7.86.0_2-win64-mingw\bin
  • Виведіть довідку по cURL :
curl -h
  • Перевірте роботу методу GET наступним чином, де вставте URL вашого API режиму виконання:
curl -L https://script.google.com/macros/s/AKfycbyPDQrLEi20cmHw/exec
  • Перевірте отриманий результат.

Опція -L потрібна для того, щоб у випадку коли сервер повідомляє, що запитану сторінку переміщено в інше місце (позначене заголовком Location: і кодом відповіді 3XX), ця опція змусить curl повторити запит у новому місці (деталі). Google Apps Script працює саме через перенаправлення заради безпеки, тому ця опція потрібна.

  • Перевірте роботу методу POSTнаступним чином, де вставте URL вашого API режиму виконання:
curl -L https://script.google.com/macros/s/AKfycbyPDQrLEiQjV8YCLplk2FENdnEWssuQK0AVuhLkP8VckZXmJyyml5EtDBHynACJ20cmHw/exec -H "Content-Type:application/json" -d "{\"device\":\"testdevice\", \"field1\":\"1\", \"field2\":\"2\", \"field3\":\"3\"}"
  • Перевірте отриманий результат і що запис був записаний у лист Google Sheet.

У наведеному прикладі використовувалися опції:

  • -H для вказівки заголовку
  • -d для вказівки даних що передаються, що автоматично переключає утиліту в режим використання методу POST

Крім того, враховуючи щ в JSON форматі використовуються дужки, необхідно їх дзеркалювати зворотною косою \, щоб вони не були прийняті як частина синтаксису команди curl

8. Відправки даних з Mikrotik

У даному пункті необхідно реалізувати HTTP клієнта на маршрутизаторі Mikrotik, вірніше на віртуальній машині з ОС Mikrotik, який буде періодично відправляти повідомлення з вказівкою часу з моменту включення.

Для цього використовуються вбудовані в маршрутизатор скрипти на мові RouterOS (повний опис), які викликатимуться по певним подіям планувальника (повний опис).У межах цієї лабораторної роботи не будемо заглиблюватися в деталі реалізації, зупинимося лише на основних моментах.

Для обміну по HTTP в RouterOS використовується схожа за функціоналом до cURL вбудована утиліта Fetch . Це один із інструментів консолі в Mikrotik RouterOS, який як правило використовується для копіювання файлів на/з мережевого пристрою через HTTP/HTTPs, FTP або SFTP, але його також можна використовувати для надсилання запитів POST/GET і надсилання будь-яких даних на віддалений сервер

  • Запустіть віртуальну машину Mikrotik RouterOS
  • Залогуйтеся у консольному вікні віртуальної машини
  • Наберіть команду ip address print щоб дізнатися IP адресу віртуальної машини маршрутизатору
  • За вказаною адресою зайдіть на веб-консоль маршрутизатору і залогуйтеся
  • Перейдіть на закладку WebFig далі в розділ System->Scripts
  • Створіть новий скрипт з іменем periodic, наведений нижче, замінивши URL, на відповідний з вашого API
# send periodic message
:local upTime1 [/system resource get uptime];
:global URL "https://script.google.com/macros/s/0AVuhLkP8VckZXmJyyml5EtDBHynACJ20cmHw/exec"
:global httpdata1 ("{\"device\":\"router\", \"uptime\":\"" . $upTime1 . "\"}");
/tool fetch \
	http-method=post \
	http-header-field="Content-Type: application/json" \
	http-data=$httpdata1  \
	url=$URL
  • Натисніть Apply після чого Run Script. Зачекайте кілька секунд і у Gogle Sheet повинен з'явитися лист з відповідним записом.
  • Натисніть Ok

image-20221207151140977

рис.4.11. Створення скрипта для запису часу роботи на WEB застосунок

Прокоментуємо скрипт написаний вище

:local і :global - це інструкції для створення глобальних та локальних змінних. Так створюються наступні змінні.

  • Змінна upTime1 якій при створенні назначається значення з системної властивості /system resource get uptime (її значення можна подивитися на відповідній вкладці веб-консолі). За необхідності можна записувати аналогічним чином будь яку доступну властивість на маршрутизаторі.

  • Змінній URL назначається значення рядку що відповідає за URL.

  • Змінній httpdata1 назначається значення корисного навантаження. Зверніть увагу, що тут також використовується екранування

  • команда /tool fetch викликає утиліту fetch до якої передаються параметри:

    • http-method - метод
    • http-header-field - заголовки
    • http-data - тіло (корисне навантаження)
    • url
  • У веб-консолі Mikrotik перейдіть на закладку System->Scheduler. Натисніть Add New.

  • Створіть задачу яка буде запускати скрипт з іменем periodic кожні 5 хвилин. І натисніть Ok

image-20221207153148624

рис.4.12. Налаштування планувальника.

  • Через 5 хвилин проконтролюйте, що створився новий запис в таблиці Google Sheet.

Таким чином можна віддалено контролювати працездатність маршрутизатора, його доступ до інтернету та оцінювати час його перезавантаження.

9. Відправки даних з Android

У даному пункті у якості клієнта використовується мобільний застосунок, який за потребою користувача відправляє географічні координати та текстову примітку, яку він вводить. Таким чином, користувач може фіксувати певну інформацію вдповідно до локації, де він знаходиться.

Даний пункт передбачає використання смартфона під ОС Android з включеною геолокацією. Якщо у здобувача немає такої можливості, пункт можна не виконувати.

  • Встановіть на свій смартфон застосунок HTTP Shortcuts
  • Запустіть застосунок.
  • Створіть дві глобальні змінні (доступні для всіх ярликів) типу Static Variable, в яких вкажіть тільки назву:
  • geolacation
  • note

image-20221207165856214

рис.4.13. Створення змінних

  • Створіть новий Shortcut: натисніть + для добавлення, для якого (рис.4.14):

  • у виборі натисніть Regular Shorcuts.

  • надайте ім'я та виберіть піктограму.

  • у Basic request settiings вкажіть метод POST, а в рядок заголовку потрібний URL, який можна передати на смартфон наприклад через Telegram (пункт "Збережене")

  • у request body виберіть тип application/json та означте структуру тіла, в якому в якості імені пристрою передається myphone, у властивості location передається значення geolocation, а у властивості note значення змінної note (зверніть увагу на лапки!); для вставлення змінних використовується кнопка {}

  • у полі scripting для Run Before Execution (виконується перед запуском HTTP запиту) записати скрипт який буде записувати у значення змінних:

    • geolocation значення функції getGeolocation, яка повертає плинну позицію телефону
    • note результат виклику діалогової функції, яка попросить оператора ввести нотатку

image-20221207171108517

рис.4.14. Створення Shortcut

  • Збережіть Shortcut натиснувши галочку.
  • Запустіть на виконання, натиснувши по назві. Введіть користувацький текст на запрошення.
  • Перевірте чи результат прийшов без помилок.
  • Перевірте, що відповідний запис з'явився в листі Google Sheet myphone.

10. Реєстрація Telegram

  • Якщо у Вас немає облікового запису Telegram - завантажте клієнтський застосунок і створіть обліковий запис за посиланням. Це безкоштовно, потребується тільки номер телефону.
  • Знайдіть в телеграмі і додайте до своїх контактів @BotFather - це бот, який створює ботів
  • і введіть команду /start з'явиться вікно з доступними командами

img

рис.4.15. Доступні команди створення телеграм-бота

  • напишіть (або натисніть) команду /newbot для створення нового бота

img

рис.4.16. Команда створення телеграм-бота

  • дайте йому ім'я, наприклад RPI Ivanenko Ivana

img

рис.4.17. Надання імені телеграм-боту

  • тепер треба ввести ім'я користувача для бота, який повинен закінчуватися на Bot , наприклад RPI_IvanenkoIvana_Bot . За допомогою цього нікнейма можна знайти й додати вашого бота до своїх контактів.

img

рис.4.18. Надання імені користувача телеграм-боту

  • Збережіть токен, який видав бот, бо він нам знадобиться згодом для керування.
  • Добавте бота до своїх контактів t.me/<username>.
  • Відправте боту повідомлення /start

За допомогою RPI_IvanenkoIvana_Bot ви зможете завжди відредагувати своїх ботів. Перелік своїх ботів можна подивитися через команду /mybots де також можна отримати по ньому всю необхідну інформацію

11. Перевірка роботи з ботом через RESTED

  • Відкрийте RESTED
  • Зробіть запит GET в форматі:
https://api.telegram.org/botXXX:YYYY/getUpdates

де замість XXX:YYYY підставте маркер (токен) отриманий від бота.

У результаті бот відповість повідомленням з історією останніх повідомлень, наприклад:

{
  "ok": true,
  "result": [
    {
      "update_id": 60872760,
      "message": {
        "message_id": 514,
        "from": {
          "id": 7654321,
          "is_bot": false,
          "first_name": "Oleksandr",
          "last_name": "Pupena",
          "username": "pupena_san",
          "language_code": "uk"
        },
        "chat": {
          "id": 1234567,
          "first_name": "Oleksandr",
          "last_name": "Pupena",
          "username": "pupena_san",
          "type": "private"
        },
        "date": 1670484704,
        "text": "/start",
        "entities": [
          {
            "offset": 0,
            "length": 6,
            "type": "bot_command"
          }
        ]
      }
    }
  ]
}
  • Знайдіть в повідомленні id у структурі chat у прикладі це 1234567 і зробіть наступний запит POST за URL https://api.telegram.org/botXXX:YYYY/sendMessage (вставте туди токен) та наступним змістом body та заголовків:

image-20221208104533416

рис.4.19. Приклад відправки повідомлення sendMessage

Деталі по sendmsg можна почитати в оригінальному описі за посиланням

12. Перевірка Telegram бота в GAS

  • Створіть новий файл Google Scripts за допомогою кнопки + "Додати файл", дайте йому назву telegram
  • Впишіть туди наступний фрагмент коду і збережіть.
const token = 'XXX:YYYY';
const tgBotUrl = 'https://api.telegram.org/bot' + token;
const chat_id = 1234567

let payload = {
   chat_idchat_id,
   text'Привіт чатботу від Google Scripts!',
}  
sendToTelegram(payload);

function sendToTelegram(payload){
  let options = {
    method : 'post',
    contentType'application/json',
    headers: {"Content-Type":"application/json"},
    payloadJSON.stringify(payload),
    muteHttpExceptions: true 
  }
  // відправляє http запит з вказним URL та опціями
  return UrlFetchApp.fetch(tgBotUrl + '/sendMessage', options);
}
  • Запустіть код на виконання, погодьтеся з тим, що він буде використовувати доступ до ваших застосунків Google.

13. Створення коду для генерування повідомлення про стан маршрутизатору

У цьому пункті необхідно реалізувати фрагмент програми, яка буде перевіряти активність маршрутизатору і повідомляти по Телеграму власника про те, що маршрутизатор з'явився в мережі або зник з неї. Це буде відбуватися за наступним принципом. Оскільки маршрутизатор періодично (раз в 5 хв) відправляє повідомлення про себе, які пишуться в Google Sheet, то відсутнє повідомлення більше ніж за 5 хвилин говорить про його зникнення. При цьому запам'ятовується статус пристрою як відключений "isConnected" : "false". Коли пристрій з'являється статус знову стає "isConnected" : "true", а користувачу відправляється відповідне повідомлення.

Перевірка статусу проводиться раз/хвилину, для цього використовується вбудовані в Google Scripts таймерні тригери. Для збереження стану пристрою використовується властивості скрипта, які можна змінювати під час роботи.

  • Вимкніть віртуальну машину Mikrotik, якщо вона включена.

  • Закоментуйте усі частини коду, які використовувалися для тестування (тобто поза функціями) щоб вони не викликалися. У Вас повинно залишитися незакоментованими тільки функції, тобто:

  • doGet

  • doPost

  • LogToSheet

  • sendToTelegram

  • Додайте у властивості скрипта RouterStatus

{"device" : "router", "isConnected" : "false", "onConnect": "false", "onDisconnect": "false",  "lastupdate" : "", "uptime": ""}

image-20221208145959795

рис.4.20. Добавлення властивості скрипта

Це дасть можливість зберігати дані між викликами.

  • У частині файлу telegram.gs допишіть наступний фрагмент.
// зчитуємо стан маршрутизатору зі властивості скрипта
let RouterStatus = JSON.parse (PropertiesService.getScriptProperties().getProperty('RouterStatus'));
// обробляємо плинний статус
GetActivity (RouterStatus);
// зберігаємо плинний статус у властивості скрипта
PropertiesService.getScriptProperties().setProperty('RouterStatus', JSON.stringify(RouterStatus));

// функція обробки плинного статусу 
function GetActivity (status){
  let now = new  Date();
  let ss = SpreadsheetApp.getActive();  
  let sheets = ss.getSheets();
  let sheet = ss.getSheetByName(status.device);
  if (sheet) {
     // у другому рядку знаходиться останній запис від маршрутизатору
     // у другій комірці дата та час запису
     let dt = sheet.getRange (2,2,1,1).getValue();
     if (typeof dt == 'object') {
        let deviceupdate = new Date(dt);
        // різниця між плинною датою і датою фіксації в секундах
        let delta = (now - deviceupdate)/1000;
        // стан "підключео", якщо різниця менше 6 хвилин 
        let isConnected  =  delta < 360; 
        // стан тількино підключився
        status.onConnect =  isConnected === true && status.isConnected === false;
        // стан тількино віддключився        
        status.onDisconnect =  isConnected === false && status.isConnected === true;
        status.isConnected = isConnected;
        status.lastupdate = deviceupdate;
        // також користувачу може бути цікавим час роботи маршрутизатору
        status.uptime = sheet.getRange (2,3,1,1).getDisplayValue();
     }    
  }
  let text = '';
  // значення в локальному форматі дати та часу
  let localenow =  now.toLocaleDateString('uk-UA') + ' ' + now.toLocaleTimeString('uk-UA');
  let localedt = status.lastupdate.toLocaleDateString('uk-UA') + ' ' + status.lastupdate.toLocaleTimeString('uk-UA');
  if (status.onConnect === true) { // тільки но включився
    text = `${status.device} з'явився в мережі о ${localedt} час роботи ${status.uptime}`
  }
  if (status.onDisconnect === true) { // тільки но відключився
    text = `${status.device} зник з мережі десь між ${localedt} і ${localenow}, час роботи ${status.uptime}`
  }
  if (status.onDisconnect==true || status.onConnect == true){
    sendToTelegram({chat_idchat_id,text}); // відправляємо в Телеграм   
  }
}
  • Створіть тригер, який буде викликати скрипт кожну хвилину. Збережіть його.

image-20221208151349365

рис.4.21. Добавлення тригеру

  • Запустіть віртуальну машину з ОС Mikrotik. Дочекайтеся біля 5 хвилин, коли з'явиться повідомлення в Google Sheet. Десь ще через хвилину повинно прийти повідомлення про те, що маршрутизатор з'явився в мережі.
  • Виключіть віртуальну машину з ОС Mikrotik. Дочекайтеся біля 6-7 хвилин повинно прийти повідомлення про те, що маршрутизатор зник з мережі.