Code Monkey home page Code Monkey logo

paxapos / fiscalberry Goto Github PK

View Code? Open in Web Editor NEW
55.0 15.0 39.0 6.63 MB

[JSON ↔ HW] Connect things using JSON API with the fiscalberry websocket server interact easily with any kind of Hardware. Another IoT solution...

Home Page: https://paxapos.github.io/fiscalberry/

License: Apache License 2.0

JavaScript 5.44% Python 85.08% HTML 7.78% Shell 1.67% Batchfile 0.02%
raspberry-pi raspberry-pi-3 iot fiscal-printer impresora-fiscal imprimir json servidor epson hasar

fiscalberry's People

Contributors

alanemiliano avatar alevilar avatar carlospiad avatar cmacri avatar edunola13 avatar gonzaabel avatar intelintec avatar leapoli avatar pwqw avatar spartanj avatar spetrungaro avatar ssaid avatar wdirac avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fiscalberry's Issues

Problemas con Emulador Fiscar usando Epson Driver

Hola amigos, driver: Hasar y driver: File funciona todo de maravillas, pero cuando uso el driver: Epson tengo errores.

Esto es lo que aparece en consola:

inicializando ConectorDriverComando driver de Epson
inicializando ConectorDriverComando driver de ReceiptDirectJet
Exception in thread Thread-6:
Traceback (most recent call last):
File "C:\Python27\lib\threading.py", line 801, in __bootstrap_inner
self.run()
File "C:\Python27\lib\threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "C:/fiscalberry\ConectorDriverComando.py", line 23, in init_driver
self.driver = driverClass(**kwargs)
TypeError: init() got an unexpected keyword argument 'path'

Iniciando Fiscalberry Server
iniciando en modo HTTP
Hay 2 impresoras disponibles

  • IMPRESORA_FISCAL
    marca: Epson, driver: Epson
  • IMPRESORA_RED
    marca: EscP, driver: ReceiptDirectJet

El error esta saltando en ConectorDriverComando.py, cuando entra a la funcion "init_driver" y ahi me pierdo y no se que pasa.

Revisando un poco el codigo (tengo muy poco de python) encontre eso:

En ComandoInterface.py linea 152:

def _sendCommand(self, commandNumber, parameters, skipStatusErrors=False): print "_sendCommand", commandNumber, parameters try: logging.getLogger().info("sendCommand: SEND|0x%x|%s|%s" % (commandNumber, skipStatusErrors and "T" or "F", str(parameters))) return self.conector.sendCommand(commandNumber, parameters, skipStatusErrors) except **epsonFiscalDriver**.ComandoException, e: logging.getLogger().error("epsonFiscalDriver.ComandoException: %s" % str(e)) raise ComandoException("Error de la impresora fiscal: " + str(e))

"Unresolved Reference" me dice mi IDE.

En EpsonDriver.py Linea 3:
from Drivers.FiscalPrinterDriver import FiscalPrinterDriver agregue ",ComunicationError" como esta en el HasarDriver".

No pude probar todavia en una fiscal Epson verdadera, estoy usando el emulador de http://www.impresoras-fiscales.com/emulador.htm

Saludos!
Catriel

No funciona con P-441F

Estimados

Hemos estado probando con una hasar nueva modelo P-441F y no funciona. Pero tampoco tira error, solo queda "tildado" al intentar imprimir.

¿Alguna recomendación de como podríamos solucionar el inconveniente?.

Gracias.

mandar un mensaje de error (capturar exception) cuando se envia un comando no valido

AttributeError: TraductorReceipt instance has no attribute 'printTicket'

Cuando se quiere mandar un comando a un traductor que no lo tiene se muestra un error,. Aunque el programa sigue ejecutandose, no se enmtiende bien el motivo del error, y no llega al JS por medio del websocket.
Seria importante que mande un mensaje diciendo "No es un comando valido para TraductorReceipt"

Tambien seria util si al listar las impresoras no recibimos un listado de acciones o comandos disponibles para el traductor indicado.

Por ejemplo el TraductorReceipt tiene un juego de comandos distinto al TraductorFiscal

Mientras que uno es para impresoras de comandas, el otro es para impresoras fiscales.

Generación de duplicados para impresora Lx 300

Me ha funcionado espectacular la libreria... pero queria consultar ¿Cómo puedo hacer para emitir un duplicado para el caso de las impresoras epson lx300 en el caso de no poseer carbónico?

[feat] evolucion: driver center para kit fiscal dominicana

Llevar el fiscalberry a un producto de la talla del https://www.odoo.com/page/point-of-sale-hardware#part_3 POSBOX una caja ARM que centraliza el hardware (impresoras) y envia las ordenes.. ya que el piunto de venta de ambos proyectos no es desktop sino web

En este capitulo es implementar un driver fiscalberry/Drivers/EpsonDriver.py que domine el kit fiscal de Rep dominicana, esto implica algunas cosas que lelvan a la evolucion:

  1. los drivers no pueden tener el nombre de la impresora simplemente, esto complica el desarrollo, ya que cada pais tiene su propio kit, incluso puede haber dos empresas distintas con la misma impresora en el mismo pais
  2. el lenguaje es python, un tanto dificil de aprender (de aprender avanzado para trabajar con hardware, muy distinto a la curva de avance de BASIC y GAMBAS) se requiere mas informacion especifica de como hacer esto con hardware en python para no perder tiempo en el avance, ya que todos nostros tenemos tambien trabjao y vidas que atender..
  3. lamentablemtne hay que hablar con los proveedores, en el caso de dominicana es especial, porque el proveedor del kit no es de dominicana, es argrentino y es la propia epson, se adjunta el pdf con las especificaciones a bajo nivel

estoy realmente decidido a implementar esto porque solos no podemos, juntos si de eso se trata el software de contribucion..

Soporte de EscP para comanderas con conexción USB en Windows

[Question]
Hola! Buenas.
Quiero saber si el programa soporta la conexcion USB en windows.
Si se soporta como tengo que configurar el config.ini.

[impresora1]
marca = EscP
driver = RecieptUSB
path = USB002

¿Por ejemplo, así sería?
No sé, qué tengo que poner en vez de "/dev/ttyUSB0" al parametro path para que funcione en windows con la conexción USB.

La impresora es: SAM4S Ellix 30

Saludos

UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 2: ordinal not in range(128)

Buenas tardes. Estamos usando la version para PHP con una impresora Hasar 441F.
Para Imprimir facturas y ticket no tenemos problemas pero para imprimir nota de creditos no da el siguiente error:
UnicodeDecodeError: 'ascii' codec can't decode byte 0x93 in position 2: ordinal not in range(128)

El formato del json es el siguiente:
{
"printTicket": {
"encabezado": {
"tipo_cbte": "NCB",
"referencia": "00105838"
},
"items": [{
"alic_iva": "21.00",
"importe": 1,
"ds": "DEPILACION",
"qty": "1"
}],
"pagos": []
},
"printerName": "IMPRESORA_FISCAL"
}

python-serial windows

Hola,
De qué manera puedo instalar python-serial bajo el sistema operativo windows.

Desde ya muchas gracias

Hasar 715v2 repite Direccion del cliente

Amigos, modifique el codigo del HasarComando.py porque para la 715 me estaba enviando 2 veces la direccion.

copio el codigo modificado a ver que les parece:

` def _setCustomerData(self, name=" ", address=" ", doc=" ", docType=" ", ivaType="T"):
# limpio el header y trailer:

    #self.setHeader()
    #self.setTrailer()
    doc = str(doc)
    doc = doc.replace("-", "").replace(".", "")
    if doc and docType != "3" and filter(lambda x: x not in string.digits, doc):
        # Si tiene letras se blanquea el DNI para evitar errores, excepto que sea
        # docType="3" (Pasaporte)
        doc, docType = " ", " "
    if not doc.strip():
        docType = " "

    if ivaType != "C" and (not doc or docType != "C" ):
        raise ValidationError("Error, si el tipo de IVA del cliente NO es consumidor final, "
            "debe ingresar su número de CUIT.")

parameters = [self._formatText(name, 'customerName'),

doc or " ",

ivaType, # Iva Comprador

docType or " ", # Tipo de Doc.

address or " ",

]

if self.model in ["715v1", "715v2", "320"]:

parameters.append(self._formatText(address, 'custAddressSize') or " ") # Domicilio

    parameters = [self._formatText(name, 'customerName'),
                  doc or " ",
                  ivaType,   # Iva Comprador
                  docType or " ", # Tipo de Doc.
                  self._formatText(address,'custAddressSize') or " ", #Domicilio
                  ]
    return self._sendCommand(self.CMD_SET_CUSTOMER_DATA, parameters)

`

Saludos
Catriel

Error al iniciar fiscalberry por primera vez:

2018-01-02 09:38:15,453 - FiscalberryApp - INFO - *** Websocket Server Started as HTTP at 127.0.1.1 port 12000***

2018-01-02 09:38:24,664 - FiscalberryApp - INFO - new connection


2018-01-02 09:38:32,857 - FiscalberryApp - INFO - ----- - -- - - - ---

2018-01-02 09:38:32,857 - FiscalberryApp - INFO - {"findAvaliablePrinters":""}

2018-01-02 09:38:32,857 - root - INFO - Iniciando procesamiento de json...

{u'findAvaliablePrinters': u''}
2018-01-02 09:38:32,857 - root - INFO - Iniciando la busqueda por nmap

2018-01-02 09:38:32,886 - FiscalberryApp - ERROR - No option 'ip_privada' in section: 'SERVIDOR'- No option 'ip_privada' in section: 'SERVIDOR'

Traceback (most recent call last):

  File "/home/gonzaabel/fiscalberry/FiscalberryApp.py", line 65, in on_message
    response = traductor.json_to_comando(jsonMes)

  File "/home/gonzaabel/fiscalberry/Traductores/TraductoresHandler.py", line 81, in json_to_comando
    self._findAvaliablePrinters()

  File "/home/gonzaabel/fiscalberry/Traductores/TraductoresHandler.py", line 222, in _findAvaliablePrinters

    self.__getPrintersAndWriteConfig()
  File "/home/gonzaabel/fiscalberry/Traductores/TraductoresHandler.py", line 151, in __getPrintersAndWriteConfig

    printerlist = self.__getDeviceData()
  File "/home/gonzaabel/fiscalberry/Traductores/TraductoresHandler.py", line 125, in __getDeviceData
    ipPrivada = self.config.config.get('SERVIDOR', 'ip_privada')

  File "/usr/lib/python2.7/ConfigParser.py", line 618, in get
    raise NoOptionError(option, section)

NoOptionError: No option 'ip_privada' in section: 'SERVIDOR'

Eso pasa al tirar cualquier comando y no deja ejecutar ninguno.
Reiniciando el servidor se arregla, el problema es que no puede leer ese parámetro cuando se supone que esta ya escrito en el config.ini una vez que arrancas fiscalberry por primera vez. (Por eso se arregla al reiniciar).

Nuevas impresoras fiscales

Hola gente, antes que nada, gracias por el esfuerzo. Leyendo encontré que sólo operan con ciertos tipos de impresoras fiscales ¿Están considerando incoporar los nuevos controladores fiscales en el proyecto? ¿Cómo podemos ayudar?

Saludos!

Agregar compatibilidad con Hasar 615

textSizeDict = {
Utilizar estos parametros
"615": {'nonFiscalText': 40,
'customerName': 30,
'custAddressSize': 40,
'paymentDescription': 30,
'fiscalText': 20,
'lineItem': 20,
'lastItemDiscount': 20,
'generalDiscount': 20,
'embarkItem': 108,
'receiptText': 106,
},

Obtener el numero de punto de venta

Hola amigos, es para agregar una mejora, un comando que devuelva el punto de venta que esta configurado en la impresora fiscal, por lo que leí en hasar esta el comando GetInitData ese da el punto de venta.
En Epson enviando el comando 2a Tipo C también se podría obtener el punto de venta.
Yo todavía no tuve tiempo de analizar el código del fiscalberry, pero si puedo agregar esto se los paso.

Es importante lo del punto de venta para guardar el numero completo del ticket Ej.: FA-0001-000001234

Saludos
Catriel

Bloqueo con https

Hola, ya tengo todo funcionando, de forma local no tengo ningún problema. Pero al pasar todo el sistema a mi servidor el cual funciona bajo https, el navegador bloquea el uso del ws://, la solución para evitar ese bloqueo fue cambiarla a wss://, pero el problema ahora es que no se establece una conexión con el servidor de fiscalberry.
Alguna recomendación ya que no tengo mucha experiencia en python.

No logro que la impresora Epson U220AFII imprima

Hola!
Primero felicitarte y agradecerte por el trabajo que hiciste, es muy completo.
Tengo todo instalado en un raspberry pi 3. El servidor funciona y si lo configuro para imprimir a un archivo veo los comandos.
Pero cuando utilizando por nombre de impresora la que tengo configurada hacia la Epson, me da el error "Inappropriate ioctl for device".
La impresora la probé en windows y funciona OK.
Desde un equipo mando por websocket el json y en el raspberry veo este error que te pego:

Te agradesco tu ayuda, probe de todo pero no logro encontrarle la vuelta.
Saludos!
Configuracion
[IMPRESORA_FISCAL]
marca = Epson
modelo = tickeadoras
path = /dev/usb/lp0
driver = Epson

Error completo:
"ERROR:root:SerialException("Could not configure port: (25, 'Inappropriate ioctl for device')",)- Could not configure port: (25, 'Inappropriate ioctl for device')
Traceback (most recent call last):
File "/home/pi/Downloads/fiscalberry-server-rc/FiscalberryApp.py", line 59, in on_message
response = traductor.json_to_comando(jsonMes)
File "/home/pi/Downloads/fiscalberry-server-rc/Traductores/TraductoresHandler.py", line 60, in json_to_comando
traductor = self.__init_printer_traductor(printerName)
File "/home/pi/Downloads/fiscalberry-server-rc/Traductores/TraductoresHandler.py", line 180, in __init_printer_traductor
comando = comandoClass(**dictSectionConf)
File "/home/pi/Downloads/fiscalberry-server-rc/ComandoInterface.py", line 144, in init
self.conector = ConectorDriverComando(self, driver, **kwargs)
File "/home/pi/Downloads/fiscalberry-server-rc/ConectorDriverComando.py", line 23, in init
self.driver = driverClass(**kwargs)
File "/home/pi/Downloads/fiscalberry-server-rc/Drivers/FiscalPrinterDriver.py", line 53, in init
self._serialPort = serial.Serial(port=path, timeout=None, baudrate=speed)
File "/usr/lib/python2.7/dist-packages/serial/serialutil.py", line 236, in init
self.open()
File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 272, in open
self._reconfigure_port(force_update=True)
File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 315, in _reconfigure_port
raise SerialException("Could not configure port: {}".format(msg))
SerialException: Could not configure port: (25, 'Inappropriate ioctl for device')"

AttributeError: EpsonComandos instance has no attribute 'traductor'

Estoy probando desde una pc con windows, este es mi CONFIG.INI, solo falla al cofigurar marca y driver con Epson. Con Hasar funciona OK

CONFIG.INI

[SERVIDOR]
puerto = 12000

[IMPRESORA_FISCAL]
marca = Epson
modelo = tm-220-af
path = COM2
driver = Epson

[IMPRESORA_RED]
marca = EscP
host = 127.0.0.1
driver = ReceiptDirectJet

Salida de consola:

C:\Python27\python.exe C:/xampp/htdocs/dolibarr35/htdocs/fiscalprinter/fiscalberry-master/server.py
inicializando ConectorDriverComando driver de Epson
Traceback (most recent call last):
File "C:/xampp/htdocs/dolibarr35/htdocs/fiscalprinter/fiscalberry-master/server.py", line 37, in
traductor = TraductoresHandler()
File "C:\xampp\htdocs\dolibarr35\htdocs\fiscalprinter\fiscalberry-master\Traductores\TraductoresHandler.py", line 83, in init
self.__init_cola_traductores_printer()
File "C:\xampp\htdocs\dolibarr35\htdocs\fiscalprinter\fiscalberry-master\Traductores\TraductoresHandler.py", line 160, in __init_cola_traductores_printer
self.init_printer_traductor(s)
File "C:\xampp\htdocs\dolibarr35\htdocs\fiscalprinter\fiscalberry-master\Traductores\TraductoresHandler.py", line 145, in init_printer_traductor
traductorComando = comando.traductor
AttributeError: EpsonComandos instance has no attribute 'traductor'

[feat] fiscalberry -> fiscalbox evolucionar a caja de hardware

Llevar el fiscalberry a un producto de la talla del https://www.odoo.com/page/point-of-sale-hardware#part_3 POSBOX una caja ARM que centraliza el hardware (impresoras) y envia las ordenes.. ya que el punto de venta de ambos proyectos no es desktop sino web

Esto PODRA LEVAR EL PAXAPOS A USARSE SIN PC SINO EN LAS TABLETS/PHONES QUE SON EL FUTURO DE LA CLIENTELA, menos cables menos complicado, mas vendible, menos espacio y equipos que perturben el ambiente del negocio especialmente si es restorante.

¿Qué es -PosBox- FISCALBOX?

PosBox es un dispositivo pequeño que le permite usar los mismos periféricos USB POS estándar de la industria en todos los dispositivos (PC, Mac, Linux, iOS, Android).

Permitira que el cliente y el negocio pueda usar el Paxapos en la tablet, en un dispositivo mas independiente de un pc con un apache corriendo, sino que en todo el negocio se corre una sola solucion empresarial unica con servidor unico, menos costes y mas dinero en soporte. (Esto hace que mas clientes se sumen por su simplicidad y bajo costes en infraestructrura)

Esto implica:

  1. los drivers no pueden tener el nombre de la impresora simplemente, esto complica el desarrollo, ya que cada pais tiene su propio kit, incluso puede haber dos empresas distintas con la misma impresora en el mismo pais
  2. lamentablemtne hay que hablar con los proveedores, en el caso de dominicana es especial, porque el proveedor del kit no es de dominicana, es argrentino y es la propia epson, se adjunta el pdf con las especificaciones a bajo nivel
  3. SE TIENE QUE TENER WIFI/BLUETOOT EN EL FISCALBERRY, ademas se tiene que tener un terminal wifi/bluetooh en cada terminal dispositivo, ejemplo un escaner debe tener un conector wifi/bluetooh que se empalme con el fiscalberry.

...estoy realmente decidido a implementar esto porque solos no podemos, juntos si de eso se trata el software de contribucion..

Esto seria despues de los issues #46 y #45 porque necesito progresar para contruir el dipositivo WiFI terminal, que conjuntos y otros mas llevarian a fiscal berry a una caja de impresion completa ERP una vez que se tenga comunicacion con el kit se puede hablar de implementacion de los hardware.

cuando se ejecuta como daemond no encuentra el config.ini.install

el problema esta en la linea 48 del Configberry.py

porque cuando el server.py es ejecutado desde un path distinto (ejemlo cuando es daemond que se eecuta desde el init.d/ o cuando lo quise convertir a ejecutable mediante pyinstaller, es necesario implementar otra logica de lectura para esa variable de path

def __create_config_if_not_exists(self):
		if not os.path.isfile(CONFIG_FILE_NAME):
			savedPath = os.getcwd()
			newpath = os.path.dirname(os.path.realpath(__file__))
			os.chdir(newpath)
			os.chdir("../")
			import shutil
			shutil.copy ("config.ini.install", CONFIG_FILE_NAME)
			os.chdir(savedPath)

Descuentos en items de facturas

Hola amigos, lo que no veo en la documentacion es como informar un descuento en los Items de las facturas.

Saludos
Catriel

itemNegative falla en P-441F

Estimados

Quería consultarles si existe algún bug conocido al enviar items negativos en la impresora fiscal Hasar P-441F.

El comportamiento observado, es que comienza la impresión, imprime los items normales y corta la impresión al llegar al item negativo dejando inconcluso el ticket.

Luego de eso, no imprime nada más, hasta mandar un Cierre X, el cual anula la impresión del ticket y vuelve a funcionar la impresora.

Según pudimos ver, es siempre que se le manda un item con la siguiente configuración...

{
  "alic_iva" : 21,
  "importe" : 10.00,
  "ds" : "Descuento",
  "qty" : 1,
  "itemNegative" : true
}

¿Alguna idea de que podría estar causando la falla?.

Muchas gracias por la asistencia.

Saludos!

Se cuelga el servicio ante situaciones de error

Cuando por algun motivo hay error (la impresor no responde, se desconecto, el comando es incorrecto, o lo que fuera) tira el error en el servidor y el servicio deja de responder; para que continue hay que cerrarlo y volver a ejecutar el server.py.
Hay posibilidad de que retorne el error y luego continue esperando comandos?

Saludos!

Evento Fiscalberry

eventomeetup

Hola, soy integrante del equipo de desarrollo de PaxaPos y quiero invitarlos a participar en una charla de programadores sobre el proyecto Fiscalberry.
Sera este jueves 22 de febrero a las 19:00 PM de Argentina (-03GMT) mediante la plataforma Google Hangouts (para poder participar en la charla no es necesario tener altos conocimientos de programación).
Los temas que se van tratar son relacionados al proyecto Open Source de Fiscalberry los cuales serán:

  1. Presentarnos
  2. Compartir conocimientos entre todos y la experiencia de cada uno.
  3. Organizar el proyecto y priorizar tareas de desarrollo entre todos
  4. Inclusión de todas las personas que quieran participar en este proyecto
  5. Mini-tutorial sobre como comenzar a desarrollar un driver o comando para fiscalberry. Conceptos básicos de la arquitectura.

Si quieres asistir o te interesa la propuesta podrás marcar la opción deseada en nuestro evento en Facebook: https://www.facebook.com/events/1580220802025689/
Atte.
Equipo de desarrollo PaxaPos.

bug comandera no imprime pedidos

2018-05-08 13:21:58,569 - FiscalberryApp - INFO - ----- - -- - - - ---
2018-05-08 13:21:58,570 - FiscalberryApp - INFO - {"printPedido":{"items":[{"ds":"FANTA","qty":"5","unidad_de_medida":"Planta","importe":"1","observacion":"TEST DE GONZA PAXAPOS"}]},"printerName":"barra"}
2018-05-08 13:21:58,570 - root - INFO - Iniciando procesamiento de json...
{u'printPedido': {u'items': [{u'observacion': u'TEST DE GONZA PAXAPOS', u'unidad_de_medida': u'Planta', u'importe': u'1', u'ds': u'FANTA', u'qty': u'5'}]}, u'printerName': u'barra'}
inicializando ConectorDriverComando driver de ReceiptDirectJet
<class 'Drivers.ReceiptDirectJetDriver.ReceiptDirectJetDriver'>
()
{'mac': '00:0E:C3:20:20:BF', 'vendor': 'Logic Controls', 'host': '192.168.1.124'}
2018-05-08 13:21:58,647 - FiscalberryApp - ERROR - Error parseando el JSON init() got an unexpected keyword argument 'vendor'
Traceback (most recent call last):
File "/home/gonza/fiscalberry/FiscalberryApp.py", line 69, in on_message
response = traductor.json_to_comando(jsonMes)
File "/home/gonza/fiscalberry/Traductores/TraductoresHandler.py", line 60, in json_to_comando
traductor = self.__init_printer_traductor(printerName)
File "/home/gonza/fiscalberry/Traductores/TraductoresHandler.py", line 191, in __init_printer_traductor
comando = comandoClass(**dictSectionConf)
File "/home/gonza/fiscalberry/ComandoInterface.py", line 144, in init
self.conector = ConectorDriverComando(self, driver, **kwargs)
File "/home/gonza/fiscalberry/ConectorDriverComando.py", line 27, in init
self.driver = driverClass(**kwargs)
File "/home/gonza/fiscalberry/Drivers/ReceiptDirectJetDriver.py", line 24, in init
escpos.Escpos.init(self, *args, **kwargs)
TypeError: init() got an unexpected keyword argument 'vendor'
Exception AttributeError: "'NoneType' object has no attribute 'shutdown'" in <bound method ReceiptDirectJetDriver.del of <Drivers.ReceiptDirectJetDriver.ReceiptDirectJetDriver object at 0x7fed726d1a90>> ignored

Problemas c/windows

Pruebas realizada con Windows 10 x64. Python 2.7.13

Este el es el error de la consola:

C:\Python27\python.exe C:/fiscalberry/server.py
Traceback (most recent call last):
File "C:/fiscalberry/server.py", line 5, in
from FiscalberryApp import FiscalberryApp
File "C:\fiscalberry\FiscalberryApp.py", line 18, in
from signal import signal, SIGPIPE, SIG_DFL, SIGTERM, SIGINT
ImportError: cannot import name SIGPIPE

Process finished with exit code 1

Saludos
Catriel

[feat] evolucion: driver basic para kit fiscal de venezuela

Llevar el fiscalberry a un producto de la talla del https://www.odoo.com/page/point-of-sale-hardware#part_3 POSBOX una caja ARM que centraliza el hardware (impresoras) y envia las ordenes.. ya que el piunto de venta de ambos proyectos no es desktop sino web

En este capitulo es implementar un driver fiscalberry/Drivers/EpsonDriver.py que domine el kit fiscal de Venezuela, esto implica algunas cosas que llevan a la evolucion:

  1. los drivers no pueden tener el nombre de la impresora simplemente, esto complica el desarrollo, ya que cada pais tiene su propio kit, en el caso de Venezuela para Epson hay un solo proveedor el cual ya toda comunicacion yo la se, pero no podemos meter todo el codigo en un solo archivo que domine todas las Epson,
  2. ademas el kit de las Epson de Vnzla es particular porque rescata las facturas y es capaz de prosegir y guardar las transacciones, es practicamente un minipos, no siendo asi para las Bixolon/Samsung pero para estas no hay implementacion en linux, lo que acorta su implementacion en el fiscalberry, se tiene pendiente un manual de bajo nivel
  3. el lenguaje es python, un tanto dificil de aprender (de aprender avanzado para trabajar con hardware, muy distinto a la curva de avance de BASIC y GAMBAS) se requiere mas informacion especifica de como hacer esto con hardware en python para no perder tiempo en el avance, ya que todos nostros tenemos tambien trabjao y vidas que atender..

estoy realmente decidido a implementar esto porque solos no podemos, juntos si de eso se trata el software de contribucion..

Ya yo he hablado con los proveedores de Epson en este caso, y ya se comunicarme, para saber el estado por ejemplo es 0x02+0x5F+0x03 (comando "_" de estatus) y devuekve un string simple de impelmentar.

Se uso un programa el stc https://www.teuniz.net/serial-com-tester/index.html ya se tienen los principales comandos y como se envian, en el programa es ma simple, se enviaba es 025f03 muy simple, sin embargo sin saber nada de python avanzado (veo que se programo orientado objetos) la curva de implementacion sera muy lenta..

Procesar respuesta del cierre fiscal

{'CerrarJornadaFiscal': {'Reporte': 'ReporteZ'}}
INICIANDO::::
<Response [200]>
{u'CerrarJornadaFiscal': {u'DNFH_CantidadEmitidos': u'0', u'NC_TotalTributos': u'0.00', u'Fecha': u'180219', u'NC_TotalGravado': u'0.00', u'NC_TotalIVA': u'0.00', u'DF_TotalGravado': u'0.00', u'NC_Total': u'0.00', u'Secuencia': u'16', u'Numero': u'3', u'Estado': {u'Fiscal': [u'MemoriaFiscalInicializada'], u'Impresora': []}, u'DF_TotalExento': u'0.00', u'NC_TotalNoGravado': u'0.00', u'DF_CantidadEmitidos': u'1', u'DF_TotalNoGravado': u'0.00', u'DF_CantidadCancelados': u'1', u'Reporte': u'ReporteZ', u'DF_Total': u'0.00', u'NC_CantidadEmitidos': u'0', u'DF_TotalIVA': u'0.00', u'NC_CantidadCancelados': u'0', u'DNFH_Total': u'0.00', u'DF_TotalTributos': u'0.00', u'NC_TotalExento': u'0.00'}}
{
        "CerrarJornadaFiscal":
        {
                "Secuencia": "16",
                "Estado":
                {
                        "Impresora":
                        [
                        ],
                        "Fiscal":
                        [
                                "MemoriaFiscalInicializada"
                        ]
                },
                "Reporte": "ReporteZ",
                "Numero": "3",
                "Fecha": "180219",
                "DF_Total": "0.00",
                "DF_TotalGravado": "0.00",
                "DF_TotalNoGravado": "0.00",
                "DF_TotalExento": "0.00",
                "DF_TotalIVA": "0.00",
                "DF_TotalTributos": "0.00",
                "DF_CantidadEmitidos": "1",
                "DF_CantidadCancelados": "1",
                "NC_Total": "0.00",
                "NC_TotalGravado": "0.00",
                "NC_TotalNoGravado": "0.00",
                "NC_TotalExento": "0.00",
                "NC_TotalIVA": "0.00",
                "NC_TotalTributos": "0.00",
                "NC_CantidadEmitidos": "0",
                "NC_CantidadCancelados": "0",
                "DNFH_Total": "0.00",
                "DNFH_CantidadEmitidos": "0"
        }
}
salio la respuesta

Problemas con codepage, no funciona

2018-05-08 13:44:02,920 - root - INFO - Iniciando procesamiento de json...
{u'printPedido': {u'encabezado': {u'pedido_recepcionado': False, u'telefono': u'-', u'nombre_proveedor': u'BEBIDAS DEL MAR', u'cuit': u'20407214634'}, u'items': [{u'observacion': u'', u'unidad_de_medida': u'Kilo', u'importe': u'', u'ds': u'yogur', u'qty': u'3.00'}, {u'observacion': u'', u'unidad_de_medida': u'Bolsa', u'importe': u'', u'ds': u'mirinda', u'qty': u'2.00'}]}, u'printerName': u'barra'}
inicializando ConectorDriverComando driver de ReceiptDirectJet
<class 'Drivers.ReceiptDirectJetDriver.ReceiptDirectJetDriver'>
()
{'codepage': 'cp858', 'vendor': 'zaraza', 'host': '192.168.1.124'}
2018-05-08 13:44:02,976 - FiscalberryApp - ERROR - UnicodeDecodeError('ascii', 'Nueva \xc3\xb3rden de compra \n', 6, 7, 'ordinal not in range(128)')- 'ascii' codec can't decode byte 0xc3 in position 6: ordinal not in range(128)
Traceback (most recent call last):
File "/home/gonza/fiscalberry/FiscalberryApp.py", line 69, in on_message
response = traductor.json_to_comando(jsonMes)
File "/home/gonza/fiscalberry/Traductores/TraductoresHandler.py", line 65, in json_to_comando
rta["rta"] = traductor.run(jsonTicket)
File "/home/gonza/fiscalberry/Traductores/TraductorInterface.py", line 19, in run
res = fnAction(**jsonTicket[action])
File "/home/gonza/fiscalberry/Traductores/TraductorReceipt.py", line 11, in printPedido
return self.comando.printPedido(**kwargs)
File "/home/gonza/fiscalberry/Comandos/EscPComandos.py", line 64, in printPedido
printer.text("Nueva órden de compra \n")
File "/usr/local/lib/python2.7/dist-packages/escpos/escpos.py", line 435, in text
self._raw(txt.encode(self.codepage))
File "/usr/lib/python2.7/encodings/cp858.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 6: ordinal not in range(128)
Exception socket.error: error(9, 'Bad file descriptor') in <bound method ReceiptDirectJetDriver.del of <Drivers.ReceiptDirectJetDriver.ReceiptDirectJetDriver object at 0x7f7f3af54ad0>> ignored

Errores de parametros en metodos al usar el driver File

{'path': '/tmp/respuestasComandera.txt'}
2018-01-06 12:52:51,747 - FiscalberryApp - ERROR - Error parseando el JSON set() takes exactly 1 argument (6 given)
Traceback (most recent call last):
  File "/home/gonzaabel/fiscalberry/FiscalberryApp.py", line 65, in on_message
    response = traductor.json_to_comando(jsonMes)
  File "/home/gonzaabel/fiscalberry/Traductores/TraductoresHandler.py", line 64, in json_to_comando
    rta["rta"] = traductor.run(jsonTicket)
  File "/home/gonzaabel/fiscalberry/Traductores/TraductorInterface.py", line 20, in run
    res = fnAction(**jsonTicket[action])
  File "/home/gonzaabel/fiscalberry/Traductores/TraductorReceipt.py", line 7, in printRemito
    return self.comando.printRemito(**kwargs)
  File "/home/gonzaabel/fiscalberry/Comandos/EscPComandos.py", line 62, in printRemito
    printer.set("CENTER", "A", "A", 1, 1)
TypeError: set() takes exactly 1 argument (6 given)

Tira errores de ese estilo, problemas con parámetros de los métodos, o en algunos casos, métodos indefinidos que el driver no posee, por ejemplo: el método cut().

Agregar en la pagina HTML posibilidad de modificar el config.ini facilmente

Actualmente ya existe una forma de cambiar los parametros del config.ini mediante un comando JSON.,

En esta ocasion, la idea es que se pueda visualizar facilmente la configuracion actual y por medio de inputs que se pueda ir modificando facilemente. Tambien se deberia poder agregar nuevas impresoras de manera simple.

Device disconnected or multiple access on port?

Buenas, nos ocurre lo siguiente aleatoriamente que el port de la impresora queda en estado desconectado o que de esta intentando acceder en forma simultánea y no lo podemos controlar lo que nos genera problemas.

He visto en algunos foros de PySerial, pero hacian referencia a un bug en una versión antigua de Kernel de Linux.

Lo tengo funcionando sobre Linux Ubuntu 16.04 x64 y parece que ante un problema con un mensaje enviado a imprimir, no se recupera y lo deja en modo "ocupado" por sobre una Epson TM-U220 conectada por el cable RJ-45 a DB3 + adaptador Manhatan de DB9 a USB para llegar al Linux y usarlo como /Dev/ttyUSB[x]

return_value = printer.getLastNumber("A")
File "/usr/local/lib/python2.7/dist-packages/pyfiscalprinter/epsonFiscal.py", line 361, in getLastNumber
reply = self._sendCommand(self.CMD_STATUS_REQUEST, ["A"], True)
File "/usr/local/lib/python2.7/dist-packages/pyfiscalprinter/epsonFiscal.py", line 108, in _sendCommand
return self.driver.sendCommand(commandNumber, parameters, skipStatusErrors)
File "/usr/local/lib/python2.7/dist-packages/pyfiscalprinter/epsonFiscalDriver.py", line 112, in sendCommand
reply = self._sendMessage( message )
File "/usr/local/lib/python2.7/dist-packages/pyfiscalprinter/epsonFiscalDriver.py", line 166, in _sendMessage
c = self._read(1)
File "/usr/local/lib/python2.7/dist-packages/pyfiscalprinter/epsonFiscalDriver.py", line 85, in _read
ret = self._serialPort.read( count )
File "/usr/local/lib/python2.7/dist-packages/pyserial-3.4-py2.7.egg/serial/serialposix.py", line 501, in read
'device reports readiness to read but returned no data '
SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

Gracias (totales)
Jose Luis Bossio

en EPSON TM-220 no funciona la NCB

[ERR] ComandoException('Error de la impresora fiscal: Campo de datos no v\xc3\xa1lido',)- Error de la impresora fiscal: Campo de datos no válido

al enviar
´´´json
{
"printTicket": {
"encabezado": {
"tipo_cbte": "NCB",
"referencia": "001000000025"
},
"items": [{
"alic_iva": 21.0,
"importe": 0.01,
"ds": "PEPSI",
"qty": 1.0
}, {
"alic_iva": 21.0,
"importe": 0.12,
"ds": "COCA",
"qty": 2.0
}]
},
"printerName": "IMPRESORA_FISCAL"
}
´´´

error puerto abierto

Buenas @alevilar
Con js_browser_client, al actualizar la página intentan conectarse de nuevo al ws y da este error.

Reading config file: config.ini
Impresora disponible:
  - IMPRESORA_FISCAL
      marca: Epson, modelo: tm-220-af (COM1)
*** Websocket Server Started at 169.254.18.61 port 8080***
new connection
Iniciando procesamiento de json...
esto es lo que estoy viendo
{u'getStatus': {}}
connection closed
ERROR:tornado.application:Uncaught exception
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\tornado\http1connection.py", line 238, in _read_message
    delegate.finish()
  File "C:\Python27\lib\site-packages\tornado\httpserver.py", line 289, in finish
    self.delegate.finish()
  File "C:\Python27\lib\site-packages\tornado\web.py", line 2022, in finish
    self.execute()
  File "C:\Python27\lib\site-packages\tornado\web.py", line 2042, in execute
    **self.handler_kwargs)
  File "e:\fiscalberry-master/server.py", line 35, in __init__
    self.traductor = Traductor('IMPRESORA_FISCAL')
  File "e:\fiscalberry-master\Traductor.py", line 74, in __init__
    self.comando = EpsonComandos(deviceFile, driverName=driverName)
  File "e:\fiscalberry-master\Comandos\EpsonComandos.py", line 59, in __init__
    self.conector = ConectorDriverComando(self, driverName, deviceFile, speed)
  File "e:\fiscalberry-master\ConectorDriverComando.py", line 36, in __init__
    raise ConectorError("Imposible establecer comunicación.", e)
ConectorError: ('Imposible establecer comunicaci\xc3\xb3n.', SerialException("could not open port 'COM1': WindowsError(5, 'Acceso denegado.')",))
pyProc.stderr: ERROR:tornado.application:Uncaught exception
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\tornado\http1connection.py", line 238, in _read_message
    delegate.finish()
  File "C:\Python27\lib\site-packages\tornado\httpserver.py", line 289, in finish
    self.delegate.finish()
  File "C:\Python27\lib\site-packages\tornado\web.py", line 2022, in finish
    self.execute()
  File "C:\Python27\lib\site-packages\tornado\web.py", line 2042, in execute
    **self.handler_kwargs)
  File "e:\fiscalberry-master/server.py", line 35, in __init__
    self.traductor = Traductor('IMPRESORA_FISCAL')
  File "e:\fiscalberry-master\Traductor.py", line 74, in __init__
    self.comando = EpsonComandos(deviceFile, driverName=driverName)
  File "e:\fiscalberry-master\Comandos\EpsonComandos.py", line 59, in __init__
    self.conector = ConectorDriverComando(self, driverName, deviceFile, speed)
  File "e:\fiscalberry-master\ConectorDriverComando.py", line 36, in __init__
    raise ConectorError("Imposible establecer comunicación.", e)
ConectorError: ('Imposible establecer comunicaci\xc3\xb3n.', SerialException("could not open port 'COM1': WindowsError(5, 'Acceso denegado.')",))

Hasar 615 campo direccion

Despues del https://github.com/paxapos/fiscalberry/issues/19
Ahora pasa algo mal con el modelo 615 el error esta en la direccion.
Con la 715v1 y 715v2 sale OK

Paso salida de consola.
ComandoException: Error de la impresora fiscal: Campo de datos no válido.
Comando enviado: SEND|0x62|F|['Loco Computacion SRL', '30709211101', 'C', 'C', u'Av. Mitre 1111']

Sale con esa "u"

En RaspberryPi 3 no veo /dev/ttyUSB, solo /dev/usb/pl0 pero no funciona

Hola! perdona que insista, En RaspberryPi 3 no veo /dev/ttyUSB, solo /dev/usb/pl0 pero no funciona.... estoy conectandola con un cable USB al RPi3 y mini USB a una Epson 220 AFII.
Funciona por el puerto USB de la impresora o es por medio de la entrada Serial de la impresora si o si?

Gracias y saludos!!

Auto detectar impresoras

Agregar comando en JSON que inicie la deteccion automatica de las impresoras en red (comanderas compatibles).

El resultado debera ser un listado de imrpesoras, con su mac, IP y el nombre del fabricante (vendor):

Probar con libreria python-nmap.

Filtrar por MACADDRESS,

  • Bematech comienzan con: "00:07:25"
  • Star comienzan con: "00:11:62"

Driver fiscal Samsung?

Buenas, quería consultar si existe documentación en algún sitio para conocer el listado de drivers completo para configurar en el archivo config.ini.

En particular, estoy buscando si existe el driver para conectar con el modelo de impresora fiscal Samsung SRP-270F. En teoría me dijeron que es igual al driver para Epson TM U220 AF (Que tampoco conozco si esta soportado).

¿Podrían indicarme a dónde buscar esta info?.

Gracias!

Problemas con metodo getAvaliablePrinters

No lista las impresoras.
OS: Windows 10
Python: 2.7.13

A la impresora llega bien el comando 0x2A

Copio el config.ini
`[SERVIDOR]
puerto = 12000

[IMPRESORA_FISCAL]
marca = Hasar
modelo = 615
path = COM2
driver = Hasar

[IMPRESORA_RED]
marca = EscP
host = 127.0.0.1
driver = ReceiptDirectJet`

Respuesta desde la consola:
`C:\fiscalberry>python server.py
inicializando ConectorDriverComando driver de Hasar
inicializando ConectorDriverComando driver de ReceiptDirectJet
Iniciando Fiscalberry Server
iniciando en modo HTTP
Hay 2 impresoras disponibles

  • IMPRESORA_FISCAL
    marca: Hasar, driver: Hasar
  • IMPRESORA_RED
    marca: EscP, driver: ReceiptDirectJet

*** Websocket Server Started at 192.168.56.1 port 12000***
new connection
connection closed
new connection


{"getAvaliablePrinters":""}
{u'getAvaliablePrinters': u''}
Traceback (most recent call last):
File "C:\fiscalberry\FiscalBerryStarter.py", line 41, in on_message
response = traductor.json_to_comando( jsonMes )
File "C:\fiscalberry\Traductores\TraductoresHandler.py", line 116, in json_to_comando
rta["rta"] = self._getAvaliablePrinters()
File "C:\fiscalberry\Traductores\TraductoresHandler.py", line 276, in _getAvaliablePrinters
self.__getPrintersAndWriteConfig()
File "C:\fiscalberry\Traductores\TraductoresHandler.py", line 189, in __getPrintersAndWriteConfig
printer = self.__getDeviceData(macs)
File "C:\fiscalberry\Traductores\TraductoresHandler.py", line 151, in __getDeviceData
nm = nmap.PortScanner()
AttributeError: 'module' object has no attribute 'PortScanner'
`

Saludos
Catriel

Les funciona con Notas de Credito ?

Ya en las versiones anteriores tampoco me funciono, y como estaba con otras cosas no le di mucha bola, pero ahora vuelvo a retomar el tema.

Pego la salida de la consola con Impresora Epson LX-300F
_sendCommand 96 ['M', 'C', u'A', '1', 'P', '17', 'E', 'F', 'Carlos Tevez', '', '-', '-', 'N', 'zaraza', '', '', '-', '', 'C']
2017-12-18 19:44:01,930 - root - INFO - sendCommand: SEND|0x60|F|['M', 'C', u'A', '1', 'P', '17', 'E', 'F', 'Carlos Tevez', '', '-', '-', 'N', 'zaraza', '', '', '-', '', 'C']
2017-12-18 19:44:01,930 - root - ERROR - PrinterException: Campo de datos no válido
2017-12-18 19:44:01,930 - FiscalberryApp - ERROR - ComandoException('Error de la impresora fiscal: Campo de datos no v\xc3\xa1lido',)- Error de la impresora fiscal: Campo de datos no válido
Traceback (most recent call last):
File "C:/fiscalberry\FiscalberryApp.py", line 69, in on_message
response = traductor.json_to_comando(jsonMes)
File "C:/fiscalberry\Traductores\TraductoresHandler.py", line 64, in json_to_comando
rta["rta"] = traductor.run(jsonTicket)
File "C:/fiscalberry\Traductores\TraductorInterface.py", line 20, in run
res = fnAction(**jsonTicket[action])
File "C:/fiscalberry\Traductores\TraductorFiscal.py", line 47, in printTicket
self._abrirComprobante(**encabezado)
File "C:/fiscalberry\Traductores\TraductorFiscal.py", line 110, in _abrirComprobante
pos_fiscal, referencia)
File "C:/fiscalberry\Comandos\EpsonComandos.py", line 112, in openBillCreditTicket
return self._openBillCreditTicket(type, name, address, doc, docType, ivaType, isCreditNote=True)
File "C:/fiscalberry\Comandos\EpsonComandos.py", line 179, in _openBillCreditTicket
return self._sendCommand(self.CMD_OPEN_BILL_TICKET, parameters)
File "C:/fiscalberry\Comandos\EpsonComandos.py", line 76, in _sendCommand
raise ComandoException("Error de la impresora fiscal: " + str(e))
ComandoException: Error de la impresora fiscal: Campo de datos no válido


Pego el config.ini
[SERVIDOR]
puerto = 12000
ip_privada = 10.0.0.13

[IMPRESORA_FISCAL]
marca = Epson
modelo = epsonlx300
path = COM2
driver = Epson

[IMPRESORA_RED]
marca = EscP
host = 127.0.0.1
driver = ReceiptDirectJet


Pego salida de Consola con impresora Hasar 715v2

2017-12-18 19:55:31,009 - root - INFO - sendCommand: SEND|0x62|F|['Carlos Tevez', '20407778884', 'I', 'C', 'zaraza']
2017-12-18 19:55:31,009 - root - INFO - reply: ['0080', '0600']
2017-12-18 19:55:31,009 - root - INFO - sendCommand: SEND|0x93|F|['1', '00066778']
2017-12-18 19:55:31,009 - root - INFO - reply: ['0080', '0600']
2017-12-18 19:55:31,009 - root - INFO - sendCommand: SEND|0x80|F|['R', 'T', '00066778']
2017-12-18 19:55:31,026 - root - ERROR - PrinterException: Campo de datos no válido
2017-12-18 19:55:31,026 - FiscalberryApp - ERROR - NameError("global name 'ComandoException' is not defined",)- global name 'ComandoException' is not defined
Traceback (most recent call last):
File "C:/fiscalberry\FiscalberryApp.py", line 69, in on_message
response = traductor.json_to_comando(jsonMes)
File "C:/fiscalberry\Traductores\TraductoresHandler.py", line 64, in json_to_comando
rta["rta"] = traductor.run(jsonTicket)
File "C:/fiscalberry\Traductores\TraductorInterface.py", line 20, in run
res = fnAction(**jsonTicket[action])
File "C:/fiscalberry\Traductores\TraductorFiscal.py", line 47, in printTicket
self._abrirComprobante(**encabezado)
File "C:/fiscalberry\Traductores\TraductorFiscal.py", line 110, in _abrirComprobante
pos_fiscal, referencia)
File "C:/fiscalberry\Comandos\HasarComandos.py", line 272, in openBillCreditTicket
self._sendCommand(self.CMD_OPEN_CREDIT_NOTE, [type, "T", reference])
File "C:/fiscalberry\Comandos\HasarComandos.py", line 144, in _sendCommand
raise ComandoException("Error de la impresora fiscal: %s.\nComando enviado: %s" %
NameError: global name 'ComandoException' is not defined

Consulta Estado

No puedo precisar en que version empezo esto, pero lo que veo es que no llegan mas consulta de estado a la impresora. (si esta sin papel, o tapa abierta).
En versiones anterioes veia que cada minuto aproximandamente habia una consulta de estado.

Saludos
Catriel

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.