Programación Script (picoC)

INFORMACIÓN GENERAL

Esta documentación describe cómo se puede programar un objeto personalizado.

Requisitos

Necesita LoxoneConfig 2.1 en adelante para usar PicoC-Scripts en el software de configuración. Consulte nuestras versiones beta más recientes para usar los scripts.

Fundamental

Se utiliza el lenguaje de programación PicoC (http://code.google.com/p/picoc/). PicoC es un intérprete de C muy pequeño para las secuencias de comandos. Originalmente se escribió para crear una secuencia de comandos del sistema de vuelo a bordo de un UAV y también es muy adecuado para otras aplicaciones robóticas, integradas y no integradas.

Copyright PicoC

IMPORTANTE

  • Tenga en cuenta que la especificación C completa no se puede cumplir.
  • El código del programa se interpreta. Por lo tanto, mantenga el código lo más bajo posible. Evite estructuras complejas del programa.
  • Cada programa se ejecuta en una tarea separada, por lo tanto, asíncrono al SPS.
  • Las salidas con printf se escribirán en la ventana de registro de Loxone Config.
  • Tenga en cuenta también que con una programación propia, el sistema puede provocar un bloqueo. Programe sus instrucciones con cuidado. En caso de emergencia, se debe crear una tarjeta SD para que el sistema vuelva a funcionar.
  • Si desea ejecutar el programa indefinidamente, agregue en los bucles del programa implícitamente una función de suspensión para que el programa no consuma tiempo innecesario de la CPU.
  • Un número entero tiene 32 bits, little endian.
  • 128kB están disponibles para el montón y la pila. Use memoria ahorrativa; no te olvides de liberar memoria.
  • Todas las funciones que devuelven un puntero deben reasignar la memoria con free (), a menos que el puntero se haya pasado como parámetro.
  • Los valores de tiempo se indican en segundos desde el 1.1.2009 0 reloj UTC.
  • Las cadenas están codificadas en UTF-8.
  • Use la función matemática con moderación: el procesador en el Miniserver no tiene una unidad matemática de hardware.
Los bloques de programa erróneos (PicoC) provocan que el Miniserver realice reinicios de seguridad u otros problemas serán desactivados por el Miniserver. Esos bloques permanecen desactivados hasta que se arreglen dentro de Loxone Config.

Los scripts solo funcionan si el archivo de configuración se guarda en el Miniserver.

Objetos SPS

El objeto del programa tiene 16 entradas y salidas. Puede insertarlo seleccionándolo en «General» en la pestaña «Mi proyecto».

El programa también tiene una salida de error (TeQ), donde se lanzan eventuales mensajes de error de intérprete. Esto permite la detección de errores de sintaxis.

El código del programa se puede editar haciendo doble clic en el objeto del programa.

programm

FUNCIONES DISPONIBLES

En los siguientes capítulos se enumeran todas las funciones disponibles y se describen todas las funciones específicas de Miniserver. Para todas las funciones estándar de C, se puede encontrar mucha información en la literatura apropiada (por ejemplo, www.cplusplus.com/reference/clibrary/).

C Funciones de la Biblioteca

char *getprogramname();
void printf(char *format, …);
char *sprintf(char *ptr, char *format, …);
void exit();
void *malloc(int size);
void *calloc(int num,int size);
void *realloc(void *ptr,int size);
void free(void *ptr);
int atoi(char *str);
float atof(char *str);
void strcpy(char *dst,char *src);
void strncpy(char *dst,char *src,int len);
int strcmp(char *str1,char *str2);
int strncmp(char *str1,char *str2,int len);
void strcat(char *dst,char *src);
char *strdup(char *str);
char* strstr(char *str,char *strfind);
int strfind(char *str,char *strfind,int pos);
int strlen(char *str);
void memset(void *ptr,int val,int len);
void memcpy(void *dst,void *src,int len);
int memcmp(void *ptr1,void *ptr2,int len);
void errorprintf(char *format,…);

Funciones matemáticas

float sin(float x);
Returns the sine of an angle of x radians.
float cos(float x);
Returns the cosine of an angle of x radians.
float tan(float x);
Returns the tangent of an angle of x radians.
float asin(float x);
Returns the principal value of the arc sine of x, expressed in radians. In trigonometrics, arc sine is the inverse operation of sine.
float acos(float x);
Returns the principal value of the arc cosine of x, expressed in radians. In trigonometrics, arc cosine is the inverse operation of cosine.
float atan(float x);
Returns the principal value of the arc tangent of x, expressed in radians. In trigonometrics, arc tangent is the inverse operation of tangent.
float sinh(float x);
Returns the hyperbolic sine of x.
float cosh(float x);
Returns the hyperbolic cosine of x.
float tanh(float x);
Returns the hyperbolic tangent of x.
float exp(float x);
Returns the base-e exponential function of x, which is the e number raised to the power x.
float fabs(float x);
Returns the absolute value of x
float log(float x);
Returns the natural logarithm of x.
float log10(float x);
Returns the common (base-10) logarithm of x.
float pow(float base,float exponent);
Returns base raised to the power exponent.
float sqrt(float x);
Returns the square root of x.
float round(float x);
Returns rounded value of x.
float ceil(float x);
Returns the smallest integral value that is not less than x.
float floor(float x);
Returns the largest integral value that is not greater than x.

 

Funciones extendidas de la biblioteca C

int batoi(char *str);
float batof(char *str);
char* strstrskip(char *str,char *strfind);
char *index(char *,int);
int lineno();

 

Funciones SPS

Las siguientes funciones están disponibles:

void setlogtext(char *str);
float getio(char *str);
int setio(char *str,float value);
int getinputevent();
float getinput(int input);
char *getinputtext(int input);
void setoutput(int output,float value);
void setoutputtext(int output,char *str);

 

Funciones de archivo

FILE *fopen(char *filename,char *mode);
int fclose(FILE *f);
int fprintf(FILE *f,char *format, … );
int fputc(int character,FILE *f);
int fputs(char *str, FILE *f);
int fflush(FILE *f);
int fwrite (void *ptr,int size,int count,FILE *f);
int fgetc(FILE *f);
char *fgets(char *str,int num,FILE *f);
int fread(void *,int size,int count,FILE *f);
int fseek(FILE *f,long offset,int origin);
int remove(char *filename);
int rename(char *oldname,char *newname);
FILE* tmpfile();
char *tmpnam(char* str);

 

Funciones HTTP

char*httpget(char*address,char*page);

 

Funciones de Buffer

int getshort(void * p,int bBigEndian);
unsigned int getushort(void * p,int bBigEndian);
int getint(void * p,int bBigEndian);
unsigned int getuint(void * p,int bBigEndian);
float getfloat(void * p,int bBigEndian);
float getdouble(void * p,int bBigEndian);

 

Funciones de secuencias

STREAM *stream_create(char* filename,int read,int append);
void stream_printf(STREAM* stream,char *format, …);
int stream_write(STREAM* stream,void* ptr,int size);
void stream_flush(STREAM* stream);
int stream_read(STREAM* stream,void* ptr,int size,int timeout);
int stream_readline(STREAM* stream,void* ptr,int maxsize,int timeout);
void stream_close(STREAM* stream);

 

Descripción de las funciones extendidas de la biblioteca C

atoi

int batoi(char *str);

Funciona como la función C estándar de atoi con la excepción de que
se permiten espacios en blanco al comienzo del parámetro str.
Ejemplo:

atoi(“ 21”); // return value = NULL
batoi(“ 21”); // return value = 21

 

batof

float batof(char *str);

Funciona como la función atof estándar C con la excepción de que se permiten espacios en blanco al comienzo del parámetro str. Ejemplo:

atof(“ 2.1”); // return value = NULL

batof(“ 2.1”); // return value = 2.1

 

strstrskip

char* strstrskip(char *str,char *strfind);

Funciona como la función C estándar de strstr con la excepción de que la longitud del parámetro strfind se agrega al puntero de resultado.
Ejemplo:

strstr(“das ist ein test”,”ein ”); // return value = “ein test”

strstrskip(“das ist ein test”,”ein ”); // return value = “test”

 

index

char *index(char *str,int charfind);

Devuelve un puntero a la primera aparición del carácter charfind en str, o un puntero nulo si charfind no es parte de str.
Ejemplo:

index(“0123456789”,0x32); // return value = “23456789”

 

lineno

int lineno();]

Devuelve el número de línea actual en el script.

 

getxmlvalue

char *getxmlvalue(char *str,int index,char* name);

Devuelve el valor del nombre en str, o un puntero nulo si el nombre no es parte de str.
Parámetros:
str:
Cadena XML para analizar el
índice:
el índice de aparición del nombre (primer elemento es 0)
nombre: Nombre
del atributo XML para obtener
La memoria a la que apunta el puntero devuelto debe desasignarse con la función free ().

Ejemplo:

getxmlvalue(“<XML name=\”test\”>”,0,”name”); // return value = “test”

 

getcpuinfo

int getcpuinfo();

Devuelve el valor real del uso de la CPU en %.

 

getheapusage

int getheapusage();

Devuelve el valor real del montón del sistema en kB.

 

getmaxheap

int getmaxheap();

Devuelve el valor máximo del montón del sistema en kB.

 

getspsstatus

int getspsstatus();

Devuelve el número real de ciclos procesados ​​por SPS.

 

localwebservice

char *localwebservice(char *str);

Ejecute el servicio web y devuelva un puntero a la cadena XML de respuesta.

Parámetros:
str: servicio
web

La memoria a la que apunta el puntero devuelto debe desasignarse con la función free (). Ejemplo:

char* p = localwebservice(“dev/sps/status”);
free(p);

 

Descripción de las funciones SPS

setlogtext

void setlogtext(char *str);

Escribe la cadena contenida en la cadena de parámetros en la ventana de registro de Loxone Config.

 

getio

float getio(char *str);

Devuelve el valor de la entrada virtual especificada o una salida virtual.

Ejemplo:

getio(“VI1”); // Returns the value of the virtual input VI1

 

setio

int setio(char *str,float value);

Establece el valor de la entrada virtual especificada o una salida virtual.

Ejemplo:

setio(“VI1”,6.33); // Sets the value of the virtual input VI1 to 6.33

 

getinputevent

int getinputevent();

Devuelve una máscara de bits que contiene los cambios de las entradas (bit 0 = primera entrada del objeto, comienza con entradas de texto seguidas de entradas analógicas).

Un valor de retorno de 0x02, por ejemplo, significa que la entrada 2 ha cambiado.
(ver ejemplo 1).

 

getinput

float getinput(int input);

Devuelve el valor de la entrada analógica especificada en la entrada de parámetros. (0 = primera entrada analógica) (ver ejemplo 1).

 

getinputtext

char *getinputtext(int input);

Devuelve la cadena de la entrada de texto especificada en la entrada de parámetros. (0 = primer ingreso de texto).

 

setoutput

void setoutput(int output,float value);

Establece la salida analógica especificada en el valor especificado. (0 = primera salida analógica) (ver ejemplo 1).

 

setoutputtext

void setoutputtext(int output,char *str);

Establece la salida de texto especificada en la cadena especificada en el parámetro str. (0 = primer resultado de texto) (ver ejemplo 1).

 

Descripción de las funciones de tiempo

sleep

void sleep(int ms);

sleep en milisegundos.

 

sleeps

void sleeps(int s);

Sleep en segundos.

 

getcurrenttime

unsigned int getcurrenttime();

Obtener el tiempo UTC en segundos desde 1.1. 2009

 

getyear

int getyear(unsigned int time,int local);

Obtener el año del tiempo especificado. Puede configurar los siguientes parámetros:

tiempo: tiempo
UTC en segundos desde 2009

local:
especifica el formato de hora: hora local cuando 1, UTC cuando 0

 

getmonth

int getmonth(unsigned int time,int local);

Obtenga el mes del tiempo especificado. Puede configurar los siguientes parámetros:

hora: hora UTC en segundos desde 2009
local: especifica el formato de hora: hora local cuando 1, UTC cuando 0

 

getday

int getday(unsigned int time,int local);

Obtener el día de la hora especificada. Puede configurar los siguientes parámetros:

hora: hora UTC en segundos desde 2009
local: especifica el formato de hora: hora local cuando 1, UTC cuando 0

 

gethour

int gethour(unsigned int time,int local);

Obtener hora de tiempo especificado. Puede configurar los siguientes parámetros:

hora: hora UTC en segundos desde 2009
local: especifica el formato de hora: local cuando 1, UTC cuando 0

 

getminute

int getminute(unsigned int time,int local);

Obtener minuto de tiempo especificado. Puede configurar los siguientes parámetros:

hora: hora UTC en segundos desde 2009
local: especifica el formato de hora: local cuando 1, UTC cuando 0

 

getsecond

int getsecond(unsigned int time,int local)

Obtener el segundo del tiempo especificado. Puede configurar los siguientes parámetros:

hora: hora UTC en segundos desde 2009
local: especifica el formato de hora: local cuando 1, UTC cuando 0

 

gettimeval

unsigned int gettimeval(int year,int month,int day,int hour,int minutes,int seconds,int local);

Obtenga la hora UTC en segundos desde 2009. Si los parámetros año, mes, día, hora, minutos y segundos son hora UTC, el parámetro local debe establecerse en 0. Si los parámetros año, mes, día, hora, minutos y segundos son hora local, El parámetro local debe establecerse en 1.

 

convertutc2local

unsigned int convertutc2local(unsigned int timeutc);

Convierte la hora UTC en hora local.

 

convertlocal2utc

unsigned int convertlocal2utc(unsigned int timelocal);

Convierte la hora local a la hora UTC.

 

Descripción de las funciones de archivo

fseek

int fseek(FILE *f,long offset,int origin);

Hay una diferencia en la función C fseek estándar: el origen debe ser 0, 1 o 2.
Si alguien quiere usar la sintaxis C estándar, tiene que hacer las siguientes definiciones en el script PicoC:

#define SEEK_CUR 0 // seek from current position
#define SEEK_SET 1 // seek from beginning of file
#define SEEK_END 2 // seek from end of file

Para todas las demás funciones estándar de archivos C, se puede encontrar mucha información en la literatura apropiada (por ejemplo, www.cplusplus.com/reference/clibrary/ ).

 

Descripción de las funciones http

httpget

char *httpget(char *address,char *page);

Descarga la página especificada desde la dirección especificada. Puede configurar los siguientes parámetros:

dirección: Dirección del servidor, por ejemplo,
página «de.wikipedia.org» : página en el servidor especificado, por ejemplo, «/ wiki / Intelligentes_Wohnen»

La memoria a la que apunta el puntero devuelto debe desasignarse con la función free ().

 

Descripción de las funciones del buffer

getshort

int getshort(void * p,int bBigEndian);

Lee datos binarios (2 bytes con signo corto) del búfer con el puntero p.

Si bBigEndian es desigual 0, los datos se interpretan como «big endian».

 

getushort

unsigned int getushort(void * p,int bBigEndian);

Lee datos binarios (2 bytes sin signo cortos) del búfer con el puntero p.

Si bBigEndian es desigual 0, los datos se interpretan como «big endian».

 

getint

int getint(void * p,int bBigEndian);

Lee datos binarios (4 bytes con signo int) del búfer con el puntero p.

Si bBigEndian es desigual 0, los datos se interpretan como «big endian».

 

getuint

unsigned int getuint(void * p,int bBigEndian);

Lee datos binarios (4 bytes sin signo int) del búfer con el puntero p.

Si bBigEndian es desigual 0, los datos se interpretan como «big endian».

 

getfloat

float getfloat(void * p,int bBigEndian);

Lee datos binarios (4 bytes flotante IEEE) del búfer con el puntero p.

Si bBigEndian es desigual 0, los datos se interpretan como «big endian».

 

getdouble

float getdouble(void * p,int bBigEndian);

Lee datos binarios (flotante IEEE de 8 bytes) del búfer con el puntero p.

Si bBigEndian es desigual 0, los datos se interpretan como «big endian».

 

Descripción de las funciones de stream

stream_create

STREAM *stream_create(char* filename,int read,int append);

Crea una secuencia de archivos, una secuencia tcp, una secuencia udp, una secuencia syslog o una secuencia RS232 / RS485 (consulte el ejemplo 2 y el ejemplo 3).

nombre del archivo:

Valor Descripción
/ruta /nombre de archivo File-Stream
/dev/tcp/server-address/port TCP-Stream
/dev/udp/server-address/port UDP-Stream
/dev/syslog Syslog-Stream
/dev/tty/name of RS232 or RS485 RS232/RS485 Stream (only)
Extensió stream_read is possible, no stream_write)

leer: Si la secuencia es una secuencia de archivo: 1 = leer archivo; 0 = escribir archivo
anexar: 1 = agregar texto al archivo; 0 = sobrescribir texto en el archivo

 

stream_printf

void stream_printf(STREAM* stream,char *format, …);

Escribe en el búfer de salida de la secuencia especificada una secuencia de datos formateados como lo especifica el argumento de formato. Después del parámetro de formato, la función espera al menos tantos argumentos adicionales como se especifica en el formato.

 

stream_write

int stream_write(STREAM* stream,void* ptr,int size);

Escribe una matriz de elementos de tamaño, desde el bloque de memoria apuntado por ptr hasta el búfer de salida de la secuencia especificada (ver ejemplo 2).

El indicador de posición de la secuencia avanza por el número total de bytes escritos.
Se devuelve el número total de elementos escritos correctamente. Si este número difiere del parámetro de tamaño, indica un error.

 

stream_flush

void stream_flush(STREAM* stream);

Si la secuencia dada es una secuencia de archivo y el archivo se abrió para escritura, cualquier dato no escrito en el búfer de salida se escribe en el archivo (ver ejemplo 2).

Si la secuencia dada es una secuencia tcp, una secuencia udp o una secuencia syslog, cualquier dato en el búfer de salida se envía al servidor.

 

stream_read

int stream_read(STREAM* stream,void* ptr,int size,int timeout);

Lee una matriz de elementos de tamaño del búfer de entrada de la secuencia especificada y los almacena en el bloque de memoria especificado por ptr (ver ejemplo 2).

El tiempo de espera se da en milisegundos. El indicador de posición de la transmisión avanza por la cantidad total de bytes leídos. Se devuelve el número total de elementos leídos correctamente.

 

stream_readline

int stream_readline(STREAM* stream,void* ptr,int maxsize,int timeout);

Si la secuencia dada es una secuencia de archivo, se lee la siguiente línea del archivo.

El número máximo de elementos para leer se especifica con el parámetro maxsize. El tiempo de espera se da en milisegundos.

 

stream_close

void stream_close(STREAM* stream)

Cierra la secuencia especificada y desasigna toda la memoria utilizada por la secuencia.

Ejemplos

 

Los ejemplos deberían mostrar cómo se pueden crear los programas de script.

Ejemplo 1: Computar

Este ejemplo muestra cómo se realiza una informática propia:
si se produce un cambio en cualquier entrada, el valor de la entrada 1 multiplicado por el valor de la entrada 2 más el valor de la entrada 3 se da a la salida 1.
La fórmula se emite como texto en texto salida 1.

Este fragmento de código es probable para el bloque de programa con 4 entradas. Puede cambiar la máscara de bits en la línea 8 para que el código sea adecuado para los otros bloques de programa:

Program 8: if(nEvents & 0x1c)

Program 16: if(nEvents & 0x38)

// write program here in PicoC
char szBuffer[128];
float f1,f2,f3,f4;
int nEvents;
while(TRUE)
{
nEvents = getinputevent();
if (nEvents & 0xe)
{
f1 = getinput(0);
f2 = getinput(1);
f3 = getinput(2);
f4 = f1 * f2 + f3;
setoutput(0,f4);
sprintf(szBuffer,»%f * %f + %f = %f»,f1,f2,f3,f4);
setoutputtext(0,szBuffer);
printf(szBuffer);
}
sleep(100);
}

 

Ejemplo 2: Descarga del sitio web por stream tcp

Este ejemplo muestra cómo descargar un sitio web con una transmisión tcp y cómo guardar el sitio web en un archivo.

#define BUFF_SIZE 40000
#define RD_BLOCK_SIZE 128

STREAM* pTcpStream = stream_create(«/dev/tcp/www.w3.org/80»,0,0); // create tcp stream
char* pTcpCmd = «GET / HTTP/1.0\r\nHost: www.w3.org\r\nUser-Agent: LoxLIVE [en]\r\nContent-Type: text/html; charset=utf-8\r\n\r\n»;
stream_write(pTcpStream,pTcpCmd,strlen(pTcpCmd)); // write to output buffer
stream_flush(pTcpStream); // flush output buffer
char szBuffer[BUFF_SIZE];
char szTmpBuffer[RD_BLOCK_SIZE];
int nCnt;
int nBytesReceived = 0;
// read stream
do
{
nCnt = stream_read(pTcpStream,szTmpBuffer,RD_BLOCK_SIZE,4000);
if (nCnt + nBytesReceived > BUFF_SIZE)
{
nBytesReceived = -1;
break; //File is too large
}
else if(nCnt > 0)
{
strncpy((char*)szBuffer + nBytesReceived, szTmpBuffer, nCnt);
nBytesReceived += nCnt;
}
}
while (nCnt > 0);
if (nBytesReceived > 0)
{
FILE* pw = fopen(«/w3.html»,»w»); // open file
fprintf(pw,»%s»,szBuffer); // write file
printf(«Bytes received: %d»,nBytesReceived);
fclose(pw);
}
stream_close(pTcpStream);

 

Ejemplo 3: Conexión a un usv apc, si apcupsd se utiliza en la pc

Este ejemplo muestra la carga real (AQ1), la capacidad de la batería (AQ2) y las fallas de energía (AQ3).

char* p,*pS;
char szBuffer[1500];
int nLen;
int bOnline = 0;
double dCharge,dLoad;
printf(«Start APC watch»);
while(TRUE)
{
STREAM* stream = stream_create(«/dev/tcp/192.168.1.9/3551″,0,0);
if (stream != NULL)
{
szBuffer[0] = 0;
szBuffer[1] = 6;
stream_write(stream,szBuffer,2);
stream_flush(stream);
stream_write(stream,»status»,6);
stream_flush(stream);
nLen = stream_read(stream,szBuffer,2,1000);
nLen = stream_read(stream,szBuffer,sizeof(szBuffer) – 1,1000);
stream_close(stream);
szBuffer[nLen] = 0;
szBuffer[nLen + 1] = 0;
//printf(«APC Len=%d»,nLen);
pS = szBuffer;
while(*pS)
{
p = strstr(pS,»STATUS :»);
if (p != NULL)
{
p = strstr(pS,»STATUS : ONLINE»);
if (p != NULL)
bOnline = 1;
else
bOnline = 0;
}
else
{
p = strstr(pS,»LOADPCT :»);
if (p != NULL)
{
dLoad = batof(p + 11);
setoutput(0,dLoad);
}
else
{
p = strstr(pS,»BCHARGE :»);
if (p != NULL)
{
dCharge = batof(p + 11);
setoutput(1,dCharge);
break;
}
}
}
pS += (strlen(pS) + 1);
}
if (bOnline)
{
setoutput(2,1);
//printf(«Power OK Charge: %f%% Load: %f%%»,dCharge,dLoad);
}
else
{
setoutput(2,0);
//printf(«Power lost Charge: %f%% Load: %f%%»,dCharge,dLoad);
}
}
else
printf(«APC no connection»);
sleeps(10); // wait 10 seconds
}

 

Ejemplo 4: leer desde la RS232 Extension vía stream de RS232

Este ejemplo lee los bytes recibidos de la extensión RS232 y lo coloca en la salida de texto 1. El número total de bytes recibidos se coloca en la primera salida analógica.

#define BUFF_SIZE 256

STREAM* pRs232Stream = stream_create(«/dev/tty/my_rs232_extension»,0,0);// create rs232 stream
char szBuffer[BUFF_SIZE];
int nCnt;
int nBytesReceived = 0;
while(1)
{
nCnt = stream_read(pRs232Stream,szBuffer,BUFF_SIZE,100); // read stream
nBytesReceived += nCnt;
setoutput(0,(float)nBytesReceived);
setoutputtext(0,szBuffer);
sleep(100);
}

 

PICO-C COPYRIGHT

picoc se publica bajo la «Nueva Licencia BSD».
http://www.opensource.org/licenses/bsd-license.php

Copyright (c) 2009, Zik Saleeba
Todos los derechos reservados.

Se permite la redistribución y el uso en fuentes y binarios, con o sin modificación, siempre que se cumplan las siguientes condiciones:

  • Las redistribuciones del código fuente deben conservar el aviso de copyright anterior, esta lista de condiciones y el siguiente descargo de responsabilidad.
  • Las redistribuciones en forma binaria deben reproducir el aviso de copyright anterior, esta lista de condiciones y el siguiente descargo de responsabilidad en la documentación y / u otros materiales proporcionados con la distribución.
  • Ni el nombre de Zik Saleeba ni los nombres de sus colaboradores pueden usarse para respaldar o promocionar productos derivados de este software sin un permiso previo por escrito específico.

ESTE SOFTWARE ES PROPORCIONADO POR LOS TITULARES Y LOS CONTRIBUIDORES DE LOS DERECHOS DE AUTOR
«TAL CUAL» Y CUALQUIER GARANTÍA EXPRESA O IMPLÍCITA, INCLUYENDO, PERO SIN
LIMITACIÓN, LAS GARANTÍAS IMPLÍCITAS DE COMERCIABILIDAD Y APTITUD PARA
UN PROPÓSITO EN PARTICULAR. EN NINGÚN CASO EL
PROPIETARIO DE DERECHOS DE AUTOR O LOS CONTRIBUYENTES SERÁN RESPONSABLES POR NINGÚN DAÑO DIRECTO, INDIRECTO, INCIDENTAL,
ESPECIAL, EJEMPLAR O CONSECUENTE (INCLUYENDO, PERO SIN
LIMITARSE A, LA ADQUISICIÓN DE BIENES O SERVICIOS SUSTITUTOS; PÉRDIDA DE USO,
DATOS O GANANCIAS; O INTERRUPCIÓN EMPRESARIAL) SIN EMBARGO CAUSADO Y EN CUALQUIER
TEORÍA DE RESPONSABILIDAD, YA SEA POR CONTRATO, RESPONSABILIDAD ESTRICTA O TORTURA
(INCLUYENDO NEGLIGENCIA O DE OTRA MANERA) QUE SURJA DE CUALQUIER FORMA FUERA DEL USO
DE ESTE SOFTWARE, INCLUSO SI SE LE INDICA LA POSIBILIDAD DE TALES DAÑOS.