update
This commit is contained in:
parent
099b6cd71b
commit
cdf28ee55c
5 changed files with 469 additions and 0 deletions
84
bin/nodemecu
Executable file
84
bin/nodemecu
Executable file
|
@ -0,0 +1,84 @@
|
|||
#!/bin/bash
|
||||
if [ $UID -ne 0 ]; then
|
||||
echo "Ejecute 'sudo $0'"
|
||||
exit
|
||||
fi
|
||||
|
||||
# LECTURA FICHERO DE CONFIGURACION
|
||||
|
||||
config=/etc/nodemecu.conf
|
||||
envs=/opt/nodemecu/envs
|
||||
source $config
|
||||
source $envs
|
||||
source $funciones
|
||||
|
||||
[ -z $1 ] && exit
|
||||
|
||||
|
||||
com=$1
|
||||
|
||||
case $com in
|
||||
|
||||
configurar)
|
||||
echo "Complete los cambios a continuación:
|
||||
"
|
||||
echo "Nombre del dispositivo."
|
||||
read -p "nombre: " -a entrada_usuario
|
||||
funcion_configurar nombre ${entrada_usuario[@]}
|
||||
echo ""
|
||||
echo "Servidor de entrega de datos."
|
||||
read -p "servidor (ej. https://url.del/servidor): " entrada_usuario
|
||||
funcion_configurar servidor $entrada_usuario
|
||||
echo ""
|
||||
echo "Intervalo de toma de muestras, entre 1 y 60 minutos."
|
||||
read -p "intervalo: " entrada_usuario
|
||||
funcion_configurar intervalo $entrada_usuario
|
||||
echo ""
|
||||
echo "Creando juego de llaves"
|
||||
source $config
|
||||
comentario="$nombre $numero_serie"
|
||||
generate_private_key "$comentario"
|
||||
echo ""
|
||||
echo "El modo de operación por defecto es 'test' y se envían datos simulados, cambie a 'sensores' con el comando 'sudo nodemecu modo sensores'
|
||||
"
|
||||
;;
|
||||
|
||||
nombre)
|
||||
funcion_configurar $@
|
||||
;;
|
||||
servidor)
|
||||
funcion_configurar $@
|
||||
;;
|
||||
intervalo)
|
||||
funcion_configurar $@
|
||||
;;
|
||||
modo)
|
||||
funcion_configurar $@
|
||||
;;
|
||||
captura)
|
||||
|
||||
test_conf_nombre || exit
|
||||
test_conf_intervalo || exit
|
||||
test_conf_key || exit
|
||||
funcion_captura $2
|
||||
;;
|
||||
monitor)
|
||||
funcion_monitor
|
||||
;;
|
||||
cllave)
|
||||
if [ -z $nombre ]; then
|
||||
echo "Debe establecer primero el nombre del dispositivo"
|
||||
else
|
||||
echo "Creando juego de llaves"
|
||||
generate_private_key
|
||||
fi
|
||||
;;
|
||||
|
||||
|
||||
*)
|
||||
exit
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
|
4
bin/reset
Normal file
4
bin/reset
Normal file
|
@ -0,0 +1,4 @@
|
|||
rm stack/*
|
||||
rm historical/*
|
||||
printf "" > errors.log
|
||||
printf "0" > counter
|
31
envs
Normal file
31
envs
Normal file
|
@ -0,0 +1,31 @@
|
|||
# NO MODIFICAR ESTE FICHERO !!!!!!!!!!
|
||||
|
||||
numero_serie=0000000083a999fd
|
||||
curl_err=/tmp/curl_err
|
||||
directorio_instalacion=/opt/nodemecu
|
||||
registros=$directorio_instalacion/registros
|
||||
historicos=$directorio_instalacion/historicos
|
||||
log=/var/log/nodemecu_errors.log
|
||||
registros_corruptos=$directorio_instalacion/corruptos
|
||||
lock=$directorio_instalacion/lock
|
||||
funciones=$directorio_instalacion/funciones
|
||||
arduinos_py=$directorio_instalacion/arduinos.py
|
||||
key_dir=$directorio_instalacion/llaves
|
||||
private_key=$key_dir/$numero_serie.key
|
||||
public_key=$key_dir/$numero_serie.key.pub
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
270
funciones
Normal file
270
funciones
Normal file
|
@ -0,0 +1,270 @@
|
|||
#!/bin/bash
|
||||
#set -x
|
||||
get_stack () {
|
||||
if [[ ! -z $1 && $1 == "wc" ]];then
|
||||
ls -I "*.sig" $registros | wc -l
|
||||
else
|
||||
ls -I "*.sig" $registros | tail -1
|
||||
fi
|
||||
}
|
||||
|
||||
# Generar una llave privada ECDSA si no existe
|
||||
generate_private_key () {
|
||||
test -f "$private_key" && return 1
|
||||
|
||||
ssh-keygen -t ecdsa -f "$private_key" -N "" -C "$@"
|
||||
}
|
||||
|
||||
# Firmar el archivo usando la llave privada.
|
||||
#
|
||||
# Uso: sign_file archivo.json
|
||||
# Devuelve: La firma
|
||||
sign_file () {
|
||||
local _file="$1"
|
||||
|
||||
test ! -f "$_file" && return 1
|
||||
test -f "$_file.sig" || ssh-keygen -Y sign -f "$private_key" -n file "$_file" >/dev/null 2>&1
|
||||
cat "${_file}.sig" | grep -v SIGNATURE | tr -d "\n"
|
||||
}
|
||||
|
||||
|
||||
funcion_datos_simulados() {
|
||||
|
||||
lecturas="id:dummy_plug-01 tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 AD_ARDUINO id:dummy_plug-02 tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 AD_ARDUINO id:dummy_plug-03 tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 AD_ARDUINO id:dummy_plug-04 tp:temp vl:$(( $RANDOM % 20 + 15 )) un:C er:99 AD_SENSOR tp:hum vl:$(( $RANDOM % 50 + 35 )) un:percent er:99 END"
|
||||
|
||||
}
|
||||
|
||||
funcion_datos_sensores() {
|
||||
|
||||
peticiones=1
|
||||
arduinos=( 0x01 0x02 )
|
||||
for arduino_id in ${arduinos[@]};do
|
||||
lectura_arduino=($(timeout 3 $arduinos_py $arduino_id))
|
||||
|
||||
let "bloques = (${#lectura_arduino[@]} - 1) / 4"
|
||||
|
||||
lecturas="$lecturas id:${lectura_arduino[0]}"
|
||||
|
||||
indice=1
|
||||
vueltas=1
|
||||
|
||||
while [ $vueltas -le $bloques ]; do
|
||||
|
||||
lecturas="$lecturas tp:${lectura_arduino[$indice]} vl:${lectura_arduino[$(expr $indice + 1 )]} un:${lectura_arduino[$(expr $indice + 2 )]} er:${lectura_arduino[$(expr $indice + 3 )]}"
|
||||
|
||||
if [ $vueltas -lt $bloques ]; then
|
||||
lecturas="$lecturas AD_SENSOR"
|
||||
fi
|
||||
|
||||
let "indice = $indice + 4 "
|
||||
|
||||
((vueltas++))
|
||||
done
|
||||
|
||||
if [ $peticiones -lt ${#arduinos[@]} ];then
|
||||
lecturas="$lecturas AD_ARDUINO"
|
||||
fi
|
||||
((peticiones++))
|
||||
|
||||
|
||||
done
|
||||
lecturas="$lecturas END"
|
||||
}
|
||||
|
||||
|
||||
|
||||
funcion_configurar() {
|
||||
local comando=$1
|
||||
local parametro=$2
|
||||
local parametros=$*
|
||||
local url_regex='(https?|HTTPS?)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]'
|
||||
local nuevo_modo='(test|sensores)'
|
||||
|
||||
case $comando in
|
||||
nombre)
|
||||
while :;do
|
||||
nuevo_nombre=$(echo $parametros | sed 's/nombre //g' | sed 's/ /_/g')
|
||||
|
||||
if [[ "$nuevo_nombre" =~ ^[a-zA-Z0-9_]+$ ]];then
|
||||
sed -i 's/nombre='$nombre'/nombre='$nuevo_nombre'/' $config
|
||||
echo "nombre: $nuevo_nombre"
|
||||
break
|
||||
else
|
||||
echo "El nombre solo puede contener carateres alfanumericos."
|
||||
read -p "nombre: " parametro
|
||||
fi
|
||||
done
|
||||
;;
|
||||
|
||||
servidor)
|
||||
while :;do
|
||||
if [[ $parametro =~ $url_regex ]]; then
|
||||
sed -i 's}servidor='$servidor'}servidor='"$parametro"'}' $config
|
||||
echo "Servidor $parametro"
|
||||
break
|
||||
else
|
||||
echo "Intruzca una url válida."
|
||||
read -p "url: " parametro
|
||||
fi
|
||||
done
|
||||
;;
|
||||
|
||||
intervalo)
|
||||
while :;do
|
||||
if [[ $parametro -ge 1 && $parametro -le 60 ]]; then
|
||||
sed -i 's/intervalo=[0-9]*/intervalo='$parametro'/' $config
|
||||
echo "Intervalo seteado en $parametro"
|
||||
echo "Para aplicar los cambios ejecute
|
||||
sudo nodemecu captura dentener
|
||||
sudo nodemecu captura iniciar"
|
||||
break
|
||||
else
|
||||
echo "Establezca un valor entre 1 y 60."
|
||||
read -p "Intervalo: " parametro
|
||||
fi
|
||||
done
|
||||
;;
|
||||
modo)
|
||||
while :;do
|
||||
if [[ $parametro =~ $nuevo_modo ]]; then
|
||||
sed -i 's/modo='$modo'/modo='$parametro'/' $config
|
||||
break
|
||||
else
|
||||
echo "Los modos posibles son 'test' y 'sensores'"
|
||||
read -p "modo: " parametro
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
funcion_captura() {
|
||||
|
||||
|
||||
if [ "$1" = "iniciar" ]; then
|
||||
|
||||
echo "Iniciando la captura de datos en modo '$modo'"
|
||||
echo ""
|
||||
read -p "Desea continuar? Presione 'enter' para continuar o 'ctrl-c' para cancelar..."
|
||||
echo "*/$intervalo * * * * $directorio_instalacion/generador_json" > /tmp/nodemecu.crontab
|
||||
crontab -u root /tmp/nodemecu.crontab
|
||||
echo ""
|
||||
echo "Se tomarán datos cada $intervalo minutos."
|
||||
echo ""
|
||||
exit
|
||||
elif [ "$1" = "detener" ]; then
|
||||
crontab -u root -r
|
||||
echo "Se detuvo la toma de datos."
|
||||
echo ""
|
||||
else
|
||||
echo "Ingrese una orden válida: 'iniciar' o 'detener'."
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
### Validaciones
|
||||
|
||||
test_conf_nombre() {
|
||||
|
||||
if [ -z $nombre ]; then
|
||||
echo "No se establecio un nombre para el dispositivo."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
test_conf_servidor () {
|
||||
|
||||
if [ -z $servidor ];then
|
||||
echo "No se establecio un servidor de entrega."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_conf_intervalo() {
|
||||
|
||||
if [ -z $intervalo ];then
|
||||
echo "No se establecio un intervalo de captura."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_conf_key() {
|
||||
|
||||
if [ ! -f $private_key ];then
|
||||
echo "No se creo juego de llaves."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
funcion_validador_json() {
|
||||
|
||||
validar="$@"
|
||||
|
||||
echo $validar | jsonlint-php > /dev/null 2>&1 || return 1
|
||||
}
|
||||
|
||||
funcion_verificar_internet() {
|
||||
|
||||
if host fsf.org > /dev/null 2>&1; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
funcion_espera() {
|
||||
sleep 1m
|
||||
#sleep ${intervalo:-1}m
|
||||
|
||||
}
|
||||
|
||||
|
||||
funcion_envio_registro() {
|
||||
|
||||
curl -s --show-error -w "~%{http_code}" \
|
||||
-X POST -H "X-Signature: $(sign_file $registros/$file)" \
|
||||
-H "Content-Type: application/json" -d @$registros/$file \
|
||||
$servidor 2> $curl_err
|
||||
|
||||
}
|
||||
|
||||
|
||||
funcion_monitor() {
|
||||
local sb="\x1b["
|
||||
local eb="\x1b[K\x1b[0m"
|
||||
local st="\e["
|
||||
local et="\e[0m"
|
||||
|
||||
while :;do
|
||||
clear
|
||||
echo -e "${sb}1;44;97m Nodemecu Monitor${eb}"
|
||||
echo ""
|
||||
echo -e "${st}1;94mNombre:${et} $nombre ${st}1;94mServidor:${et} $servidor ${st}1;94mIntervalo:${et} $intervalo"
|
||||
echo ""
|
||||
echo -e "${sb}1;44;97m Registros${eb}"
|
||||
echo ""
|
||||
echo -e "En cola: $(ls -I *.sig $registros| wc -l)"
|
||||
echo -e "Enviados: $(ls -I *.sig $historicos | wc -l)"
|
||||
echo -e "Registros corrupts: $(ls -I *.sig $registros_corruptos | wc -l)"
|
||||
echo ""
|
||||
echo -e "${sb}1;44;97m Ultimos mensajes${eb}"
|
||||
echo ""
|
||||
echo -e ${st}1m"Systemd unit 'nodemecu.service'${et}"
|
||||
journalctl -n 3 -u nodemecu
|
||||
echo ""
|
||||
echo -e ${st}1m"Fichero '$log'${et}"
|
||||
cat /var/log/nodemecu_errors.log | grep -v "Salida de curl" | grep -v '[*<>{}]' | tail -3
|
||||
|
||||
sleep 2
|
||||
done
|
||||
|
||||
}
|
||||
|
80
registrador
Executable file
80
registrador
Executable file
|
@ -0,0 +1,80 @@
|
|||
#!/bin/bash
|
||||
#set -x
|
||||
source /etc/nodemecu.conf
|
||||
source /opt/nodemecu/envs
|
||||
source $funciones
|
||||
|
||||
while :;do
|
||||
|
||||
# archivo a procesar
|
||||
file=$(get_stack)
|
||||
|
||||
# si no hay nada que procesar reinicia el bucle
|
||||
test -z $file && funcion_espera && continue
|
||||
|
||||
# si no hay servidor definido se reinicia el bucle
|
||||
test -z $servidor && echo "No se configuró nigun servidor de entrega." && funcion_espera && continue
|
||||
|
||||
# si no hay internet reinica el bucle
|
||||
if ! funcion_verificar_internet; then
|
||||
err_time=$(date +%Y-%m-%d-%H:%M:%S)
|
||||
echo "$err_time - Parece no haber internet." | tee -a $log
|
||||
funcion_espera
|
||||
continue
|
||||
fi
|
||||
|
||||
# si el fichero 'lock' existe (se esta creando un nuevo registro) reinicia el bucle
|
||||
test -f $lock && continue
|
||||
|
||||
# validación del fichero
|
||||
if ! funcion_validador_json "$(cat $registros/$file)";then
|
||||
mv $registros/$file $registros_corruptos
|
||||
continue
|
||||
fi
|
||||
|
||||
# firmado de regisro
|
||||
firma=$(sign_file $registros/$file)
|
||||
|
||||
# UUID del registro a enviar
|
||||
uuid_registro=$(jq -r '."transaction_uuid"' $registros/$file)
|
||||
|
||||
# envio de registro
|
||||
transaccion=$(curl -v -s --show-error -w "~%{http_code}" -X POST -H "X-Signature: $(sign_file $registros/$file)" -H "Content-Type: application/json" -d @$registros/$file $servidor 2> $curl_err)
|
||||
|
||||
# respuestas del servidor
|
||||
respuesta_servidor="$(echo $transaccion | cut -d '~' -f 1)"
|
||||
error_servidor="$(echo $transaccion | cut -d '~' -f 2)"
|
||||
|
||||
if [ ${#respuesta_servidor} -eq 36 ] && [ "$uuid_registro" == "$respuesta_servidor" ]; then
|
||||
echo -e "$respuesta_servidor: \e[92mOK\e[0m"
|
||||
mv $registros/$file $registros/$file.sig $historicos
|
||||
else
|
||||
|
||||
err_time=$(date +%Y-%m-%d-%H:%M:%S)
|
||||
srv_msg="$(echo $respuesta_servidor | grep -o '<body.*>.*</body>')"
|
||||
echo -e "$err_time - $uuid_registro: \e[91mFAIL\e[0m"
|
||||
|
||||
echo "$err_time - $uuid_registro - Error del servidor: $error_servidor" >> $log
|
||||
echo "$err_time - $uuid_registro - Mensaje del servidor:" >> $log
|
||||
echo "$srv_msg" >> $log
|
||||
if [ -s $curl_err ];then
|
||||
echo "$err_time - $uuid_registro - Salida de curl:" >> $log
|
||||
cat $curl_err >> $log
|
||||
fi
|
||||
|
||||
rm $curl_err
|
||||
#funcion_espera
|
||||
fi
|
||||
|
||||
#exit
|
||||
done
|
||||
|
||||
|
||||
|
||||
######
|
||||
|
||||
# se testea que el servidor responda
|
||||
#test_url="$(curl -s -X POST -o /dev/null -w "%{http_code}" $servidor)"
|
||||
#if [ $test_url -eq 404 ];then
|
||||
# echo "$(date +%Y-%m-%d-%H:%M:%S) - $url - $test_url" >> /opt/nodemecu/errors.log && sleep 300 && continue
|
||||
#fi
|
Loading…
Reference in a new issue