You are viewing limited content. For full access, please sign in.



Using Laserfiche to Make Coffee: A Guide

posted on December 25, 2017 Show version history

This is a guide on how to start a coffee machine with an SMS message using Laserfiche and an Arduino micro-controller. I built this system about a year ago but haven't had a chance to write about it until now. If you're looking to "get your nerd on" over the holidays, it could be a fun project. smiley

What is Needed

  • 1 coffee machine with a flippable on/off switch (I used this thing)
  • 1 Arduino or similar microcontroller (I used an Arduino Uno)
  • 1 PowerTail Switch, basically a relay to interface with AC voltage
  • A gateway computer with an Internet connection
    • Arduino IDE (used to develop programs that run on the Arduino)
    • Processing (used to send signals to the Arduino via the USB port)
  • A web server
  • A web service on the web server that can receive webhooks and initiate workflows
  • A Twilio account with a phone number
  • Laserfiche Workflow


How It Works

  1. User sends an SMS message containing the word "on" or "off" to a phone number (acquired from Twilio)
  2. Twilio receives the text message and sends an HTTP POST to an endpoint on the web server
  3. The endpoint runs a simple application that is basically a wrapper around the workflow rest API. The application initiates a workflow with the SMS message content as input parameters
  4. Based on whether the SMS says "on" or "off", Workflow changes the contents of a text file on the web server to 1 or 0, respectively
  5. A program that runs on the gateway computer periodically (i.e. every 5 seconds) polls a virtual directory on the web server
  6. The endpoint serves the contents of the text file to the program
  7. The gateway computer sends the relevant signal to the Arduino based on the response
  8. Arduino turns the PowerTail Switch relay on or off, which turns the coffee machine on or off


Twilio Setup

This part is pretty straightforward. We create a Twilio account, buy a phone number (they're super cheap), then create a programmable SMS Messaging Service on Twilio and configure it to send webhooks to an endpoint on our web server.

Webhook Processor to Initiate Workflows

The webserver endpoint runs a simple application that receives the HTTP POST and starts a workflow with it. For me this is an ASP.NET application with a single controller:

using Webhooks.WorkflowRestAPI;
using System.Web.Mvc;
using System.Web.Configuration;
using System.IO;

namespace Webhooks.Controllers
    public class WorkflowsController : Controller
        // POST: /workflows/coffee/
        public string coffee()
            var config = WebConfigurationManager.OpenWebConfiguration("~");
            string endpoint = config.AppSettings.Settings["WorkflowWebURL"].Value + "/api/RestWorkflowAPI.svc";
            System.ServiceModel.EndpointAddress address = new System.ServiceModel.EndpointAddress(endpoint);

            Stream req = Request.InputStream;
            req.Seek(0, System.IO.SeekOrigin.Begin);
            string json = new StreamReader(req).ReadToEnd();

            using (WorkflowAPIBaseClient WorkflowService = new WorkflowAPIBaseClient())
                WorkflowService.Endpoint.Address = address;
                InstanceCreationData creationData = new InstanceCreationData();
                creationData.Initiator = new InstanceUserData();
                creationData.Initiator.InitiatorName = "Admin";

                InstanceParameterData webhookPayload = new InstanceParameterData();
                webhookPayload.Name = "payload";
                webhookPayload.Value = json;

                creationData.ParameterCollection = new InstanceParameterCollection();

                InstanceCreationResultData results = WorkflowService.CreateWorkflowInstance("Process Webhook", creationData);
                return results.instanceId;

You'll note that it uses the Workflow Rest API.

The "Process Webhook" Workflow

This is the workflow that is initiated by the web service. Note that it receives "payload" as an input parameter.


The conditional branches check the contents of the payload. The scripts inside the conditional branches change the contents of the text file on the hard drive to "0" or "1":

namespace WorkflowActivity.Scripting.Changetextfileto1
    using System.Text;
    using System.IO;

    public class Script1 : ScriptClass90

        protected override void Execute()
            File.WriteAllText(@"C:\My IIS Websites\Arduino\coffee.txt", "1");

Serving the Text File Contents on the Web Server

Next we make the contents of the text file available to requesters. This is also very easy. Simply create a virtual directory and map it to the folder containing the text file, and specify the Virtual Path:

We need to have Directory Browsing enabled and also Anonymous Access enabled, otherwise we won't be able to access specific files (i.e. the text file) via the web.

Code Running on the Gateway Computer

The gateway computer is responsible for periodically checking the text file on the web server and communicating the appropriate action to the Arduino that is connected to it via USB. There are many ways to do this. In my case I'm using an open-source development tool called Processing and I'm running the following Java program:

import processing.serial.*;
Serial ComPort;
String input[];

//Set up the serial port at 9600 baud
void setup() {
  String portName = Serial.list()[0];
  ComPort = new Serial(this, portName, 9600);

//Check a text file on the server and send its value to the serial port
void draw() {
  input = loadStrings("");
  if (input != null) {
    if(input.length != 0) {
      int status = Integer.parseInt(input[0]);
  delay(5000); //Check the text file every five seconds

Every 5 seconds, this program checks the text file on the server and sends the response as an integer to the serial port.

The setup() function has to set up the serial port at 9600 baud, since that's the bit rate the Arduino expects (seen in the next section).

Code Running on the Arduino

// control power socket
const int powerPin = A0;
int incomingByte;  //a variable to read incoming serial data 

void setup() {
  //initialize the Arduino by initiating serial communication at 9600 baud:
  Serial.println(F("starting up"));
  pinMode(powerPin, OUTPUT);
  digitalWrite(powerPin, HIGH);

//This function runs continuously
void loop() {

  // read serial messages
  if (Serial.available() > 0) {

    int key =;
    if (key == 1) { //Turn on the PowerTail Switch if text file on the server is "1"
      digitalWrite(powerPin, LOW);
    } else { //Turn off the PowerTail Switch if text file on the server is "0"
      digitalWrite(powerPin, HIGH);
    //read all the bytes in the serial buffer
    while (Serial.available()) incomingByte =;

Arduino has the above code running on it. It listens to the serial port and adjusts the power pin's voltage accordingly.

PowerSwitch Tail Relay

Lastly, the Arduino itself is connect to the PowerSwitch Tail relay, which turns the circuit on or off depending on the voltage on the connected Arduino socket. Here are a couple of pictures of my setup:

Final Thoughts

Obviously this system is a lot more complex than it needs to be. After all you can just buy an IoT coffee machine these days and use that instead of dealing with micro-controllers and circuits and web services! Still though, this was a lot of fun to develop and I learned a lot in the process too.

The nice thing about the whole thing is that you can replace the whole Twilio/SMS part with a simple Laserfiche form that kicks off the workflow. Then you also wouldn't need to deal with the web service and the workflow rest API. But SMS is probably more user-friendly in this case. You may also be able to ditch the gateway computer completely if you get an Arduino with built-in wifi.

Anyways, my coworkers initially got quite excited at the prospect of having fresh coffee ready for them in the morning. Unfortunately we realized someone would need to reload fresh coffee into the coffee machine after each batch. I need to figure out how to automate that part next. Time to buy some mechanical parts... laugh

Happy holidays!

22 0
replied on June 2

@Ege good start. 

I see that you have already spotted a few holes in the process - like getting fresh grains in there for the next brew. But there are a few other things you might need to consider.

1) the water level in the resevoir - this can be done by the arduino with a water level sensor. You could add a simple persistaltic pump (check out the 3d printed one on instructables) to keep the water level high enough to always be ready. Then you only need to fill an external resevoir.

2) then you may need a pressure sensor on the heated plate to make sure the pot is actually on there and maybe full still before starting another brew. This can be a simple scale e.g. 200grms = empty pot and 1kg = full pot. But that sensor would also have to handle the heat.

lastly to keep the Health and Safety police off your back you may need to be able to automatically switch off the machine if it has been on too long or your external water resevoir is empty.

I am quite sure there is more missing in this puzzle (if you can check out how they do it in the hot drinks dispensers - they are really interesting inside).

1 0
replied on June 2

I know this is an older post, but it's nice to see folks still fiddling to push boundaries a bit.

0 0
replied on September 30, 2019

Fantastic.  I wonder if you could utilize something in IFTTT instead of (or even with) Twilio, that way you could make a button on your phone to tap for turning it on/off

0 0
replied on December 27, 2017

Ok, this is AMAZING. smiley


0 0
replied on December 27, 2017

This is a great post, Ege. Lots of usable ideas here.

0 0
replied on December 26, 2017

Nice write up Ege.
I mentioned to my wife I might have finally found a practical use for my Raspberry Pi which was met with a resounding NO. :)   You did give me some ideas for alarms and flashing lights in the office whenever there is a suspended forms instance.   Hmmmm
Anyhow, enjoyed your post.  Thanks & Happy Holidays

~ Andrew

1 0
replied on December 27, 2017

It's a bit trickier with the Raspberry Pi because it (or at least the one I have) doesn't have an analog output by default, which makes it harder to directly interface with devices. But yeah, with some fiddling and mods it's definitely capable of doing similar stuff.

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.