Autor Tema: Plataformas gratuitas para probar dispositivos IOT  (Leído 2587 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3476
    • Pinballsp
Plataformas gratuitas para probar dispositivos IOT
« en: 23 de Febrero de 2018, 22:23:21 »
 
Buenas.
¿ Teneis experiencia con plataformas gratuitas para almacenar datos de dispositivos IOT ?.

Hoy me llamó un posible cliente interesado en un proyecto que inicié ya hace bastante tiempo para otro cliente que al final me dejó tirado. Los prototipos aún los conservo, aunque llevan un PIC32, que de continuar el proyecto lo reemplazaría por un STM32, un Kinetis, un SAM S70 o el nuevo NXP RT1020 que está a punto de salir.

El producto es para transmitir la información de las recaudaciones de maquinas recreativas y similares (billares, futbolines, pinball, tragaperras, gruas de premio y demás artilugios de ocio). La conexión a estas máquinas, en principio es muy sencilla, capturar la señal del monedero, que suele ser un pulso (negativo o positivo, creo que no hay un estandard).

Husmeando por Google, me encuentro unas cuantas de estas plataformas, como las que comentan en este enlace, https://programarfacil.com/podcast/proyectos-iot-con-arduino/

Otra opción que tendría es montar un server en casa, pero estoy de faena hasta las orejas, no tengo apenas tiempo para meterme en otro lío. Preferiría programar mi placa para que por GPRS suba los datos a uno de estos sitios gratuitos. Le doy la placa al cliente, que le ponga la tarjeta SIM con tarifa para datos, y que la tenga a prueba un tiempo, si le interesa ya lo hablamos. Tiene 90 máquinas en explotación y está muy interesado en poder controlar la recaudación a distancia, desde casita por internet, sobre todo cuando pone máquinas en locales nuevos, para ver si tienen aceptación y recaudan, sin necesidad de tener que desplazarse, porque pierde mucho tiempo.
« Última modificación: 23 de Febrero de 2018, 22:28:39 por planeta9999 »

Desconectado tsk

  • PIC16
  • ***
  • Mensajes: 249
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #1 en: 24 de Febrero de 2018, 00:35:06 »
Si quieres te puedo dar tips al respecto, ya he probado ese tipo de plataformas, incluso me he montado servidores con mosquitto, e incluso he usado plataformas como Google App Engine y Heroku.

Estos los puedes usar si no quieres montar un servidor en casa.

Si no requieres usar sockets y demás cosas con el Google App Engine que es gratuito (hasta cierto punto) podrías salir a flote, ya que no tienes que implementar ningún servidor, sólo tienes que realizar la programación en python, que es bastante sencilla y para el desarrollo puedes usar tu propia pc y después subir el resultado, lo cual facilita todo.

Otro que he visto pero no he probado son los droplets de digitalocean.

https://www.digitalocean.com/products/droplets/

El más económico con 5 USD por mes, y puedes poner que se te antoje, o al menos eso creo, ya que no lo he probado, pero te ofrece 1 GB en RAM, 25GB en SSD y 1TB de transferencia mensual, pero si puedes instalar en el droplet lo que se te venga en gana, entonces es una ventaja en comparación del Google App Engine. El GAE no permite conexiones permanentes, que es necesario para actualizar datos en tiempo real.

Por ejemplo esto es en tiempo real.

El demo lo hice usando MQTT con mosquitto como broker y como servidor Flask+SocketIO (python) para que fuera en tiempo real y poder actualizar los datos (gráficas a todos los clientes conectados).

Lo otro que debes de pensar es en que el cliente va a querer ver los datos en su móvil cuando no esté en casa. Si no quieres realizar una aplicación entonces el se tendría que conectar a la aplicación web por lo que debe ser responsiva. Para esto tienes varias opciones:

1.- Foundation
2.- Bootstrap
3.- Flexbox

Los primeros dos son librerías, el tercero tengo entendido que ya todos los navegadores lo soportan. Así que yo me iría por el último.

Este es un demo que hice con Flexbox (Página servida por un STM32)

Para una página web sencilla, hasta aquí te vale, pero cuando quieres ir por más y darle una mejor experiencia de usuario, limitar las conexiones puedes usar Angular, de tal forma que la mayoría de la aplicación se ejecute del lado del usuario. En el demo de arriba estoy usando Angular, y puedes ver que aunque escribo /#/one, no se aprecia que se recargue de nueva cuenta la página.

Con Angular+Google App Engine podrías darle a tu cliente una sensación de que las gráficas se actualizan en tiempo real sin que él tenga que recargar la página y sin la necesidad de websockets.

Si te interesa, puedo buscar el demo que hice con mosquitto y flask+SocketIO para que lo puedas probar en tu máquina.

Saludos

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3476
    • Pinballsp
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #2 en: 24 de Febrero de 2018, 02:16:56 »

Gracias tsk, le echaré un ojo a todo lo que comentas.
¿ Esto de mosquitto y flask+SocketIO, que rueda en un PC ?.

Mi idea es que la placa, tenga un micro ARM, probablemente un Kinetis o un STM32, aunque si me llegan samples del RT1020, lo podría estrenar con este proyecto. Todo el desarrollo en C++. Le pondría un módulo GPRS SIM800L, y para los casos en que tenga varias máquinas en el mismo local, o si el local tiene WIFI, llevarían un ESP8266.

En la otra parte, tengo experiencia haciendo páginas web con PHP y MySQL, llegado el momento le puedo hacer una aplicación o montarle un Joomla y desarrollarle un módulo en PHP para que gestione todos los datos que reciba de las placas, con estadísticas, gráficos y todas esas cosas, creo que hay librerías para la parte gráfica. O buscarle una de esas plataformas web expresamente para IOT, aunque sea de pago, que seguramente estará más orientada a este proyecto.

« Última modificación: 24 de Febrero de 2018, 02:20:40 por planeta9999 »

Desconectado tsk

  • PIC16
  • ***
  • Mensajes: 249
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #3 en: 24 de Febrero de 2018, 04:52:17 »
Mosquitto es un broker del protocolo MQTT que se puede instalar en cualquier PC y en servidores.

Con respecto a las páginas que mencionas, el que más he escuchado es el de thingspeak, pero no mencionan otros como bluemix de IBM o incluso Amazon cuenta con su propio SDK para aplicaciones IoT.

https://aws.amazon.com/es/iot/sdk/

También no mencionan Node-Red, entre otros, que en este momento no recuerdo.

Flask es una de tantas librería de python para crear servicios web (Bottle, tornado, Django, etc.)

Código: Python
  1. import os
  2. import sys
  3. from flask import Flask, request, jsonify, session, send_from_directory
  4. import random
  5. import time
  6.  
  7. app = Flask(__name__)
  8. app.config["STATIC_FOLDER"] = "../fs/"
  9.  
  10. users = {"admin":"password",
  11.          "guest":"password2"
  12.          }
  13.  
  14. '''
  15. username
  16. ip
  17.  
  18. '''
  19. data_points ={}
  20. io_states = {
  21.         "opto1": False,
  22.         "opto2": False,
  23.         "opto3": False,
  24.         "opto4": False,
  25.         "relay1":False,
  26.         "relay2":False,
  27.         "relay3":False,
  28.         "relay4":False,
  29.         "biled1_red":False,
  30.         "biled1_green":False,
  31.         "biled2_red":False,
  32.         "biled2_green":False,
  33.         "relay_c1_1": False,
  34.         "relay_c1_2":False,
  35.         "relay_c2_1": False,
  36.         "relay_c2_2":False,
  37.         "com1": False,
  38.         "com2": False
  39.         }
  40. sessions = {}
  41.  
  42. def gen_data():
  43.     global data_points
  44.     global io_states
  45.  
  46.     vbat = [(i, random.random()) for i in range(20)]
  47.     vrec = [(i, random.random()) for i in range(20)]
  48.     data_points['vbat'] = vbat
  49.     data_points['vrec'] = vrec
  50.  
  51.     for key in io_states:
  52.         io_states[key] = random.choice([True, False])
  53.  
  54.  
  55. def session_add(user,password,ip):
  56.     session={}
  57.     if user in users:
  58.         if password == users[user]:
  59.             session["user"] = user
  60.             session["ip"] = ip
  61.             session["admin"] = False
  62.             if user == "admin":
  63.                 session["admin"] = True
  64.             sessions[ip] = session
  65.             return True
  66.         return False
  67.     else:
  68.         return False
  69.  
  70. def session_search(ip):
  71.     if ip in sessions:
  72.         return sessions[ip]
  73.     return {}
  74.  
  75. def login_func(user,password,ip):
  76.     return(session_add(user,password,ip))
  77.  
  78. @app.route('/')
  79. def index():
  80.     return send_from_directory(app.config['STATIC_FOLDER'],'index.html')
  81.  
  82. @app.route('/css/<path:filename>')
  83. def custom_static_css(filename):
  84.     path = os.path.join(app.config['STATIC_FOLDER'],'css')
  85.     return send_from_directory(path, filename)
  86.  
  87. @app.route('/js/<path:filename>')
  88. def custom_static_js(filename):
  89.     path = os.path.join(app.config['STATIC_FOLDER'],'js')
  90.     return send_from_directory(path, filename)
  91.  
  92. @app.route('/partials/<path:filename>')
  93. def custom_static_partials(filename):
  94.     path = os.path.join(app.config['STATIC_FOLDER'],'partials')
  95.     return send_from_directory(path, filename)
  96.  
  97. @app.route('/api/status.cgi')
  98. def api_status():
  99.     session = session_search(request.remote_addr)
  100.     if session != {}:
  101.         return(jsonify({'status':True}))
  102.    
  103.     return jsonify({'status':False})
  104.  
  105. @app.route('/api/user_level.cgi')
  106. def api_user_level():
  107.     session = session_search(request.remote_addr)
  108.     if session != {}:
  109.         if session['user'] == 'admin':
  110.             return(jsonify({'status':True}))
  111.     return jsonify({'status':False})
  112.  
  113. @app.route('/api/logout.cgi')
  114. def api_logout():
  115.     sessions.pop(request.remote_addr,None)
  116.     return jsonify({'status':True})
  117.  
  118. @app.route('/api/login.cgi')
  119. def login():
  120.     password = request.args.get("pwd")
  121.     user = request.args.get("user")
  122.     ip = request.remote_addr
  123.     status = login_func(user,password,ip)
  124.     print(status)
  125.     print(sessions)
  126.     return jsonify({'status':status})
  127.  
  128. @app.route('/api/get_system_state.cgi')
  129. def api_get_system_sate():
  130.     gen_data()
  131.     return(jsonify({"io_states":io_states,"data_points":data_points}))
  132.  
  133. @app.route('/api/get_params.cgi',methods=['GET', 'POST'])
  134. def api_get_params():
  135.     print(request.method)
  136.     print(request.args)
  137.     return("<h1>test</h1>")
  138.  
  139.  
  140. if __name__ == "__main__":
  141.     app.run(host="0.0.0.0",debug=True)
  142.  

Por lo general en una aplicación web el cliente hace la petición y el servidor responde y cierra la conexión. Para aplicaciones como la que quieres hacer se requiere una comunicación bidireccional para que al momento que el servidor reciba un dato de los nodos, el cliente los vea reflejado en su pantalla. Aquí es donde entra SocketIO, que te crea los llamados websocket. Hacer esto no se que tan fácil sea en PHP.

Google App Engine (GAE) no permite websockets en el plan gratuito, por ello mencionaba Angular para dar la impresión de tiempo real al cliente además de gráficas dinámicas.

Una aplicación Angular es realmente sencilla, y la mayoría de la aplicación se ejecuta del lado del cliente, por lo que te ahorras ancho de banda y CPU, además que separas el servidor de la aplicación, es decir, que no importa si estás usando PHP, Python, Ruby, Go, o lo que sea, mientras la aplicación de angular pueda acceder a los mismos recursos y rutas, todo va a funcionar sin cambios.

Por ejemplo

app.js
Código: [Seleccionar]
var myApp = angular.module('myApp',['ngRoute']);

myApp.value('Dashboard', {});

myApp.config(function ($routeProvider) {
  $routeProvider
  .when('/',{
    templateUrl:'partials/index.html',
    access:{restricted:false}
  })
  .when('/dashboard',{
    templateUrl:'partials/dashboard.html',
    controller:'dashBoardController',
    access:{restricted:false, admin:false, userlevel:[0,1,2]}
  })
  .when('/admin_page',{

    templateUrl: 'partials/admin.html',
    controller:'adminController',
    access:{restricted:false, admin:true, userlevel:[0]}
  })
  .when('/logs',{
    template: '<h1>Logs Page!</h1>',
    access:{restricted:true, admin:true, userlevel:[0,1]}
  })
  .when('/access_error', {
    template:"<h1>You don't have the rights to access this page</h1>"
  })
  .when('/login', {
    templateUrl:'partials/login.html',
    controller: 'loginController',
    access:{restricted:false}
  })
  .otherwise({
    redirectto:'/'
  });
});

myApp.run(function ($rootScope, $location, $route, AuthService) {
  $rootScope.$on('$routeChangeStart',
    function (event, next, current) {
      AuthService.getUserStatus()
      .then(function(){
        if (next.access.restricted && !AuthService.isLoggedIn()){
          $location.path('/login');
          $route.reload();
        } else if(next.access.restricted && AuthService.isLoggedIn() && AuthService.UserPermited(next.access.userlevel))
        {
          $location.path('/access_error');
          $route.reload();
        }
      });
  });
});

controllers.js (controladores)
Código: [Seleccionar]
angular.module('myApp').controller('loginController',
  ['$scope', '$location', 'AuthService',
  function ($scope, $location, AuthService) {

    $scope.login = function () {

      // initial values
      $scope.error = false;
      $scope.disabled = true;

      // call login from service
      AuthService.login($scope.loginForm.user, $scope.loginForm.password)
        // handle success
        .then(function () {
          $location.path('/');
          $scope.disabled = false;
          $scope.loginForm = {};
        })
        // handle error
        .catch(function () {
          $scope.error = true;
          $scope.errorMessage = "Invalid username and/or password";
          $scope.disabled = false;
          $scope.loginForm = {};
        });

    };

}]);

angular.module('myApp').controller('logoutController',
  ['$scope', '$location', 'AuthService',
  function ($scope, $location, AuthService) {

    $scope.logout = function () {

      // call logout from service
      AuthService.logout()
        .then(function () {
          $location.path('/login');
        });

    };

}]);


angular.module('myApp').controller('adminController',
  ['$scope','$location','AuthService','$http',
  function($scope,$location, AuthService,$http) {
      $http.get('/api/get_system_config.cgi')
      .success(function(data){
        console.log(data);
        var htmObject = $(data);
        console.log(htmObject);
        var json_data = JSON.parse(htmObject[1].getAttribute("data-all"));
        var json_data_c = JSON.parse(htmObject[4].getAttribute("config-all"));
        console.log(json_data_c);
        $scope.data=json_data_c;
      })
    .error(function(data){
    });
    $scope.submit_network = function(){
      AuthService.updateConfig($scope.data.network);
    }
    $scope.openTab = function(evt, tab_active) {
    // Declare all variables
    console.log(evt);
  console.log(tab_active);
    var i, tabcontent, tablinks;

    // Get all elements with class="tabcontent" and hide them
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }

    // Get all elements with class="tablinks" and remove the class "active"
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }

    // Show the current tab, and add an "active" class to the button that opened the tab
    document.getElementById(tab_active).style.display = "flex";
    evt.currentTarget.className += " active";
}
}]);

angular.module('myApp').controller('dashBoardController',
  ['$scope','$interval','$location','AuthService','$http',
  function($scope,$interval,$location, AuthService,$http) {
    $scope.reload = function() {
      $http.get('/api/get_system_state.cgi')
      .success(function(data){
        console.log(data);
        $scope.v1_last_val = data.data_points.vbat[19][1];
        $scope.v2_last_val = data.data_points.vrec[19][1];
        $scope.io_states = data.io_states;
      });
    };
    $scope.reload();
    var get_data = $interval($scope.reload,1000);
    $scope.$on("$destroy", function() {
      if (get_data) {
        $interval.cancel(get_data);
      }
    });
}]);

services.js (servicios)
Código: [Seleccionar]
angular.module('myApp').factory('AuthService',
  ['$q','$timeout','$http',
    function($q, $timeout, $http)
    {
      var user = null;

      return ({
        isLoggedIn: isLoggedIn,
        login: login,
        getUserStatus: getUserStatus,
        getUserLevel: getUserLevel,
        isAuthorized: isAuthorized,
        UserPermited: UserPermited,
        updateConfig: updateConfig
      });

      function isLoggedIn(){
        if(user) {
          return true;
        } else {
          return false;
        }
      }

      function isAuthorized(){
        if(admin) {
          return true;
        } else {
          return false;
        }
      }

      function getError()
      {
        return error;
      }

    function UserPermited(userlevel){
      var deferred = $q.defer();
      $http.get('/api/user_level.cgi')
      .success(function(data,status){
      })
      .error(function(data) {
      });
    }

    function updateConfig(data){
      var deferred = $q.defer();
      console.log(JSON.stringify(data));
      $http.get('/api/update_config.cgi?q='+JSON.stringify(data))
      .success(function(data, status){
      })
      .error(function(data){
      });
    }

    function login(username, password) {

      // create a new instance of deferred
      var deferred = $q.defer();

      // send a post request to the server
      $http.get('/api/login.cgi?user='+username+'&pwd='+password)
        // handle success
        .success(function (data, status) {
          var htmObject = $(data);
          var json_data = JSON.parse(htmObject[1].getAttribute("data-all"));
          if(json_data.status){
            user = true;
            deferred.resolve();
          } else {
            user = false;
            deferred.reject();
          }
        })
        // handle error
        .error(function (data) {
          user = false;
          deferred.reject();
        });

      // return promise object
      return deferred.promise;

    }

    function logout() {

      // create a new instance of deferred
      var deferred = $q.defer();

      // send a get request to the server
      $http.get('/api/logout.cgi')
        // handle success
        .success(function (data) {
          user = false;
          deferred.resolve();
        })
        // handle error
        .error(function (data) {
          user = false;
          deferred.reject();
        });

      // return promise object
      return deferred.promise;

    }
   
    function getUserStatus() {
      return $http.get('/api/status.cgi')
      // handle success
      .success(function (data) {
        var htmObject = $(data);
        var json_data = JSON.parse(htmObject[1].getAttribute("data-all"));
        if(json_data.status){
          user = true;
        } else {
          user = false;
        }
      })
      // handle error
      .error(function (data) {
        user = false;
      });
    }

    function getUserLevel(){
       return $http.get('/api/user_level.cgi')
        .success(function(data){
          var htmObject = $(data);
          var json_data = JSON.parse(htmObject[1].getAttribute("data-all"));
        if(json_data.status) {admin=true;} else {admin=false;}
}).error(function(data){ admin=false;});
    }
}]);


En si no requieres librerías gráficas, un simple canvas y a dibujar se ha dicho, aunque si quieres algo más complicado, si se requerirá de una librería como D3.js.

Como se define un canvas

Código: [Seleccionar]
<canvas id='vat' width="350" height="250" class='hidden'></canvas>
Como se dibuja en él sin librerías.

Código: [Seleccionar]
function drawAxes(ctx, width,height) {
  ctx.strokeStyle= "white";
  ctx.beginPath();
  ctx.moveTo(10,10);
  ctx.lineTo(10,height);
  ctx.stroke();
  ctx.moveTo(0,height-10);
  ctx.lineTo(width, height-10);
  ctx.stroke();
}

function drawGrid(ctx, width, height) {
  ctx.strokeStyle = "green"
  ctx.strokeWidth = 2;
  ctx.beginPath();
  i = 30;
  j = 10;
  /* Y Grid */
  while (i < width)
  {
    ctx.moveTo(i,j);
    ctx.lineTo(i,height-10);
    ctx.stroke();
    i+=20;
  }
  /* X Grid */
  i=10;
  j=30;
  while(j<height)
  {
    ctx.moveTo(i,j);
    ctx.lineTo(i,height-j);
    ctx.stroke();
    j+=20;
    i+=20;
  }
}

function clean(ctx,width, height) {
  ctx.clearRect(0,0, width, height);
}

function plot(ctx,width,height, data_points) {
  ctx.strokeStyle = "blue";
  ctx.beginPath()
  ctx.moveTo(10,height- (height*(data_points[0][1])));
  j=1;
  for(var i in data_points) {
    ctx.lineTo(j*17, height- (height*data_points[i][1]));
    ctx.stroke();
    j++;
  }
}


index.html
Código: [Seleccionar]
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <link href="/css/styles.css" rel="stylesheet">
  </head>
  <body ng-app="myApp" class="body">
    <div id="left_c" class="column">
      <div id="letf_c_header"></div>
      <div id="left_c_content">
        <input type="checkbox" id="checkbox1" />
        <label for="checkbox1">
          <ul class="menu demo">
            <li><a href="/#/">HOME</a></li>
            <li><a href="/#/dashboard">DASHBOARD</a></li> 
            <li><a href="/#/logs">LOGS</a></li>
            <li><a href="/#/admin_page">CONFIGURATION</a></li>
            <li><a href="/#/login">LOGIN</a></li>
          </ul>
          <span class="toggle">☰</span>
        </label>
      </div>
    </div>
    <div>
    <div ng-view></div>
</div>

  <!--<script src="/js/jquery.min.js"></script>
  <script src="/js/angular.min.js"></script>
  <script src="/js/angular_route.min.js"></script>
  -->
  <script
  src="http://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-route.min.js"></script>
  <script src="/js/utils.js"></script>
  <script src="/js/app.js"></script>
  <script src="/js/services.js"></script>
  <script src="/js/controllers.js"></script>
  </body>
</html>


dashboard.html
Código: [Seleccionar]
<h2>IO States</h2>
<table style="width:100%">
  <tr>
    <th aling-content="left">Var Name</th>
    <th aling-content="left">State</th>
  </tr>
  <tr ng-repeat="(key,value) in io_states">
    <td>{{key}}</td>
    <td>{{value}}</td>
  </tr>
</table>
</div>
</div>



Y te preguntaras de donde saco es io_states.
Dentro de app.js existe este código
Código: [Seleccionar]
  .when('/dashboard',{
    templateUrl:'partials/dashboard.html',
    controller:'dashBoardController',
    access:{restricted:false, admin:false, userlevel:[0,1,2]}
  })
Lo que le dice es que cuando estemos en la ruta /dashboard va a traer la vista definida por la plantilla dashboard.html y el controlador va a ser "dashBoardController"

El controlador se encuentra dentro del archivo controllers.js

Código: [Seleccionar]
angular.module('myApp').controller('dashBoardController',
  ['$scope','$interval','$location','AuthService','$http',
  function($scope,$interval,$location, AuthService,$http) {
    $scope.reload = function() {
      $http.get('/api/get_system_state.cgi')
      .success(function(data){
        console.log(data);
        $scope.v1_last_val = data.data_points.vbat[19][1];
        $scope.v2_last_val = data.data_points.vrec[19][1];
        $scope.io_states = data.io_states;
      });
    };
    $scope.reload();
    var get_data = $interval($scope.reload,1000);
    $scope.$on("$destroy", function() {
      if (get_data) {
        $interval.cancel(get_data);
      }
    });
}]);

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3476
    • Pinballsp
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #4 en: 24 de Febrero de 2018, 16:16:54 »

OK, lo iré mirando todo, veo que hay mucho material. De momento solo quiero preparar algo sencillo, rehacer mi placa con un ARM y programarla para que envíe un dato a una plataforma gratuita IOT, cada vez que alguien eche una moneda en la máquina.

Con eso, le doy al cliente el prototipo, que le ponga la tarjeta SIM y que lo vaya probando en sus máquinas. Si le gusta, ya trataré el tema económico según la cantidad de unidades que quiera, y ya me liaría con el tema del servidor web, la programación para visualizar estadísticas, gráficos y todas esas cosas. Ya veo que hay muchas opciones.

Mi duda es si vale la pena, optar por plataformas exclusivamente dedicadas al IOT u optar por un server convencional y programación a medida o con algún aplicativo de libre acceso. En ambos casos, servicios de pago para tener algo decente.

En programación para el server, me manejo con PHP y MySQL, para crear páginas dinámicas con HTML. El HTML5 no lo llegué a ver apenas, supongo que permite hacer muchas cosas interesantes. Java Script lo conozco muy superficialmente, algo toqué en su día, pero poco, validaciones de datos y esas cosas, de  Phyton nada.
« Última modificación: 24 de Febrero de 2018, 16:25:26 por planeta9999 »

Desconectado tsk

  • PIC16
  • ***
  • Mensajes: 249
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #5 en: 24 de Febrero de 2018, 17:06:18 »
Lo que vale la pena es que al principio sea una demo en la que tus gastos sean bajos. El problema que veo es que los servicios gratuitos de IoT tienen límites en cuanto a las conexiones y a la tasa de transmisión, aunque desconozco el taza de trasferencia que tendría tu aplicación, pero puedes fácilmente iniciar con una de esas plataformas y dejar que tu cliente decida si quiere algunas de esas plataformas o que tu le hagas algo personalizado.

Si quieres algo rápido lo que haría sería una API simple para subir los datos, nada de MQTT porque batallarías en su implementación en el MCU en un inicio, y ya que tienes experiencia con PHP, pues GAE tiene soporte

https://cloud.google.com/appengine/docs/standard/php/download
https://cloud.google.com/appengine/docs/standard/php/quickstart

Tan sólo requieres tener una cuenta de gmail. Y si el tráfico de tu cliente es muy bajo, entonces el no tendría que pagar por usar la plataforma, ya que te dan ciertas cuotas gratuitas que no son nada despreciables.

Por otro lado, con el soporte que ya tienen los navegadores a HTML5+CSS3 puedes maquetar de una forma más sencilla una página web, y de igual forma con flexbox te evitas mucho código extra, como sería agregarle Bootstrap o Foundation.

Por ejemplo en HTML5 ya cuentas con etiquetas como NAV,HEADER, MAIN, ARTICLE, FOOTER

puedes hacer transparencias y cierto tipo de animaciones con lo te evitas el uso de Flash e incluso algo de Javascript(no todo pero si es mucho más fácil).

Aquí vienen algunos ejemplos de animaciones con HTML5

https://cloudinary.com/blog/creating_html5_animations.

Otra cosa que puedes tambien hacer es reproducir videos, capturar la webcam, entre otras cosas, así como el uso de WebGL para animaciones tanto en 2D como en 3D.

http://webglsamples.org/aquarium/aquarium.html
http://webglsamples.org/dynamic-cubemap/dynamic-cubemap.html

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3476
    • Pinballsp
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #6 en: 24 de Febrero de 2018, 20:46:06 »
 
Voy a retomar el proyecto, y le preparo el cliente un prototipo con un SIM800L, y un STM32.

Lo lamentable es que NXP sigue en su desastrosa política de distribución, no hay manera humana de conseguir los MK64, e incluso los MK24 que hace poco conseguí casi de milagro en Mouser, ya están agotados, y sin plazo de entrega previsto. Solo podría echar mano de los MK20 que están en Amidata. Es de vergüenza lo que está haciendo NXP. Encima vas a sus foros, expones tu queja, y sale algún responsable a dar una respuesta oficial, diciendo que van a mejorar para el 2018, indignante. Y no es porque los chips vayan al sector de automoción, según la respuesta oficial, los Kinetis no están preparados para ese sector, asi que no se que hacen con esos chips, o es que desde que NXP se quedó con Freescale, pasan olímpicamente y los quieren matar a favor de los LPC, si es así al menos que lo digan y no hagan perder el tiempo a la gente con nuevos desarrollos.

Así que para este proyecto, muy a mi pesar, echaré mano de un STM32F4, hubiera preferido un Kinetis por la gran cantidad de librerías y código de ejemplo que hay para Teensy, tambien porque tengo hecho un bootloader encriptado que va de fábula, pero coseguir el micro es prácticamente imposible.

Del módulo GPRS SIM800L tenía un puñado de plaquitas que les compré a los chinos hace algunos años, también unas antenas de goma, pero no las encuentro por ningún lado. Así que he tenido que comprarlas de nuevo. Buscando me encuentro que están en Amazon, pero también en Satkit que es donde las he pedido. En los chinos mucho más barato, pero para un par de unidades, con el transporte saldría carísimo.

El prototipo no llevará mucho más, la plaquita con el SIM800L ya lleva el zócalo para la tarjeta SIM. A mi placa le añadiré un tarjetero micro SD para guardar datos de configuración (PIN, dirección web para el IOT y creo que nada más). Las entradas del monedero de la máquina entran a mi placa por un optoacoplador, pondre dos entradas, una para pulsos positivos y otra para pulsos negativos. Alimentación a 5 voltios con un conector de tornillos y un jack redondo. Programación en C++ con Cubemx.

Para las pruebas, miraré a ver que plataforma IOT elegir. El tráfico será muy bajo, unos pocos bytes cada vez que alguien eche una moneda en la máquina para jugar, indicando también fecha y hora para las estadísticas.
« Última modificación: 24 de Febrero de 2018, 20:49:57 por planeta9999 »

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3476
    • Pinballsp
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #7 en: 25 de Febrero de 2018, 14:19:46 »
 
Empiezo a recavar información. Prácticamente lo único nuevo para mi es el acceso GPRS, no lo he hecho nunca, porque en el anterior proyecto que no se acabó, aún no había tocado ese punto.

Casi todo lo que hay por internet con módulos GSM/GPRS es la típica aplicación que se comunica enviando SMS.

De momento he encontrado estas librerías y código, para Arduino, aunque es extrapolable a cualquier otro micro con algunos cambios.

https://github.com/carrascoacd/ArduinoSIM800L
https://www.exploreembedded.com/wiki/Setting_up_GPRS_with_SIM800L
https://www.prometec.net/gprs-internet/

Datasheet y notas para aplicaciones IP
https://cdn-shop.adafruit.com/datasheets/sim800_series_ip_application_note_v1.00.pdf

Esta librería es para Teensy 3, osea Kinetis MK20, el único Kinetis del que hay stock actualmente.
https://github.com/mikenz/Teensy-SIM800L-Temp-Sensor


Lo que no tengo aún claro es la definición del punto de acceso con AT+CSTT

"Access Point Name, User name and Password needs to be set before data connectivity can be established. Please use APN name of your SIM card provider. Note that for most service providers PIN and Password are not set. If your provider or you have set it up please this as well. "

Tampoco recuerdo el comando AT para entrar el PIN de la tarjeta SIM.




« Última modificación: 25 de Febrero de 2018, 15:22:29 por planeta9999 »

Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2225
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #8 en: 25 de Febrero de 2018, 16:00:50 »
Probé un par de plataformas IoT el verano pasado: Cayenne y CloudMQTT y la impresión fue muy positiva en ambos casos.

El caso de Cayenne es realmente sencillo porque, a decir verdad, te lo dan todo hecho. La instalación en una RPi son cinco minutos y para Arduino tienes, además de su propia librería, un montón de programas de ejemplo. También una App propia para Android e Ios y websocket para el uso -por ejemplo- de la extensión MQTTLens en Chrome.
Ya en plan más avanzado puedes usar librerías para la MQTT Api desde C++, Python, etc.

Lo probé en RPi y Arduino, con su app de Android y vía navegador. Mi opinión: Está pensado para torpes, pero eso no le resta prestaciones. Recomiendo darle un ojo.

No recuerdo con seguridad si era posible gestionar más de un dispositivo individual a la vez y desde el mismo panel, pero creo que no y por tanto entiendo que no te serviría para tu proyecto.

CloudMQTT es igualmente sencillo de utilizar aúnque su dinámica no tenga que ver con el anterior. Te animo a que pruebes su opción gratuita, que además tiene la ventaja de ser escalable a opciones de pago sin necesidad de tocar una coma, cosa que no siempre sucede.
Una nota: la opción gratuita te da solamente 10Kbit/s y parece una ruina pero en la práctica, al menos con un esp8266-12 usado para las pruebas, las respuestas eran inmediatas. No sé cómo se portará con más conexiones simultáneas.

Lo probé con un ESP8266-12 (Ide Arduino + librería PubSubClient) y MQTT Dashboard en Android.

Un tutorial sobre MQTT over TCP en módulos SIM800/900

un saludo


Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2225
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #9 en: 25 de Febrero de 2018, 16:27:45 »
Yo en el caso que planteas no tendría dudas con respecto a MQTT:
- mucho más ligero que http
- posibilidad de usuario y contraseña
- posibilidad de cifrado
- QoS

Además de probar las plataformas mencionadas instalé un server mosquitto en el pc y usé Wireshark para analizar tráfico. Créeme, nada que ver si comparas el peso de una comunicación http con lo enviado por el protocolo MQTT. He leído en más de una ocasión que un envío MQTT puede llegar a pesar tan sólo 2 bytes y a mi no me da esa cuenta ni por casualidad, pero desde luego es considerablemente menor.

saludo

pd: también empecé con Node-Red, pero las circunstancias personales dieron un giro y ahí se quedó todo a medias...

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3476
    • Pinballsp
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #10 en: 25 de Febrero de 2018, 16:31:10 »
 
Gracias xocas, lo probaré, desconocía esto del MQTT, pensé que era algún tipo de sofware.

La duda que tengo ahora mismo es si el módulo SIM800L soporta redes 3G o tendré que usar otro. Tengo por aquí también una plaquita con un SIM900A.

Desconozco como va la compatibilidad entre 2G y 3G, si depende del módulo o de la tarjeta SIM. Si recuerdo que cuando la compañía telefónica pasó de 2G a 3G nos cambiaron las tarjetas SIM, pero mi teléfono móvil sigue siendo el mismo.
« Última modificación: 25 de Febrero de 2018, 16:35:43 por planeta9999 »

Desconectado xocas

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 2225

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2155
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #12 en: 25 de Febrero de 2018, 17:34:01 »
Dale un ojo: http://www.raviyp.com/embedded/208-don-t-use-sim900-sim908-sim800-sim808-modules-in-usa-2g-sunset

Es justo lo contrario. Van a obsoletar 3g pero no 2g debido a la cantidad de IoT que están saliendo y que funcionan con GPRS. Al menos eso dicen es España. .. no pongo la mano en el fuego pero tiene cierto sentido...

 https://www.google.es/amp/www.eleconomista.es/noticias-amp/8118117/Los-operadores-moviles-espanoles-apagaran-antes-la-red-3G-que-la-de-2G

Saludos!
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3476
    • Pinballsp
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #13 en: 25 de Febrero de 2018, 18:20:00 »
 
Bueno, pues lo probaré cuando me llegue el modulito SIM800L. Si me va por GPRS, con ese me quedo, son muy baratos, fáciles de programar, y casi que con las plaquitas pasantes mejor que comprar la pastilla para soldar.

Por algún sitio por casa, tengo un puñao de SIM800L que compré hace unos años a los chinos, tiene narices, ahora que las necesito no los encuentro y me ha tocado comprar un par a Satkit, aunque no a precio de chino.

Como tengo un cable USB a serie TTL, lo conectaré al PC y le enviaré los comandos AT a mano desde un hiperterminal, así puedo ver que contesta el módulo.

He pensado en montar un prototipo para el cliente, usando una placa de prototipos de esas cutres de baquelita que tengo por casa. Le pongo el SIM800L pasante, un Teensy 3.5 con bootloader encriptado que también tengo, un par de optos para los monederos y un par de diodos en serie para bajar los 5v a unos 4v que necesita el SIM800L. Programo el Kinetis para que enganche con Cayenne o CloudMQTT, y arreando, que lo vaya probando en sus máquinas.
« Última modificación: 25 de Febrero de 2018, 18:32:13 por planeta9999 »

Desconectado tsk

  • PIC16
  • ***
  • Mensajes: 249
Re:Plataformas gratuitas para probar dispositivos IOT
« Respuesta #14 en: 25 de Febrero de 2018, 21:55:19 »
Yo en el caso que planteas no tendría dudas con respecto a MQTT:
- mucho más ligero que http
- posibilidad de usuario y contraseña
- posibilidad de cifrado
- QoS

Además de probar las plataformas mencionadas instalé un server mosquitto en el pc y usé Wireshark para analizar tráfico. Créeme, nada que ver si comparas el peso de una comunicación http con lo enviado por el protocolo MQTT. He leído en más de una ocasión que un envío MQTT puede llegar a pesar tan sólo 2 bytes y a mi no me da esa cuenta ni por casualidad, pero desde luego es considerablemente menor.

saludo

pd: también empecé con Node-Red, pero las circunstancias personales dieron un giro y ahí se quedó todo a medias...

No había visto Cayenne, incluso veo que ofrece los SDK (que usan eclipse paho) tanto para mbed, arduino, así como C y C++.

Por otro lado, no recordaba que planeta9999 usa el Teensy, y en el Arduino ya vienen las librerías para el MQTT con el módulo GPRS, así que le va a ser bastante rápida la implementación.

Con respecto a los dos bytes, no había escuchado que el tamaño del mensaje era sólo dos bytes, el formato del mensaje inicialmente son dos bytes, pero el segundo byte le indica la longitud del mensaje, así que con sólo dos bytes el mensaje estaría vacío (o al menos eso creo).

Otra cosa es que hay dos versiones del MQTT, la primera es la que va por TCP/IP y la segunda puede usar cualquier otro medio como Zigbee, y a este se le conoce como MQTT-SN.

Tomando el MQTT que va sobre TCP/IP y que TCP/IP va sobre Ethernet, implica que el tamaño de la trama más pequeña que se puede enviar es de 64 bytes y el mas grande esta definida por el MTU que por lo general son alrededor 1500 bytes. Si el tamaño de la trama es menor a los 64 bytes entonces se rellena el payload para que la trama alcance los 64 bytes.

Así que por más pequeño que sea  el mensaje MQTT, la trama va a ser de 64 bytes, en este caso.

Saludos.