Archivo de la categoría: Sin categoría

“Mapear” accesos al servidor III (y fin)

Y solo nos quedaba la web:

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <meta name="viewport" content="initial-scale=1.0">
		<meta charset="utf-8">
		<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fcode.jquery.com%2Fjquery-1.10.2.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
    
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cstyle%3E%0A%20%20%20%20%20%20%23map%20%7B%0A%20%20%20%20%20%20%20%20height%3A%20100%25%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20html%2C%20body%20%7B%0A%20%20%20%20%20%20%20%20height%3A%20100%25%3B%0A%20%20%20%20%20%20%20%20margin%3A%200%3B%0A%20%20%20%20%20%20%20%20padding%3A%200%3B%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fstyle%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;style&gt;" title="&lt;style&gt;" />

		<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%09%09%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
  </head>
  <body>
		
<div id="map"></div>

		
<div id="content"></div>

    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%3E%0A%09%09%09var%20map%3B%0A%09%09%09var%20markers%3D%5B%5D%3B%0A%09%09%09%0A%09%09%09%2F%2F%20Inicializamos%20el%20mapa%20(callback%20desde%20la%20carga%20de%20la%20librer%C3%ADa%20de%20GMaps)%0A%20%20%20%20%20%20function%20initMap()%20%7B%0A%09%09%09%09directionsService%20%3D%20new%20google.maps.DirectionsService%3B%0A%09%09%09%09directionsDisplay%20%3D%20new%20google.maps.DirectionsRenderer%3B%0A%09%09%09%09%0A%20%20%20%20%20%20%20%20map%20%3D%20new%20google.maps.Map(document.getElementById('map')%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20center%3A%20%7Blat%3A%2040%2C%20lng%3A%20-4%7D%2C%0A%20%20%20%20%20%20%20%20%20%20zoom%3A%202%0A%09%09%09%09%7D)%3B%0A%09%09%09%7D%0A%0A%09%09%09%2F%2F%20Esta%20funci%C3%B3n%20crea%20un%20marcador%20y%20lo%20agrega%20al%20mapa.%0A%09%09%09function%20addMarker(lat%2C%20lng%2C%20t%2C%20icon)%20%7B%0A%09%09%09%09var%20myLatlng%20%3D%20new%20google.maps.LatLng(lat%2C%20lng)%3B%0A%09%09%09%09var%20marker%20%3D%20new%20google.maps.Marker(%7B%0A%09%09%09%09%09%09position%3A%20myLatlng%2C%0A%09%09%09%09%09%09title%3At%2C%0A%09%09%09%09%09%09icon%3A%20icon%2C%0A%09%09%09%09%09%09anchor%3A%20new%20google.maps.Point(9%2C%2032)%2C%20%2F%2F%20Hace%20falta%20centrar%20bien%20esta%20chincheta%0A%09%09%09%09%09%09draggable%3A%20false%09%0A%09%09%09%09%7D)%3B%0A%09%09%09%09marker.setMap(map)%3B%0A%09%09%09%09markers.push(marker)%3B%0A%09%09%09%7D%0A%0A%09%09%09var%20socket%3B%0A%09%09%09%2F%2F%20Esperamos%20a%20que%20todo%20cargue.%0A%09%09%09%24(document).ready(function%20()%20%7B%0A%09%09%09%09%2F%2F%20Creamos%20la%20conexi%C3%B3n%20socket.io%20con%20el%20servidor%0A%09%09%09%09socket%20%3D%20io()%3B%0A%09%09%09%09%2F%2F%20Y%20que%20pasa%20cuando%20nos%20llegue%20un%20mensaje.%0A%09%09%09%09socket.on('pos'%2C%20function(obj)%7B%0A%09%09%09%09%09%2F%2F%20Un%20icono%20para%20casos%20que%20no%20deber%C3%ADan%20pasar...%0A%09%09%09%09%09var%20icon%3D'http%3A%2F%2Fmaps.google.com%2Fmapfiles%2Fms%2Ficons%2Fpurple-pushpin.png'%3B%0A%09%09%09%09%09%2F%2F%20Dependiendo%20del%20puerto%20destino%20ponemos%20un%20icono%20u%20otro.%0A%09%09%09%09%09switch%20(parseInt(obj.DPT))%20%7B%0A%09%09%09%09%09%09case%2022%3A%0A%09%09%09%09%09%09%09icon%3D'http%3A%2F%2Fmaps.google.com%2Fmapfiles%2Fms%2Ficons%2Fred-pushpin.png'%3B%0A%09%09%09%09%09%09%09break%3B%0A%09%09%09%09%09%09case%2080%3A%0A%09%09%09%09%09%09%09icon%3D'http%3A%2F%2Fmaps.google.com%2Fmapfiles%2Fms%2Ficons%2Fgrn-pushpin.png'%3B%0A%09%09%09%09%09%09%09break%3B%0A%09%09%09%09%09%09case%2021%3A%0A%09%09%09%09%09%09%09icon%3D'http%3A%2F%2Fmaps.google.com%2Fmapfiles%2Fms%2Ficons%2Fblue-pushpin.png'%3B%0A%09%09%09%09%09%09%09break%3B%0A%09%09%09%09%09%7D%0A%09%09%09%09%09%2F%2F%20Y%20a%C3%B1adimos%20el%20marcador%20al%20mapa%0A%09%09%09%09%09addMarker(obj.lat%2C%20obj.lng%2C%20obj.info%2C%20icon)%3B%0A%09%09%09%09%7D)%3B%0A%09%09%09%7D)%3B%0A%0A%20%20%20%20%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
        <!-- Cambiadme el AIzaSyAJNaGAoEMYp9k2KOzkmWArlj6Cb439oy por vuestro propio codigo de API GMaps... plissss.... -->
		<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fmaps.googleapis.com%2Fmaps%2Fapi%2Fjs%3Fkey%3DAIzaSyAJNaGAoEMYp9k2KOzkmWArlj6Cb439oyU%26callback%3DinitMap%22%20async%20defer%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
		<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22%2Fsocket.io%2Fsocket.io.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />	
		<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fcode.jquery.com%2Fui%2F1.11.4%2Fjquery-ui.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
		<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fcode.jquery.com%2Fcolor%2Fjquery.color-2.1.2.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="&lt;script&gt;" title="&lt;script&gt;" />
  </body>
</html>

Primera entrada: https://blog.norsip.com/2017/09/27/mapear-accesos-al-servidor-i/

Segunda parte: https://blog.norsip.com/2017/09/27/mapear-accesos-al-servidor-ii/

Github: https://github.com/luisesn/mapa-conexiones

“Mapear” accesos al servidor II

Y ahora a la parte Node del meollo. Es fácil:

Nos van a hacer falta unos cuantos módulos: express para mostrar la web, socket.io para enviar los eventos al mapa, chokidar para vigilar los cambios en el fichero del log y geoip-lite para geolocalizar las ips.

Así que creamos un directorio, lo inicializamos para node e instalamos los paquetes necesarios.

mkdir mapa
cd mapa
npm init
npm install express socket.io chokidar geoip-lite --save

 

Y ahora… a picar código:

nano index.js

 

Lo primero cargar los módulos que necesitamos.

'use strict';

var express     = require('express');
var app         = express();
var serverHttp  = require('http').Server(app);  
var io          = require('socket.io')(serverHttp);
var chokidar    = require('chokidar'); // "Vigilante" de fichres
var fs          = require('fs');
var geoip       = require('geoip-lite'); // Librería de localización de ips

 

Ahora creamos un servidor web que sirva el directorio estático «web» que contendrá un fichero index.html único y que será nuestro mapa.

app.use(express.static('web'));

serverHttp.listen(65081, function() {  
  console.log(getDateTime() + " Servidor a la escucha");
});

 

Y lo que será el meollo del programa:

// Inicializamos el "vigilante" de ficheros
var watcher = chokidar.watch('/var/log/netlog.log', {
  ignored: /(^|[\/\\])\../,
  persistent: true
});

watcher.on('change', (path, stats) => {
  // Si el tamaño del fichero es mayor de cero lo leemos línea a línea
  // si está vacio pasamos
  if (stats.size>0) {
    var lineReader = require('readline').createInterface({
      input: require('fs').createReadStream(path)
    });
    
    lineReader.on('line', function (line) {
      // Por cada línea hacemos un pequeño "parsing" y creamos una propiedad en un objeto con cada una
      var o=line.split(" ");
      var obj={};
      for (var i=0; i<o.length; i++) {
        var tmp=o[i].split("=");
        if (tmp.length==2) {
          obj[tmp[0]]=tmp[1];
        }
      }
      // Verificamos si hay información geográfica de la ip
      var pais=geoip.lookup(obj.SRC);
      if (pais!=null) {
        //console.log(pais);
        obj.lat=pais.ll[0];
        obj.lng=pais.ll[1];
        obj.info=pais.country;
        // Si la hay enviamos un mensaje "pos" vía socket.io a los clientes que tengamos conectados con los datos
        io.emit('pos', obj);
      } else {
        // Sino hay información lo imprimimos por consola, en el mapa no nos vale para nada.
        console.log("Sin info de " + obj.SRC);
      }
    });

    // Cuando acabemos de procesar el ficheo
    lineReader.on('close', function () {
      // Lo borramos, igual se pierde algo por el camino pero así limpiamos, esto es un juguete eeeh
      fs.closeSync(fs.openSync(path, 'w'));
    });
  }
});

 

Nos falta una pequeña función que uso mucho para imprimir la fecha y la hora:

function getDateTime() {
  var date = new Date();
  var hour = date.getHours();
  hour = (hour < 10 ? "0" : "") + hour;
  var min = date.getMinutes();
  min = (min < 10 ? "0" : "") + min;
  var sec = date.getSeconds();
  sec = (sec < 10 ? "0" : "") + sec;
  var year = date.getFullYear();
  var month = date.getMonth() + 1;
  month = (month < 10 ? "0" : "") + month;
  var day = date.getDate();
  day = (day < 10 ? "0" : "") + day;
  return day + '/' + month + '/' + year + " " + hour + ":" + min + ":" 
+ sec;
}

 

Y con esto tenemos la parte de node. Nos falta la web…

Primera parte: https://blog.norsip.com/2017/09/27/mapear-accesos-al-servidor-i/

 

SmartWeekend Santander

Participaremos junto con varias empresas y personas en el SmartWeekend Santander 2015, tendréis a Darío Balbontin, a Iberobotics, Concano Games, y muchos mas. Y hablaremos y jugaremos con tecnología, wordpress, drones, robots, arduino y un largo etc.

Tenéis mas información y el resumen de actividades en el portal de Juventud:

http://portal.ayto-santander.es/portal/page/portal/juventud_santander/ficha?itemId=10436928

CARTEL-SmartWeekendSantander-1100x1556

Detector de caras + voz

Un pequeño ejemplo en python de como usar OpenCV y Festival TTS para detectar caras en la RaspiCam y avisar por voz de ello

import numpy as np
import cv2
import time
import os

#cargamos la plantilla e inicializamos la webcam:
print "loading classifier..."
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface.xml')
print "configurando camara"
cap = cv2.VideoCapture(0)
cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH ,640)
cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT ,480)
minS=250
 
while(True):
    start = time.clock()
    #leemos un frame y lo guardamos
    ret, img = cap.read()
    #convertimos la imagen a blanco y negro
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    #gray = cv2.equalizeHist(gray)
    #buscamos las coordenadas de los rostros (si los hay) y
    #guardamos su posicion
    faces = face_cascade.detectMultiScale(gray, 1.1, 2, minSize=(minS, minS), flags=cv2.cv.CV_HAAR_SCALE_IMAGE)

    if len(faces)>0:
        os.system("echo \"Careto detectao\" | festival --tts")
        print "Careto detectao"
    #Dibujamos un rectangulo en las coordenadas de cada rostro
    i=1
    for (x,y,w,h) in faces:
        #print x,y,w,h
        x=x-int(w*0.1)
        y=y-int(h*0.1)
        w=int(w*1.2) 
        h=int(h*1.2)
        cv2.rectangle(gray,(x,y),(x+w,y+h),(255,0,0),2)
        i=i+1
 
    #Mostramos la imagen
    #cv2.imshow('img2',gray)
     
    #con la tecla 'q' salimos del programa
    tecla = cv2.waitKey(1) & 0xFF
    if tecla == ord('q'):
        break
    elif tecla == ord('s'):
        cv2.imwrite("caras/"+str(nimagen)+".png",gray);
        print "guardada"
        nimagen=nimagen+1
    end = time.clock()
    print 1/(end-start)," fps ", len(faces), " caras"

cap.release()
cv2.destroyAllWindows()

Sacando a pasear el «drone»

Iberobotics nos invitó a pasear el «drone» en el cursillo «Robótica, Arduino e impresoras 3D» que se impartió entre el 9 y el 24 de noviembre en el Centro Municipal de Formación de Camargo. Una pequeña charla con el «como funcionan» y a volar.

¡Incluso alguno se atrevió a pilotarle!

IMG_9267 IMG_9261 IMG_9222

 

(Fotos y cursillo: Ayuntamiento de Camargo)

http://noticiasdecamargo.es/2015/09/24/el-centro-de-formacion-de-camargo-incorpora-un-curso-sobre-robotica-y-arduino-a-su-oferta-de-este-trimestre/

Streaming (bestia) con VLC

Con el objeto de forzar unas líneas de transmisión hemos configurado 3 emisiones de vídeo por red con el VLC para poder acceder a ellas vía Windows Media Player ( ¬¬ )

mms://ip:8080/
mms://ip:8081/
mms://ip:8082/

#!/bin/bash
vlc -I dummy jdc.avi --repeat --sout "#transcode{vcodec=DIV3,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}:std{access=mmsh,mux=asfh,dst=0.0.0.0:8080}" --sout-keep
vlc -I dummy jdc3.avi --repeat --sout "#transcode{vcodec=DIV3,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}:std{access=mmsh,mux=asfh,dst=0.0.0.0:8081}" --sout-keep
vlc -I dummy tbbt.mp4 --repeat --sout "#transcode{vcodec=DIV3,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}:std{access=mmsh,mux=asfh,dst=0.0.0.0:8081}" --sout-keep

-I dummy
Ejecutar el vlc sin interfaz

–repeat
Repetir en bucle la emisión

{vcodec=DIV3,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}
Esta línea es la configuración con la que se codifica el vídeo, idealmente sería h264 pero no hay codecs en el reproductor… así que así.

std{access=mmsh,mux=asfh,dst=0.0.0.0:8081}
Salida por protocolo mms, contenedor asf, escuchando en la ip 0.0.0.0 (todas las interfaces) y el puerto 8081.

Sí… los nombres de los vídeos son … «casuales»

Una pequeña exhibición despues de la charla de robótica

Realizamos una pequeña exhibición con un multicóptero dentro de la conferencia ‘La robótica en la sociedad actual: pasado, presente y futuro’ impartida por Iván Bermejo de (Iberobotics).

Cargamos el maletero

IMG-20141001-WA0004

 

Vemos la charla después de dejar el multicóptero listo:

IMG_20141001_194808240

 

y a volar:

 

 

Mas fotos:
http://www.radiocamargo.es/index.php/component/k2/item/1081-los-drones-y-robots-protagonizan-una-conferencia-impartida-este-miercoles-en-el-centro-de-empresas-de-camargo-fotos.html