epaperd

Note

The epaperd-code is being compiled using CMake. Check out the reference CMakeLists.txt at the bottom of this page.

The epaperd reference-program will will pick up PPM images (P6) from a given folder and use libepaper-central to send them to nearby OpenEPaperLink displays.

Image filenames are expected to be tag mac addresses (e.g. 00112233aabbccdd.ppm for a tag with mac address 00:11:22:33:aa:bb:cc:dd) with a fallback to default.ppm in case no specific image file exists for a tag – in this case the mac address will be visible on the display in addition until an applicable .ppm-file becomes available in the cache folder.

epaperds code provides a basic overview over the way-of-working with libepaper-central, the main snippet can be seen here:

epaperd.c

#include "epaper-central.h"

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "util.h"

//

struct EctrPixmap *img = NULL;
struct PpmData *default_image = NULL;

//

const char *serial_dev = "/dev/ttyACM0";
const char *cache_dir;

struct option opts[] = {
    { "help", no_argument, 0, 'h' },
    { 0, 0, 0, 0 }
};

void print_usage()
{
    printf("Usage: epaperd [-h] [D /dev/ttyACM0] </cache/directory>\n\n"

           "      -h, --help   Print usage info\n"
           "      -D <dev>     The ZigBee radio device (default: %s)\n\n", serial_dev);
}

void parse_options(int argc, char* const argv[])
{
    int c;
    while (1)
    {
        c = getopt_long(argc, argv, "D:h", opts, 0);
        if (c == -1) break;

        switch (c)
        {
        case 'h':
            print_usage();
            exit(0);
        case 'D':
            serial_dev = optarg;
            break;
        }
    }

    if (argc < optind + 1)
    {
        print_usage();
        exit(1);
    }
    cache_dir = argv[optind];
}

struct EctrPixmap *pixmap_for_tag(uint64_t mac)
{
    char smac[25];
    mac_to_string(smac, mac, 0);

    char filename[strlen(cache_dir)+22];
    sprintf(filename, "%s/%16s.ppm", cache_dir, smac);

    if (access(filename, F_OK) == 0)
    {
        struct PpmData *dat = load_ppm(filename);

        img = ectr_pixmap_from_rgb(dat->pixels, dat->len, dat->w);
        free(dat->pixels-dat->_pxlOffset);

        return img;
    }

    struct PpmData canvas;
    canvas.len = default_image->len;
    canvas.pixels = malloc(canvas.len);
    memcpy(canvas.pixels, default_image->pixels, canvas.len);

    canvas.w = default_image->w;
    canvas.h = default_image->h;

    mac_to_string(smac, mac, ':');
    smac[sizeof(smac)-1] = 0;
    ppm_draw_hex_text(&canvas, smac, 130, 110, 1); // red

    img = ectr_pixmap_from_rgb(canvas.pixels, canvas.len, canvas.w);
    free(canvas.pixels);

    return img;
}

int main(int argc, char* const argv[])
{
    parse_options(argc, argv);
    printf("Running epaperd v%u.%u.%u\n", ECTR_VERSION_MAJOR, ECTR_VERSION_MINOR, ECTR_VERSION_PATCH);

    cache_dir = argv[1];
    default_image = load_ppm(EPAPERD_DATA_DIR"/default.ppm");
    ectr_pixmap_for_tag_callback = &pixmap_for_tag;

    if (ectr_init(serial_dev))
    {
        printf("error: %s\n", ectr_error);
        exit(1);
    }

    while (1)
    {
        ectr_poll();
        if (img)
        {
            ectr_pixmap_free(img);
            img = NULL;
        }
    }

    return 0;
}

To see all additional sources and headers included by epaperd.c, check out the epaperd/ subdirectory of the main repository.

CMakeLists.txt

add_executable(epaperd
    epaperd.c
    util.c)

target_link_libraries(epaperd PRIVATE
    epaper-central)