MQTT in Ember.js

Ember Octane mqtt.js

Less than 2 years ago I started a new project with the company I work for that requires to an Ember Octane app to control several connected IoT devices around the world. We choosed the MQTT publish/subscribe network protocol to interact with our on-field devices for its lightweight message structure and its limited network bandwith requirements.

After googling for a javascript MQTT library I’ve found the MQTT.js client. At the moment of my search the asynchronous version was not yet released, so I had to wrap the event based client into an Ember service and transform it into a Promise based client.

This is a mandatory requirement because I need broker connection before subscribing to a topic or I need topic subscription before publishing on it. Sometimes you had retain messages on a topic for receiving last published value after the subscription. Other times you need publishing an empty value on a topic to request the status of a given device. So you need working subscribtion on a topic before sending a message. That said javascript Promises are the only way to accomplish this tasks.

When I wrote this service I didn’t find an Ember addon ready to do this things. Therefore I decided to dive into the docs and learn how to build an addon. The ember-mqttjs addon is my first Ember addon!

The code

This service extends the Evented Ember object for raising events on new messages as well as connect, disconnect events and many others you can find on its readme. In addition of raising this events it returns a Promise for connect, subscribe, unsubscribe and publish methods.

This is an example of another service that uses the ember-mqttjs service:

import Service, { inject as service } from '@ember/service';
import { bind } from '@ember/runloop';

export default class YourService extends Service {
  @service mqtt;
  constructor() {
    super(...arguments);
    //...
    let _fOnMessage = bind(this, this._onMessage);
    this.mqtt.on('mqtt-message', _fOnMessage); 
  }

  _onMessage(sTopic, sMessage) {
    //code to manage messages received on a certain topic
  }

  async subscribeAndPublish(sTopic, sMessage) {
    try {
      await this.mqtt.connect(HOST, USERNAME, PASSWORD)
    } catch (oError) {
      //code on connection error
    }
    try {
      await this.mqtt.subscribe(sTopic);
    } catch (oError) {
      //code for subscription error
    }
    try {
      await this.mqtt.publish(sTopic, sMessage);
    } catch (oError) {
      //code for message publish error
    }
    return Promise.resolve();
  }
//...
}

I’ve just refactored the addon code to use async/await features and I moved the CI from travis to github action (thanks to this Jeldrik Haschke’s repo).
Many improvements can be done in the future starting from writing more tests to cover other cases.
If you have any suggestions or proposal to improve the code as well as the tests you are welcome!

Contact me or start contributing on GitHub project repo!

Ember + Boostrap 5

Today I welcome a new template for my blog by returning to write a post after a very long time!

This WordPress theme is built on top of the latest Bootstrap release, Bootstrap 5 and with this post I would like to explain you how to use this hugely popular front-end framework in an Ember app.

With this major new release the developers have focused most of their efforts towards removing jQuery as a dependency of the framework to make it lighter and usable by a wider audience now interested in saving as much kb as possible.

For those who knows and uses the previous Bootstrap version (v4) I suggest to dive into the migration guide, to understand what breaking changes were made in this new update.

As an experiment (I will tell you later about what I am working on in my spare time) I’ve tried to use Bootstrap 5 in a new Ember Octane app and thank to the release of the bootstrap npm package this turned out to be tremendously simple.

Let’s see the steps:

First you have to install the bootstrap npm package:

npm install --save-dev bootstrap

Then you have to modify your ember-cli-build.js file:

'use strict';

const EmberApp = require('ember-cli/lib/broccoli/ember-app');

module.exports = function (defaults) {
  let app = new EmberApp(defaults, {
    // Add options here
    sassOptions: {
      includePaths: ['node_modules/bootstrap/scss'],
    },
  });
  app.import('node_modules/bootstrap/dist/js/bootstrap.bundle.min.js');
  return app.toTree();
};

The last few steps are required to be able to import bootstrap SCSS files.
First you have to install ember-cli-sass addon:

ember install ember-cli-sass

Then you have to rename your app style app.css to app.scss and insert the line to import the bootstrap files:

@import 'bootstrap';

You are now ready to use Bootstrap 5 in your Ember app!

Uno script Gulp per automatizzare la compilazione dei files Sass (scss)

Gulpjs

Gulp js è una libreria javascript che permette di automatizzare svariate tipologie di noiose procedure che gli sviluppatori normalmente fanno “a mano”.

Proprio in questa direzione ho deciso di scrivere un breve script gulp che consente di automatizzare la ricompilazione dei fogli di stile SASS (scss), per evitarmi di lanciare, ad ogni modifica dei files, il comando sass sorgente.scss destinazione.css.

L’unico prerequisito per utilizzare gulp è di aver installato Nodejs ed il suo package manager npm (che viene installato di default insieme a node). Una volta installato node e scaricati i sorgenti del mio script basterà lanciare:

sudo npm install

…ed npm installerà per voi tutte le dipendenze necessarie!

Lo script prevede due modalità di esecuzione tramite i seguenti comandi:

  • gulp: compila i vostri scss presenti nella sottocartella src in un unico css nella root directory minifizzato (sass –style compressed)
  • gulp dev: compila gli scss in modalità espansa (sass –style expanded)

Questi due comandi avviano un task che rimane “in ascolto” e ad ogni modifica di un file scss rilancia il comando evitando il noioso compito di lanciare ogni volta la compilazione dei files per vedere le modifiche allo stile delle vostre web app/siti. In questo modo potrete scrivere le direttive di stile come si faceva prima dell’avvento di SASS/LESS e vedere immediatamente le nuove modifiche “live”.

Ho previsto un repository github “gulp-for-sass” con questo mini-progetto, scaricabile e modificabile liberamente!

Aggirare le limitazioni delle API di Google Maps per il calcolo dei percorsi

Google Maps API

Torno a scrivere sul mio blog per trattare un argomento a mio giudizio interessante, anche se un po’ specifico.
Per conto di un cliente mi sto occupando delle API di Google Maps, in particolare l’ultima versione, ossia la V3.
Premetto, per chi non conoscesse l’argomento, che dalla versione 2 c’è stato un grande passo avanti, con ottime nuove funzionalità e tanti metodi che fanno risparmiare un sacco di tempo… D’altronde stiamo parlando di Big G!

Lo script che pubblico in questa pagina serve per rimediare al problema delle limitazioni poste da Google su ogni singola richiesta di calcolo di un percorso. Il cliente in questione deve visualizzare sulla mappa il tragitto tra due punti, passando però per un numero indefinito di punti intermedi.

Per fare questo Google rende disponibili le directions API impostando però il limite di 2500 richieste giornaliere e 8 punti intermedi per richiesta. L’idea è semplice, ottimizzare le richieste includendo al massimo 8 punti intermedi, settando però, dalla seconda richiesta in avanti, il punto di partenza uguale al punto finale della richiesta precedente.

Vediamo il codice javascript:

    var map = null;
    var markers = new Array();
    var coordinates = new Array();
    var directionsDisplay = new Array();
    var directionsService = new google.maps.DirectionsService();
    function placeMarker(lat, lng){
        var markerPos = new google.maps.LatLng(lat, lng);
        var marker = new google.maps.Marker({
            position: markerPos,
            map: map,
            draggable: true,
            animation: google.maps.Animation.DROP
        });
        markers.push(marker);
    }

    function removeRoutes(){
        for(var i = 0; i < directionsDisplay.length; i++){
            directionsDisplay[i].setMap(null);
        }
        directionsDisplay = new Array();
    }

    function drawRoute(begin, end, waypts){
        var request = {
            origin: begin,
            destination: end,
            waypoints: waypts,
            optimizeWaypoints: true,
            travelMode: google.maps.TravelMode.DRIVING
        };
        directionsService.route(request, function(response, status) {
            if (status === google.maps.DirectionsStatus.OK) {
                var dirDisp = new google.maps.DirectionsRenderer({suppressMarkers: true});
                dirDisp.setMap(map);
                dirDisp.setDirections(response);
                directionsDisplay.push(dirDisp);
            }
        });
    }

    function calculateRoutes(){
        removeRoutes();
        var begin = new google.maps.LatLng(coordinates[0][0], coordinates[0][1]);
        var end = null;
        var waypts = new Array();
        var wCount = 0;
        var REQUEST_WAYPOINTS_LIMIT = 8;
        var i;
        for(i = 1; i < (coordinates.length-1); i++){
            if(wCount === REQUEST_WAYPOINTS_LIMIT){
                i++;
                end = new google.maps.LatLng(coordinates[i][0], coordinates[i][1]);
                drawRoute(begin, end, waypts);
                begin = end;
                wCount = 0;
                waypts = new Array();
            }
            waypts.push({
                location: new google.maps.LatLng(coordinates[i][0], coordinates[i][1]),
                stopover: true
            });
            wCount++;
        }
        if(waypts.length > 0){
            end = new google.maps.LatLng(coordinates[coordinates.length-1][0], coordinates[coordinates.length-1][1]);
            drawRoute(begin, end, waypts);
        }
        for(var i = 0; i < coordinates.length; i++){
            placeMarker(coordinates[i][0], coordinates[i][1]);
        }
    }

Nel codice qui sopra come potete vedere ho un array di coordinate che contiene i vari punti da rappresentare sulla mappa, e il percorso deve essere calcolato partendo dalla prima coordinata presente in array per arrivare all’ultima cella dell’array, passando per tutte le altre.

Ho dato per scontato che la mappa sia già stata inizializzata e che la variabile map contenga l’oggetto google.maps.Map.

Un’ulteriore miglioria già fatta (che tratterò in un futuro articolo) sarà quella di colorare e numerare i marker dinamicamente e di adattare automaticamente lo zoom della mappa ai markers attivi sulla mappa visualizzata.

Eseguire chiamate AJAX con jQuery e JSON in WordPress

Ajax and WordPress

Succede sempre più di frequente di dover effettuare delle chiamate ajax in WordPress. In questo articolo vedremo come effettuare delle chiamate asincrone senza dover creare nuove pagine WordPress ma sfruttando lo script utilizzato dall’interfaccia del wp-admin.
Nell’esempio in questione, la chiamata AJAX restituirà un file JSON formato davvero utile per rappresentare i dati restituiti da una query. Lato javascript useremo la funzione $.getJSON(…) di jQuery mentre lato server scriveremo il nostro script all’interno del file functions.php presente in qualsiasi tema WordPress.

Per prima cosa dobbiamo creare la corrispondenza tra una nuova action e la nostra funzione php:

add_action('wp_ajax_myaction', 'my_function');

Fatto ciò possiamo scrivere la nostra funzione my_function la quale corrisponderà all’azione myaction (il nome è puramente indicativo, potete chiamare l’azione e la funzione come preferite):

function my_function() {
  global $wpdb;
  $id = $_GET['id'];
  $rows = array();
  $q = "SELECT * FROM my_table WHERE id = ".$id;
  $rows['results'] = $wpdb->get_results($q, ARRAY_A);
  if(count($rows) <= 0){
    return false;
  }
  echo json_encode($rows);
  exit();
}

In questo script trovate tutto l’indispensabile per completare la parte lato server. Come si può intuire la query dovrà utilizzare un parametro passato in GET, poi utilizzando la variabile globale wpdb effettueremo la query sul database. La json_encode trasformerà l’array associativo con i record letti tramite la SELECT in una stringa JSON e la stamperemo a video tramite l’echo. Non dimenticate la exit() finale perchè altrimenti verrà stampato uno “0” che vi metterà in difficoltà nel parsificare il JSON.

Un ultimo particolare di cui tenere conto è che la add_action crea un’azione per l’admin-ajax.php che è un file accessibile solo da utenti loggati, quindi per consentire l’esecuzione dell’azione sia da utenti registrati sia da ospiti sarà necessario aggiungere un’ulteriore linea di codice come questa:

add_action('wp_ajax_nopriv_myaction', 'my_function');

Dopo aver completato lo script PHP possiamo passare al lato client, con il codice javascript per la chiamata della funzione:

$jQ.getJSON('<?php echo get_bloginfo('url'); ?>/wp-admin/admin-ajax.php',{action: 'myaction',id: 'tuo_id'}, function(json){...Codice javascript per parsificare il json...}

Ho omesso l’inclusione di jquery in WordPress, ma potete trovare come fare in un mio precedente articolo che trattava l’argomento nello specifico.

A questo punto non vi resta che sbizzarrirvi con le chiamate ajax nel vostro template oppure dai vostri plugin (in quest’ultimo caso basta spostare il codice PHP in un file del vostro plugin).

Nuovo tema per il blog!

Come (spero) vi siate accorti, sono riuscito finalmente ad ultimare il nuovo tema per il mio blog.

Mi sono sempre promesso che prima o dopo avrei lavorato alla realizzazione di un mio tema, visto che fino ad oggi avevo sempre utilizzato temi scaricati dalla sezione apposita di wordpress e oggi ho finalmente un tema tutto mio.

Ho cercato di renderlo più leggero del precedente, riducendo al minimo il codice javascript, alleggerendo il css ed ispirandomi a design minimalisti, senza troppi fronzoli per rendere il tema intuitivo e cercando di ricordare qualche regola di HCI.

Spero vi piaccia, ma aspetto critiche e suggerimenti e ovviamente se trovate dei bugs, segnalatemeli, thanks!

Includere jQuery nel proprio tema wordpress

Il titolo potrebbe farvi pensare che questo post potrebbe essere inutile… Infatti il metodo più semplice per usare jQuery in un tema per wordpress è quello di inserire una nuova sorgente per uno script javascript con il tag:

<script type="text/javascript" src="......./jquery.js"></script>

Inizialmente il tutto potrebbe anche funzionare e non è detto che possa filare tutto liscio senza crearvi nessun fastidio.

I problemi però potrebbero iniziare quando deciderete di includere un plugin nel vostro blog.

Infatti molti plugin di wordpress richiedono un framework javascript (non necessariamente jQuery) per funzionare. WordPress include già il file .js di jQuery e quando un plugin lo richiede, il sistema include già lo script.

Per questo il modo più semplice è sicuro di inserire jQuery nel proprio tema è quello di inserire nel file header.php sopra il richiamo della funzione wp_head():

wp_enqueue_script("jquery");
wp_head();

Ora wordpress includerà il file javascript di jQuery, ma bisogna ancora compiere un passo per poter essere sicuri di aver risolto tutti i problemi. Se fossero necessarie altre librerie javascript diverse da jQuery, quest’ultimo potrebbe andare in conflitto, perciò risolviamo il problema con queste istruzioni javascript:

var $jQ = jQuery.noConflict();

$jQ(document).ready(function(){
       alert("Hello World!");
});

Se avrete fatto tutto come si deve, al caricamento della pagina apparirà una finestra di avviso con scritto Hello World! ;-)

jQuery User Interface: interfacce utente in javascript!

Intanto benvenuti a tutti nel mio nuovo-vecchio blog. Ho solamente cambiato indirizzo, mantenendo tutto il vecchio blog e cambiando la veste grafica… Un piccolo aggiornamento contro la noia, insomma! ;-)

Detto ciò in per inaugurare davideferrero.com, voglio portarvi a conoscenza di un tool molto utile, se non lo conoscete ancora.

Come tutti ormai sapete (non lo sapete? sapevatelo :-P ) sono fan e infognato (leggi “addicted” che fa più figo) di jQuery, un javascript framework molto intuitivo, semplice e abbastanza leggero per animare e migliorare le proprio pagine web.

Bene, usando un po’ jQuery noterete subito di aver bisogno di interfacce grafiche per l’utente, ad esempio per una scelta di date (ne avevo già parlato qui) o per creare dei blocchi trascinabili (drag&drop), barre di caricamento, pulsanti “slider” o dei tabs… Ok, con jQuery UI tutto ciò è possibile, potete crearvi il vostro tema personalizzato scegliendo i colori e le caratteristiche dei vari oggetti e scaricarvi i file (javascript, css e immagini), personalizzandovi il pacchetto di download con solo gli oggetti di cui avete bisogno. Per tutte le personalizzazioni dei vari gadget, troverete un’ampia documentazione che vi aiuterà nel caso aveste problemi a farli funzionare.

Appena pubblicheremo il progetto a cui sto ancora lavorando in ufficio, potrete vedere all’opera alcune di queste UI… a presto per i prossimi aggiornamenti su questo argomento!

PS: aggiornate il feed rss facendolo puntare al nuovo indirizzo se non lo avete ancora fatto, ma soprattutto se vi eravate abbonati a quello vecchio… Se invece non lo avevate aggiunto tra i vostri preferiti, avete un motivo in più per farlo ora! ;-)
[ad#ad-1]

Web & Flash: risolvere tutti i problemi di compatibilità

Come spiega il titolo, in questi giorni, ho avuto qualche piccolo problema nell’embedding di oggetti flash in alcune pagine web a cui stavo lavorando.

Chiunque si sia cimentato, anche solo per poco, nel mestiere del web developer, avrà certamente incontrato problemi nel rendere uguale per tutti i browser le pagine web. Con quasi tutti i browser, le pagine vengono renderizzate in un certo modo, mentre con altri browser no (notare, non c’è la “s” del plurale :-P ). E così è anche per gli oggetti flash. Il browser appena linkato pensa bene di riconoscere l’embedd come controllo Active X, e non lo visualizza (a meno che… ma la storia si fa lunga e tortuosa). Googleggiando, ci si imbatte quasi subito in swfobject, un oggetto javascript che ci toglie le castagne dal fuoco e mette in pista in un attimo il nostro lavoro. Il codice da scrivere è veramente ridotto all’osso, vi riporto l’esempio che faceva al caso mio con l’embedd del player flash di livestream.com (una piattaforma di streaming video):

  1. Includere la libreria nel tag <head>:
    <script type="text/javascript" src="swfobject.js"></script>
  2. Creare il div che ospiterà l’oggetto flash:
    <div id="livestreamPlayer"></div>
  3. Creare l’oggetto con il codice javascript:
    <script type="text/javascript">
    	flashvars = { channel: 'livestreamearth' };
    	params = { AllowScriptAccess: 'always' };
    	swfobject.embedSWF("http://cdn.livestream.com/chromelessPlayer/wrappers/
    SPlayer.swf","livestreamPlayer", "400", "300", "9.0.0", "expressInstall.swf",
    flashvars, params);
    </script>

Come si può intuire la variabile flashvars conterrà le variabili di cui l’oggetto flash necessita per funzionare mentre params conterrà i settaggi flash per l’oggetto. Il primo parametro è invece il path dell’oggetto flash da embeddare, il secondo è l’id del div che lo conterrà nella nostra pagina, seguito da width e height, versione di flash richiesta e oggetto flash(fornito insieme ad swfobject) che consente di aggiornare la propria versione di flash installata sul pc.

Con questi semplici passi si otterrà il caricamente dell’oggetto flash tramite javascript, che consentirà di bypassare il blocco di alcuni browser e di eseguirlo senza problemi in tutti gli altri ;-).

Eccovi il link per scaricare lo zip contenente swfobject: http://bit.ly/3GWdi6

<script type="text/javascript" src="swfobject.js"></script>

[ad]

Librerie Jquery…for programmers only!

Librerie JQuery

Da qualche giorno sul lavoro ho dovuto realizzare un’applicazione in jsp che permettesse, al click su un link, di far comparire dei dati aggiuntivi… Appena ho sentito cosa dovevo fare, lo stack-trace della mia memoria era all’incirca questo:

AJAX…AJAX…AJAX…AJAX…AJAX…AJAX…AJAX…AJAX…AJAX…AJAX…AJAX…AJAX

Mi sono quindi sbattuto altamente… per cercare qualcosa che mi semplificasse il lavoro…:-P.

Dopo breve googleggiamento mi sono imbattuto in una libreria Javascript che dopo poco ho scoperto essere molto sciccosa… JQuery mette a disposizione infatti molti strumenti, sia per creare effetti grafici con javascript, sia per gestire gli eventi sui vari oggetti presenti nella pagina  e non ultimo di utilizzare AJAX in modo molto semplice…

Bè ora potete spassarvela con queste librerie… Ah dimenticavo, vengono utilizzate da Google, Dell e molti altri ancora, anche per questo credo che siano davvero un ottimo strumento…

Se le volete provarle, il link per scaricarle è questo:  http://docs.jquery.com/Downloading_jQuery

Se non avete idea di metterci le mani dentro, vi basterà scaricare il minified, dovrebbe essere la versione compressa che funziona allo stesso modo del .js… Buon lavoro![ad]