Quantcast
Channel: Найцікавіше на DOU
Viewing all articles
Browse latest Browse all 8115

Android Things: барометр/термометр з Raspberry Pi 3 та клієнт на Android для нього

$
0
0

Відразу після анонсу Android Things мені закортіло отримати один з девайсів для тестування. Я вирішив зробити кімнатний барометр/термометр з можливістю віддаленого перегляду даних зі смартфону. Спочатку була ідея написати невеликий сервер для зберігання даних, але потім я згадав про існування Firebase Realtime Database. :)

Мною був обраний одноплатний комп’ютер Raspberry Pi 3. Крім нього був придбаний корпус, блок живлення, радіатори, а також барометр MP180.

Так це виглядає у зібраному вигляді:

Після монтажу можна приступати до написання коду. Для того, щоб розробляти під Android Things потрібно додати залежність до build.gradle:

provided 'com.google.android.things:androidthings:0.1-devpreview'

В AndroidManifest.xml в тегу Application потрібно вказати:

<uses-library android:name="com.google.android.things"/>

І також налаштувати intent-filter для вашої основної Activity. Це дозволить запускатись вашій аплікації разом з девайсом:

<intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.IOT_LAUNCHER"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter>

Для того, щоб підключити і працювати зі сторонніми девайсами, у Google розробили концепт User-Space Drivers, який дозволяє самостійно написати драйвер.
Для деяких девайсів вже є готові написані драйвери, знайти ви можете на GitHub Android Things.

На жаль, під мій датчик, на момент написання статті, готового драйвера не було, а писати самому було лінь. Але на GitHubя знайшов драйвер сторонньої реалізації, він і був використаний у проекті, за що і хочу подякувати автору.

Для написання був обраний Kotlin. По суті вся моя аплікація для Android Things складається з однієї Activity, в якій раз на 10 хвилин беруться покази з датчика і пишуться у Firebase для того, щоб потім їх зміг забрати мобільний Android клієнт. Для зручної реалізації таймера була використана RXJava.

private fun startSensorPolling() {
        disposable = getSensorDataAsFlowable()
                .repeatWhen { it.delay(10, TimeUnit.MINUTES) }
                .retryWhen { it.delay(10, TimeUnit.MINUTES) }
                .subscribe({ storeToDB(it) },
                        { Log.e(TAG, "Can't read data from sensor:", it) })
    }

    private fun storeToDB(data: Bmp180Data?) {
        val firebase = FirebaseDatabase.getInstance()
        val reference: DatabaseReference = firebase.getReference(SENSOR_DATA_REFERENCE)
        reference.push().setValue(data)
        Log.d(TAG, "${data.toString()}  saved into firebase")
    }

    private fun getSensorDataAsFlowable(): Flowable<Bmp180Data> {
        return Flowable.fromCallable { getSensorData() }
    }

    private fun getSensorData(): Bmp180Data {
        val temp = mBmp180.readTemperature()
        val press = mBmp180.readPressure()
        val alt = mBmp180.readAltitude()
        return Bmp180Data(temp.toInt(), press, alt.toInt())
    }

Далі напишемо клієнт для телефону. Для того щоб отримувати останній показ датчика, зареєструємо Firebase ChildEventListener і вкажемо ліміт

private val bmp180Reference: DatabaseReference by lazy { fireBase.getReference(CONNECTION_DATA_REFERENCE) }
private fun registerFirebaseListener() { bmp180Reference.orderByChild("date").limitToLast(1).addChildEventListener(this) }

І тільки з’являться нові дані у Firebase ми зможемо отримати їх у колбеці

    override fun onChildAdded(dataSnapshot: DataSnapshot?, p1: String?) {
        showContent()
        fillUI(dataSnapshot?.getValue(Bmp180Data::class.java))
    }

Ось і результат:

Код проекту доступний на GitHub. На зауваження, пропозиції з радістю дам відповіді у коментарях.


Viewing all articles
Browse latest Browse all 8115

Trending Articles