Статьи

Обработка и анализ данных датчика: подход DIY

Этот пост был написан Марио Коппеном в блоге comSysto.

Воодушевленные текущим проектом клиента (и интересным характером проектов больших данных из отрасли в целом), мы решили получить данные датчиков. Мы хотели узнать, как обрабатывать, хранить и анализировать данные, а также с какими конкретными проблемами сталкиваются сенсорные данные.

Чтобы получить данные датчиков, мы решили сгенерировать свои собственные, поместив датчики в наш офис. Нам показалось, что  система кирпичей и кирпичей в Tinkerforge довольно удобна и проста для начала, поэтому мы выбрали этот вариант.

Мы получили следующие четыре сенсорных блока:

  • Интенсивность звука (в основном маленький микрофон)
  • температура
  • Мультитач-кирпич (можно подключить 12 самодельных сенсорных панелей из алюминиевой фольги)
  • Детектор движения

Четыре кирпича связаны с мастер-кирпичом, который, в свою очередь, подключен к Raspberry Pi.

Мы поместили датчик температуры в центральное место в офисе. Мы установили детектор движения в коридоре, ведущем на кухню и в ванную. Мы поместили датчик интенсивности звука рядом с дверью кухни и разместили сенсорные датчики на кофемашине, дверце холодильника и дверной ручке для мужской ванной комнаты.

Хотя это явно игрушечная установка (и вам придется долго ждать, пока данные станут большими), мы быстро столкнулись с некоторыми ключевыми проблемами, которые также возникают в реальных ситуациях с включенными датчиками.

В качестве решения для хранения данных мы выбрали MongoDB, главным образом потому, что оно также использовалось в проекте заказчика, который мотивировал лабораторию.

Данные, сгенерированные четырьмя датчиками, могут быть сгруппированы в две категории: в то время как датчики температуры и интенсивности звука выводят постоянный поток данных, детектор движения и сенсор Multi-Touch запускаются событиями, которые обычно не происходят с фиксированной частотой. ,

Это привело к появлению двух разных моделей документов в MongoDB. Для первой категории (потоковая передача) мы использовали модель, которую MongoDB фактически предлагает в качестве наилучшей практики для такой ситуации, и которую можно назвать «Модель временного ряда» (см. Http://blog.mongodb.org/post/65517193370/ проектирование схемы для временных рядов данных в mongodb ). Он состоит из одной коллекции с вложенными документами. Количество уровней вложенности и количество вложенных документов на каждом уровне зависит от временной детализации данных. В нашем случае самое высокое временное разрешение датчиков Tinkerforge составляет 100 мс, что приводит к следующей структуре документа:

  • Один документ в час
  • Поля: временная метка часа, тип датчика, значения
  • Values: nested set of subdocuments: 60 subdocuments for each minute, 60 subdocs for each second, 10 subdocs for each tenth of a second
{
    "_id" : ObjectId("53304fcd74fece149f175975"),
    "timestamp_hour" : "ISODate(2014-03-24T16:00:00)",
    "type" : "SI",
    "values" : {
        "10l" : {
            "05" : {
                "00" : -500,
                "01" : -500,
                "02" : -500,
                "03" : -500,
                "04" : -500,                 
                "05" : -500, 
                "06" : -500, 
                "07" : -500,
                "08" : -500,
                "09" : 0
            }
        }
    }
}

The documents are pre-allocated in MongoDB, initalizing all data fields to a value that is outside the range of the sensor data. This is done to avoid constantly growing documents which MongoDB would have to keep moving around on disk.

Data of the second type (event-driven/triggered) is stored in a “bucket”-like document model. For each sensor type, a number of documents with a fixed number of entries for the values (a bucket of size of e.g. 100) are pre-allocated. Events are then written into these documents as they occur. Each event corresponds to a subdocument which sits in an array with 100 entries. The subdocument carries the start and end time of the event as well as its duration. As the first record/event is written into the document, the overall document gets a timestamp corresponding to the start date/time. On each write to the database, the application checks whether the current record is the last fitting into the current document. If so, it sets the end date/time of the document and starts directing writes to the next document.

{
    "_id" : ObjectId("532c1f9774fece0aa9325a13"),
    "end" : ISODate("2014-03-21T12:18:12.648Z"),
    "start" : ISODate("2014-03-21T12:16:39.047Z"),
    "type" : "MD",
    "values" : [
        {
            "start" : ISODate("2014-03-21T12:16:44.594Z"),
            "length" : 5,
            "end" : ISODate("2014-03-21T12:16:49.801Z")
        },
        {
            "start" : ISODate("2014-03-21T12:16:53.617Z"),
            "length" : 5,
            "end" : ISODate("2014-03-21T12:16:59.615Z")
        },
        {
            "start" : ISODate("2014-03-21T12:17:01.683Z"),
            "length" : 3,
            "end" : ISODate("2014-03-21T12:17:05.147Z")
        },
        {
            "start" : ISODate("2014-03-21T12:17:55.223Z"),
            "length" : 5,
            "end" : ISODate("2014-03-21T12:18:00.470Z")
        }, 
        {
            "start" : ISODate("2014-03-21T12:18:04.653Z"),
            "length" : 7,
            "end" : ISODate("2014-03-21T12:18:12.648Z")
        }
    ]
}

These two document models represent the edge cases of a trade-off that seems to be quite common with sensor data.

The “Time Series” model suggested by MongoDB is great for efficient writing and has the advantage of having a nice, consistent schema: every document corresponds to a natural unit of time (in our case, one hour), which makes managing and retrieving data quite comfortable. Furthermore, the “current” document to write to can easily be inferred from the current time, so the application doesn’t have to keep track of it.

The nested structure allows for the easy aggregation of data at different levels of granularity – although you have to put up with the fact that these aggregations will have to be done “by hand” in your application. This is due to the fact that in this document model there are no single keys for “minute”, “second” and “millisecond”. Instead, every minute, second and millisecond has its own key.

This model has issues as soon as the data can be sparse. This is obviously the case for the data coming from the motion and multi-touch sensors: There is just no natural frequency for this data since events can happen at any time. For the Time Series document model this would mean that a certain fraction of the document fields would never be touched, which obviously is a waste of disk space.

Sparse data can also arise in situations where the sensor data does not seem to be event-driven at first. Namely, many sensors, although they measure data with a fixed frequency, only automatically output this data if the value has changed compared to the last measurement. This is a challenge one has to deal with. If one wanted to stick with the time series document model, one would have to constantly check whether values were omitted by the sensor and update the corresponding slots in the database with the last value that was sent from the sensor. Of course, this would introduce lots of redundancy in the database.

Continue reading here.