Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером

в 10:47, , рубрики: cordova, groove, Intel Edison, intel xdk, IoT, ThingHTTP, ThingSpeak, ThingTweet, TweetControl, Twilio, twitter api, Блог компании Intel, программирование микроконтроллеров, Разработка для интернета вещей

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 1

Многие, кто в первый раз берёт в руки Intel Edison, не знают с чего начать. Сегодня мы узнаем, как создавать простые проекты с большими возможностями. Будет рассмотрено подключение к облачному сервису, реагирование на твиттер-сообщения, создание мобильных приложений Cordova, работа с эмулятором мобильного устройства и просмотр графиков по данным с сенсора, которые хранятся в облаке. Всё это стороны Internet of Things (IoT) — интернета вещей.

Данная статья содержит переработанные и дополненные материалы практической лаборатории интернета вещей Developer Kit SFTL005 проведённой на форуме разработчиков IDF15, проходившем 18-20 августа 2015 года в Сан-Франциско. Статья помогает разобраться, как использовать Intel Edison для построения законченного решения и описывает общие принципы, которые можно использовать в других проектах для интернета вещей.

Описана серия практических упражнений с использованием платформы Intel Edison, где показано, как установить и использовать Edison и программное обеспечение. Рассмотрено подключение платформы к интернету, работа к сенсорам и обмен данными с облачным сервисом. Рассказывается, как создать приложение, которое удаленно отслеживает состояние датчика прикосновения.

Intel IoT Developer Kit это законченное аппаратное и программное решение, которое помогает разработчикам попробовать себя в области интернета вещей и реализовать свой проект. Сам Intel Edison это небольшая, экономичная, но мощная вычислительная платформа, разработанная для создания прототипов и продуктов для интернета вещей и носимых устройств. Она управляется двухъядерным процессором Intel Atom с частотой 500 МГц, реализованном как система на чипе, и дополнительно содержащая 32-битный микроконтроллер Intel Quark с частотой 100МГц. Intel Edison имеет встроенные Wi-Fi и Bluetooth модули. Подробнее можно почитать в статье «Практикум «Intel IoT». Edison — могучая «кроха»».

Операционная система платформы Intel Edison основана на Yocto. Yocto Project – это проект с открытым исходным кодом, целью которого является упрощение разработки специальных дистрибутивов Linux для встраиваемых систем и обеспечение их переносимости между различными платформами.

Платформа Intel Edison также объединяет среду разработки Arduino с Linux системой, позволяя использовать системные вызовы и сервисы Linux в Arduino скетчах.
В разработке для платформы Intel Edison можно использовать JavaScript в среде Intel XDK, C/C++ в среде Eclipse, обычные скетчи в Arduino IDE и визуальное программирование в Wyliodrin. Также доступен Python и командная строка.
В этой статье будет рассказано, как создавать проекты для интернета вещей в Intel XDK на JavaScript, как их загружать на плату, запускать и отлаживать.

Ключевые элементы интернета вещей

Интернет вещей состоит из четырёх ключевых элементов: генератора данных, сборщика данных, облачного сервиса и принятия решений. Генераторы данных содержат в себе сенсоры. Набор Intel Developer Kit упрощает добавление сенсоров и актюаторов к IoT проекту и сбор информации. Информация, собранная на уровне устройства, передаётся в облачный сервис и затем доставляется конечному пользователю.

Нам потребуются следующие компоненты:

Детальные инструкции по сборке Intel Edison можно найти в статье «Assembling Intel Edison».

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 2

Начинаем

Если у вас новая плата, то необходимо обновить её прошивку. Сделать это надо и в том случаем, если вы давно этого не делали. Проверить номер версии прошивки (последняя на данный момент — 159) можно командой:

configure_edison --version

Чтобы загрузить последнюю версию и программу для прошивки, перейдите на Intel® Edison Board Software Downloads. Прочтите инструкцию, чтобы установить программу Intel Phone Flash Tool Lite и затем записать образ последней прошивки на плату Intel Edison.

Основные шаги:

  1. Установите инсталлятор драйверов для 64-разрядной Windows. Он также установит и среду разработки Arduino.
  2. Скачайте последнюю версию прошивки для Intel Edison. (На данный момент это 2.1)
  3. Скачайте программу Intel Phone Flash Tool Lite.
  4. Прошейте Intel Edison, используя скачанную прошивку.
  5. Установите последовательный терминал.

Настройка платформы Intel Edison

Если вы установили терминал по последовательному порту через USB, то вы можете настроить Intel Edison.
В консоли, на Intel Edison введите:

configure_edison --setup

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 3

Следуя подсказкам, установите пароль для пользователя root. Это необходимо для правильной работы среды Intel XDK. Также задайте имя платы, чтобы потом было проще найти её в сетевых устройствах. Убедитесь, что вы дали уникальное имя. Пожалуйста, не используйте имя «edison», так как обычно это приводит к проблемам с mDNS.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 4

Для подробного описания подключения Intel Edison к локальной сети Wi-Fi, посмотрите инструкцию.

После того как вы подключились к локальной сети Wi-Fi, введите:

wpa_cli status

Проверьте, что состояние соединения «COMPLETED» и присвоен IP адрес.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 5

Набор Seeed Studios Grove Starter Kit Plus

Набор «Seeed Studios Grove Starter Kit Plus» это коллекция различных сенсоров и актюаторов, которые можно использовать без какой-либо пайки. Набор содержит различные базовые модули и сенсоры для ввода и вывода. Инструкции по установки базового шилда и подключению компонентов можно найти в статьях «Ингредиенты IoT деликатесов быстрого приготовления: Intel Edison + Intel XDK + JavaScript + Grove Kit» и «Creating JavaScript-based Intel® IoT projects with the Grove — Starter Kit».

Установка Intel XDK IoT Edition

Intel XDK IoT Edition это бесплатный инструмент, который дает возможность создавать, тестировать, отлаживать и запускать приложения на Intel Edison. В нём есть примеры кода, которые взаимодействуют с датчиками и актюаторами. Он также предлагает список виртуальных мобильных устройств, которые разработчик может использовать для тестирования своего приложения. Чтобы скачать, установить и подключить Intel XDK к плате Intel Edison посмотрите статью «Getting Started with the Intel XDK IoT Edition».

Создание нового проекта

Новый проект можно создать либо из шаблона, либо оставить пустым. Мы рассмотрим по шагам создание простейшего проекта в Intel XDK для работы со световым датчиком.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 6

Создайте пустой проект и назовите его LightSensor.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 7

Примеры кода для сенсоров можно найти на странице с их описанием. Чтобы посмотреть пример кода для светового датчика, слева в выпадающем списке «Connection Type» выберите AIO и в показанном списке сенсоров найдите «Grove Light Sensor».

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 8

  • Скопируйте пример «Grove Light Sensor» на JavaScript в файл main.js проекта LightSensor, который вы только что создали.
  • Подключите модуль Intel Edison и компьютер к одной Wi-Fi сети.
  • Для изменения настроек Wi-Fi на платформе Intel Edison используйте:
    configure_edison --wifi
  • Для определения IP адреса на плате Intel Edison надо выполнить команду:
    wpa_cli status

Также можно установить на компьютер службу Bonjour, которая позволит определять IP адрес платы Edison автоматически в Intel XDK.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 9

В этом примере световой сенсор подключен к аналоговому входу A0.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 10

Постройте и загрузите проект LightSensor с использованием среды разработки Intel XDK IoT Edition.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 11

Запустите проект LightSensor.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 12

Облако ThingSpeak

Существует много облачных приложений для интернета вещей. В этой статье мы поговорим о ThingSpeak.
ThingSpeak это платформа, которая предлагает сервисы для построения IoT приложений. ThingSpeak включает сбор и обработку данных в реальном времени, визуализацию данных в форме диаграмм, графиков, возможность создавать плагины и приложения для ThingTweet, ThingHTTP, TweetControl, TimeControl, React и многого другого.
Для начала надо зарегистрировать аккаунт на thingspeak.com и создать новый канал.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 13

Канал это место, где ваше приложение хранит и получает данные с использованием ThingSpeak API. Каждый из них имеет уникальный идентификатор Channel ID. Когда приложение читает данные из канала, Channel ID используется для его идентификации. В каждом можно использовать до 8 полей данных. После того, как канал создан, ThingSpeak публикует и обрабатывает данные, которые ваш проект может затем получить. Если вы сделаете канал общедоступным, другие люди смогут найти его и получить доступ к данным. Если сделаете его закрытым, только вы получите к нему доступ.
Теперь дайте имя полям (Field 1, Field 2, ...), чтобы знать какие данные вы помещаете в них.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 14

Затем перейдите к вкладке ключей «API Keys» и получите ключ «writeKey» для записи и «readKey» для чтения.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 15

Простейший способ загрузки данных, это изменить значение поля вручную, используя специальный URL. Если в окне браузера появится «0», значит, возникла ошибка при посылке данных. В противном случае обновление было удачным. Значение «api_key» для запроса на обновление данных, это ранее описанный ключ «writeKey».

http://api.thingspeak.com/update?api_key=KSX88EAFTV19S2CH&field1="110"

Загрузка значения нескольких полей:

http://api.thingspeak.com/update?api_key=KSX88EAFTV19S2CH&field1="110"&field2="120"

ThingSpeak это IoT приложение с открытым исходным кодом. Чтобы начать использовать ThingSpeak на платформе Intel Edison, установите модуль клиента thingspeakclient через терминал.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 16

Сейчас вы готовы написать простое приложение с использованием ThingSpeakClient. URL адрес по умолчанию для ThingSpeakClient() это https://api.thingspeak.com

var ThingSpeakClient = require('thingspeakclient');
var client = new ThingSpeakClient();

По умолчанию включена задержка перед отправкой данных на сервер. Чтобы данные отправлялись немедленно, можно её выключить:

var client = new ThingSpeakClient({useTimeoutMode:false});

Если значение задержки задано, то каждая следующая порция данных будет отправляться через указанный промежуток времени.
Значение задержки по умолчанию для обновлений равно 15 секундам. Чтобы задать другую задержку, например, 20 секунд, сделайте следующее (время задается в миллисекундах):

var client = new ThingSpeakClient({useTimeoutMode:20000});

Для выполнения updateChannel() присоедините канал, используя или только ключ на запись «writeKey», или оба ключа — «readKey» на чтение и «writeKey» на запись. Если была задана callback функция, то она возвратит ошибку и ответ. В данном примере 50568 – это Channel ID, идентификатор канала.

Пример 1. ThingSpeak – Присоединение к каналу:

// Присоединение канала с ключом «writeKey» только для обновления канала
client.attachChannel(50568, {writeKey:'KSX88EAFTV19S2CH'}, callBack);
// Присоединение канала с ключами на запись и на чтение
client.attachChannel(50568, {writeKey:'KSX88EAFTV19S2CH', readKey:'B2PPOW7HGOCL4KZ6'}, callBack);

Пример 2: ThingSpeak — Обновление канала:

// Создание объекта светового сенсора, подключенного к A0
var light = new groveSensor.GroveLight(0);
var lightValue = light.value();

// Обновление поля field3 на канале
client.updateChannel(50568, { field3: lightValue }, function(err, response) {
});

Пример 3. ThingSpeak — getLastEntryInFieldFeed(), чтение данных:

client.getLastEntryInFieldFeed(50568, 3, function(err, response) {
    if (err == null) {
        console.log('read successfully. value is: ' + response.field3);
    }
});

Следующий пример объединяет работу со световым сенсором из проекта LightSensor с проектом ThingSpeak. Он читает значение со светового сенсора и загружает его в ThingSpeak.

var ThingSpeakClient = require('thingspeakclient');
var client = new ThingSpeakClient();

//var client = new ThingSpeakClient({useTimeoutMode:false});
var client = new ThingSpeakClient({updateTimeout:20000});

//var client = new ThingSpeakClient({useTimeoutMode:false});
// Set the timeout to 20 seconds (Default value is 15 secondes)
var client = new ThingSpeakClient({updateTimeout:20000});

var callBack = function(err) {
    if(!err) {
        console.log('error: ' + err);
    }
}

// Attached a channel with only a writeKey for update a channel:
//client.attachChannel(50568, {writeKey:'KSX88EAFTV19S2CH'}, callBack); // ok

// Attached a channel with both writeKey and readKey:
client.attachChannel(50568, {writeKey:'KSX88EAFTV19S2CH', readKey:'B2PPOW7HGOCL4KZ6'}, callBack);

// Load Grove module
var groveSensor = require('jsupm_grove');

// Create the light sensor object using AIO pin 0
var light = new groveSensor.GroveLight(0);

// Read the input and print both the raw value and a rough lux value.
// Upload the light value to field 3 of the channel.
function uploadLightValueToThingSpeak() {
    var lightValue = light.value();
    console.log(light.name() + " raw value is " + light.raw_value() +
            ", which is roughly " + light.value() + " lux");
    client.updateChannel(50568, { field3: lightValue }, function(err, response) {
        console.log('err = ' + err);
        console.log('response = ' + response);
        if (err == null && response > 0) {
            console.log('Update successfully. Entry number was: ' + response);
        }
    });
}
setInterval(uploadLightValueToThingSpeak, 20000);

Данные со светового сенсора публикуются в поле field3 «light» на канале в реальном времени:

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 17

ThingTweet

Приложение ThingTweet соединяет ваш твиттер-аккаунт с ThingSpeak и посылает твиттер-сообщение (твит) с использованием простого API.

  • Залогиньтесь на https://thingspeak.com/
  • Во вкладке «Apps» нажмите ThingTweet, затем нажмите «Link Twitter Account» для авторизации приложения, чтобы подтвердить правильность твиттер-аккаунта.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 18

Если у вас нет твиттер-аккаунта, зарегистрируйтесь на https://twitter.com и авторизируйте приложение.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 19

Сейчас вы сможете послать твиттер-сообщение через updateChannel(), передавая имя пользователя и сообщение, как показано ниже:

client.updateChannel(50568, { field3: lightValue,
                twitter: ' IoTIntelEdison ', tweet: ‘Intel Edison platform is awesome’},
function(err, response) {
    if (err == null && response > 0) {
        console.log('Update successfully. Entry number was: ' + response);
    }
});

Чтобы посмотреть свой твит, залогинтесь на twitter.com

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 20

ThingHTTP и Twilio

Приложение ThingHTTP позволяет вам присоединить устройства к веб-серверу посредством HTTP запросов. Для ThingHTTP доступны методы GET, POST, PUT, and DELETE. Twilio это ещё одна облачная платформа для коммуникации по SMS и телефонным звонкам. Она поддерживает HTTPs запросы и позволяет соединить ThingHTTP приложение с платформой Intel Edison. Ниже приведен пример посылки SMS сообщения при помощи Twilio через приложение ThingHTTP.

Чтобы начать, зайдите на Twilio и нажмите «Show API Credentials» для получения ACCOUNT_SID and AUTH_TOKEN.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 21

TweetControl

TweetControl слушает команды от Твиттера и затем выполняет действие. В примере ниже, TweetControl слушает Твиттер для запускающего слова «cool», а затем выполняет действие ThingHTTP «Twilio SMS».

  • Twitter Account — имя пользователя в Твиттере. Если включен «Anonymous TweetControl», тогда кто угодно может запускать ваш TweetControl.
  • Trigger – слово из твиттер-сообщения, включающее TweetControl, который надо выполнить.
  • ThingHTTP Action – запрос ThingHTTP для выполнения.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 22

Сейчас, когда ThingHTTP и TweetControl установлены, вы можете посылать сообщения из твиттер-аккаунта. В посылаемом твите должно быть указано ключевое слово — фильтр и запускающее слово — триггер. Фильтры могут быть следующие:

  • #thingspeak
  • thingspeak
  • #tweetcontrol
  • tweetcontrol

Структура твита:

filter trigger

Пример твита:

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 23

После того как вы послали твит «#thingspeak IntelEdison is so cool!», TweetControl включится по слову «cool» и заставит «Twilio SMS» ThingHTTP послать SMS-сообщение «Hello Intel Edison» на ваш телефон.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 24

TimeControl

TimeControl также может выполнить ThingHTTP запрос, но он будет выполнен автоматически по расписанию. Итак, создайте новый TimeControl и заполните форму следующим образом:

  • Name — имя для TimeControl.
  • Date и Time — выберите дату и время, когда TweetControl должен выполниться.
  • Action – необходимое действие. Выберите приложение ThingHTTP и затем выберите ThingHTTP запрос «Twilio SMS».

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 25

Когда срабатывает TimeControl, выполняется «Twilio SMS» приложения ThingHTTP и посылается текстовое сообщение «Hello Intel Edison» на мобильный телефон.

React

React выполняет ThingHTTP запрос или посылает ThingTweet сообщение, когда данные на вашем канале ThingSpeak удовлетворяют заданному условию. Посмотрите документацию, чтобы создать «Light React» для посылки твита «Your light is dim» («Свет погас») используя ThingTweet, когда значение яркости света будет меньше чем «6».

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 26

Создание приложение Touch Notifier и его запуск в эмуляторе

Среда разработки Intel XDK IoT Edition позволяет создавать приложения Cordova с использованием HTML5, CSS и JavaScript, чтобы отслеживать состояние сенсоров из набора Grove. Созданное приложение можно протестировать с использованием эмулятора или реального устройства. Мы создадим приложение «Touch Notifier», которое получает данные и уведомляет пользователя, изменяя цвет кружка на мобильном устройстве, если сенсор касания был активирован.

  • Чтобы увидеть список доступных шаблонов, перейдите слева в «Start a New Project» и под заголовком «Internet of Things Embedded Application» нажмите «Templates».
  • Выберите Touch Notifier и продолжайте создание нового проекта.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 27

  • Присоедините сенсор касания (Touch sensor) к разъёму платы расширения Grove, обозначенного как D2, а пищалку (Buzzer) к разъёму D6.
  • Подключите Intel XDK к плате Intel Edison, затем постройте и запустите приложение Touch Notifier на ней.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 28

Так как приложение Touch Notifier использует socket.io для создания HTTP сервера, убедитесь, что модуль socket.io установлен.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 29

Запомните номер порта 1337, который слушает веб-сервер, он понадобится позднее.
Чтобы создать приложение Apache Cordova, перейдите к «HTML5 Companion Hybrid Mobile for Web App» на вкладке слева, затем нажмите «Samples and Demos» и «General».
Чтобы показать список шаблонов, перейдите на вкладку «HTML5 + Cordova».
Для создания приложения нажмите «Touch Notifier Companion App».

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 30

Теперь вы находитесь на экране проекта «Cordova Touch Notifier».

  • Нажмите вкладку «Emulate» и выберите мобильное устройство из выпадающего списка в верхнем левом углу. По умолчанию это Motorola Droid 2.
  • Введите IP адрес платы Intel Edison, номер порта 1337 и затем нажмите «Submit». IP адрес платы Intel Edison можно получить командой «wpa_cli status» в её консоли. Заметьте, что Intel Edison должен находиться в той же Wi-Fi сети, что и сам компьютер.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 31

Если появится сообщение «Connection Error! Server Not Available», убедитесь, что приложение «Touch sensor» из секции «Internet of Things Embedded Application» всё ещё запущено. Теперь прикоснитесь к сенсору нажатия и посмотрите, что цвет кружка изменился на зелёный и воспроизведен звук из пищалки.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 32

Создание приложения Touch Notifier и его запуск на мобильном устройстве

Чтобы запустить приложение Cordova на физическом мобильном устройстве, таком как телефон, планшет или iPad, сделайте следующее:

  • Загрузите и установите приложение «Intel App Preview» из Google Play, Window Store или Apple AppStore.
  • Переключитесь на вкладку «Test» в «Intel XDK» и затем нажмите «I have installed app preview».

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 33

Если вы уведите следующее сообщение, нажмите «Sync», чтобы синхронизироваться с тестовым сервером.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 34

Мобильное устройство, компьютер и плата Intel Edison должна быть в той же локальной сетке, чтобы они могли общаться друг с другом.

  • Откройте «Intel® App Preview» на мобильном устройстве, переключитесь на «ServerApps» и запустите «Touch Notifier».
  • Подключитесь к Intel Edison, используя его IP адрес и порт 1337. Если появится сообщение «Connection Error! Server Not Available», проверьте, что приложение «Things Embedded Application» запущено.

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 35

Если подключение прошло успешно, приложение «Touch Notifier» запустится, как показано ниже:

Практическая работа с Intel IoT Developer Kit, Intel XDK, Edison, облаками и Твиттером - 36

Заключение

В этой статье мы описали, как настроить платформу Intel Edison, чтобы начать работу с сенсорами и обмен данными в облачном сервисе ThingSpeak. На странице «Sensors Bring IoT Projects to Life» можно узнать, какие ещё сенсоры доступны.
Мы рассмотрели достаточно простые проекты, но вы можете сами придумать, как использовать всю мощь платформы Intel Edison.

Ссылки

Автор: Intel

Источник


  1. Алексей:

    Вопрос автору статьи. Может Вы подскажете как реализовать следующее:
    Например текущие данные с field1 нужно отправить GET запросом на мой сервер на страницу data.php. Т.е нужно настроить так, чтоб отправлялся запрос вида http://host.ru/data.php?tr=field1 только вместо field1 чтоб было значение с этого поля. На хостинге соответственно лежит php файл который в любой момент готов принять значение переменной tr и записать ее в базу данных.

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js