Сервер домашньої метеостанції на Arduino - віджет для OS X
З'явився у мене комп'ютер Apple. Не сказати, щоб я про нього сильно мріяв, але вдалося купити б/у за прийнятну ціну, і я вирішився. Полмісяця пролежав він мертвим вантажем, і з'явилося час зайнятися ним. Після тижня спілкування розумієш, чому комп'ютери Apple вважають найкращими. Зовсім інший рівень спілкування.
Після перших захоплень, бажання щось запрограмувати. Робимо віджет для OS X для сервера домашньої метеостанції на Arduino.
Віджети представляють собою невеликі несамостійні програми з простим графічним інтерфейсом. У більшості випадків вони використовуються для швидкого отримання необхідної інформації з Інтернету і служать своєрідною альтернативою браузеру.
В операційній системі Mac OS X Lion передбачена зручна середа розробника, що дозволяє дещо полегшити цей процес. Ця програма отримала назву Dashcode. Завантажити програму Dashcode можна безкоштовно зі сторінки https://developer.apple.com/downloads/index.action,
для цього необхідно зареєструватися на сайті developer.apple.com.
Встановлюємо програму. У мене встановлена остання версія OS X - 10.9 Mavericks. При запуску програми Dashcode вона видає помилку:
Дана версія програми не може бути використана з даною версією OS X. Пропонують відкотитися до версії OS X 10.8. Виявляється, Apple не розробила додаток Dashcode для даної версії операційної системи ?!!! Пропонують почекати. ???? - уявляв раніше Apple компанією, де все до дрібниць.
Пробуємо запустити Dashcode в терміналі. Відкриваємо Finder -- Програми -- xcode44dashcode6938116a.dmg.
Для додатку Dashcode.app вибираємо Показати вміст пакета.
Через деякий час додаток з'являється в панелі Dock, але вікно не відкривається. Натискаємо на значок Dashcode і вікно програми відкрите.
Тепер можна розпочати програмування віджета.
Створюємо порожній проект, при цьому можна вибрати кілька стандартних шаблонів, але вибираємо Custom - користувацький.
Базовий віджет має основний і допоміжний стани (відповідно, front і back у лівій панелі). Перше відображається в звичайному режимі роботи, друге — для налаштування параметрів віджета. Переключатися між ними можна вибираючи відповідні пункти в списку компонентів зліва.
Відкриваємо бібліотеку компонентів — (кнопка Library справа вгорі) і перетаскуємо на віджет потрібні компоненти, тут мені достатньо компонентів типу Text для front і один компонент типу TextField для back. Тепер відкриваємо
Inspector (також кнопка справа вгорі) і з його допомогою налаштовуємо розміри, кольори і так далі для нашого віджета.
GUI нашого віджета готовий. Тепер можна запустити віджет на виконання і по натисканню кнопок i і Done виробляти переключення між панелями front і back.
Далі програмна реалізація віджета. Код пишеться на мові JavaScript. Правимо файл main.js.
Необхідно по таймеру раз у 2 хвилини звертатися за адресою 77.39.66.172:10001.
function startTimer(msec) { updateTimer = setTimeout("updateStats()", msec); } function stopTimer() { clearTimeout(updateTimer); } function updateStats() { alert("Це працює!"); execStatsRequest(); startTimer(updateInterval); }
При цьому будемо отримувати дані в форматі JSON. Після парсинга даних виводимо їх у відповідні поля віджета.
function execStatsRequest() { var Url = "http://"+ip_address; alert("Url= " + Url); xmlHttp = new XMLHttpRequest(); xmlHttp.onreadystatechange = processStatsRequest; xmlHttp.overrideMimeType('application/json'); xmlHttp.open("GET", Url, true); xmlHttp.send(); } function processStatsRequest() { if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { alert(xmlHttp.responseText); try { var data = JSON.parse(xmlHttp.responseText); document.getElementById("valT1").innerText =data.meteo.temp1; document.getElementById("valT2").innerText =data.meteo.temp3; document.getElementById("valH").innerText =data.meteo.humidity4; document.getElementById("valP").innerText =data.meteo.pressure5; var datenow=new Date(); var strdatetime=(datenow.getHours()<10) ? ("0"+datenow.getHours().toString()) :(datenow.getHours().toString()); strdatetime+=":"; strdatetime+=(datenow.getMinutes()<10) ? ("0"+datenow.getMinutes().toString()) :(datenow.getMinutes().toString()); strdatetime+=":"; strdatetime+=(datenow.getSeconds()<10) ? ("0"+datenow.getSeconds().toString()) :(datenow.getSeconds().toString()); strdatetime+=" "; strdatetime+=(datenow.getDate()<10) ? ("0"+datenow.getDate().toString()) :(datenow.getDate().toString()); strdatetime+="-"; strdatetime+=(datenow.getMonth()<9) ? ("0"+(datenow.getMonth()+1).toString()) :((datenow.getMonth()+1).toString()); strdatetime+="-"; strdatetime+=""+(datenow.getYear()+1900).toString()+""; document.getElementById("timeDay").innerText=strdatetime; } catch(e) { alert("помилка"); } } }
Також виводимо час останнього успішного отримання даних
Зворотна сторона віджета - зміна ip-адреси блоку датчиків. При виході з зворотного боку (натискаючи кнопку Готово) зберігаємо нове значення ip-адреси і робимо новий запит на отримання даних датчиків. Таймер на час видимості зворотного боку зупиняється.
function showBack(event) { var front = document.getElementById("front"); var back = document.getElementById("back"); if (window.widget) { widget.prepareForTransition("ToBack"); } front.style.display = "none"; back.style.display = "block"; if (window.widget) { setTimeout('widget.performTransition();', 0); } // stopTimer(); alert("showBack!"); } function showFront(event) { var front = document.getElementById("front"); var back = document.getElementById("back"); if (window.widget) { widget.prepareForTransition("ToFront"); } front.style.display="block"; back.style.display="none"; if (window.widget) { setTimeout('widget.performTransition();', 0); } // ip_address=document.getElementById("ipSensors").value; savePrefs(); //loadPrefs(); execStatsRequest(); startTimer(updateInterval); }
Також необхідно написати процедури збереження параметра (ip-адреси)
function loadPrefs() { var ip = widget.preferenceForKey("weatheripsensors"); ip_address=ip; document.getElementById("ipSensors").value=ip; } function savePrefs() { alert("зберегти="); widget.setPreferenceForKey(document.getElementById("ipSensors").value, "weatheripsensors"); }
Зберігати налаштування необхідно постійно, щоб показувати останні значення видане сервером метео, він часто зависає. Тепер у мене показання з домашніх датчиків не тільки на планшеті, але і на екрані Mac'а, який у мене завжди з собою на роботі.
І відео установки і роботи віджета (на відео варіант з 20 сек запитом даних)
В прикріплених файлах сам віджет і файли проекту
- weather41.zip (183 Кб)
- weather41_dcproj.zip (161 Кб)