lunes, 22 de septiembre de 2008

Monitorear UPS desde GNU/Linux

Recientemente compramos una UPS APC CS 500 para el servidor del CENEHA (mi trabajo). Como la mayoría de los fabricantes de hardware el software de monitoreo que incluye en el cd es para window$, y por lo tanto no me sirve para un carajo.

Por suerte el software libre tiene motorcito propio y siempre -o casi siempre- encontrás algún paquete que te sirve para llevar a cabo tu objetivo: monitorear la UPS desde GNU/Linux.

El modelo CS 500 posee un cable para conectar la UPS al servidor, del lado de la PC es un conector USB y en el otro extremo un RJ-45. Una vez realizada la conexión pasamos a instalar el software que dialogará con la batería.

El tema fue bastante más sencillo de lo que creía, simplemente se deben instalar los siguientes paquetes (www.apcupsd.org): apcupsd, apcupsd-cgi y apcupsd-doc:

#aptitude install apcupsd acpupsd-cgi apcupsd-doc


Una vez instalado pasamos a la configuración, en el archivo /etc/apcupsd/apcupsd.conf se deben establecer los parámetros que le indican -entre otras cosas- el tipo de conexión (USB, serial, etc). Este archivo es muy explicativo, así que si no se entiende lo que escribo acá, basta con leer las instrucciones del mismo y no hay manera de pifiar.

Bien, en mi caso tuve que poner modificar los siguientes parámetros:

UPSCABLE usb
UPSTYPE usb
DEVICE

NOTAR que luego de DEVICE se deja en blanco.

Por último, lo que nos queda es ejecutar el script que nos devuelve los parámetros encuestados a la UPS:

#apcaccess

APC : 001,043,1025
DATE : Mon Sep 22 16:49:13 ART 2008
HOSTNAME : ceneha
RELEASE : 3.14.2
VERSION : 3.14.2 (15 September 2007) debian
UPSNAME : ups
CABLE : USB Cable
MODEL : Back-UPS CS 500
UPSMODE : Stand Alone
STARTTIME: Fri Sep 19 14:39:21 ART 2008
STATUS : ONLINE
LINEV : 228.0 Volts
LOADPCT : 23.0 Percent Load Capacity
BCHARGE : 100.0 Percent
TIMELEFT : 28.1 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME : 0 Seconds
OUTPUTV : 230.0 Volts
SENSE : Medium
DWAKE : 000 Seconds
DSHUTD : 000 Seconds
LOTRANS : 180.0 Volts
HITRANS : 266.0 Volts
RETPCT : 000.0 Percent
ITEMP : 29.2 C Internal
ALARMDEL : Always
BATTV : 13.5 Volts
LINEFREQ : 50.0 Hz
LASTXFER : Low line voltage
NUMXFERS : 0
TONBATT : 0 seconds
CUMONBATT: 0 seconds
XOFFBATT : N/A
SELFTEST : NO
STATFLAG : 0x07000008 Status Flag
SERIALNO : 4B0824P03005
BATTDATE : 2008-06-10
NOMOUTV : 230
NOMINV : 230
NOMBATTV : 12.0
FIRMWARE : 808.q8.I USB FW:q8
APCMODEL : Back-UPS CS 500
END APC : Mon Sep 22 16:49:27 ART 2008


Y ahí tenemos toda la data que nos puede llegar a interesar sobre lo que está pasando con nuestra UPS, voltaje de la linea, frecuencia, etc.

Un detalle que acabo de encontrar es un programa cliente que nos muestra gráficamente estos valores, para mi caso no me sirve porque el servidor es interno y no tenemos acceso desde internet, sin embargo a alguien que tenga una pc cliente o un servidor con interfaz gráfica les puede interesar. El programa se llama gapcmon cuya interfaz -que no es un picasso- es muy fácil de manejar e interpretar, aquí les dejo una captura:


Para la próxima les prometo un script para obtener esta información y luego graficarla usando cacti.

miércoles, 17 de septiembre de 2008

Caracteres en un archivo binario usando C++

Escribir y leer datos en un archivo binario no presenta demasiadas dificultades. Por ejemplo, para escribir un entero "e" y un float "f" en un archivo binario "bin" hacemos lo siguiente:


int e=10;
float f=12.5;
fstream bin("archivo.bin", ios::binary|ios::out);
bin.write((char *)&e, sizeof(int));
bin.write((char *)&f, sizeof(float));
bin.close();


Todo es lindo y prolijo, ahora, qué pasa si tengo una cadena de caracteres al estilo C de 14 caracteres?

Bien, las cadenas de caracteres al estilo C son vectores de bytes, y por lo tanto el identificador de la variable es un puntero a la dirección de memoria del primer caracter. O sea que para escribir este flujo de 14 bytes debemos ir iterando y guardar dato por dato. Vamos a los bifes, supongamos que tenemos una cadena "pianobar":


char pianobar[14]="nace una flor";
fstream bin("archivo.bin", ios::binary|ios::out);
for (int i=0;i<14;i++){
bin.write((char *)&pianobar[i], 1)
}


Ahora, vamos a leer esta cadena:

char pianobar[14];
fstream bin("archivo.bin", ios::binary|ios::in);
bin.read((char *)&pianobar, 14)



De lo anterior vemos que la escritura se hace caracter por caracter, dejando un espacio de 1 byte por cada uno, luego al momento de leer el dato, se indica la cantidad total de bytes (para el ejemplo 14) y se asigna a la variable.

El único detalle a tener en cuenta es que la longitud de la cadena que hemos definido es de 14, sin embargo posee un máximo de 13 caracteres, ya que el último caracter queda reservado para el siguiente código de finalización "\0". Otro punto a tener en cuenta es que las cadenas, al igual que los vectores comienzan en la posición 0.

lunes, 15 de septiembre de 2008

getline luego de cin

Desde no hace mucho estoy intentando aprender C++. Viste que todo el mundo te dice: "Un informático no puedo no saber C++...", así que como creo que tienen algo de razón encaminé mi vida por el sendero del qué dirán.

C++ tiene muchas diferencias con respecto a otros lenguajes, no es solo aprenderse la nueva sintaxis, sino que existen nuevos conceptos previamente inexistentes para mi. Aparte de esto, a veces me encuentro con pequeños detalles pelotudos que me hacen renegar. Uno de esos detalles "pelotudos" se me dio este fin de semana: Simplemente utilizaba para leer un número entero el cin>>n y líneas más abajo para leer un renglón completo utilizaba un cin.getline().

Todo parecía y compilaba bien, pero al momento de ejecutar mi pequeño programa obtenía comportamientos NO esperados (para mi pobre lógica). Acá un fragmento de código que reproduce el problema:


cout<<"Cantidad de cadenas a ingresar:";
cin>>n;
for (int i=1;i<=n;i++){
cout<<"Cadena: ";
cin.getline(cadena);
}


La salida da lo siguiente:

Cantidad de cadenas a ingresar: 3
Cadena: Cadena:


Como se ve, el programa no esperó para ingresar la primer cadena, sino que siguió con el ingreso de la segunda cadena. ¿Por qué pasa esto?

El tema es que cin>> agrega al flujo de entrada previo al dato a leer un (caracter "\n") e ignora el último (caracter "\n"). Luego, cuando getline() encuentra en el flujo ingresado previamente el primer "\n" culmina su ejecución -recordemos que el getline() lee hasta encontrar un salto de carro, o sea un "\n"-.

Solución:

Yo la hice simple, uso luego del cin un getline que lea un caracter, de modo que captura el "\n" que tanto jodía antes, quedaría así:


char s[1];
cout<<"Cantidad de cadenas a ingresar:";
cin>>n;
cin.getline(s);

for (int i=1;i<=n;i++){
cout<<"Cadena: ";
cin.getline(cadena);
}



jueves, 4 de septiembre de 2008

gif animados

Cortito y al pie:

1)- Instalate imagemagick:
aptitude install imagemagick
2)- Suponiendo que en el directorio /home/emiliano/img tenes los archivos jpg con los que tenés que armar el gif animado, hace esto:
$convert -delay 120 -loop 0 *.jpg test.gif
Parámetros:
-delay : milisengundos entre cada imagen
-loop : la cantidad de veces que se repita, 0 significa un loop infinito.

Algo para tener en cuenta, además de las imagenes tengas las mismas dimensiones, es que el gif final pesa aproximadamente el doble de la suma del peso de cada imagen.

miércoles, 6 de agosto de 2008

Hacelo por mi

La semana pasada, luego de las vacaciones, me tuve que poner a terminar un práctico larguísimo y que implicaba muchísimos cálculos: multiplicación de grandes polinomios, derivación, reemplazo... realmente me negaba a tener que hacer tanta tarea tediosa y en forma repetitiva, por eso, mientras mis compañeros avanzaban en el práctico, me puse un par de horas a buscar algún programejo que lo haga por mi.

He escuchado por ahí que el objetivo de los sysadmin es buscar la manera de lograr la mayor automatización para luego no laburar, asi que saqué a relucir mi espíritu sysadminero -que tantas alegrias me ha dado- y así fue como me topé con maxima.


Maxima es un sistema para la manipulación de expresiones simbólicas y numéricas, incluyendo diferenciación, integración, expansión en series de Taylor, transformadas de Laplace, ecuaciones diferenciales ordinarias, y vectores, matrices y tensores, etc.

Además existe un front-end denominado wxmaxima muy sencillo e intuitivo de manejar, y como si fuese poco permite seleccionar el idioma castellano.
Como ejemplo, les muestro una captura del cálculo de la tercera derivada de la función f(x) = 1 / (1+x² )


Luego de haber calculado estas derivadas, se usa la función sustituir, del menú simplificar, luego se ingresa la variable que deseamos sustituir, el valor con el que se reemplazará y la función o el identificador de la función correspondiente... listo! un laburo cansador que nada nos hubiese aportado, hecho por maxima!
Conclusión: altamente recomendable, ahorro de horas de laburo.

sábado, 12 de julio de 2008

Graficador de funciones

A lo largo de la carrera de grado y posgrado (de la rama de las ciencias -mal llamadas- duras) siempre nos cruzamos con algún tipo de matemática, física o lo que sea y tenemos que graficar resultados de ecuaciones, series, etc. En la mayoría de las materias todo esta armadito para que recurramos al excel y grafiquemos desde ahi lo que nos tiren, esto significa para mi, al menos dos problemas:

1- Usar excel
2- Volver a usar windows

La solución para evitar [1] y [2] y a la vez para no caer en una suite de oficina equivalente, como openoffice, había sido gnuplot.
Gnuplot es muy flexible, completo y simple, pero... -siempre tiene que haber un pero- los gráficos no son muy lindos, y para cambiar detalles demanda laburo extra. Ya le dedicaré un post exclusivo a gnuplot, sin más perorata vayamos a la recomendación de hoy.

El software se llama QtiPlot - Data Analisys and Scientific Plotting.
Con ese nombre ya se darán cuenta que es mucho más que un graficador de funciones. Realmente aún no he tenido tiempo par usarlo demasiado, o mejor dicho, para desgranarlo, pero dándole el mismo uso del que le daba al gnuplot he obtenido gráficos inmensamente superiores y sobretodo fáciles de modificar.
Las características que hasta ahora puedo destacar:

  • Permite levantar de archivos planos datos (exportar / importar)
  • Modificaciones sobre el mismo gráfico (ejes,colores)
  • Gráficas fácilmente exportables como imagenes o pdf
  • Zoom
  • Generar automáticamente la transformada rápida de fourier de un conjunto de datos.


Acá dejo una captura, en donde importé dos archivos de texto plano generados a partir de un código en fortran y ambos se comparan en una misma gráfica.


Este software parece buenísimo, de esos que sirven para simplificar la vida de los estudiantes o de aquellos que laburan con este tipo de herramientas. Espero que le encuentren provecho. y si aún su tosquedad los mantiene usando windows también existe un ejecutable para dicho sistema operativo: http://soft.proindependent.com/login_exe.html

jueves, 19 de junio de 2008

Pedime arreglo

Ayer estaba tratando de programar el algoritmo bit-reverse order que se usa en la fft y primeramente lo había hecho a pata, bien "a lo bruto", después me puse a mirar acá y vi que si lo hacía de manera implícita era una boludez.
Lo hice con una función recursiva, así sirve para cualquier arreglo de longitud potencia de 2, en fin, la parte del algoritmo que pone en la primer mitad los elementos de índice par y en la segunda los de índice impar, se puede hacer en dos lineas, y así economizar código. Si c es nuestro arreglo auxiliar y x el arreglo de entrada, y ambos van de 0 a N-1,

c(0:N/2 -1)=x(0:N-1:2) !-- pares
c(N/2:N-1)=x(1:N-1:2) !-- impares


Como decía arriba, si a esto lo pongo en una función a la que llamo recursivamente pasandole la primera mitad del vector c y luego la segunda mitad, el bit-reverse order sale por un tubo.