Viendo 6 entradas - de la 1 a la 6 (de un total de 6)
  • Autor
    Entradas
  • #31207
    Javier Ader
    Participante

    Buenas. Por lo que vi libertya no soporta actualmente controladores Epson y en otro thread uno de ustedes sugirió que para implementar el soporte uno tendría que mirar un poco el paquete org.openXpertya.print.fiscal.hasar y asi basarse en la forma en que esta implementado para controladores Hasar. Bueno, el tema es que llegue a a la interface org.openXpertya.print.fiscal.comm.FiscalComm (que si no me falla la intuición es la que define los métodos para comunicación “en bruto” con el controlador) y buscando sus implemetaciones solo encontré SpoolerTCPComm (via AbstractFiscalComm). Ok, pero si no me equivoco esto estaría enviando los “comandos” al controlador via tcp a alguna forma de spooler, pero en ningún caso sobre la linea serial (lo cual tengo entendido es bastante común); asi que mi pregutna es en que clases (o paquetes), si es que existen, se da la comunicación en “crudo” sobre la linea serial?
    El tema es un poco “curiosidad” y otro poco porque en un futuro tal vez sea necesario para mi utilización de libertya implementar (ok, por lo menos intentar) el soporte para controladores Epson (de más esta decir que si lo hiciese, lo daría libremente a la libertya, un poco por respeto a la filosofía y otro poco por cuestiones obvias de calidad de software)

    #33802

    Javier,
    No encontraste las clases de manejo del puerto serie porque no existen. El mecanismo de “dialogo” con la impresora Hasar es a través del programa wspooler de hasar (tambien existe el spooler para DOS y para Linux / UNIX y funcionan todos de la misma manera. La gente de Hasar se toma las cosas en serio) que se encarga de la comunicacion serial y provee una interfaz TCP para enviar los comandos (ademas de una interfaz por archivos y por comandos).
    Esta es la principal causa por la cual Libertya solo maneja impresoras Hasar: ya esta la mitad del trabajo hecho.
    Este esquema además, permite que la impresora este conectada físicamente en cualquier lugar (no solo en el equipo donde está el Cliente java) y permite una gran flexibilidad.
    La gente de Hasar ademas, provee el codigo fuente de dichos utilitarios (ya no recuerdo en que licencia, pero creería que alguna openSource) por lo que tal vez sea posible adaptarlos a las impresoras Epson. Si tu curiosidad y necesidades se alinean y si tenés los conocimientos para hacer esta modificación, estaremos encantados en darte una mano en lo que podamos para que puedas armar el driver para Epson.

    Saludos
    Antonio.

    #33803
    Javier Ader
    Participante

    Y Epson no tiene algo parecido? Bueno, si me pasas el link de descarga (o alguna otra forma de obtenerlo) de los fuentes de wspooler los miro un poco y veo si se puede adaptar (si no, siempre algo se puede aprender). Yo de hasar tengo actualmente los controles activeX y en zip nombrado “Drivers y manuales …” aparece el wspooler (junto con otros), pero solo los binarios y algunos archivos headers de C.
    Para probar tengo actualmente un “emulador” de controladores fiscales (tanto de hasar como de epson), http://www.impresoras-fiscales.com.ar/emulador.htm , aunque solo corre bajo Windows, es cerrado y no se que tan bien los simulará (ya que no proviene ni de epson ni de hasar). No se si habrá otras opciones de emulación disponibles.
    Igual, me da la sensación que lo que debería llevar más trabajo es interiorizarse en los comandos internos de los distintos modelos de Epson, los manuales a primera vista parecen bastante “gorditos” (aunque me da la sensación que deben tener un “filosía” similar a los de hasar).

    #33815

    Hasta donde se (pero hace varios años de esto) no existe algo similar en Epson, pero puede ser que ahora lo tengan (en su momento, solo había un .bat que tomabaun archivo y lo pasaba a la impresora, pero no era multiplataforma y nada amigable)

    Podes trabajar con el wspooler (para win) o el spooler para linux.
    Tenes que abrir (dentro del ZIP) /drivers/linux/linux.tar y adentro del tar -> /spooler/tcpip
    Para win, dentro de /drivers/win32 hay un archivo winfis32.bas
    No se si con todo ésto alcanza o faltan alguna librerias.

    Ademas, adjunto al post un zip que me enviaron hace algunos años (por lo que puede ser que sea una versión vieja .. es del 2005) de los fuentes linux

    Por favor, comentanos de tus avances al respecto. Si conseguis que se conecte con las impresoras epson sería muy bueno para la gente que prefiere esa marca.

    Suerte!
    Antonio. [file name=Fuentes_Linux.zip size=107282]https://www.libertya.org/media/kunena/attachments/legacy/files/Fuentes_Linux.zip[/file]

    #33826

    transribo el “acuerdo” de Hasar que fija las limitaciones y autorizaciones sobre el uso de los fuentes del post anterior:

    Quote:
    DISCLAIMER
    IMPORTANTE
    LEA ESTE ACUERDO DETENIDAMENTE ANTES DE ABRIR EL ARCHIVO ZIPEADO QUE
    CONTIENE LOS FUENTES SUMINISTRADOS POR CIA. HASAR SAIC.
    Este Acuerdo de Uso (ACUERDO) de Cía. HASAR saic (HASAR) es un convenio legal entre
    Usted, el Usuario (USUARIO), -sea un individuo o una sola entidad dedicada al desarrollo de
    software- y HASAR en el que se especifican los términos y condiciones según los cuales se le
    permite al USUARIO utilizar el paquete de archivos fuentes (SOFTWARE) incluido con este
    ACUERDO; paquete que permite la generación de software a utilizar como driver, librería y/o
    utilitario, y al solo efecto de permitir el diálogo entre un software para puntos de venta, de-
    sarrollado por el USUARIO, y una impresora fiscal homologada por HASAR.
    Por el simple hecho de abrir el archivo zipeado que contiene el SOFTWARE, el USUARIO in-
    dica que comprende las condiciones contenidas en este ACUERDO y que acepta estar obli-
    gado a ellas.
    Si no está de acuerdo con las condiciones de este ACUERDO, no está autorizado a abrir el
    archivo zipeado, ni a utilizar el SOFTWARE contenido en él.
    Este ACUERDO no constituye una venta de SOFTWARE; es decir, el USUARIO no es el pro-
    pietario del SOFTWARE por el hecho de haberlo utilizado. HASAR retiene el derecho de pro-
    piedad sobre el SOFTWARE y todas las copias del mismo, y se reserva todos los derechos
    no específicamente concedidos bajo los términos de este ACUERDO.
    Este ACUERDO constituye el convenio completo y exclusivo, oral o escrito, entre HASAR y
    cualquiera de sus empresas asociadas con relación al Software.
    1. CONCESIONES DEL ACUERDO
    Este ACUERDO le autoriza:
    a) A configurar el SOFTWARE adaptándolo para uso propio agregando o quitando fuentes,
    modificar los fuentes recibidos o crear trabajos basados en el uso de este SOFTWARE o
    de alguna parte del mismo.
    2. LIMITACIONES DEL ACUERDO
    a) HASAR no ofrece ninguna garantía, expresa o implícita. El SOFTWARE se suministra
    «TAL Y COMO ESTÁ», sin garantías de ningún tipo, y HASAR, sus empleados, distribui-
    dores, y agentes, específicamente deniegan garantías de toda y cualquier índole, expre-
    sas o implícitas.
    #33804
    Javier Ader
    Participante

    Bueno, un poco lo mire. Hace solicite a hasar de las Clases Fiscales Multiplaforma (antes me habian mandado la versión en ActiveX) con la esperanza de que me mandaran las fuentes del spooler actual; pero no… Esta libreria C++ esta hecha para comunicarse directamente al controlador via el puerto serial o al spooler via tcp (la unica clase que tratan con TCP/IP son unas llamadas SocketTCP y SocketUDP; tiene metodos simples como enviarByte(), recibirByte pero no mucho más); basicamente tienen toda la lógica de genración de comandos “crudos” (orden de campos, chequeos de errores) que despues lo envian por RS232, TCP o UDP. Esto me hace pensar que el spooler no tienen mocho trabajo más que lo que viene por TCP/IP enviarlo a un puertdo serial y viceversa (ok, esto si puede ser bastante trabajo si se lo quiere hacer multiplataforma).
    De cualquier manera, si no hay un spooler de epson (o si genera algun tipo de problemas de licencias ) me da la sensación que esta “mitad” del problema se podria resolver relativamente facil. Como no estoy como para programar en C o C++ y andar haciendo malabares con #endif y librerias que no conozco para poder acceder a los puertos seriales (alguien en algún momento lo va a tener que hacer) intente simplificar y ver si se podia desde Java. Encontre dos librerias, una de Sun que no esta en JDK (creo…) y que me parece que no anda bajo Windows (y tampoco mire mucho la licencia) y esta http://code.google.com/p/giovynetserialport/ , que anda bajo Windwos y Linux y esta bajo GPL. A partir de esta se podria hacer un spoolercito más o menos rápido (falta como manejar TCP/IP, pero eso en Java debe ser incluso más fácil; he visto servers webs de un solo archivo java!).
    La otra parte es viene por el lado de manejar la idiosincracia de Epson y entrar en los detalles del protocolo y formato de los paquetes. En este sentido , por lo que vi, tiene buena documentación (y el protocolo y el formato general de los comandos parece bastante simples byteInicio + byteSequencia + byteComando + (byteLimitadorDeCampo + bytesDeValor)* + byteFin + 4byteCodigoBCC ) asi que lei un poco y juntando un poco todo lo anterior hice este programita

    serial.Serial.java

    Code:
    package serial;

    import app.Com;
    import app.Parameters;

    public class Serial {

    /***
    * Pequeño programa que muestra información sobre el controladores/impresores fiscales
    * epson modelos TM-2000AF+,TM300AF+, TM-2000AF, TM-U950F,TM-285F,LX-300F
    * @param args
    * @throws Exception
    */
    public static void main(String[] args) throws Exception{

    String strPort= “COM4”;
    if (args.length> 0)
    strPort = args[0];

    Parameters param = new Parameters();
    param.setPort(strPort);
    param.setBaudRate(“9600″);
    Com portCom = new Com(param);

    //intervalo entre envio de caracteres
    int intervalo = 50; //20 caracteres por segundo en envio, sera mucho?

    char numSeq = ComandoEpson.NumSeqInicial;

    char codComandoInfo = 0x2a; //codigo de comando de solicitud de informacion
    //comando de informacion Normal
    ComandoEpson cmdInfoN = ComandoEpson.crearComando(numSeq, codComandoInfo,”N”);
    //comando de info sobre las capacidades del controlador
    numSeq = ComandoEpson.proximoNumSeq(numSeq);
    ComandoEpson cmdInfoP = ComandoEpson.crearComando(numSeq, codComandoInfo,”P”);
    //comando de solicitud de info del contribuyente
    numSeq = ComandoEpson.proximoNumSeq(numSeq);
    ComandoEpson cmdInfoC = ComandoEpson.crearComando(numSeq, codComandoInfo,”C”);
    //comando de info sobre los contadores internos de docs. fiscales y no fiscales
    numSeq = ComandoEpson.proximoNumSeq(numSeq);
    ComandoEpson cmdInfoA = ComandoEpson.crearComando(numSeq, codComandoInfo,”A”);
    //comando de info sobre el documento que se esta emitiendo
    numSeq = ComandoEpson.proximoNumSeq(numSeq);
    ComandoEpson cmdInfoD = ComandoEpson.crearComando(numSeq, codComandoInfo,”D”);

    ComandoEpson[] comandos = new ComandoEpson[] {
    cmdInfoN, cmdInfoP,cmdInfoC,cmdInfoA, cmdInfoD };

    for (int i = 0 ; i < comandos.length; i ++) { ComandoEpson cmd = comandos[i]; System.out.println("Enviando comando..."); portCom.sendString(cmd.getStringRaw(), intervalo); System.out.println("Leyendo respuesta..."); //se lee hasta encontrar el inicio de datos; FALTA VErificar que puede enviar //el controlador en respuestas... portCom.receiveToString(ComandoEpson.INICIODATOS, 10); //lee hasta encontrar el caracter de fin de datos String respSinBCC = portCom.receiveToString(ComandoEpson.FINDATOS, 10); respSinBCC = ComandoEpson.INICIODATOS + respSinBCC; //despues lee los ultimo 4 carateres (deberian ser hexa) que son el BCC String respBCC = portCom.receiveToString(4, 10); System.out.println("Respuesta:" + respSinBCC ); System.out.println("BCC Respuesta: " + respBCC ); char seqResp = respSinBCC.charAt(1); //chequa que el numeor de secuencia sea el esperado System.out.println(cmd.getNumSequencia() == seqResp ? "Secuencia OK!" :"ERORR: Fuera de secuencia"); //chequea el BCC de la respuesta String bccEsperado = ComandoEpson.calBCC(respSinBCC); //por alguna cuestion rara, la documentacion de epson muestra ejemplos //con BCC en minusculas; el emulador que tengo retonra en minuscla //asi que como fix hago el egual ignorando cases System.out.println(respBCC.equals(bccEsperado)?"BCC de Resp OK!" :"ERROR: BCC de Resp"); } portCom.close(); } }


    serial.ComandoEpson.java

    Code:
    package serial;

    import java.util.*;

    public class ComandoEpson {

    public static final char INICIODATOS = 0x02;
    public static final char SEPARADORCAMPOS = 0x1c;
    public static final char FINDATOS = 0x03;

    public static final char NumSeqInicial = 0x20;
    //los numeros de secuencia deben estar
    //entre 0x20 y 0x7f inclusive
    public static char proximoNumSeq(char i)
    {
    if (i >= 0x7f) //se vuelve al primero
    return 0x20;
    if (i < 0x20) //no deberia pasar... return 0x20; return 0x20 +1; } char numSeq; char cod; List valoresDeCampos;
    boolean error = false;
    String descError = “”;
    String stringRaw;
    public char getNumSequencia() { return numSeq;}
    public char getCodigoComando() { return cod;}
    public List
    getValoresDeCampos(){ return valoresDeCampos;}
    public boolean getTieneError(){ return error;}
    public String getDescError() { return descError;}
    public String getStringRaw() { return stringRaw;}

    protected ComandoEpson(char cod, char numSeq, List valoresDeCampos ,
    boolean error, String descError, String stringRaw)
    {
    this.cod = cod;
    this.numSeq = numSeq;
    this.valoresDeCampos = valoresDeCampos;
    this.error = error;
    this.descError = descError;
    this.stringRaw = stringRaw;
    }

    public static ComandoEpson crearComando(char numSeq, char codComando,
    String valCampo1)
    {
    List valoresDeCampos = new ArrayList();
    valoresDeCampos.add(valCampo1);

    return crearComando(numSeq,codComando,valoresDeCampos);
    }

    public static ComandoEpson crearComando(char numSeq, char codComando,
    String valCampo1,String valCampo2)
    {
    List valoresDeCampos = new ArrayList();
    valoresDeCampos.add(valCampo1);
    valoresDeCampos.add(valCampo2);

    return crearComando(numSeq,codComando,valoresDeCampos);
    }
    public static ComandoEpson crearComando(char numSeq, char codComando,
    String valCampo1,String valCampo2, String valCampo3)
    {
    List valoresDeCampos = new ArrayList();
    valoresDeCampos.add(valCampo1);
    valoresDeCampos.add(valCampo2);
    valoresDeCampos.add(valCampo3);

    return crearComando(numSeq,codComando,valoresDeCampos);
    }

    public static ComandoEpson crearComando(char numSeq,
    char codComando, List valoresDeCampos ){
    validarNumSeq(numSeq);
    validarCodComando(codComando);
    //faltaria valirde la lista de los valores de los campos

    //construye la forma “raw” del comado
    StringBuilder strB = new StringBuilder();
    //cabezera; 0x02, numero de secuencia, codigo de comando
    strB.append(new char[]{INICIODATOS,numSeq,codComando});

    for(String valCampo : valoresDeCampos )
    {
    strB.append(SEPARADORCAMPOS);
    strB.append(valCampo);
    }
    strB.append(FINDATOS);
    //ahora calcula el bcc y se lo agrega
    String bcc = calBCC(strB.toString());
    strB.append(bcc);
    String strRaw = strB.toString();

    //falta
    boolean error = false;
    String descError = “”;
    ComandoEpson cmd = new ComandoEpson(codComando,numSeq,valoresDeCampos,error,
    descError,strRaw);
    return cmd;

    }
    private static void validarNumSeq(char num)
    {
    if (num > 0x7f || num <0x20)
    throw new Error("Número de secuencia invalido");

    }
    private static void validarCodComando(char cod)
    {
    //FALTA
    }
    public static String calBCC (String s)
    {
    char[] chars = s.toCharArray();
    int res = 0;
    for(int i = 0; i< chars.length; i++) { res = res + chars[i]; } //che.. no confio si >> es portable….
    // comvierte res a una string hexa
    char d = (Integer.toHexString(res % 16)).charAt(0);
    res = res / 16;
    char c = (Integer.toHexString(res % 16)).charAt(0);
    res = res / 16;
    char b = (Integer.toHexString(res % 16)).charAt(0);
    res = res / 16;
    char a = (Integer.toHexString(res % 16)).charAt(0);
    String bccStrHexa = new String (new char[]{a,b,c,d});

    //la documentacion de epson NO DEJA EN claro (al menos en los ejemplos)
    //si el BCC va en mayuscula o en minuscula… mi emulador retorna
    //en mayuscula y parece aceptar cualquirea forma
    return bccStrHexa.toUpperCase();
    }

    }

    Arranco siendo un prueba de concepto, pero me termino gustando (mas que nada la clase ComandoEpson que un posible uso real con un par de mejoras).
    Que hace: basicamente envia por el port serial que recibe como parametro (el nombre; bajo Windwos tomas COMx, bajo linux, no me fije, pero casi seguro algo de la forma /dev/algox ) el comando “Solicitud de Estado” (pagina 42 del manual MANPRG23.pdf que se puede bajar desde Epson) con sus 4 variantes:
    N: Información normal o compatible con TM-300AF . Homologado por GR22 AFIP-DGI (voy a tener que buscar en diccionario “homologado”)
    P: Información de las caracterizaticas de controlador
    C: Información del contribuyente (CUIT, punto de venta, sit. iva, etc)
    A: Información sobre los contadores de documentos fiscales y no fiscales
    D: Información sobre el documento que se esta emitiendo
    (OJO, lo que retorna el controlador no lo “parsea” simlemente lo manda a la consola, asi que si lo corren desde una terminal puede traer problemas ya que muchos datos no son “ascii”, muchos son binarios puros; redirección la salida a un arhcivo o corranlo dese eclipse que trae su propia cosola).

    Bueno, más allá de si tiene utilidad por si mismo (puede servir para testear si un controlador fiscal real al menos esta respondiendo y ver cierta información importante) lo interesante es que lo probé contra un emulador de controladores fiscales (que de paso emula un puerto virtual; por eso en el codigo se ve el nombre “COM4” y no algo mas natural como COM1) lo recibia perfectamente y reconocia los comandos validos (hace un chequeo bastante correcto al parecer; en varias pruebas me detectaba por ej, comandos desconocidos de manera correcta, ed. retornando un error; y tambien chequeba el codigo de comprobación BCC) y retornaba al parecer, lo que tenia que retorna (al menos no le erraba en el numero de secuenca ni el BCC de la respuesta).

    Pongo el último spoiler con los un ejemplo de salida (enviando los 4 comando que hablo mas arriba)

    Code:
    Enviando comando…
    Leyendo respuesta…
    Respuesta: *008006000091126101539123410001000EMULADOR FISCALTEXTO DE AUDITORIA
    BCC Respuesta: 1101
    Secuencia OK!
    BCC de Resp OK!
    Enviando comando…
    Leyendo respuesta…
    Respuesta:!*00800600080070050080085SSS2REMULADORFISCAL
    BCC Respuesta: 0BCB
    Secuencia OK!
    BCC de Resp OK!
    Enviando comando…
    Leyendo respuesta…
    Respuesta:!*00800600000000000010001C21001000000001000Razon Social
    BCC Respuesta: 0DA9
    Secuencia OK!
    BCC de Resp OK!
    Enviando comando…
    Leyendo respuesta…
    Respuesta:!*008006000000000000000000000000000000000000000000000000000000000
    BCC Respuesta: 0D46
    Secuencia OK!
    BCC de Resp OK!
    Enviando comando…
    Leyendo respuesta…
    Respuesta:!*00808620No hay 1 comprobante fiscal abierto
    BCC Respuesta: 0EFE
    Secuencia OK!
    BCC de Resp OK!

    (notese que hay caracters no ascii; es un copy and past crudo)

    Bueno, un comando ya esta implementado… faltan los 99 restantes jajaj

    P.D: el que lo quiera probar compilarlo y correrlo miren en la página de la librería http://www.giovynet.com/serialport.html que explica como hacerlo bajo eclipse como si el que lee fuera un nene de dos años (lo cual me sirvio muchisimo a ya que mi destreza bajo eclipse es casi nula jaja). Como emulador use el que esta en el post de más arriba; pero estaria bueno sacudirle a un controlador epson real (algún valiente?)

Viendo 6 entradas - de la 1 a la 6 (de un total de 6)
  • Debes estar registrado para responder a este debate.