<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Henri Bergius - Fbp</title>
    <description>Latest posts in category 'fbp'</description>
    <link>https://bergie.iki.fi</link>
    <language>en</language>
    <lastBuildDate>Tue, 05 May 2026 19:17:08 +0000</lastBuildDate>
    
    <item>
      
      <title>Flow-Based Programming, a way for AI and humans to develop together</title>
      <description>&lt;p&gt;I think by now everybody reading this will have seen how the new generation of &lt;a href=&quot;https://en.wikipedia.org/wiki/Large_language_model&quot;&gt;Large Language Models&lt;/a&gt; like ChatGPT are able to produce &lt;a href=&quot;https://tylerglaiel.substack.com/p/can-gpt-4-actually-write-code&quot;&gt;somewhat useful code&lt;/a&gt;. Like any advance in software development—from IDEs to high-level languages—this has generated some discussion on the future employment prospects in our field.&lt;/p&gt;

&lt;p&gt;This made me think about how these new tools could fit the world of &lt;a href=&quot;https://en.wikipedia.org/wiki/Flow-based_programming&quot;&gt;Flow-Based Programming&lt;/a&gt;, a software development technique I’ve been involved with for quite a while. In Flow-Based Programming these is a very strict boundary between reusable “library code” (called &lt;em&gt;Components&lt;/em&gt;) and the “application logic” (called the &lt;em&gt;Graph&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Here’s what the late &lt;a href=&quot;https://jpaulm.github.io&quot;&gt;J. Paul Morrison&lt;/a&gt; wrote on the subject in his seminal work, &lt;em&gt;Flow-Based Programming: A New Approach to Application Development&lt;/em&gt; (2010):&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Just as in the preparation and consumption of food there are the two roles of cook and diner, in FBP application development there are two distinct roles: the component builder and the component user or application designer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;…The application designer builds applications using already existing components, or where satisfactory ones do not exist s/he will specify a new component, and then see about getting it built.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Remembering that passage made me wonder, could I get one of the LLMs to produce useful &lt;a href=&quot;https://noflojs.org&quot;&gt;NoFlo&lt;/a&gt; components? Armed with &lt;a href=&quot;https://www.bing.com/new&quot;&gt;New Bing&lt;/a&gt;, I set out to explore.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/b8c302b0-c698-11ed-8b42-09bd596b6d87Robot%20software.png&quot; alt=&quot;AI and humans working together&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The first attempt was specifying a pretty simple component:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/new-bing-noflo-component.png&quot; alt=&quot;New Bing writing a component&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That actually looks quite reasonable! I also tried asking New Bing to make the component less verbose, as well as generating TypeScript and CoffeeScript variants of the same. All seemed to produce workable things! Sure, there might be some tidying to do, but this could remove a lot of the tedium of component creation.&lt;/p&gt;

&lt;p&gt;In addition to this trivial math component I was able to generate some that to call external REST APIs etc. Bing was even able to switch between HTTP libraries as requested.&lt;/p&gt;

&lt;p&gt;What was even cooler was that it actually &lt;em&gt;suggested&lt;/em&gt; to ask it how to &lt;em&gt;test the component&lt;/em&gt;. Doing as I was told, the result was quite astonishing:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/new-bing-fbp-spec.png&quot; alt=&quot;New Bing writing fbp-spec tests&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s &lt;a href=&quot;https://github.com/flowbased/fbp-spec&quot;&gt;fbp-spec&lt;/a&gt;! The declarative testing tool we came up with! Definitely the nicest way to test NoFlo (or any other FBP framework) components.&lt;/p&gt;

&lt;p&gt;Based on my results, you’ll definitely want to check the generated components and tests before running them. But what you get out is not bad at all.&lt;/p&gt;

&lt;p&gt;I of course also tried to get Bing to produce NoFlo graphs for me. This is where it stumbled quite a bit. Interestingly the results were better in the &lt;a href=&quot;https://github.com/flowbased/fbp#language-for-flow-based-programming&quot;&gt;fbp language&lt;/a&gt; than in the JSON graph format. But maybe that even more enforces that the &lt;em&gt;sweet spot would be AI writing components and a human creating the graphs that run those&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/28a14660-c698-11ed-8b42-09bd596b6d87Robot%20software.png&quot; alt=&quot;AI and humans working together&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As I’m not working at the moment, I don’t have a current use case for this way of collaborating. But I believe this could be a huge productivity booster for any (and especially Flow-Based) application development, and expect to try it in whatever my next gig ends up being.&lt;/p&gt;

&lt;p&gt;&lt;small&gt;Illustrations: MidJourney, from prompt &lt;em&gt;Robot software developer working with a software architect. Floating flowcharts in the background&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;
</description>
      <pubDate>Mon, 20 Mar 2023 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Ffbp-ai-human-collaboration%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/fbp-ai-human-collaboration/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/fbp-ai-human-collaboration/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
    <item>
      
      <title>Building c-base @ 35C3 with Flowhub</title>
      <description>&lt;p&gt;The &lt;a href=&quot;https://events.ccc.de/congress/2018/wiki/index.php/Main_Page&quot;&gt;35th Chaos Communication Congress&lt;/a&gt; is now over, and it is time to write about how we built the software side of the &lt;a href=&quot;https://c-base.org&quot;&gt;c-base&lt;/a&gt; assembly there.&lt;/p&gt;

&lt;h2 id=&quot;c-base-at-35c3&quot;&gt;c-base at 35C3&lt;/h2&gt;

&lt;p&gt;The Chaos Communication Congress is a major fixture of the European security and free software scene, with thousands of attendees. As always, the “&lt;a href=&quot;https://wiki.hackerspaces.org/c-base&quot;&gt;mother of all hackerspaces&lt;/a&gt;” had a big presence there, with a custom booth that we spend nearly two weeks constructing.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/c-base-assembly-35c3.JPG&quot; alt=&quot;the c-base assembly at 35C3&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This year’s theme was “Refreshing Memories”, and accordingly we brought various elements of the history of the c-base space station to the event. On hardware side we had things like a scale model the &lt;a href=&quot;https://en.wikipedia.org/wiki/Fernsehturm_Berlin&quot;&gt;c-base antenna&lt;/a&gt;, as well as vintage arcade machines and various artifacts from over the years.&lt;/p&gt;

&lt;p&gt;With software, we utilized &lt;a href=&quot;https://bergie.iki.fi/blog/flowhub-iot-workshop-c-base/&quot;&gt;the existing IoT infrastructure at c-base&lt;/a&gt; to control lights, sound, and drive videos and other information to a set of information displays. All of course powered by &lt;a href=&quot;https://flowhub.io/ide&quot;&gt;Flowhub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This was a quite full-stack development effort, involving microcontroller firmware programming, server-side NoFlo and MsgFlo development, and front-end infoscreen web design. We also did quite a bit of devopsing with Travis CI, Docker, and docker-compose.&lt;/p&gt;

&lt;h3 id=&quot;local-msgflo-setup&quot;&gt;Local MsgFlo setup&lt;/h3&gt;

&lt;p&gt;The first step in bringing c-base’s IoT setup was to prepare a “portable” version of the environment. An MQTT broker, MsgFlo, some components, and a graph with any on-premise c-base hardware or service dependencies removed. As this was for a CCC event, we decided to call it &lt;a href=&quot;https://github.com/c-base/c3-flo&quot;&gt;c3-flo&lt;/a&gt; (in comparison to the &lt;a href=&quot;https://github.com/c-base/c-flo&quot;&gt;c-flo&lt;/a&gt; that we run at c-base).&lt;/p&gt;

&lt;p&gt;We already have a quite nice setup where our various systems get built and tested on Travis, and uploaded to &lt;a href=&quot;https://hub.docker.com/u/cbase&quot;&gt;Docker Hub’s cbase namespace&lt;/a&gt;. Some repositories weren’t yet integrated, and so the first step was to Dockerize them.&lt;/p&gt;

&lt;p&gt;To make the local setup simple to manage, we decided to go with a &lt;a href=&quot;https://github.com/c-base/c3-flo/blob/master/docker-compose.yml&quot;&gt;single docker-compose environment&lt;/a&gt; that would start all systems needed. This would be easy to run on any x86 machine, and provide us with a quite comprehensive set of features from the IoT parts to NASA’s &lt;a href=&quot;https://bergie.iki.fi/blog/nasa-openmct-iot-dashboard/&quot;&gt;Open MCT dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Of course we kept adding to the system throughout 35C3, but in the end the graph looked like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c3-flo-35c3.JPG&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/c3-flo-35c3.JPG&quot; alt=&quot;c-base at 35C3 as seen in Flowhub&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;wifi-setup&quot;&gt;WiFi setup&lt;/h3&gt;

&lt;p&gt;To make our setup more portable, we decided to bring a local instance of the “c-base botnet” WiFi used to Congress. This way all of our IoT devices could work at 35C3 with the exact same firmware and networking setup as they do at c-base.&lt;/p&gt;

&lt;p&gt;Normally Congress doesn’t recommend running your own access point. But if needed, there are guidelines available on how to do it properly if needed. As it happens, out of this year’s 558 unofficial access points, the c-base one was the &lt;a href=&quot;https://media.ccc.de/v/35c3-9576-35c3_infrastructure_review&quot;&gt;only one conforming to the guidelines&lt;/a&gt; (commentary around the 25 minute mark).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/c-base-35c3-wifi.JPG&quot; alt=&quot;WiFi numbers from 35C3&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;info-displays&quot;&gt;Info displays&lt;/h3&gt;

&lt;p&gt;Like any station, c-base has a &lt;a href=&quot;https://github.com/msgflo/msgflo-browser&quot;&gt;set of info screens&lt;/a&gt; showing various announcements, timelines, and statistics. These are built with Raspberry Pi 3s running Chrome in Kiosk Mode, with a single-page webapp that connects to our MsgFlo infrastructure over WebSockets with &lt;a href=&quot;https://github.com/msgflo/msgflo-browser&quot;&gt;msgflo-browser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each screen has a customized rotation of different pages to show, and we can send URLs to announce events like members arriving to c-base or a space launch livestream via MQTT.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/c-base-infodisplay-35c3.JPG&quot; alt=&quot;c-base info screen showing an announcement&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For 35C3 we built a new set of pages tailed for the Congress experience:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Tweaked version of the normal c-base events view showing current and upcoming talks&lt;/li&gt;
  &lt;li&gt;Video player to rotate various videos from the history of c-base&lt;/li&gt;
  &lt;li&gt;Photo slideshow with a &lt;a href=&quot;https://www.flickr.com/photos/metavolution/albums/72157631227136604/&quot;&gt;nice set of pictures&lt;/a&gt; from c-base&lt;/li&gt;
  &lt;li&gt;Countdown screen for some event (c-base crash, teardown of the assembly at the end of Congress)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;crashing-c-base&quot;&gt;Crashing c-base&lt;/h2&gt;

&lt;p&gt;Highlight of the whole assembly was a re-enactment of the &lt;a href=&quot;https://en.wikipedia.org/wiki/C-base#Mythological_self-image_of_the_c-base&quot;&gt;c-base crash&lt;/a&gt; from billions of years ago. Triggered by a dropped bottle of space soda, this was an experience incorporating video, lights, and audio that we ran several times every day of the conference.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-crash-35c3-small.GIF&quot; alt=&quot;Crash Alarm!&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The c-base &lt;a href=&quot;https://github.com/c-base/c3-flo/blob/master/animations/crash.yml&quot;&gt;crash animation&lt;/a&gt; was managed by a &lt;a href=&quot;https://noflojs.org&quot;&gt;NoFlo&lt;/a&gt; graph integrated to the our MsgFlo setup with the standard &lt;a href=&quot;https://github.com/noflo/noflo-runtime-msgflo&quot;&gt;noflo-runtime-msgflo&lt;/a&gt; tool. With this we could trigger the “crash” with a MQTT message (sent by a physical button), and run a timed sequence of actions on lights, a sound system, and our info screens.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/c-base-35c3-crash-button.JPG&quot; alt=&quot;Button for triggering the crash of c-base&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;timeline-manager&quot;&gt;Timeline manager&lt;/h3&gt;

&lt;p&gt;There were some new components that we had to build for this purpose. The most important was a &lt;a href=&quot;https://github.com/noflo/noflo-tween/blob/master/components/Timeline.js&quot;&gt;Timeline component&lt;/a&gt; that was upstreamed as part of the &lt;a href=&quot;https://github.com/noflo/noflo-tween&quot;&gt;noflo-tween animation library&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/500x/noflo-tween-timeline.JPG&quot; alt=&quot;Timeline component from noflo-tween&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With this you can define a multi-tracked timeline as JSON or YAML, with actions triggered on each track on their appropriate second. With MsgFlo this meant we could send timed commands to different devices and create a coordinated experience.&lt;/p&gt;

&lt;p&gt;For example, &lt;a href=&quot;https://github.com/c-base/c3-flo/blob/master/animations/crash.yml&quot;&gt;our animation&lt;/a&gt; started by showing a short video on all info screens. When the bottle fell in the video, we triggered the appropriate soundtrack, and switched the lights through various animation modes. After the video ended, we switched to a “countdown to crash” screen, and turned all lights to a red alert mode.&lt;/p&gt;

&lt;p&gt;After the crash happened, everything went dark for a few seconds, before the c-base assembly was returned into its normal state.&lt;/p&gt;

&lt;h3 id=&quot;controlling-mclighting&quot;&gt;Controlling McLighting&lt;/h3&gt;

&lt;p&gt;All LED strips we used at 35C3 were run using the &lt;a href=&quot;https://github.com/toblum/McLighting&quot;&gt;McLighting firmware&lt;/a&gt;. By default it allows switching between different light modes with a &lt;a href=&quot;https://github.com/toblum/McLighting/wiki/WebSocket-API&quot;&gt;simple WebSocket API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For our requirements, we wanted the capability to send new commands to the lights with minimal latency, and to be able to restore the lights to whatever mode they had before the crash started in the end.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/500x/noflo-mclighting.JPG&quot; alt=&quot;noflo-mclighting in action&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The component is available in &lt;a href=&quot;https://github.com/noflo/noflo-mclighting&quot;&gt;noflo-mclighting&lt;/a&gt;. The only thing you need is running the NoFlo graph in the same network as the LED strips, and to send the WebSocket addresses of your LED strips to the component. After that you can control them with normal NoFlo packets.&lt;/p&gt;

&lt;h2 id=&quot;finally&quot;&gt;Finally&lt;/h2&gt;

&lt;p&gt;The whole setup took a couple of days to get right, especially regarding timings and tweaking the light modes. But, it was great! You can see &lt;a href=&quot;https://vimeo.com/309632677&quot;&gt;a video of it&lt;/a&gt; below:&lt;/p&gt;

&lt;iframe src=&quot;https://player.vimeo.com/video/309632677&quot; width=&quot;640&quot; height=&quot;360&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot; mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;And if you’re interested in experimenting this stuff, check out the “portable c-base IoT setup” at &lt;a href=&quot;https://github.com/c-base/c3-flo&quot;&gt;https://github.com/c-base/c3-flo&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Sat, 05 Jan 2019 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Fcbase-35c3-flowhub%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/cbase-35c3-flowhub/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/cbase-35c3-flowhub/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
    <item>
      
      <title>MicroFlo and IoT: measuring air quality</title>
      <description>&lt;p&gt;Fine particulate matter is a serious issue in many cities around the world. In Europe, it is &lt;a href=&quot;https://ec.europa.eu/jrc/en/news/air-quality-atlas-europe-mapping-sources-fine-particulate-matter&quot;&gt;estimated to cause&lt;/a&gt; 400.000 premature deaths per year. European Union has published standards on the matter, and warned several countries that haven’t been able to reach the safe limits.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Germany saw the highest number of deaths attributable to all air pollution sources, at 80,767. It was followed by the United Kingdom (64,351) and France (63,798). These are also the most populated countries in Europe. (source: &lt;a href=&quot;http://www.dw.com/en/air-pollution-kills-half-a-million-people-in-europe-eu-agency-reports/a-40920041&quot;&gt;DW&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The associated health issues don’t come cheap: 20 billion euros per year on health costs alone.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“To reduce this figure we need member states to comply with the emissions limits which they have agreed to,” Schinas said. “If this is not the case the Commission as guardian of the (founding EU) treaty will have to take appropriate action,” he added. (source: &lt;a href=&quot;https://phys.org/news/2018-01-eu-summons-france-germany-uk.html&quot;&gt;phys.org&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One part of solving this issue is better data. Government-run measurement stations are quite sparse, and — in some countries — their published results can be unreliable. To solve this, &lt;a href=&quot;https://okfn.de/en/&quot;&gt;Open Knowledge Foundation Germany&lt;/a&gt; started the &lt;a href=&quot;https://luftdaten.info/&quot;&gt;luftdaten.info&lt;/a&gt; project to crowdsource air pollution data around the world.&lt;/p&gt;

&lt;iframe src=&quot;https://player.vimeo.com/video/257288126&quot; width=&quot;640&quot; height=&quot;360&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot; mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Last saturday we hosted a luftdaten.info workshop at &lt;a href=&quot;https://c-base.org/&quot;&gt;c-base&lt;/a&gt;, and used the opportunity to build and deploy some particulate matter sensors. While &lt;a href=&quot;https://luftdaten.info/en/construction-manual/&quot;&gt;luftdaten.info has a great build guide&lt;/a&gt; and we used their parts list, we decided to go with a &lt;a href=&quot;https://github.com/c-base/microflo-luftdaten&quot;&gt;custom firmware&lt;/a&gt; built with MicroFlo and integrated with the existing IoT network at c-base.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/luftdaten-sensor-workshop2.jpg&quot; alt=&quot;Building an air quality sensor&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;microflo-on-esp8266&quot;&gt;MicroFlo on ESP8266&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://microflo.org/&quot;&gt;MicroFlo&lt;/a&gt; is a flow-based programming runtime targeting microcontrollers. Just like NoFlo graphs run inside a browser or Node.js, the MicroFlo graphs run on an Arduino or other compatible device. The result of a MicroFlo build is a firmware that can be flashed on a microcontroller, and which can be live-programmed using tools like &lt;a href=&quot;https://flowhub.io/iot/&quot;&gt;Flowhub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;ESP8266 is an Arduino-compatible microcontroller with integrated WiFi chip. This means any sensors or actuators on the device can easily connect to other systems, like we do with &lt;a href=&quot;https://github.com/c-base/c-flo/tree/master/devices&quot;&gt;lots of different sensors&lt;/a&gt; already at c-base.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/luftdaten-sensor-esp8266.jpg&quot; alt=&quot;ESP8266 sensor in preparation&quot; /&gt;&lt;/p&gt;

&lt;p&gt;MicroFlo &lt;a href=&quot;https://github.com/microflo/microflo/blob/master/CHANGES.md#microflo-063&quot;&gt;recently added&lt;/a&gt; a feature where Wifi-enabled MicroFlo devices can automatically connect with a MQTT message queue and expose their in/outports as queues there. This makes MicroFlo on an ESP8266 a fully-qualified &lt;a href=&quot;https://msgflo.org/&quot;&gt;MsgFlo participant&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;building-the-firmware&quot;&gt;Building the firmware&lt;/h2&gt;

&lt;p&gt;We wanted to build a firmware that would periodically read both the DHT22 temperature and humidity sensor, and the SDS011 fine particulate sensor, even out the readings with a running median, and then send the values out at a specified interval. MicroFlo’s &lt;a href=&quot;https://github.com/microflo/microflo-core&quot;&gt;core library&lt;/a&gt; already provided most of the building blocks, but we had to write &lt;a href=&quot;https://github.com/c-base/microflo-luftdaten/tree/master/components&quot;&gt;custom components&lt;/a&gt; for dealing with the sensor hardware.&lt;/p&gt;

&lt;p&gt;Thankfully Arduino libraries existed for both sensors, and this was just a matter of wrapping those to the MicroFlo component interface.&lt;/p&gt;

&lt;p&gt;After the components were done, we could build the firmware &lt;a href=&quot;http://app.flowhub.io/#github/c-base/microflo-luftdaten&quot;&gt;as a Flowhub graph&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://app.flowhub.io/#github/c-base/microflo-luftdaten&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/microflo-luftdaten-graph.png&quot; alt=&quot;MicroFlo luftdaten graph&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To verify the build we enabled &lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis CI&lt;/a&gt; where we build the firmware both against the MicroFlo Arduino and Linux targets. The Arduino one is there to verify that the build works with all the required libraries, and the Linux build we can use for test automation with &lt;a href=&quot;https://github.com/flowbased/fbp-spec&quot;&gt;fbp-spec&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To flash the actual devices you need the &lt;a href=&quot;https://www.arduino.cc/en/Main/Software&quot;&gt;Arduino IDE&lt;/a&gt; and Node.js. Then use MicroFlo to generate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.ino&lt;/code&gt; file, and flash that to the device with the IDE. WiFi and MQTT settings can be tweaked in the &lt;a href=&quot;https://github.com/c-base/microflo-luftdaten/blob/master/secrets.example.h&quot;&gt;secrets.h&lt;/a&gt; and &lt;a href=&quot;https://github.com/c-base/microflo-luftdaten/blob/master/config.h&quot;&gt;config.h&lt;/a&gt; files.&lt;/p&gt;
&lt;h2 id=&quot;sensor-deployment&quot;&gt;Sensor deployment&lt;/h2&gt;

&lt;p&gt;The recommended weatherproofing solution for these sensors is quite straightforward: place the hardware in a piece of drainage pipe with the ends turned downwards.&lt;/p&gt;

&lt;p&gt;Since we had two sensors, we decided to install one in the patio, and the other in the c-base main hall:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/luftdaten-sensor-mainhall.jpg&quot; alt=&quot;Particulate matter sensor in c-base main hall&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;working-with-the-sensor-data&quot;&gt;Working with the sensor data&lt;/h2&gt;

&lt;p&gt;Once the sensor devices had been flashed, they became available in &lt;a href=&quot;https://github.com/c-base/c-flo&quot;&gt;our MsgFlo setup&lt;/a&gt; and could be connected with other systems:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/luftdaten-sensor-msgflo.png&quot; alt=&quot;Particulate matter sensor in c-base main hall&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In our case, we wanted to do two things with the data:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Log it in the c-base telemetry system to be &lt;a href=&quot;https://bergie.iki.fi/blog/nasa-openmct-iot-dashboard/&quot;&gt;visualized with NASA OpenMCT&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Submit the data from the outdoor sensor to the &lt;a href=&quot;https://luftdaten.info/&quot;&gt;luftdaten.info database&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first one was just a matter of adding &lt;a href=&quot;https://github.com/c-base/cbeam-telemetry-server/pull/61&quot;&gt;couple of configuration lines&lt;/a&gt; to our OpenMCT server. For the latter, I built a &lt;a href=&quot;https://github.com/c-base/c-flo/blob/master/components/SendToLuftDaten.py&quot;&gt;simple Python component&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Our sensors have been tracking for a couple of days now. The public data can be seen in &lt;a href=&quot;https://www.madavi.de/sensor/graph.php?sensor=msgflo-00000042-sds011&quot;&gt;the madavi service&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/luftdaten-sensor-madavi.png&quot; alt=&quot;Readings from the c-base outdoor sensor&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We’ve &lt;a href=&quot;http://luftdaten.info/feinstaubsensor-bauen/#feinstaubsensor-konfiguration&quot;&gt;submitted our sensor&lt;/a&gt; for inclusion in the luftdaten.info database, and hopefully soon there will be another covered area in the &lt;a href=&quot;http://berlin.maps.luftdaten.info/#13/52.5150/13.4211&quot;&gt;Berlin air quality map&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/luftdaten-sensor-berlin.png&quot; alt=&quot;luftdaten.info Berlin map&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you’d like to build your own air quality sensor, the &lt;a href=&quot;https://luftdaten.info/en/construction-manual/&quot;&gt;instructions on luftdaten.info&lt;/a&gt; are pretty comperehensive. Get the parts from your local electronics store or AliExpress, connect them together, flash the firmware, and be part of the public effort to track and improve air quality!&lt;/p&gt;

&lt;p&gt;Our &lt;a href=&quot;https://github.com/c-base/microflo-luftdaten&quot;&gt;MicroFlo firmware&lt;/a&gt; is a great alternative if you want to do further analysis of the data yourself, or simply want to get the data on MQTT.&lt;/p&gt;
</description>
      <pubDate>Mon, 26 Feb 2018 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Fmicroflo-particulate-sensors%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/microflo-particulate-sensors/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/microflo-particulate-sensors/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
    <item>
      
      <title>asComponent: turn any JavaScript function into a NoFlo component</title>
      <description>&lt;p&gt;Version 1.1 of &lt;a href=&quot;https://noflojs.org&quot;&gt;NoFlo&lt;/a&gt; shipped this week with a new convenient way to write components. With the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.asComponent&lt;/code&gt; helper you can turn any JavaScript function into a well-behaved NoFlo component with minimal boilerplate.&lt;/p&gt;

&lt;p&gt;Usage of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.asComponent&lt;/code&gt; is quite simple:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noflo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;noflo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getComponent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noflo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;asComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case we have a function that doesn’t take arguments. We detect this, and produce a component with a single “bang” port for invoking the function:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/500x/ascomponent-result.png&quot; alt=&quot;Math.random as component&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You can also amend the component with helpful information like a textual description and and icon:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noflo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;noflo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getComponent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noflo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;asComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Generate a random number&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;icon&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/500x/ascomponent-custom-icon.png&quot; alt=&quot;Math.random with custom icon&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;multiple-inputs&quot;&gt;Multiple inputs&lt;/h2&gt;

&lt;p&gt;The example above was with a function that does not take any arguments. With functions that accept arguments, each of them becomes an input port.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noflo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;noflo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;findItemsWithId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getComponent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noflo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;asComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;findItemsWithId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/500x/ascomponent-multiple-inports.png&quot; alt=&quot;asComponent and multiple inports&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The function will be called when both input ports have a packet available.&lt;/p&gt;

&lt;h2 id=&quot;output-handling&quot;&gt;Output handling&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asComponent&lt;/code&gt; helper handles three types of functions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Regular synchronous functions: return value gets sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;out&lt;/code&gt;. Thrown errors get sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Functions returning a Promise: resolved promises get sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;out&lt;/code&gt;, rejected promises to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Functions taking a Node.js style asynchronous callback: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;err&lt;/code&gt; argument to callback gets sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;error&lt;/code&gt;, result gets sent to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;out&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this, it is quite easy to write wrappers for asynchronous operations. For example, to call an external REST API with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API&quot;&gt;Fetch API&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noflo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;noflo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;getFlowhubStats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://api.flowhub.io/stats&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getComponent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;noflo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;asComponent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getFlowhubStats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;How that you have this component, it is quick to do a graph utilizing it (&lt;a href=&quot;https://app.flowhub.io/#github/bergie/flowhubstats&quot;&gt;open in Flowhub&lt;/a&gt;):&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://app.flowhub.io/#github/bergie/flowhubstats&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/ascomponent-fetch-graph.png&quot; alt=&quot;Example graph with asynchronous asComponent&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we get the BODY element of the browser runtime. When that has been loaded, we trigger the fetch component above. If the request succeeds, we process it through a string template to write a quick report to the page. If it fails, we grab the error message and write that.&lt;/p&gt;

&lt;h2 id=&quot;making-the-components-discoverable&quot;&gt;Making the components discoverable&lt;/h2&gt;

&lt;p&gt;The default location for a NoFlo component is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;components/ComponentName.js&lt;/code&gt; inside your project folder. Add your new components to this folder, and NoFlo will be able to run them.&lt;/p&gt;

&lt;p&gt;If you’re using &lt;a href=&quot;https://flowhub.io/ide&quot;&gt;Flowhub&lt;/a&gt;, you can also write the components in the integrated code editor, and they will be sent to the runtime.&lt;/p&gt;

&lt;p&gt;We’ve already updated the hosted NoFlo browser runtime to 1.1, so you can get started with this new component API right away.&lt;/p&gt;

&lt;h2 id=&quot;advanced-components&quot;&gt;Advanced components&lt;/h2&gt;

&lt;p&gt;In many ways, asComponent is the inverse of the &lt;a href=&quot;https://bergie.iki.fi/blog/ascallback/&quot;&gt;asCallback embedding feature&lt;/a&gt; we introduced a year ago: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asComponent&lt;/code&gt; turns a regular JavaScript function into a NoFlo component; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asCallback&lt;/code&gt; turns a NoFlo component (or graph) into a regular JavaScript function.&lt;/p&gt;

&lt;p&gt;If you need to work with more complex firing patterns, like combining streams or having control ports, you can of course still write regular &lt;a href=&quot;https://noflojs.org/documentation/components/#component-api&quot;&gt;Process API&lt;/a&gt; components.&lt;/p&gt;

&lt;p&gt;The regular component API is quite a bit more verbose, but at the same time gives you full access to NoFlo APIs for dealing with manually controlled preconditions, state management, and creating &lt;a href=&quot;https://noflojs.org/documentation/components/#generator-components&quot;&gt;generators&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, thinking about the hundreds of NoFlo components out there, most of them could be written much more simply with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asComponent&lt;/code&gt;. This will hopefully make the process of developing NoFlo programs a lot more straightforward.&lt;/p&gt;

&lt;p&gt;Read more &lt;a href=&quot;https://noflojs.org/documentation/components/&quot;&gt;NoFlo component documentation&lt;/a&gt; and &lt;a href=&quot;https://noflojs.org/api/AsComponent/&quot;&gt;asComponent API docs&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Fri, 23 Feb 2018 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Fascomponent%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/ascomponent/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/ascomponent/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
    <item>
      
      <title>Publish your data on the BIG IoT marketplace</title>
      <description>&lt;p&gt;When building IoT systems, it is often useful to have access to data from the outside world to amend the information your sensors give you. For example, indoor temperature and energy usage measurements will be a lot more useful if there is information on the outside weather to correlate with.&lt;/p&gt;

&lt;p&gt;Thanks to the open data movement, there are many data sets available. However, many of these are hard to discover or available in obscure formats.&lt;/p&gt;

&lt;h2 id=&quot;the-big-iot-marketplace&quot;&gt;The BIG IoT marketplace&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://big-iot.eu/&quot;&gt;BIG IoT&lt;/a&gt; is an EU-funded research project to make datasets easier to share and discover between organizations. With it there is a common semantic standard for how datasets are served, and a &lt;a href=&quot;https://market.big-iot.org/allOfferings&quot;&gt;centralized marketplace&lt;/a&gt; for discovering and subscribing to data offerings.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;For data providers&lt;/strong&gt; this means they can focus on providing correct information, and let the marketplace handle API tokens, discoverability, and — for commercial datasets — billing&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;For data consumers&lt;/strong&gt; there is a single place and a single API to access multiple datasets. No need to handle different Terms of Usage or different API conventions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As an example, if you’re building a car navigation application, you can use BIG IoT to get access to multiple providers of routing services, traffic delay information, or parking spots. If a dataset comes online in a new city, it’ll automatically work with your application. No need for contract negotiations, just a query to find matching providers on-demand.&lt;/p&gt;

&lt;h2 id=&quot;flowhub-and-big-iot&quot;&gt;Flowhub and BIG IoT&lt;/h2&gt;

&lt;p&gt;Last summer &lt;a href=&quot;https://flowhub.io&quot;&gt;Flowhub&lt;/a&gt; was one of the companies accepted into the BIG IoT &lt;a href=&quot;http://big-iot.eu/first-open-call/&quot;&gt;first open call&lt;/a&gt;. In it, we received some funding to make it possible to publish data from Flowhub and &lt;a href=&quot;https://noflojs.org/&quot;&gt;NoFlo&lt;/a&gt; on the marketplace. In &lt;a href=&quot;https://youtu.be/wYrw7RlV8Ng&quot;&gt;this video&lt;/a&gt; I’m talking about the project:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/wYrw7RlV8Ng&quot; frameborder=&quot;0&quot; allow=&quot;autoplay; encrypted-media&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;In the project we built three things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/flowhub/bigiot-js&quot;&gt;BIG IoT JavaScript library&lt;/a&gt; – a Node.js library for publishing datasets in the BIG IoT marketplace&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/flowhub/bigiot-bridge&quot;&gt;Flowhub BIG IoT bridge&lt;/a&gt; – a set of NoFlo components for creating BIG IoT providers&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://market.big-iot.org/provider/Flowhub_UG-ParkingProductionNew&quot;&gt;Deutsche Bahn and Cologne parking offerings&lt;/a&gt; – a set of live examples of integrating existing IoT datasets with the marketplace using Flowhub&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;creating-a-data-provider&quot;&gt;Creating a data provider&lt;/h2&gt;

&lt;p&gt;While it is easy enough to use the &lt;a href=&quot;https://big-iot.github.io/&quot;&gt;BIG IoT Java library&lt;/a&gt; to publish datasets, the Flowhub integration we built it makes it even easier. You need your data source available on a message queue, a web API, or maybe a timeseries database. And then you need NoFlo and the &lt;a href=&quot;https://github.com/flowhub/bigiot-bridge&quot;&gt;flowhub-bigiot-bridge&lt;/a&gt; library.&lt;/p&gt;

&lt;p&gt;The basic building block is the &lt;strong&gt;Provider&lt;/strong&gt; component. This creates a Node.js application server to serve your datasets, and registers them to the BIG IoT marketplace.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/noflo-bigiot-provider.png&quot; alt=&quot;NoFlo BIG IoT Provider&quot; /&gt;&lt;/p&gt;

&lt;p&gt;What you need to do is to describe your data offering. For this, you can use the &lt;strong&gt;CreateOffering&lt;/strong&gt; component. You can use IIPs to categorize the data, and then a set of &lt;strong&gt;CreateDatatype&lt;/strong&gt; components to describe the input and output structure your offering uses.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/noflo-bigiot-offering.png&quot; alt=&quot;NoFlo BIG IoT Offering config&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;request&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;response&lt;/code&gt; ports of the Provider need to be hooked to your data source. The request outport will send packets with whatever input data your subscribers provided, and you need to send the resulting output data to the response port.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/noflo-bigiot-request-response.png&quot; alt=&quot;Request-response loop with BIG IoT Provider&quot; /&gt;&lt;/p&gt;

&lt;p&gt;For real-world deployment, the Flowhub BIG IoT bridge repository also includes examples on how to test your offerings, and how to build and deploy them with Docker.&lt;/p&gt;

&lt;p&gt;Here’s how a full setup with two different parking datasets looks like:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/800x/noflo-bigiot-parking-provider.png&quot; alt=&quot;NoFlo BIG IoT parking provider&quot; /&gt;&lt;/p&gt;

&lt;p&gt;If you’re participating in the &lt;a href=&quot;http://bcw.bosch-si.com/berlin/hackathon/&quot;&gt;Bosch Connected World hackathon&lt;/a&gt; in Berlin next week, we’ll be there with the BIG IoT team to help projects to utilize the BIG IoT datasets.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This project has received funding from the European Union’s Horizon 2020 research and innovation program under grant agreement No 688038.&lt;/em&gt;&lt;/p&gt;
</description>
      <pubDate>Mon, 12 Feb 2018 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Fbig-iot%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/big-iot/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/big-iot/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
    <item>
      
      <title>Get ready for NoFlo 1.0</title>
      <description>&lt;p&gt;After &lt;a href=&quot;https://bergie.iki.fi/blog/noflo-six-years/&quot;&gt;six years of work&lt;/a&gt;, and bunch of different projects done with &lt;a href=&quot;https://noflojs.org&quot;&gt;NoFlo&lt;/a&gt;, we’re finally ready for the big 1.0. The two primary pull requests for the 1.0.0 cycle &lt;a href=&quot;https://github.com/noflo/noflo/blob/master/CHANGES.md#100-git-master&quot;&gt;landed today&lt;/a&gt;, and so it is time to talk about how to prepare for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tl;dr&lt;/strong&gt; If your project runs with &lt;a href=&quot;https://bergie.iki.fi/blog/noflo-0-8/&quot;&gt;NoFlo 0.8&lt;/a&gt; without deprecation warnings, you should be ready for NoFlo 1.0&lt;/p&gt;

&lt;h2 id=&quot;es6-first&quot;&gt;ES6 first&lt;/h2&gt;

&lt;p&gt;The primary difference between NoFlo 0.8 and 1.0 is that now we’re shipping it as ES6 code utilizing features like classes and arrow functions.&lt;/p&gt;

&lt;p&gt;Now that &lt;a href=&quot;https://kangax.github.io/compat-table/es6/&quot;&gt;all modern browsers&lt;/a&gt; support ES6 out of the box, and &lt;a href=&quot;https://medium.com/the-node-js-collection/news-node-js-8-moves-into-long-term-support-and-node-js-9-becomes-the-new-current-release-line-74cf754a10a0&quot;&gt;Node.js 8 is the long-term supported release&lt;/a&gt;, it should be generally safe to use ES6 as-is.&lt;/p&gt;

&lt;p&gt;If you need to support older browsers, Node.js versions, or maybe PhantomJS, it is of course possible to compile the NoFlo codebase into ES5 using &lt;a href=&quot;https://babeljs.io/&quot;&gt;Babel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We recommend new components to be written in ES6 instead of CoffeeScript.&lt;/p&gt;

&lt;h2 id=&quot;easier-webpack-builds&quot;&gt;Easier webpack builds&lt;/h2&gt;

&lt;p&gt;It has been possible to build NoFlo projects for browsers since 2013. Last year &lt;a href=&quot;https://bergie.iki.fi/blog/noflo-webpack/&quot;&gt;we switched to webpack&lt;/a&gt; as the module bundler.&lt;/p&gt;

&lt;p&gt;However, at that stage there was still quite a lot of configuration magic happening inside &lt;a href=&quot;https://github.com/noflo/grunt-noflo-browser&quot;&gt;grunt-noflo-browser&lt;/a&gt;. This turned out to be sub-optimal since it made integrating NoFlo into existing project build setups difficult.&lt;/p&gt;

&lt;p&gt;Last week we extracted the difficult parts out of the Grunt plugin, and released the &lt;a href=&quot;https://github.com/noflo/noflo-component-loader&quot;&gt;noflo-component-loader&lt;/a&gt; webpack loader. With this, you can generate a configured NoFlo component loader in any webpack build. See &lt;a href=&quot;https://github.com/noflo/noflo-component-loader/tree/master/example&quot;&gt;this example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In addition to generating the component loader, your NoFlo browser project may also need two other loaders, depending how your NoFlo graphs are built: &lt;a href=&quot;https://www.npmjs.com/package/json-loader&quot;&gt;json-loader&lt;/a&gt; for JSON graphs, and &lt;a href=&quot;https://www.npmjs.com/package/fbp-loader&quot;&gt;fbp-loader&lt;/a&gt; for graphs defined in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.fbp&lt;/code&gt; DSL.&lt;/p&gt;

&lt;h2 id=&quot;removed-apis&quot;&gt;Removed APIs&lt;/h2&gt;

&lt;p&gt;There were several old NoFlo APIs that we marked as deprecated in NoFlo 0.8. In that series, usage of those APIs logged warnings. Now in 1.0 the deprecated APIs are completely removed, giving us a lighter, smaller codebase to maintain.&lt;/p&gt;

&lt;p&gt;Here is a list of the primary API removals and the suggested migration strategy:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.AsyncComponent&lt;/code&gt; class: use WirePattern or Process API instead&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.ArrayPort&lt;/code&gt; class: use InPort/OutPort with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;addressable: true&lt;/code&gt; instead&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.Port&lt;/code&gt; class: use InPort/OutPort instead&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.helpers.MapComponent&lt;/code&gt; function: use WirePattern or Process API instead&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.helpers.WirePattern&lt;/code&gt; legacy mode: now WirePattern always uses Process API internally&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.helpers.WirePattern&lt;/code&gt; synchronous mode: use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async: true&lt;/code&gt; and callback&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.helpers.MultiError&lt;/code&gt; function: send errors via callback or error port&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.InPort&lt;/code&gt; process callback: use Process API&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.InPort&lt;/code&gt; handle callback: use Process API&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.InPort&lt;/code&gt; receive method: use Process API getX methods&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;noflo.InPort&lt;/code&gt; contains method: use Process API hasX methods&lt;/li&gt;
  &lt;li&gt;Subgraph &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPORTS&lt;/code&gt; mechanism: disambiguate with INPORT/OUTPORT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The easiest way to verify whether your project is compatible is to run it with NoFlo 0.8.&lt;/p&gt;

&lt;p&gt;You can also make usage of deprecated APIs throw errors instead of just logging them by setting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NOFLO_FATAL_DEPRECATED&lt;/code&gt; environment variable. In browser applications you can set the same flag to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;window&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;scopes&quot;&gt;Scopes&lt;/h2&gt;

&lt;p&gt;Scopes are a flow isolation mechanism that was introduced in NoFlo 0.8. With scopes, you can run multiple simultaneous flows through a NoFlo network without a risk of data leaking from one scope to another.&lt;/p&gt;

&lt;p&gt;The primary use case for scope isolation is building things like web API servers, where you want to isolate the processing of each HTTP request from each other safely, while reusing a single NoFlo graph.&lt;/p&gt;

&lt;p&gt;Scope isolation is handled automatically for you when using Process API or WirePattern. If you want to manipulate scopes, the &lt;a href=&quot;https://github.com/noflo/noflo-packets&quot;&gt;noflo-packets&lt;/a&gt; library provides components for this.&lt;/p&gt;

&lt;p&gt;NoFlo in/outports can also be set as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scoped: false&lt;/code&gt; to support getting out of scopes.&lt;/p&gt;

&lt;h2 id=&quot;ascallback-and-asyncawait&quot;&gt;asCallback and async/await&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://bergie.iki.fi/blog/ascallback/&quot;&gt;noflo.asCallback&lt;/a&gt; provides an easy way to expose NoFlo graphs to normal JavaScript consumers. The produced function uses the standard Node.js callback mechanism, meaning that you can easily make it return promises with &lt;a href=&quot;http://2ality.com/2017/05/util-promisify.html&quot;&gt;Node.js util.promisify&lt;/a&gt; or &lt;a href=&quot;http://bluebirdjs.com/docs/api/promisification.html&quot;&gt;Bluebird&lt;/a&gt;. After this your NoFlo graph can be run via normal &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function&quot;&gt;async/await&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;component-libraries&quot;&gt;Component libraries&lt;/h2&gt;

&lt;p&gt;There are hundreds of &lt;a href=&quot;https://www.npmjs.com/browse/keyword/noflo&quot;&gt;ready-made NoFlo components&lt;/a&gt; available on NPM. By now, most of these have been adapted to work with NoFlo 0.8.&lt;/p&gt;

&lt;p&gt;Once 1.0 ships, we’ll try to be as quick as possible to update all of them to run with it. In the meanwhile, it is possible to &lt;a href=&quot;http://blog.kodigy.com/post/noflo_08_npm_shrinkwrap/&quot;&gt;use npm shrinkwrap&lt;/a&gt; to force them to depend on NoFlo 1.0.&lt;/p&gt;

&lt;p&gt;If you’re relying on a library that uses deprecated APIs, or hasn’t otherwise been updated yet, please file an issue in the GitHub repo of that library.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/noflo/noflo-gravatar/pull/59/files&quot;&gt;This pull request for noflo-gravatar&lt;/a&gt; is a great example of how to implement all the modernization recommendations below in an existing component library.&lt;/p&gt;

&lt;h2 id=&quot;recommendations-for-new-projects&quot;&gt;Recommendations for new projects&lt;/h2&gt;

&lt;p&gt;This post has mostly covered how to adapt existing NoFlo projects for 1.0. How about new projects? Here are some recommendations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;While NoFlo projects have traditionally been written in CoffeeScript, for new projects we recommend using ES6. In particular, follow the &lt;a href=&quot;https://github.com/airbnb/javascript&quot;&gt;AirBnB ES6 guidelines&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Use &lt;a href=&quot;https://github.com/flowbased/fbp-spec&quot;&gt;fbp-spec&lt;/a&gt; for test automation&lt;/li&gt;
  &lt;li&gt;Use NPM scripts instead of Grunt for building and testing&lt;/li&gt;
  &lt;li&gt;Make browser builds with webpack utilizing &lt;a href=&quot;https://www.npmjs.com/package/noflo-component-loader&quot;&gt;noflo-component-loader&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Use &lt;a href=&quot;https://noflojs.org/documentation/components/&quot;&gt;Process API&lt;/a&gt; when writing components&lt;/li&gt;
  &lt;li&gt;If you expose any library functionality, provide an index file using &lt;a href=&quot;https://bergie.iki.fi/blog/ascallback/&quot;&gt;noflo.asCallback&lt;/a&gt; for non-NoFlo consumers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/flowhub/bigiot-bridge&quot;&gt;BIG IoT Node.js bridge&lt;/a&gt; is a recent project that follows these guidelines if you want to see an example in action.&lt;/p&gt;

&lt;p&gt;There is also a &lt;a href=&quot;https://noflojs.org/tutorials/canadianness/&quot;&gt;project tutorial&lt;/a&gt; available on the NoFlo website.&lt;/p&gt;
</description>
      <pubDate>Thu, 02 Nov 2017 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Fnoflo-10-prep%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/noflo-10-prep/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/noflo-10-prep/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
    <item>
      
      <title>Building an IoT dashboard with NASA Open MCT</title>
      <description>&lt;p&gt;One important aspect of any Internet of Things setup is being able to collect and visualize data for analysis. Seeing trends in sensor readings over time can be useful for identifying problems, and for coming up with new ways to use the data.&lt;/p&gt;

&lt;p&gt;We wanted an easy solution for this for the &lt;a href=&quot;https://c-base.org&quot;&gt;c-base&lt;/a&gt; IoT setup. Since the &lt;a href=&quot;https://en.wikipedia.org/wiki/C-base#Mythological_self-image_of_the_c-base&quot;&gt;c-base backstory&lt;/a&gt; is that of a crashed space station, using space technology for this made sense.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-openmct.png&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-openmct-small.png&quot; alt=&quot;OpenMCT view on c-base&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://nasa.github.io/openmct/&quot;&gt;NASA Open MCT&lt;/a&gt; is a framework for building web-based mission control tools and dashboards that they’ve released as open source. It is intended for bringing together tools and both historical and real-time data, as can be seen in their &lt;a href=&quot;https://openmct-demo.herokuapp.com/&quot;&gt;Mars Science Laboratory dashboard demo&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;c-beam-telemetry-server&quot;&gt;c-beam telemetry server&lt;/h2&gt;

&lt;p&gt;As a dashboard framework, Open MCT doesn’t really come with batteries included. You get a bunch of widgets and library functionality, but out of the box there is no integration with data sources.&lt;/p&gt;

&lt;p&gt;However, they do provide a &lt;a href=&quot;https://github.com/nasa/openmct-tutorial&quot;&gt;tutorial project&lt;/a&gt; for integrating data sources. We started with that, and built the &lt;a href=&quot;https://github.com/c-base/cbeam-telemetry-server&quot;&gt;cbeam-telemetry-server&lt;/a&gt; project which gives a very easy way to integrate Open MCT with an existing IoT setup.&lt;/p&gt;

&lt;p&gt;With the c-beam telemetry server we combine Open MCT with the &lt;a href=&quot;https://www.influxdata.com/&quot;&gt;InfluxDB&lt;/a&gt; timeseries database and the &lt;a href=&quot;http://mqtt.org/&quot;&gt;MQTT&lt;/a&gt; messaging bus. This gives a “turnkey” setup for persisting and visualizing IoT information.&lt;/p&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting started&lt;/h2&gt;

&lt;p&gt;The first step is to install the c-beam telemetry server. If you want to do a manual setup, first install a MQTT broker, InfluxDB and Node.js. Optionally you can also install CouchDB for sharing custom dashboard layouts between users.&lt;/p&gt;

&lt;p&gt;Then just clone the c-beam telemetry server repo:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;git clone https://github.com/c-base/cbeam-telemetry-server.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Install the dependencies and build Open MCT with:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;npm &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now you should be able to start the service with:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;npm start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;running-with-docker&quot;&gt;Running with Docker&lt;/h3&gt;

&lt;p&gt;There is also an easier way to get going: we provide pre-built Docker images of the c-beam telemetry server for both &lt;a href=&quot;https://hub.docker.com/r/cbase/cbeam-telemetry-server/&quot;&gt;x86&lt;/a&gt; and &lt;a href=&quot;https://hub.docker.com/r/cbase/raspberrypi3-cbeam-telemetry-server/&quot;&gt;ARM&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are also docker-compose configuration files for both environments. To install and start the whole service with all its dependencies, grab the &lt;a href=&quot;https://github.com/c-base/cbeam-telemetry-server/blob/master/docker-compose.yml&quot;&gt;docker-compose.yml file&lt;/a&gt; (or the &lt;a href=&quot;https://github.com/c-base/cbeam-telemetry-server/blob/master/docker-compose-raspberrypi3.yml&quot;&gt;Raspberry Pi 3 version&lt;/a&gt;) and start with:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;docker-compose up &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We’re building these images as part of our continuous integration pipeline (&lt;a href=&quot;https://blog.hypriot.com/post/setup-simple-ci-pipeline-for-arm-images/&quot;&gt;ARM build with this recipe&lt;/a&gt;), so they should always be reasonably up-to-date.&lt;/p&gt;

&lt;h3 id=&quot;configuring-your-data&quot;&gt;Configuring your data&lt;/h3&gt;

&lt;p&gt;The next step is to create a JavaScript &lt;a href=&quot;https://github.com/c-base/cbeam-telemetry-server/tree/master/config&quot;&gt;configuration file&lt;/a&gt; for your Open MCT. This is where you need to provide a “dictionary” listing all data you want your dashboard to track.&lt;/p&gt;

&lt;p&gt;Data sets are configured like the following (configuring a temperature reading tracked for the 2nd floor):&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;floor2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Dictionary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;2nd floor&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;floor2&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;floor2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addMeasurement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;temperature&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;floor2_temperature&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;units&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;degrees&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;topic&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bitraf/temperature/1&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can have multiple dictionaries in the same Open MCT installation, allowing you to group related data sets. Each measurement needs to have a name and a unit.&lt;/p&gt;

&lt;h3 id=&quot;getting-data-in&quot;&gt;Getting data in&lt;/h3&gt;

&lt;p&gt;In the example above we also supply a MQTT topic to read the measurement from. Now sending data to the dashboard is as easy as writing numbers to that MQTT topic. On command-line that would be done with:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;mosquitto_pub &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; bitraf/temperature/1 &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; 27.3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you were running the telemetry server when you sent that message, you should’ve seen it appear in the appropriate dashboard.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-temperature-graph.jpeg&quot; alt=&quot;Bitraf temperature graph with Open MCT&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There are MQTT libraries available for most programming languages, making it easy to connect existing systems with this dashboard.&lt;/p&gt;

&lt;p&gt;The telemetry server is also compatible with our &lt;a href=&quot;https://msgflo.org/&quot;&gt;MsgFlo framework&lt;/a&gt;, meaning that you can also configure the connections between your data sources and Open MCT visually in &lt;a href=&quot;https://flowhub.io&quot;&gt;Flowhub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This makes it possible to utilize the existing MsgFlo libraries for implementing data sources. For example, with &lt;a href=&quot;https://github.com/msgflo/msgflo-arduino&quot;&gt;msgflo-arduino&lt;/a&gt; you can transmit sensor data from Tiva-C or NodeMcu microcontrollers to the dashboard.&lt;/p&gt;

&lt;h3 id=&quot;status-and-how-you-can-help&quot;&gt;Status and how you can help&lt;/h3&gt;

&lt;p&gt;The c-beam telemetry server is currently in production use in a couple of hackerspaces, and seems to run quite happily.&lt;/p&gt;

&lt;p&gt;We’d love to get feedback from other deployments!&lt;/p&gt;

&lt;p&gt;If you’d like to help with the project, here are couple of areas that would be great:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Adding tests to the project&lt;/li&gt;
  &lt;li&gt;Implementing &lt;a href=&quot;https://github.com/c-base/cbeam-telemetry-server/issues/54&quot;&gt;downsampling of historical data&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Figuring out ways to control IoT devices via the dashboard (so, to write to MQTT instead of just reading)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please file issues or make pull requests &lt;a href=&quot;https://github.com/c-base/cbeam-telemetry-server&quot;&gt;to the repository&lt;/a&gt;.&lt;/p&gt;
</description>
      <pubDate>Thu, 05 Oct 2017 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Fnasa-openmct-iot-dashboard%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/nasa-openmct-iot-dashboard/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/nasa-openmct-iot-dashboard/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
    <item>
      
      <title>Flowhub IoT hack weekend at c-base: buttons, sensors, the Big Switch</title>
      <description>&lt;p&gt;Last weekend we held the &lt;a href=&quot;https://logbuch.c-base.org/archives/2647&quot;&gt;c-base IoT hack weekend&lt;/a&gt;, focused on the &lt;a href=&quot;https://flowhub.io/iot/&quot;&gt;Flowhub IoT&lt;/a&gt; platform. This was continuation from the &lt;a href=&quot;https://bergie.iki.fi/blog/flowhub-iot-workshop-bitraf/&quot;&gt;workshop we organized at the Bitraf makerspace&lt;/a&gt; a week earlier. Same tools and technologies, but slightly different focus areas.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://c-base.org/&quot;&gt;c-base&lt;/a&gt; is one of the world’s oldest hackerspaces and a crashed space station under Berlin. It is also one of the earliest users of &lt;a href=&quot;https://msgflo.org/&quot;&gt;MsgFlo&lt;/a&gt; with quite a lot of devices connected via MQTT.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-after.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-after-small.jpg&quot; alt=&quot;Hack weekend debriefing&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;hack-weekend&quot;&gt;Hack weekend&lt;/h2&gt;

&lt;p&gt;Just like &lt;a href=&quot;https://bergie.iki.fi/blog/flowhub-iot-workshop-bitraf/&quot;&gt;at Bitraf&lt;/a&gt;, the workshop aimed to add new IoT capabilities to c-base, as well as to increase the number of members who know how to make the station’s setup do new things. For this, we used three primary tools:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/msgflo/msgflo-arduino&quot;&gt;msgflo-arduino&lt;/a&gt; and ESP8266 microcontrollers for connected devices&lt;/li&gt;
  &lt;li&gt;Raspberry Pis and &lt;a href=&quot;https://www.ansible.com/&quot;&gt;Ansible&lt;/a&gt; for info screens&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://flowhub.io/&quot;&gt;Flowhub IDE&lt;/a&gt; and &lt;a href=&quot;https://github.com/msgflo/msgflo-python&quot;&gt;msgflo-python&lt;/a&gt; for “business logic”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-neuland.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-neuland-small.jpg&quot; alt=&quot;Internet of Things&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The workshop started in Friday evening after a lecture on &lt;a href=&quot;https://en.wikipedia.org/wiki/Nuclear_pulse_propulsion&quot;&gt;nuclear pulse propulsion&lt;/a&gt; ended in the main hall. We continued all the way to late Sunday evening with some sleep breaks in between. There is something about c-base that makes you want to work there at night.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-volume-test.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-volume-test-small.jpg&quot; alt=&quot;Testing a humidity sensor&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By Sunday evening, we had built and deployed 15 connected IoT devices, with five additional ones pretty far in development. You can find the source code in the &lt;a href=&quot;https://github.com/c-base/c-flo/tree/master/devices&quot;&gt;c-flo repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-ideas.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-ideas-small.jpg&quot; alt=&quot;Idea wall&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;sensor-boxes&quot;&gt;Sensor boxes&lt;/h2&gt;

&lt;p&gt;Quite a lot of c-base was already instrumented when we started the workshop. We had details on electricity consumption, internet traffic, and more. But one thing we didn’t have was information on the physical environment at the station. To solve this, we decided to build a set of sensor boxes that we could deploy in different areas of the hackerspace.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-sensors.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-sensors-small.jpg&quot; alt=&quot;Building sensors&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The capabilities shared by all the sensor boxes we deployed were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Temperature&lt;/li&gt;
  &lt;li&gt;Humidity&lt;/li&gt;
  &lt;li&gt;Motion (via passive infrared)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For some areas of interest we provided some additional sensors:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Sound level (for the workshop)&lt;/li&gt;
  &lt;li&gt;Light level (for c-lab)&lt;/li&gt;
  &lt;li&gt;Carbon dioxide&lt;/li&gt;
  &lt;li&gt;Door open/closed&lt;/li&gt;
  &lt;li&gt;Gravity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-workshopsensor-parts.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-workshopsensor-parts-small.jpg&quot; alt=&quot;Workshop sensor on a breadboard&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We found a set of nice little electrical boxes that provided a convenient housing for these sensor boxes. This way we were able to mount them in proper places quickly. This should also protect them from dust and other elements to some degree.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-weltenbausensor.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-weltenbausensor-small.jpg&quot; alt=&quot;Installed weltenbaulab sensor&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-big-switch&quot;&gt;The Big Switch&lt;/h2&gt;

&lt;p&gt;The lights of the c-base main hall are controllable via MsgFlo, and we have a system called &lt;a href=&quot;https://github.com/c-base/farbgeber&quot;&gt;farbgeber&lt;/a&gt; to produce pleasing color schemes for any given time.&lt;/p&gt;

&lt;p&gt;However, when there are events we need to enable manual control of all lights and sound. To make this “MsgFlo vs. IP lounge” control question  clearer, we built a Big Switch to decide which controls the lights:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-bigswitch.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-bigswitch-small.jpg&quot; alt=&quot;Big Switch in action&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The switch is an old electric mains switch from an office building. It makes a satisfying sound when you turn it, and is big enough that you can see which way the setting is from across the room.&lt;/p&gt;

&lt;p&gt;To complement the Big Switch we also added a “c-boom” button to trigger the disco mode in the main hall:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-c-boom-button.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-c-boom-button-small.jpg&quot; alt=&quot;c-boom button&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;info-screens&quot;&gt;Info screens&lt;/h2&gt;

&lt;p&gt;One part of the IoT setup was to make statistics and announcements about c-base visible in different areas of the station. We did this by rolling out a set of displays with Raspberry Pi 3s connected to the MsgFlo MQTT environment.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-infoscreen-install.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-infoscreen-install-small.jpg&quot; alt=&quot;Info screens ready for installing&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The announcements shown on the screens range from mission critical information like station power consumption or whether the bar is open, to more fictional ones like the &lt;a href=&quot;https://github.com/c-base/station-announcer&quot;&gt;NoFlo-powered space station announcements&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-c-leuse.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-c-leuse-small.jpg&quot; alt=&quot;Air lock&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also built an Android version of the info display software, which enabled deploying screens using some old donated tablets.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-tablet.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-tablet-small.jpg&quot; alt=&quot;Info screen tablet&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;This was another successful workshop. Participants got to do new things, and we got lots of new IoT infrastructure installed around c-base. The Flowhub graph is definitely starting to look populated:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-graph.png&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-graph-small.png&quot; alt=&quot;c-base is a graph&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We also deployed &lt;a href=&quot;https://nasa.github.io/openmct/&quot;&gt;NASA OpenMCT&lt;/a&gt; so that we get a nice overview on the station status. Our telemetry server provides MsgFlo participants that receive data via MQTT, store it in InfluxDB, and then visualize it on the dashboard:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-openmct.png&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/c-base-iot-openmct-small.png&quot; alt=&quot;OpenMCT view on c-base&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All the c-base IoT software is available &lt;a href=&quot;https://github.com/c-base&quot;&gt;on Github&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/c-base/c-flo&quot;&gt;c-flo&lt;/a&gt; — the MsgFlo setup for c-base&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/c-base/cbeam-telemetry-server&quot;&gt;cbeam-telemetry-server&lt;/a&gt; — the OpenMCT setup for c-base&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/c-base/mqttwebview&quot;&gt;mqttwebview&lt;/a&gt; — Linux info screen implementation&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/c-base/c-beam-viewer&quot;&gt;c-beam-viewer&lt;/a&gt; — Android info screen implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;If you’d like to have a similar IoT workshop at your company, we’re happy to organize one. &lt;a href=&quot;https://flowhub.io/about/&quot;&gt;Get in touch&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;
</description>
      <pubDate>Tue, 11 Jul 2017 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Fflowhub-iot-workshop-c-base%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/flowhub-iot-workshop-c-base/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/flowhub-iot-workshop-c-base/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
    <item>
      
      <title>Flowhub IoT workshop at Bitraf: sensors, access control, and more</title>
      <description>&lt;p&gt;I just got back to Berlin from the &lt;a href=&quot;https://www.meetup.com/bitraf/events/240605453/&quot;&gt;Bitraf IoT hackathon&lt;/a&gt; we organized in Oslo, Norway. This hackathon was the first of &lt;a href=&quot;https://bergie.iki.fi/blog/msgflo-workshops-cbase-bitraf/&quot;&gt;two IoT workshops&lt;/a&gt; around MsgFlo and &lt;a href=&quot;https://flowhub.io/iot/&quot;&gt;Flowhub IoT&lt;/a&gt;. The second &lt;a href=&quot;ttps://logbuch.c-base.org/archives/2647&quot;&gt;will be held&lt;/a&gt; at c-base in Berlin this coming weekend.&lt;/p&gt;

&lt;h2 id=&quot;bitraf-and-the-existing-iot-setup&quot;&gt;Bitraf and the existing IoT setup&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://bitraf.no/&quot;&gt;Bitraf&lt;/a&gt; is a large non-profit &lt;a href=&quot;https://www.makerspaces.com/what-is-a-makerspace/&quot;&gt;makerspace&lt;/a&gt; in the center of Oslo. It provides co-working facilities, as well as labs and a large selection of computer controlled tools for building things. Members have 24/7 access to the space, and are provided with everything needed for CNC milling, laser cutting, 3D-printing and more.&lt;/p&gt;

&lt;p&gt;The space uses the &lt;a href=&quot;https://flowhub.io/iot/&quot;&gt;Flowhub IoT&lt;/a&gt; stack of &lt;a href=&quot;https://msgflo.org/&quot;&gt;MsgFlo&lt;/a&gt; and &lt;a href=&quot;https://mosquitto.org/&quot;&gt;Mosquitto&lt;/a&gt; for business-critical things like the door locks that members can open with their smartphone.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-button.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-button-small.jpg&quot; alt=&quot;Bitraf lock system&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In addition to access control, they also had various environmental sensors available on the MQTT network.&lt;/p&gt;

&lt;p&gt;With the workshop, our aim was to utilize these existing things more, as well as to add new IoT capabilities. And of course to increase the number of Bitraf members with the knowledge to work with the MsgFlo IoT setup.&lt;/p&gt;

&lt;h2 id=&quot;preparations&quot;&gt;Preparations&lt;/h2&gt;

&lt;p&gt;Being a makerspace, Bitraf already had everything needed for the physical side of the workshop — tons of sensors, WiFi-enabled microcontrollers, tools for building cases and mounting solutions. So the workshop preparations mostly focused on the software side of things.&lt;/p&gt;

&lt;p&gt;The primary tools for the workshop were:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/bitraf/bitraf-iot#running-with-docker&quot;&gt;Docker setup of Bitraf IoT&lt;/a&gt;, making running the whole IoT environment locally as easy as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose up&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/msgflo/msgflo-arduino&quot;&gt;msgflo-arduino&lt;/a&gt;, a library for making ESP8266 devices work as MsgFlo participants&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To help visualize the data coming from the sensors people were building, I integrated the &lt;a href=&quot;https://nasa.github.io/openmct/&quot;&gt;NASA OpenMCT&lt;/a&gt; dashboard with MsgFlo and &lt;a href=&quot;https://www.influxdata.com/&quot;&gt;InfluxDB&lt;/a&gt; time series database. This setup is available at the &lt;a href=&quot;https://github.com/c-base/cbeam-telemetry-server&quot;&gt;cbeam-telemetry-server&lt;/a&gt; project.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-openmct.png&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-openmct-small.png&quot; alt=&quot;OpenMCT at Bitraf&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gave us a way to send data from any interesting sensors in the IoT network to a dashboard and visualize it. Down the line the persisted data can also be interesting for further analysis or machine learning.&lt;/p&gt;

&lt;h2 id=&quot;kick-off-session&quot;&gt;Kick-off session&lt;/h2&gt;

&lt;p&gt;We started the workshop with a quick intro session about Flowhub, MsgFlo, and MQTT development. There is unfortunately no video, but &lt;a href=&quot;https://docs.google.com/presentation/d/1Xo7RxPTOOcgJpVc4rl-xuzwxtStpDWwdun4fCYCcbV8/edit?usp=sharing&quot;&gt;the slides are available&lt;/a&gt;:&lt;/p&gt;

&lt;iframe src=&quot;https://docs.google.com/presentation/d/1Xo7RxPTOOcgJpVc4rl-xuzwxtStpDWwdun4fCYCcbV8/embed?start=false&amp;amp;loop=false&amp;amp;delayms=3000&quot; frameborder=&quot;0&quot; width=&quot;960&quot; height=&quot;569&quot; allowfullscreen=&quot;true&quot; mozallowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;After the intro, we did a round of all attendees to see what skills people already had, and what they were interested in learning. Then we started collecting ideas what to work on.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-idea-wall.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-idea-wall-small.jpg&quot; alt=&quot;Bitraf IoT ideas&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;People picked their ideas, and the project work started.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-idea-wall-session.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-idea-wall-session-small.jpg&quot; alt=&quot;Idea session at Bitraf IoT&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’d like to highlight couple of the projects.&lt;/p&gt;

&lt;h2 id=&quot;new-sensors-for-the-makerspace&quot;&gt;New sensors for the makerspace&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-workshop.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-workshop-small.jpg&quot; alt=&quot;Teams at work&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building new sensors was a major part of the workshop. There were several projects, all built on top of &lt;a href=&quot;https://github.com/msgflo/msgflo-arduino&quot;&gt;msgflo-arduino&lt;/a&gt; and the ESP8266 microcontroller:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Motion sensor for tracking whether there are people in the laser cutting lab&lt;/li&gt;
  &lt;li&gt;Sensor for tracking which windows are open or closed: &lt;a href=&quot;https://github.com/Poohma/IOT_Window_Hall_sensors&quot;&gt;https://github.com/Poohma/IOT_Window_Hall_sensors&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Sensor for tracking whether a given machine is currently running or not: &lt;a href=&quot;https://github.com/slunke/onoffsensor&quot;&gt;https://github.com/slunke/onoffsensor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-sensors.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-sensors-small.jpg&quot; alt=&quot;Working on a motion sensor&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There was also a project to automatically open and close windows, but this one didn’t get completed over the weekend. You can follow the progress in the &lt;a href=&quot;https://github.com/apetrynet/altF4&quot;&gt;altF4 GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;tool-locking&quot;&gt;Tool locking&lt;/h2&gt;

&lt;p&gt;All hackerspaces have the problem that people borrow tools and then don’t return them when finished. This means that the next person needing the tool will have to spend time searching for it.&lt;/p&gt;

&lt;p&gt;To solve this, the team designed a system that enabled tools to be locked to a wall, with a web interface where members can “check out” a tool they want to use. This way the system constantly knows what tools are in their right places, and which tools are in use, and by who.&lt;/p&gt;

&lt;p&gt;You can see the tool lock system in action in &lt;a href=&quot;https://youtu.be/3u51ZDOo7UQ&quot;&gt;this demo video&lt;/a&gt;:&lt;/p&gt;

&lt;iframe width=&quot;853&quot; height=&quot;480&quot; src=&quot;https://www.youtube.com/embed/3u51ZDOo7UQ&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;Source code and schematics: &lt;a href=&quot;https://github.com/einsmein/bitraf-thelock&quot;&gt;https://github.com/einsmein/bitraf-thelock&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;after-the-hackathon&quot;&gt;After the hackathon&lt;/h2&gt;

&lt;p&gt;Before my flight out, we sat down with &lt;a href=&quot;http://www.jonnor.com/&quot;&gt;Jon&lt;/a&gt; to review how things went. In general, I think it is clear the event was a success — people got to learn and try new things, and all projects except one were completed during the two days.&lt;/p&gt;

&lt;p&gt;Our unofficial goal was to double the number of nodes in the Bitraf Flowhub graph, and I think we succeeded in this:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-flowhub-network.png&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/bitraf-flowhub-network-small.png&quot; alt=&quot;Bitraf as a graph&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are &lt;a href=&quot;https://www.meetup.com/bitraf/events/240605453/#event-comments-section&quot;&gt;couple of comments&lt;/a&gt; from the attendees:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Really fun and informative. The development pipeline also seems complete. Made it a lot easier for beginner to get started.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;this was a very fantastic hackathon! Lots of interesting things to learn, very enthusiastic participants, great stewardship and we actually got quite a few projects finished. Well done everbody.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In general the development tools we provided worked well. Everybody was able to run the full Flowhub IoT environment on their own machines using the &lt;a href=&quot;https://github.com/bitraf/bitraf-iot#running-with-docker&quot;&gt;Docker setup we provided&lt;/a&gt;. And apart from a couple of corner cases, &lt;a href=&quot;https://github.com/msgflo/msgflo-arduino&quot;&gt;msgflo-arduino&lt;/a&gt; was easy to get going on the NodeMCUs.&lt;/p&gt;

&lt;p&gt;With these two, everybody could easily wire up some sensors and see their data in both Flowhub and the OpenMCT dashboard. From the local setup going to production was just a matter of switching the MQTT broker configuration.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;If you’d like to have a similar IoT workshop at your company, we’re happy to organize one. &lt;a href=&quot;https://flowhub.io/about/&quot;&gt;Get in touch&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;
</description>
      <pubDate>Tue, 04 Jul 2017 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Fflowhub-iot-workshop-bitraf%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/flowhub-iot-workshop-bitraf/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/flowhub-iot-workshop-bitraf/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
    <item>
      
      <title>Two hackathons in a week: thoughts on NoFlo and MsgFlo</title>
      <description>&lt;p&gt;Last week I participated in two hackathons, events where a group of strangers would form a team for two or three days and build a product prototype. In the end all teams pitch their prototypes, and the best ones would be given some prizes.&lt;/p&gt;

&lt;p&gt;Hackathons are typically organized to get feedback from developers on some new API or platform. Sometimes they’re also organized as a recruitment opportunity.&lt;/p&gt;

&lt;p&gt;Apart from the free beer and camaraderie, I like going to hackathons since they’re a great way to battle test the &lt;a href=&quot;https://flowhub.io/&quot;&gt;developer tools&lt;/a&gt; I build. The time from idea to having to have a running prototype is short, people are used to different ways of working and different toolkits.&lt;/p&gt;

&lt;p&gt;If our tools and &lt;a href=&quot;https://en.wikipedia.org/wiki/Flow-based_programming&quot;&gt;flow-based programming&lt;/a&gt; work as intended, they should be ideal for these kind of situations.&lt;/p&gt;

&lt;h2 id=&quot;minds--machines-hackathon-and-electrocute&quot;&gt;Minds + Machines hackathon and Electrocute&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://mindsmachinesberlin.devpost.com/&quot;&gt;Minds + Machines hackathon&lt;/a&gt; was held on a boat and focused on decarbonizing power and manufacturing industries. The main platform to work with was &lt;a href=&quot;https://www.ge.com/digital/predix&quot;&gt;Predix&lt;/a&gt;, GE’s PaaS service.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/minds_machines_team.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/minds_machines_team_small.jpg&quot; alt=&quot;Team Electrocute&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our project was &lt;strong&gt;&lt;a href=&quot;https://devpost.com/software/electrocute-a9guqr&quot;&gt;Electrocute&lt;/a&gt;&lt;/strong&gt;, a machine learning system for forecasting power consumption in a changing climate.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;1.5°C is the global warming target set by the Paris Agreement. How will this affect energy consumption? What kind of generator assets should utilities deploy to meet these targets? When and how much renevable energy can be utilized?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;The changing climate poses many questions to utilities. With Electrocute’s forecasting suite power companies can have accurate answers, on-demand.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/minds_machines_map.png&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/minds_machines_map_small.png&quot; alt=&quot;Electrocute forecasts&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The system was built with a &lt;a href=&quot;https://noflojs.org/&quot;&gt;NoFlo&lt;/a&gt; web API server talking over &lt;a href=&quot;https://msgflo.org/&quot;&gt;MsgFlo&lt;/a&gt; with a Python machine learning backend. We also built a frontend where users could see the energy usage forecasts on a heatmap.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/minds_machines_noflo.png&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/minds_machines_noflo_small.png&quot; alt=&quot;NoFlo-Xpress in action&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately we didn’t win this one.&lt;/p&gt;

&lt;h2 id=&quot;recoding-aviation-and-skillport&quot;&gt;Recoding Aviation and Skillport&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.recodingaviation.com/&quot;&gt;Recoding Aviation&lt;/a&gt; was held at &lt;a href=&quot;https://www.hubraum.com/&quot;&gt;hub:raum&lt;/a&gt; and focused on improving the air travel experience through usage of open APIs offered by the various participating airports.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/recoding_aviation_team.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/recoding_aviation_team_small.jpg&quot; alt=&quot;Team Skillport&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://platform.recodingaviation.com/#/projects/594437673d055b0004c17f5a&quot;&gt;Skillport&lt;/a&gt;&lt;/strong&gt; was our project to make long layovers more bearable by connecting people who’re stuck at the airport at the same time.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Long layovers suck. But there is ONE thing amazing about them: You are surrounded by highly skilled people with interesting stories from all over the world. It sometimes happens that you meet someone randomly - we all have a story like that. But usually we are too shy and lazy to communicate and see how we could create a valuable interaction. You never know if the other person feels the same.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;We built a mobile app that turns airports into a networking, cultural exchange and knowledge sharing hub. Users tell each other through the app that they are available to meet and what value they can bring to an interaction.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The app connected with a J2EE API service that then communicated over MsgFlo with NoFlo microservices doing all the interactions with social and airport APIs. We also did some data enrichment in NoFlo to make smart recommendations on meeting venues.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/recoding_aviation_msgflo.png&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/recoding_aviation_msgflo_small.png&quot; alt=&quot;MsgFlo in action&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This time our project went well with the judges and we were selected as the winner of the &lt;em&gt;Life in between airports&lt;/em&gt; challenge. I’m looking forward to the helicopter ride over Berlin!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://d2vqpl3tx84ay5.cloudfront.net/recoding_aviation_winners.jpg&quot;&gt;&lt;img src=&quot;https://d2vqpl3tx84ay5.cloudfront.net/recoding_aviation_winners_small.jpg&quot; alt=&quot;Category winners&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Skillport also won a space at &lt;a href=&quot;https://www.hubraum.com/&quot;&gt;hub:raum&lt;/a&gt;, so this might not be the last you’ll hear of the project…&lt;/p&gt;

&lt;h2 id=&quot;lessons-learned&quot;&gt;Lessons learned&lt;/h2&gt;

&lt;h3 id=&quot;benefits-of-a-message-queue-architecture&quot;&gt;Benefits of a message queue architecture&lt;/h3&gt;

&lt;p&gt;I’ve written before on &lt;a href=&quot;https://bergie.iki.fi/blog/forget-http-microservices/&quot;&gt;why to use message queues for microservices&lt;/a&gt;, but that post focused more on the benefits for real-life production usage.&lt;/p&gt;

&lt;p&gt;The problems and tasks for a system architecture in a hackathon are different. Since the time is short, you want to enable people to work in parallel as much as possible without stepping on each other’s toes. Since people in the team come from different backgrounds, you want to enable a heterogeneous, polyglot architecture where each developer can use the tools they’re most productive with.&lt;/p&gt;

&lt;p&gt;MsgFlo is by its nature very suitable for this. Components can be written in any language that supports the message queue used, and we have convenience libraries for many of them. The &lt;a href=&quot;https://msgflo.org/docs/communications/index.html&quot;&gt;discovery mechanism&lt;/a&gt; makes new microservices appear on the Flowhub graph as soon as they start, enabling services to be wired together quickly.&lt;/p&gt;

&lt;h3 id=&quot;mock-early-mock-often&quot;&gt;Mock early, mock often&lt;/h3&gt;

&lt;p&gt;Mocks are a useful way to provide a microservice to the other team members even before the real implementation is ready.&lt;/p&gt;

&lt;p&gt;For example in the GE Predix hackathon, we knew the machine learning team would need quite a bit of time to build their model. Until that point we ran their microservice with a simple &lt;a href=&quot;http://github.com/msgflo/msgflo-python&quot;&gt;msgflo-python&lt;/a&gt; component that just gave &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;random()&lt;/code&gt; as the forecast.&lt;/p&gt;

&lt;p&gt;This way everybody else was able to work with the real interface from the get-go. When the learning model was ready we just replaced that Python service, and everything was live.&lt;/p&gt;

&lt;p&gt;Mocks can be useful also in situations where you have a misbehaving third-party API.&lt;/p&gt;

&lt;h3 id=&quot;dont-forget-tests&quot;&gt;Don’t forget tests&lt;/h3&gt;

&lt;p&gt;While shooting for a full test coverage is probably not realistic within the time constraints of a hackathon, it still makes sense to have at least some “happy path” tests. When you’re working with multiple developers each building a different parts of the service, interface tests serve a dual purpose:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;They show the other team members how to use your service&lt;/li&gt;
  &lt;li&gt;They verify that your service actually does what it is supposed to&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you’re using a continuous integration tool like &lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis&lt;/a&gt;, the tests will help you catch any breakages quickly, and also ensure the services work on a clean installation.&lt;/p&gt;

&lt;p&gt;For a message queue architecture, &lt;a href=&quot;https://github.com/flowbased/fbp-spec&quot;&gt;fbp-spec&lt;/a&gt; is a great tool for writing and running these interface tests.&lt;/p&gt;

&lt;h3 id=&quot;talk-with-the-api-providers&quot;&gt;Talk with the API providers&lt;/h3&gt;

&lt;p&gt;The reason API and platform providers organize these events is to get feedback. As a developer that works with tons of different APIs, this is a great opportunity to make sure your ideas for improvement are heard.&lt;/p&gt;

&lt;p&gt;On the flip side, this usually also means the APIs are in a pretty early stage, and you may be the first one using them in a real-world project. When the inevitable bugs arise, it is a good to have a channel of communications open with the API provider on site so you can get them resolved or worked around quickly.&lt;/p&gt;

&lt;h3 id=&quot;room-for-improvement&quot;&gt;Room for improvement&lt;/h3&gt;

&lt;p&gt;The downside of the NoFlo and MsgFlo stack is that there is still quite a bit of a learning curve. &lt;a href=&quot;https://noflojs.org/documentation/&quot;&gt;NoFlo documentation&lt;/a&gt; is now in a reasonable place, but with &lt;a href=&quot;https://flowhub.io/&quot;&gt;Flowhub&lt;/a&gt; and MsgFlo we have tons of work ahead on improving the onboarding experience.&lt;/p&gt;

&lt;p&gt;Right now it is easy to work with if somebody sets it up properly first, but getting there is a bit tricky. Fixing this will be crucial for enabling others to benefit from these tools as well.&lt;/p&gt;
</description>
      <pubDate>Mon, 19 Jun 2017 00:00:00 +0000</pubDate>
      <atom:link rel="payment" href="https://flattr.com/submit/auto?url=https%3A%2F%2Fbergie.iki.fi%2Fblog%2Fmsgflo-noflo-in-hackathons%2F&amp;user_id=bergie" type="text/html" />
      <link>https://bergie.iki.fi/blog/msgflo-noflo-in-hackathons/</link>
      <guid isPermaLink="true">https://bergie.iki.fi/blog/msgflo-noflo-in-hackathons/</guid>
      <author>henri.bergius@iki.fi (Henri Bergius)</author>
    </item>
    
  </channel>
</rss>
