Sunday, March 20, 2016

Playing with JRubyFX

I started looking at JRubyFX as a combination of using a proven UI solution with Ruby as the programming language and I have to admit that I am impressed with how little it takes to get a UI done -- especially when it is driven by FXML.

Unfortunately the learning curve is steep, as one has to learn JavaFX and the special way JRubyFX calls the JavaFX classes and methods. And unfortunately, Google is not returning too much results here.

Anyway: this little code already creates GUI and populates a TreeView with elements it pulls from a remote server.

require 'jrubyfx'
require 'hawkular_all'

fxml_root File.dirname(__FILE__)

class HawkFx < JRubyFX::Application

  def start(stage)
    with(stage, title: 'Hello World!', width: 800, height: 600) do
      fxml HawkFxController
      show
    end

    stage.show()
  end
end

class HawkFxController
  include JRubyFX::Controller
  fxml 'fxmain.fxml'

  def login # callback from the login button
    creds = { :username => 'jdoe' ,
              :password => 'password' }
    url = 'http://localhost:8080/hawkular/inventory'
    @inventory_client = Hawkular::Inventory::InventoryClient.new(url, creds)
    @tenant = @inventory_client.get_tenant
    @FXMLtextArea.text = "Tenant: #{@tenant}"
    feeds = @inventory_client.list_feeds

    show_initial_tree(feeds)

  end

  def show_initial_tree(feeds)
    tree_root = tree_item('Feeds') do
      feeds.each do |feed|
        item = tree_item(feed) # this already adds the item to the root
      end
    end
    # bind to the view from fxml
    @FXMLtreeView.setRoot(tree_root)

    tree_root.setExpanded true
  end
end

HawkFx.launch

Thursday, March 17, 2016

Reacting on IoT data with Hawkular

In the first post I have been talking about how send IoT sensor data to the metrics subsystem of Hawkular and then how to register the metric in Hawkular so that it can be graphed in the console.

In this article I will talk about how the Hawkular alerts component (that is already available in Hawkular-full) can be used to react on incoming data and make an LED on an Arduino blink.

DSC 0160
Arduino Uno with Ethernet shield and yellow LED

For the Arduino I have added a cheap Enc28j60 based Ethernet shield. There is a standard library available, that allows to easily set up a web server, which we are using (in fact the code is mostly from that example).

The new (full) setup is like this:

Hawk alert
Setup with Arduino as actor

Alerting

Hawkular already has an alerting component built in, that allows to compare incoming values with thresholds and then invoke plugins to forward the fired alert via email, to irc channels and many more way of communication. The plugin we are going to use here is the webhook one. As in the standard Hawkular distribution only the email plugin is present we will need to install the webhook plugin first:

Check out Hawkular-alerts

git clone https://github.com/hawkular/hawkular-alerts.git
cd hawkular-alerts

Build hawkular alerts :

mvn -Pdev -DskipTests install

Now you can copy the plugin to the Hawkular-server

cd hawkular-alerts-actions-plugins
cd hawkular-alerts-actions-webhook
cp hawkular-alerts-actions-webhook.war \
   $HAWKULAR/modules/system/layers/hawkular/org/hawkular/nest/main/deployments/

As Hawkular does not pick this up automatically you need to restart the Hawkular server after copying the webhook.war over.

Set up alerting

I have modified the ruby script to pull in a configuration file (in YAML format):

---
16617927:40.176.91.120.5.0.0.125:
  :name: Living room
  :alert:
    :comparator: :gt
    :value: 25
The first line is the id of the metric to which the following lines apply to. Second line is the display name for the UI. The next section then sets up alerting.

Let's have a look how this looks in code (you can see the full code on GitHub)

Register the webhook to be used below:

@webhook_props = { url: 'http://172.31.7.177/',   # target server
                   method: 'POST' }               # http verb
@alerts_client.create_action 'webhook', "send-via-webhook-#{metric_id}", @webhook_props

Set up a trigger and a condition, trigger first

  t = Hawkular::Alerts::Trigger.new({})
  t.enabled = true
  t.id = "trigger_#{metric_id}"
  t.tags = { :resourceId => "#{feed}/#{res_id}" }
The tags tell the UI on which resource the Trigger applies and thus enables showing the alert in the Hawkular UI

Next the condition:

  c = Hawkular::Alerts::Trigger::Condition.new({})
  c.trigger_mode = :FIRING
  c.type = :THRESHOLD
  c.data_id = metric_id
  c.operator = alert[:comparator].to_s.upcase
  c.threshold = alert[:value]

And then finally as we do not only want the alert to show in the UI, but also be forwarded to our Arduino with the webhook, we need to attach the webhook to the Trigger. Plugin id is webhook and the action_id is what we have set up above.

  # Reference an action definition
  a = Hawkular::Alerts::Trigger::Action.new({})
  a.action_plugin = 'webhook'
  a.action_id = "send-via-webhook-#{metric_id}"
  t.actions.push a
And then we can create the trigger, which will be active immediately.

  @alerts_client.create_trigger t, [c], nil

Fire away

Now when a value above the threshold comes in, the webhook will be triggered, it will open a http connection to the Arduino and the LED will blink.

In addition the alert will also be shown in the Alert Center in the Hawkular UI:

Bildschirmfoto 2016 03 17 um 16 32 37
List of high temperature alerts in the alert center.

More

Note that the above trigger definition is pretty simple and only has one comparator. Also the trigger fires each time a value above the threshold comes in. In a more real world scenario one would add some dampening that the trigger only fires when the measurement is a few times over the threshold for some interval. Or if you start your air-conditioning, you would set the trigger to auto-disable and then have a comparator to switch it back on after the temperature has fallen below a certain level.

There is even a lot more you can do with Hawkular Alerts past the above, including standalone deployment for embedding it in your own application.

Some further reading:

Hawkular Alerts for Developers -- pretty comprehensive documentation of Hawkular Alerts.
Introduction to AutoResolve triggers
Using Hawkular Alerts as a standalone engine

Wednesday, March 02, 2016

Send IoT data to Hawkular-full

In a previous blog post, I was talking about how to send IoT sensor data to Hawkular-metrics.

While this already works quite well, it also lacks the integration with other parts of Hawkular, namely Inventory and Alerting.

In this blog post I will talk about integration with Inventory and how to view the data in the Hawkular-UI. An upcoming article will then talk about Alerting.

I have modified the setup from the last post a bit:

Bridge arch
New setup with a Ruby client

Instead of PTrans I've written a small Ruby client, that makes use of the Hawkular-Client-Ruby ruby gem (it needs version 0.2.1, that has not yet been published to RubyGems.org. In addition it uses a MQTT gem, which makes the code pretty short.

The Ruby client MQTT-bridge now listens on /hawkular/+ topics. Metric arriving on /hawkular/metrics are forwarded as such and registration messages on /hawkular/register are used to register the external resource like the ESP8622 micro controller in Hawkular inventory.

The following is an example registration message:

{"feed": "esp16617927",
  "rt":"esp8266",
  "r":"mcu16617927",
  "mt":{
    "id":"thermo",
    "unit":"NONE",
    "type":"GAUGE",
    "collectionInterval":0
  },
  "m":{
    "id":"16617927:40.176.91.120.5.0.0.125",
    "mt":"thermo",
    "na":"thermo_40.176.91.120.5.0.0.125",
  }
}

You can get the client from https://github.com/pilhuhn/hawkular-mqtt-bridge and then easily run it via

$ ruby lib/hawk.rb

If you are not using a Hawkular-Server on localhost with default user, then you first need to modify the ruby code at the top.

The client will connect to the Hawkular server and then wait for messages on the MQTT topics.

The client code is still rather simplistic and does not spool data when the target Hawkular server is down.

UI

Since Hawkular 1 Alpha11 we have an Explorer (as easter egg :-) that allows to browse through inventory and to show resources and their metrics. The following shows the explorer with a chart from the thermo sensor for the last 12h.

Hawkular screenshot with chart data from thermo sensor
Hawkular UI with chart of sensor data from last 12h

The chart shows a peak at 1am - I have no idea why it is there. Possibly one of my cats examined the sensor :)

ESP Sample code

I have also provided a sample Lua script, that can be used on a ESP8266 like the Adafruit Huzzah shown in the previous post.

As the stock Huzzah comes with NodeMCU Lua 0.9.5 which was not working well for me, I have flashed it with a newer version of NodeMCU Lua. This is now running a firmware with the following modules:

NodeMCU custom build by frightanic.com
	branch: master
	commit: c8037568571edb5c568c2f8231e4f8ce0683b883
	SSL: false
	modules: cjson,file,gpio,i2c,mqtt,net,node,ow,rtcmem,rtctime,sntp,tmr,uart,wifi,ws2812
 build 	built on: 2016-02-18 08:33

Alerting?

In an upcoming post I will talk about alerting in Hawkular to act on unusually high or low temperatures.