The ESP8266 chip is a great candidate for IoT development. It provides built-in 2.4GHz WiFi capabilities, has a multitude of different general purpose I/O (GPIO) pins available, and can take advantage of the extensive libraries available in the larger Arduino community - in fact many different commercial IoT devices use the ESP8266 chip.

Introduction

The Oracle Code Card is a Wi-Fi-enabled IoT device that's built around the ESP8266 microcontroller, and includes an e-paper display.

Oracle actually give these these away at their in-person events - amazing!

The Code Cards serve as a super-cool id-badge at the actual in-person events, and they also provide a platform for a bunch of hands-on learning and development exercises post event.

This post will outline a solution that I've built specifically for the Code Card platform: it's a serverless function that transforms your Code Card into an awesome, personalized id-badge.

Overview

The serverless function is designed to assemble and display a bitmap image which includes a unique card-owner identicon that's generated on-the-fly via a 3rd party API. Generation of the identicon avatar is based on a hash of the card owner's name.

Apart from turning your Code Card into a personalized id-badge, the avatar function is a great reference for building an Oracle function, which when invoked coordinates a number of interactions with a range of OCI services, external services, and the Code Card IoT device itself.

The avatar function is implemented as an Oracle Function (i.e. an OCI managed serverless function):

  • the function is invoked via an API published via the OCI API Gateway Service
  • the Oracle Function itself is written in Python: codecard-avatar/func.py
  • the function uses a custom container image based on oraclelinux:7-slim, and also includes rh-python36 and ImageMagick: codecard-avatar/Dockerfile

Operation

In reference to the workflow illustration, there are two main elements to the workflow:

  1. During the "Configure" phase, the Code Card is configured using the Code Card Configurator mobile application (here the Code Card unique ID and owner's name are registered in a database table hosted on Oracle APEX)

2. During the "Run" phase, the avatar function is then invoked by the Code Card via the API Gateway, which initiates a series of interactions with:

Combining the gathered artefacts the function proceeds to assemble the id-badge custom bitmap using ImageMagick, and directs the Code Card to download and display the image via the object storage service.

About Oracle Functions

Oracle Functions is a fully managed, highly scalable, on-demand, Functions-as-a-Service (FaaS) platform, built on enterprise-grade Oracle Cloud Infrastructure and powered by the Fn Project open source engine. With Oracle Functions, you can deploy your code, call it directly or trigger it in response to events, and get billed only for the resources consumed during the execution.

Oracle Functions are "container-native". This means that each function is a completely self-contained Docker image that is stored in your OCIR Docker Registry and pulled, deployed and invoked when you invoke your function.

Container Image

In order to make available each of the tools used during the functions operation (e.g. image manipulation, etc.) the avatar function is implemented using a BYO container image (see snippet following) - having this degree of latitude when working with Oracle functions comes in very handy.

FROM oraclelinux:7-slim
ENV OCI_CLI_SUPPRESS_FILE_PERMISSIONS_WARNING=True
ENV PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/rh/rh-python36/root/usr/bin:/opt/rh/rh-python36/root/usr/bin/oci:${PATH}"
ENV LC_ALL=en_US.utf8
ENV LANG=en_US.utf8
ARG CLI_VERSION=2.10.3
RUN mkdir /oci-cli
RUN mkdir /function
ADD requirements.txt /function/
WORKDIR /function
RUN yum -y install oracle-release-el7 && \
    yum -y install oracle-softwarecollection-release-el7 && \
    yum-config-manager --enable software_collections && \
    yum-config-manager --enable ol7_latest ol7_optional_latest ol7_addons && \
    yum-config-manager --disable ol7_ociyum_config && \
    yum -y install scl-utils && \
    yum -y install rh-python36 && \
    yum -y install gcc && \
    yum -y install wget && \
    yum -y install unzip && \
    yum -y install jq && \
    yum -y install ImageMagick && \
    export PATH=$PATH:/opt/rh/rh-python36/root/usr/bin && \
    rm -rf /var/cache/yum && \
    pip3 install --no-cache --no-cache-dir -r requirements.txt && rm -fr ~/.cache/pip /tmp* requirements.txt func.yaml Dockerfile .venv
WORKDIR /oci-cli
RUN wget -qO- -O oci-cli.zip "https://github.com/oracle/oci-cli/releases/download/v${CLI_VERSION}/oci-cli-${CLI_VERSION}.zip" && \
    unzip -q oci-cli.zip -d .. && \
    rm oci-cli.zip && \
    pip3 install oci_cli-*-py2.py3-none-any.whl && \
    yes | oci setup autocomplete && \
    groupadd --gid 1000 fn && \
    adduser --uid 1000 --gid fn fn
ADD . /function/
ENTRYPOINT ["/opt/rh/rh-python36/root/usr/bin/fdk", "/function/func.py", "handler"]

By specifying the runtime as docker in the func.yaml configuration file, the Fn CLI will build the custom container image as a part of the function deployment process. The entrypoint directive instructs the Python FDK to run the custom Code Card identicon script upon function invocation.

schema_version: 20180708
name: codecard-avatar
version: 0.0.1
runtime: docker
entrypoint: /python/bin/fdk /function/func.py handler
memory: 256

Solution work instruction

For a full work instruction, and access to the code - follow this link to the solution git repository.

For access to a range of other tools and demos built around the Code Card platform - this link to the Code Card git repository.

Photo by Jida Li on Unsplash