Explaining IIoT and event streaming projects with models
Tags: ruby, python, iot, raspberrypi
Published: 2020-08-27 15:01:31

## How to build a hardware IIoT factory product reader and replay data using the simulator

If you work in IT or on a developer team, you may find it hard to explain the benefits of data-heavy event streaming or industrial internet of things (IIoT) projects to external stakeholders. This is when a model or simulator comes in handy.

Creating a model of the IIoT solution you're proposing can help you demonstrate how it works and why it's valuable. Enabling stakeholders to see your solution in action helps everyone better understand the technical solution — this is key to getting their support. The model needs to be functional at a moment’s notice — you never know when people will stop by! It also needs to be easily adjusted and look professional. 

In this post, we will start building such a factory IIoT model by building a product-reader sensor, which records data from various scenarios — such as a normal constant product flow, start-and-stop modes and different types of incidents. 

We want to send the warmest thank you to the etventure tech guild team for their great support on building the model’s hardware and sensors! This wouldn’t be possible without your help.

![etventure tech guild at work](https://dev-to-uploads.s3.amazonaws.com/i/aexhzzjjszlqcpzjg1qb.jpeg)

We also share concepts and tips for developing a simulator software that replays the data streams at any point in time so programmers can use it for building their own prototypes. We already operate such a simulator software for vehicles – you can learn more in our ride hail blog post. 

## Concept for a product reader sensor in the IIoT factory model

Factories have different types of product flows going in or out of their machines. To keep the factory model abstract and flexible enough to cover as many use cases as possible we use a paper strip with QR codes. Each QR code has JSON data with a specified format encoded but the product data content is fully flexible. This way when reading the QR codes we can simulate different types of products and incidents by just directly encoding them into QR.

For the product data sensor we use a Raspberry Pi 4 with a camera module and a Python script scanning the QR codes. Additionally, the Raspberry Pi runs a software very similar to our open source IIoT Server. The changes we made allow it to record locally and also stream all sensor events and API command logs via VPN to a Kafka cluster we operate.

We arrange our camera and Raspberry Pi so we can drag along the paperstrip with QR codes underneath the setup. The factory software records the events and at the same time streams them to our Kafka cluster in the cloud. The recorded events we store in a “trace file” to be replayed later by our factory simulator software.

## Make paper strips with QR codes from JSON data

We are using the following Ruby script to make HTML pages with SVG QR codes. Store the file locally on your computer as “./make_qr_strip.rb”.

```ruby
require 'json'
require 'rqrcode'              

data_file = ARGV[0]
data = JSON.parse(File.open("./qr_data/#{data_file}.json").read)
    
qr_strip_html =
  '<div>' + data.map do |row|  
    row.map do |record|
      qrcode = RQRCode::QRCode.new(record.to_json)
      '<svg>' +  qrcode.as_svg(
        offset: 0,             
        color: '000',
        shape_rendering: 'crispEdges',  
        module_size: 6,
        standalone: false      
      ) + '</svg>'
    end.join
  end.join('</div><div>') + '</div>'

html_page = '<html><head><style type="text/css">svg { margin: 20px; width: 300px; height: 300px; }</style></head><body>' + qr_strip_html + '</body><html>' 
File.open("./qr_strips/#{data_file}.html", 'w') { |f| f.puts html_page }
```


Create a directory “./qr_data/” to store your different JSON files containing product data for your various scenarios. In our case it is named “factory_intro_1.json”. Add columns and rows as desired. The format for each file is as follows:

```json
[
  [                            
    {"name":"product_id","value":"123456","data":{"variant":"2b","color":"green"}},
    {"name":"product_id","value":"123451","data":{"variant":"2b","color":"green"}}
  ],
  [
    {"name":"product_id","value":"123452","data":{"variant":"2b","color":"green"}},
    {"name":"product_id","value":"123457","data":{"variant":"2d","color":"red"}}
  ]
]
```

Create a directory “./qr_strips/” the script stores your strips in. Finally, run `ruby ./make_qr_strip.rb <YOUR QR_DATA_FILENAME>` (e.g. `ruby ./make_qr_strip.rb factory_intro_1`) and find your strip as an HTML file in folder “./qr_strips/”. Open the strip file in a browser and print it out.

H2: Install your Raspberry Pi camera module and use it as a product reader sensor

Turn off your Raspberry Pi 4 and plug your camera module into it’s camera slot. Start the Raspberry Pi and in your “Raspberry Pi Configuration” menu in tab “Interfaces” to enable the camera.

To install our QR code reader script you need Python3 and pip3 installed. Next, install the following software libraries for video stream and image processing and QR code reading via `pip3 install opencv-python imutils pyzbar`.

Store the following script locally, e.g. in a file “./product_reader.py” and start the QR code scanning product reader in a terminal with command `python3 ./product_reader.py`.

```python
from __future__ import print_function
import pyzbar.pyzbar as pyzbar 
import numpy as np
import cv2
from picamera import PiCamera
from imutils.video import VideoStream
import argparse
import datetime
import imutils
import time
import requests
from time import sleep

print("Start Video Stream")
vs = VideoStream(usePiCamera=True).start()
time.sleep(2.0)

last_3 = [None, None, None]
json_type_header = {'Content-Type': 'application/json'}

while True:
    frame = vs.read()
    frame = imutils.resize(frame, width=400)
    qr_codes = pyzbar.decode(frame) 
    for qr_code in qr_codes:
        qr_data = qr_code.data.decode('utf-8')
        if last_3.count(qr_data) == 0:
            print(qr_data)
            # DO SOMETHING USEFUL
            # In our case a local HTTP request
            # print(resp.status_code)         
            # if resp.status_code == 400:     
                # print(resp.json())              
            last_3.pop(0)
            last_3.append(qr_data)
    time.sleep(0.5)
```

Put the QR code in front of your camera and your running script should output the data encoded in your QR code. On our model we use this script to send the scanned product data to our IIoT factory server software which then will record the event and send the data to our Kafka cluster.

![QR code product reader at work](https://dev-to-uploads.s3.amazonaws.com/i/2h26o6t0w8kv1fwyi7n7.gif)

As we do this we record a trace file that we can replay in the simulator later. It looks like this:

```
{"name":"product_id","value":"123456","data":{"variant":"2b","color":"green"},"timestamp":1598365799.4526498}
{"name":"product_id","value":"123452","data":{"variant":"2b","color":"green"},"timestamp":1598365804.0941744}
{"name":"product_id","value":"123458","data":{"variant":"2c","color":"gray"},"timestamp":1598365809.2619932}
{"name":"product_id","value":"123451","data":{"variant":"2b","color":"green"},"timestamp":1598365816.2038214}
{"name":"product_id","value":"123457","data":{"variant":"2d","color":"red"},"timestamp":1598365820.4342263}
{"name":"product_id","value":"123453","data":{"variant":"2b","color":"green"},"timestamp":1598365824.5778954}
```

Next, you have 2 options. Either you could build a simulator script yourself reading the trace file and all it’s events. For example, you could group all events of a certain time interval and then iterate over these event groups, stream them to your own Kafka cluster and pause for the time interval length in between.

Or create a free [Xapix Community Edition](https://cloud.xapix.io/users/sign_up) account and **[> CONTINUE READING <](https://xapix.io/post/explaining-iiot-and-event-streaming-projects-with-models?utm_source=dev-to&utm_medium=editorial&utm_campaign=IIoT)** the full version of the article on our Xapix blog.

## Join our IIoT community

We are working on numerous follow-ups to this blog-series and will be posting updates regularly within our Discord community to help inspire you on building IIoT models and simulators. We would love to hear your ideas too and collaborate on this fun project. 

Please contact us on our [Discord community channel](http://bit.ly/discord-xapix) if you would like to discuss this tutorial or if you have questions or feedback about the Xapix Community Edition. Or really anything else as well. We look forward to hearing from you.