У статті розглядається, як розробити додаток Android IoT, що використовує Android Things. Більш детально, ця програма Android IoT надсилатиме дані, отримані від сенсорів, у хмару.
Додаток IoT допоможе нам представити деякі важливі аспекти щодо програмування додатків Android Things, які використовують сенсори.
Android Things - це нова IoT OS, розроблена компанією Google, яка забезпечує потужність Android для IoT. Використовуючи Android Things, ми можемо повторно використовувати знання Android, щоб створити додаток Android Things, використовуючи майже ті ж API. З цією метою ми розглянемо, як відправити дані, отримані сенсорами, безпосередньо в хмару, за допомогою платформи IoT cloud Ubidots. Крім того, цей пристрій Android IoT буде записувати всі дані, отримані сенсорами, у хмарі. Після цієї статті ви зможете розробити додаток Android Things з підтримкою хмари. Це типовий сценарій у проекті IoT, тому він корисний для дослідження. Крім того, ви можете додатково вдосконалити даний додаток Android IoT, щоб підтримувати інші види сенсорів або надсилати дані на іншу хмарну платформу. Це проект загального призначення, який можна налаштувати згідно з вашими потребами та технічними характеристиками вашої хмарної платформи. Якщо хочете спробувати іншу платформу IoT, ви можете прочитати цю статтю, де перераховані всі безкоштовні платформи IoT.
Навіть якщо платформа Google IoT чудово вписується в Android Things і надає кілька хмарних сервісів, Android Things не обмежується платформою Google IoT і може використовуватися в інших сценаріях з іншими платформами IoT.
Для побудови цього проекту ми будемо використовувати:
• Сенсор температури, тиску та вологості BMP280
• Raspberry Pi 3 з ОС Android Things
Крім того, додаток Android IoT використовує:
· Retrofit library
· Gson library
Як підключити Android Things до сенсора BMP280 та читати дані
На цьому кроці ми розглянемо, як підключити BMP280 до Android Things. BMP280 є сенсором I2C, тобто для підключення до нього потрібні чотири різних проводи:
• Vcc (+3В)
• GND
• CLK (сигнал тактування)
• SDA (дані)
Ми використовуємо плату Raspberry Pi 3, тому, відповідно до виводів плати, підключення виглядає так, як показано на малюнку нижче:
Як тільки правильно підключили дроти, можемо зосередити нашу увагу на розробці додатка Android IoT. Якщо ви вперше використовуєте Android Things, важливо прочитати цей підручник про те, як розпочати роботу з Android Things. У будь-якому разі, як перший крок, ви повинні клонувати сховище шаблонів з GitHub. Це порожній проект, створений для Android Studio, який ми будемо використовувати для створення нашого додатка Android IoT. Почнемо будувати додаток.
Першим кроком є додавання драйвера Android Things, який програма Android Things використовує для обміну даними з сенсором. Для цього відкрийте gradle.build (рівень додатка) і додайте наступний рядки:
dependencies {
....
compile 'com.google.android.things.contrib:driver-bmx280:0.4'
...
}
Мета цього додатка постійно отримувати дані від сенсора, тому необхідно застосувати той самий підхід, який використовується в Android, коли додаток моніторить сенсори.
Отримуйте дані від сенсорів, використовуючи Android Things: SensorManager, Listeners і Drivers
Android Things забезпечує елегантний спосіб відстежувати стан сенсора з використанням слухачів. У MainActivity додайте наступні рядки:
private Bmx280SensorDriver sensor;
private SensorManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
try {
manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
registerSensors();
sensor = new Bmx280SensorDriver(pin);
sensor.registerTemperatureSensor();
sensor.registerPressureSensor();
}
catch(IOException ioe) {
ioe.printStackTrace();
}
}
Зазначений вище код досить простий:
1. додаток отримує посилання від SensorManager
2. додаток реєструє сенсори, які слухаються для отримання сповіщення, коли сенсори отримують нові значення
3. ініціалізація драйвера BMP280
4. реєстрація динамічного зворотного виклику сенсора (температура і тиск)
Пропустимо зараз крок 2 та зосередимо нашу увагу на кроках 3 та 4. На кроці 3 додаток Android IoT створює новий екземпляр драйвера Bmx280Sensor, використовуючи ім'я виводу, до якого підключений сенсор. Для Raspberry Pi 3 це вивід - I2C1.
Перш ніж зареєструвати слухачів, щоб отримати нові значення від сенсорів, необхідно зареєструвати два різних слухача, які будуть повідомляти, коли сенсор підключений до Android Things. Даний сенсор BMP280 читає два фізичні параметри, тому він розглядається як два сенсори. Нарешті, код для реєстрації значення слухачів:
private void registerSensors() {
manager.registerDynamicSensorCallback(new SensorManager.DynamicSensorCallback() {
@Override
public void onDynamicSensorConnected(Sensor sensor) {
if (sensor.getType() == Sensor.TYPE_AMBIENT_TEMPERATURE) {
manager.registerListener(tempListener, sensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
else if(sensor.getType() == Sensor.TYPE_PRESSURE) {
manager.registerListener(pressListener, sensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
});
}
Спосіб onDynamicSensorConnected викликається, як тільки сенсор підключається до плати. У цей момент додаток може зареєструвати двох слухачів, які повідомлять, коли сенсор прочитає нові значення.
Останній крок - це читання даних з сенсора:
private SensorEventListener tempListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
// new value read
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
private SensorEventListener pressListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
// new value read
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Як ви вже здогадалися, в методі onSensorChanged програма надішле нове значення в хмару. На цьому етапі ви можете протестувати додаток Android IoT і перевірити, чи читає він дані сенсора. У будь-якому випадку, перш ніж використовувати додаток, слід додати ці дозволи в Manifest.xml:
<uses-permission
android:name="com.google.android.things.permission.MANAGE_INPUT_DRIVERS" />
<uses-permission
android:name="com.google.android.things.permission.MANAGE_SENSOR_DRIVERS" />
Налаштування Ubidots, щоб отримувати дані з додатка Android IoT
Цей крок описує, як налаштувати Ubidots для прийому даних із додатку Android Things. Перш ніж почати, потрібно мати безкоштовний обліковий запис Ubidots. Потім ми повинні налаштувати пристрій, який представлятиме наш пристрій. Ця тема також розкривається в декількох публікаціях у блозі, тому ми посилаємося на статтю:як налаштувати Ubidots для проекту IoT:
Наступним кроком буде додавання змінних, які зберігатимуть значення, надіслані з додатка Android:
Це все, всі наступні кроки, необхідні для налаштування Ubidots, завершені. Ми можемо зосередити увагу на останньому кроці надсилання даних у хмару.
Надсилання даних із Android Things в хмару
На цьому останньому кроці даного проекту додаток Android IoT надсилає дані в хмару. З цією метою додаток використовує бібліотеки, розроблені для додатків Android, що спрощують програмування додатків Android.
Ubidots виставляє набір API, який додаток може використовувати для надсилання даних. Це JSON API. У цьому контексті, бібліотеки Retrofit та Gson дуже корисні.
Додамо залежності в build.gradle:
dependencies {
...
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.google.code.gson:gson:2.8.2'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
}
Ubidots API, який викликає додаток, /api/v1.6/collections/values, який приймає масив JSON:
• ідентифікатор змінної
• значення змінної
де ідентифікатор змінної - унікальний ідентифікатор змінної, наданий Ubidots, а значення - це значення, яке надсилає додаток. Щоб розробити додаток Android IoT, який викликає цей API, ми використовуємо Retrofit. Коротко, ця бібліотека спрощує процес залучення JSON API. Для цього першим кроком є розробка інтерфейсу Java, що представляє виклик API:
public interface UbiAPI {
@POST("/api/v1.6/collections/values")
public Call<ResponseBody> sendValue(
@Body ArrayList<Data> dataList, @Query("token") String token);
}
Анотація @POST оголошує контекст API, а метод, визначений у інтерфейсі, являє собою метод, який програма запускає для надсилання даних. Цей метод приймає як тіло масив Data, так і токен, який ідентифікує наш додаток. Клас Data:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Data {
@SerializedName("variable")
@Expose
private String variable;
@SerializedName("value")
@Expose
private Double value;
public String getVariable() {
return variable;
}
public void setVariable(String variable) {
this.variable = variable;
}
public Double getValue() {
return value;
}
public void setValue(Double value) {
this.value = value;
}
}
Цей клас містить ідентифікатор змінної та значення і описує, як перетворити ці значення у формат JSON. Нарешті, ми повинні визначити клієнта, який обробляє зв'язок з Ubidots:
public class UbiClient {
private static final String TAG = UbiClient.class.getSimpleName();
private static final String UBI_BASE_URL = "http://things.ubidots.com/";
private static UbiClient client;
private UbiAPI api;
private Retrofit retroClient;
private UbiClient() {
retroClient = new Retrofit.Builder()
.baseUrl(UBI_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static final UbiClient getClient() {
if (client != null)
return client;
client = new UbiClient();
return client;
}
private UbiAPI getUbiClient() {
return retroClient.create(UbiAPI.class);
}
public void sendData(ArrayList<Data> dList, String token) {
api = client.getUbiClient();
Call c = api.sendValue(dList, token);
c.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
Log.d(TAG, "onResponse");
Log.d(TAG, "Result:" + response.isSuccessful());
}
@Override
public void onFailure(Call call, Throwable t) {
t.printStackTrace();
}
});
}
}
Це все. У нас ще є клієнт, який підключається до Ubidots і надсилає дані. На останньому кроці буде змінено код, показаний вище, де додаток зчитує значення сенсора та додає наступний код для надсилання даних у хмару:
private SensorEventListener tempListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
final Data dTemp = new Data();
dTemp.setValue( (double) event.values[0]);
dTemp.setVariable("59edbdc7c03f9721cc571662");
UbiClient.getClient().sendData(new ArrayList<Data>(){{
add(dTemp);
}}, token);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
private SensorEventListener pressListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
final Data dPress = new Data();
dPress.setVariable("59edbdcec03f97212ff872c6");
dPress.setValue( (double) event.values[0]);
UbiClient.getClient().sendData(new ArrayList<Data>(){{
add(dPress);
}}, token);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
Цікавим фрагментом коду є частина, яка надсилає дані, в яких додаток збирає інформацію для надсилання в хмару:
final Data dPress = new Data();
// Variable id
dPress.setVariable("59edbdcec03f97212ff872c6");
dPress.setValue( (double) event.values[0]);
UbiClient.getClient().sendData(new ArrayList<Data>(){{
add(dPress);
}}, token);
Не забудьте додати дозвіл на підключення до Інтернету в Manifest.xml
<uses-permission android:name="android.permission.INTERNET" />
Запускаємо додаток та отримуємо доступ до інформаційної панелі Ubidots:
Висновки
Дійшовши до кінця статті, ви, напевно, отримали знання про те, як зробити додаток Android IoT, який використовує Android Things для передачі даних у хмару. Крім того, ви отримали знання про використання сенсора I2C за допомогою Android Things.
(Джерело: survivingwithandroid.com)