Реалізація AI-розпізнавання сцен для автоматизації розумного дому у мобільному додатку
Завдання звучить гарно: телефон «бачить» що відбувається в кімнаті та автоматично керує освітленням, климатом, шторами. На практиці — це зв'язка з трьох незалежних проблем: надійне розпізнавання сцени на пристрої без сервера, низьколатентне керування IoT-девайсами, й логіка автоматизації, яка не дратує користувача ложними спрацюваннями.
Розпізнавання сцени на пристрої: CoreML vs TFLite
Відправляти кадри з камери на сервер для класифікації — погана ідея для домашної автоматизації. Латентність 200–500ms неприйнятна, плюс приватність. Все повинно працювати локально.
iOS: CoreML + Vision framework
Apple Vision Scene Classification — вбудована модель VNClassifyImageRequest. Працює офлайн, видає VNClassificationObservation з confidence score:
import Vision
import CoreML
class SceneClassifier {
private lazy var request: VNClassifyImageRequest = {
let r = VNClassifyImageRequest { [weak self] request, error in
self?.handleResults(request.results as? [VNClassificationObservation])
}
return r
}()
func classify(pixelBuffer: CVPixelBuffer) {
let handler = VNImageRequestHandler(cvPixelBuffer: pixelBuffer, options: [:])
try? handler.perform([request])
}
private func handleResults(_ results: [VNClassificationObservation]?) {
guard let top = results?.filter({ $0.confidence > 0.6 }).first else { return }
// top.identifier: "bedroom", "kitchen", "living_room", "bathroom"
SmartHomeAutomation.shared.triggerScene(top.identifier)
}
}
VNClassifyImageRequest повертає 3000+ категорій — для розумного дому потрібні тільки ~20. Фільтруємо за confidence > 0.6 та релевантними ідентифікаторами. Не торкаємось кадрів частіше ніж раз в 2–3 секунди — Vision тримає 30 FPS, але класифікація кожні 2 секунди достатня та економить батарею.
Для кастомних сценаріїв (розпізнавання конкретної меблів, присутності людей у кадрі) — Create ML для дообучення MobileNetV3 на власному датасеті. Експорт в .mlpackage, розмір ~4 МБ.
Android: ML Kit Scene Detection + TFLite
ML Kit Subject Segmentation та Google ML Kit Scene Detection працюють офлайн на пристрої:
val image = InputImage.fromMediaImage(mediaImage, rotation)
val labeler = ImageLabeling.getClient(
ImageLabelerOptions.Builder()
.setConfidenceThreshold(0.65f)
.build()
)
labeler.process(image)
.addOnSuccessListener { labels ->
val sceneLabel = labels.firstOrNull { it.text in SMART_HOME_SCENES }
sceneLabel?.let { automationEngine.trigger(it.text, it.confidence) }
}
SMART_HOME_SCENES — множина з "bedroom", "kitchen", "living room", "bathroom", "office". Для кастомних моделей — TFLite Interpreter з файлом .tflite, оптимізованим під конкретні пристрої через TensorFlow Model Maker.
Персоналізована модель через TFLite Transfer Learning: 500–1000 фото на клас, Fine-tuning MobileNetV2, Export в INT8 quantized — розмір моделі ~2 МБ, inference < 50ms на Snapdragon 778G.
Інтеграція з IoT-автоматизацією
Розпізнавання сцени — це тільки триггер. Далі потрібна логіка автоматизації без ложних спрацьовувань.
Debounce та confidence threshold. Класифікатор може коливатися між "bedroom" та "living_room" при поганому освітленні. Паттерн: зміна сцени засчитується тільки якщо одна категорія домінує 3 секунди поспіль з confidence > 0.7:
class SceneDebouncer(private val windowMs: Long = 3000) {
private var currentScene: String? = null
private var firstSeenAt: Long = 0
fun process(scene: String, confidence: Float): String? {
if (confidence < 0.7f) return null
val now = System.currentTimeMillis()
if (scene != currentScene) {
currentScene = scene
firstSeenAt = now
return null
}
return if (now - firstSeenAt >= windowMs) scene else null
}
}
Команди IoT через MQTT або Matter. Після підтвердження сцени — публікуємо команду в MQTT-брокер або відправляємо через Matter controller:
// MQTT
mqttClient.publish(
"home/automation/scene",
MqttMessage("""{"scene":"bedroom","timestamp":${System.currentTimeMillis()}}""".toByteArray()),
qos = 1,
retained = false
)
// Matter SDK (через Google Home Mobile SDK)
val deviceController = ChipDeviceController()
deviceController.sendCommand(
nodeId = lightbulbNodeId,
endpointId = 1,
clusterId = OnOffCluster.CLUSTER_ID,
commandId = OnOffCluster.Commands.On.ID,
tlvData = byteArrayOf()
)
Розписання та контекст. Автоматизація за сценою повинна враховувати час доби: "bedroom" в 23:00 → приглушити світло, "bedroom" в 7:00 → розіпнути штори. Контекст добавляється через фільтр TimeOfDay у правилах автоматизації на рівні додатку.
Приватність: камера в домашньому контексті
Додаток з постійним доступом до камери — червоний прапор для користувачів та модераторів App Store/Google Play. Правила:
- Класифікація тільки коли користувач явно включив режим «Scene Detection»
- Жодні кадри не зберігаються та не покидають пристрій
- На iOS —
NSCameraUsageDescriptionз явним поясненням локальної обробки - Privacy manifest у iOS 17+ з декларацією
NSPrivacyAccessedAPICategoryCamera
App Store reject за 4.3 Spam або privacy violations за непрозору камеру — реальний ризик. Опис у App Privacy Report повинен бути чесним.
Етапи та строки
Аудит вимог: цільові пристрої, IoT-протоколи (MQTT, Matter, Zigbee через хаб, HomeKit), набір триггерних сцен. Розробка моделі класифікації: вбудована або кастомна з дообученням. Інтеграція з MQTT-брокером або Matter SDK. Реалізація логіки debounce та автоматизації. Тестування в реальних умовах — різне освітлення, кути камери, змішані сцени.
Базове розпізнавання з 5–10 сценами та MQTT-командами: 2–4 тижні. Кастомна ML-модель з дообученням + повна інтеграція з Matter/HomeKit: 2–3 місяці. Стоимість залежить від кількості підтримуваних IoT-протоколів та складності логіки автоматизації.







