СМС-термометр зв'язки з Google scipt, Google Doc, Wolfram-Alpha і Sms.ru

Всім привіт!
Захотів зробити так, щоб на мій простенький телефон вранці приходили оповіщення про поточну погоду (зрозуміло, безкоштовно). Тому, що немає звичайного термометра, з-за цього наскільки тепло потрібно одягатися, зрозуміло не завжди.
Кому цікаво, як я це реалізував — ласкаво просимо під кат.

Пошукавши щось подібне на хабре, я натрапив на цю статтю, звідки дізнався про сервіс sms.ru про Google script і інше, за що окреме спасибі.
Інформацію про погоду вирішив отримувати з Wolfram-Alpha. Чому вольфрам-альфа? В свій час мене підкорила рядок «дані взяті з метеостанції Баландине, 119 км від центру Златоуста». Тому мені хотілося брати інформацію саме з цього сайту.

Отже, для початку нам потрібно завести (якщо немає) аккаунт на Google, а так само зареєструватися на сервісі Sms.ru (якщо, знову ж, немає). Сервіс Sms.ru надає на момент написання статті 5 безкоштовних повідомлень на свій номер телефону (на їхньому сайті написано «для програмістів»).

Після успішної реєстрації, переходимо на гугл-диск (drive.google.com) і створюємо новий порожній документ. Даємо йому ім'я і чекаємо, поки він збережеться на диску.
Тепер переходимо на script.google.com, вибираємо Blank Project. Даємо майбутнього скрипту яке-небудь ім'я (скрипт також збережеться на гугл-диску). Видаляємо все, що там є.
Тепер вставляємо наступний код:

Код скрипта
function responseWeather()
{
//Тут вписується: місто, телефонний номер для доставки SMS, унікальний ID sms.ru код документа Google
var cityTown= "zlatoust";
var phoneNum="71111111111";
var apiID="111111111111111111111111111111111111";
var docID="11111111111111111111111111111111111111111111";

//Відкриваємо документ, в який будемо записувати відповідь з вольфраму 
var serverAv = false;
while (serverAv){
try {
DocumentApp.openById(docID);
serverAv=true;
} catch (e) {
Logger.log('Помилка відкриття');
}
}
var docmain = DocumentApp.openById(docID);
var bodydoc = docmain.getBody();
bodydoc.clear();//На всякий випадок очищаємо вміст
var response = UrlFetchApp.fetch("http://www.wolframalpha.com/input/?i="+cityTown+"+weather");
bodydoc.setText(response);
var textEdit = bodydoc.editAsText();
textEdit.deleteText(0, 37280); //Видаляємо початок документа, воно нам не потрібно

/*
При налагодженні температура видається в Цельсіях.
При запуску автоматом від тригера - у Фаренгейтах.
Аналогічно зі швидкістю вітру - m\s і mph соотв.
Наголошуємо, що будемо конвертувати.
*/
if (textEdit.findText('°C')!=null){
var degree = '°C';
var convert = false;
} else {
degree = '°F';
convert = true;
}
// Знаходимо всю потрібну інформацію
textEdit.deleteText(0, textEdit.findText(degree).getStartOffset()-5); 
textEdit.replaceText('</span><span class="info"><dt></dt><dd class="conditions">', ', ');
textEdit.replaceText('</dd><dt>', '; ');
textEdit.replaceText('wind:</dt><dd>', 'wind: ');
textEdit.replaceText('<span> at </span>', ' at ');
textEdit.replaceText('humidity:</dt><dd>', 'hum.: ');
textEdit.deleteText(textEdit.findText("%").getEndOffsetInclusive()+1, textEdit.findText('" />').getEndOffsetInclusive());
textEdit.replaceText('<span class="high">', ' (buf');
textEdit.replaceText('</span><span class="low">', '...fub'); 
textEdit.replaceText("</span>", ")</span>");
textEdit.deleteText(textEdit.findText("</span>").getStartOffset(), textEdit.getText().length-1);

//На початку для мітки залишалося кілька символів - тепер вони більше не потрібні, видаляємо
if (textEdit.findText('>')!=null){
textEdit.deleteText(0, textEdit.findText('>').getEndOffsetInclusive());
}

//Конвертація
if (convert==true){
//Конвертація першого значення температури
var buffer1 = textEdit.getText();
textEdit.deleteText(textEdit.findText(degree).getStartOffset(), textEdit.getText().length-1);
var len = textEdit.getText().length-1;
var buffer2 = Number(textEdit.getText());
bodydoc.clear();
var result = Math.round((buffer2-32)/1.8);
textEdit.setText(buffer1);
textEdit.deleteText(0, len);
textEdit.insertText(0, result);
//Конвертація другого значення температури
buffer1 = textEdit.getText();
textEdit.deleteText(0, textEdit.findText("buf").getEndOffsetInclusive());
textEdit.deleteText(textEdit.findText(degree).getStartOffset(), textEdit.getText().length-1);
len = textEdit.getText().length-1;
buffer2 = Number(textEdit.getText());
bodydoc.clear();
result = Math.round((buffer2-32)/1.8);
textEdit.setText(buffer1);
textEdit.deleteText(textEdit.findText("buf").getEndOffsetInclusive()+1, textEdit.findText("buf").getEndOffsetInclusive()+1+len);
textEdit.insertText(textEdit.findText("buf").getEndOffsetInclusive()+1, result);
//Конвертація третього значення температури
buffer1 = textEdit.getText();
textEdit.deleteText(0, textEdit.findText('fub').getEndOffsetInclusive());
textEdit.deleteText(textEdit.findText(degree).getStartOffset(), textEdit.getText().length-1);
len = textEdit.getText().length-1;
buffer2 = Number(textEdit.getText());
bodydoc.clear();
result = Math.round((buffer2-32)/1.8);
textEdit.setText(buffer1);
textEdit.deleteText(textEdit.findText('fub').getEndOffsetInclusive()+1,textEdit.findText('fub').getEndOffsetInclusive()+1+len);
textEdit.insertText(textEdit.findText('fub').getEndOffsetInclusive()+1, result);
//Конвертація скоррости вітру
buffer1 = textEdit.getText();
textEdit.deleteText(0, textEdit.findText('at ').getEndOffsetInclusive());
textEdit.deleteText(textEdit.findText('mph').getStartOffset(), textEdit.getText().length-1);
len = textEdit.getText().length-1;
buffer2 = Number(textEdit.getText());
bodydoc.clear();
result = Math.round(buffer2*0.44704);
textEdit.setText(buffer1);
textEdit.deleteText(textEdit.findText('at ').getEndOffsetInclusive()+1,textEdit.findText('at ').getEndOffsetInclusive()+1+len);
textEdit.insertText(textEdit.findText('at ').getEndOffsetInclusive()+1, result);
textEdit.replaceText('mph', 'm/s');
};
//Підчищаємо...
textEdit.replaceText('buf', ");
textEdit.replaceText('fub', ");
textEdit.replaceText(degree, "*C");

//Додаємо в кінець для якогось міста
textEdit.insertText(textEdit.getText().length, ' '+cityTown);

//Якщо раптом текст буде більше одного повідомлення, то видаляємо кінцівку
if (textEdit.getText().length>70){
textEdit.deleteText(69, textEdit.getText().length-1);
}
var textSMS = bodydoc.getText();

UrlFetchApp.fetch("http://sms.ru/sms/send?api_id="+apiID+"&to="+phoneNum+"&text="+encodeURI(textSMS));
bodydoc.clear();
}




Вставляєте у відповідні змінні необхідні дані.
Змінна cityTown — місто транслітом, для якого хочете отримувати погоду; phoneNum — номер, який ви зареєстрували на Sms.ru і, відповідно, на який будуть відправлятися безкоштовні СМС (без плюса і будь-яких роздільників); apiID — унікальний ідентифікатор сервісу Sms.ru, дивитися на відповідному сайті:


docID — унікальний ідентифікатор документа (не скрипта!) на гугл-диску. Знайти можна в адресному рядку:


Після того, як всі необхідні змінні заповнені, запускаємо скрипт. При першому запуску скрипт запросить дозвіл на роботу з посиланнями та документами на гугл-диску. Вирішуємо всі. Скрипт повинен відпрацювати, і на телефон прийде повідомлення.
Тепер залишилося задати автоматичний запуск. Для цього натискаємо на значок (1), вибираємо необхідний інтервал (2).



Так як мені потрібно було знати погоду рано вранці перед виходом на роботу, я виставив таймер на 7 годин ранку. Для себе я ще виставив сповіщення на пошту в разі помилки відпрацювання коду — в інтервалі «негайно».
Зберігаємо тригер. Тепер все готово, щоранку буде приходити повідомлення про поточну погоду.

Кілька зауважень з приводу коду. Я знаю javascript поверхнево, а google-script ще менше — тому, якщо є якісь зауваження по оптимізації, буду радий дізнатися. З приводу конвертації з Фаренгейта в Цельсій. Мабуть, Вольфраму передаються дані про місцезнаходження запиту, і він підлаштовує виводяться дані під регіон. Тому, коли налагодження скрипта йде в онлайн-режимі (при запуску вручну), гугл передає, що я з Росії, а Вольфрам відповідає Цельсієм і метрами в секунду. При запуску від тригера — Гугл каже, що я в Каліфорнії, з-за чого Вольфрам видає Фаренгейтом і милі в годину.

На майбутнє я планую ще зробити запит погоди через MMS — надсиланням повідомлення на поштову скриньку з текстом «місто погода» і отриманням відповідного повідомлення. Може бути, спірне рішення, просто у мене підключений давній пакет і MMS не особливо дорогі.

Звичайний термометр я-таки повісив, бо дружина наполягла потрібно було звірити отримані дані.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.