Реализация 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 фильтр в правилах автоматизации на уровне приложения.
Privacy: камера в домашнем контексте
Приложение с постоянным доступом к камере — красный флаг для пользователей и модераторов 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-протоколов и сложности логики автоматизации.







