Зачем мне нужен второй файл для записи на принтер pos в golang, чтобы иметь возможность вывода? - PullRequest
0 голосов
/ 06 июля 2018

У меня есть принтер Epson TM-T88III на компьютере с Linux, подключенный к USB-порту. Все работает относительно хорошо, это распознается, я могу открыть устройство, я могу повторить «Hello World» в командной строке для принтера, и он печатает без проблем.

Однако в golang, когда я открываю устройство с помощью os.OpenFile и записываю некоторые тестовые последовательности в виде байтового слияния или строки, эта последовательность печатается только после того, как я сделаю еще одну запись.

Может кто-нибудь объяснить, если я что-то упустил в том, что мне нужно сделать? Я относительный новичок в Голанге, но я занимаюсь программированием на других языках.


Я открываю с:

f, err := os.OpenFile("/dev/usb/lppos",os.O_RDWR,0755)
if err != nil {
    panic(err)
}
defer f.Close()

Затем я определяю некоторые команды esc и ловлю их в байтовом слое (для этого я использую пакет escpos из panjjo):

p := escposc.New()

p.Init()
p.SetSmooth(1)
p.SetFontSize(2, 3)
p.SetFont("A")
p.Write("test ")
p.SetFont("B")
p.Write("test2 ")
p.Formfeed()

p.SetFont("B")
p.SetFontSize(1, 1)

p.SetEmphasize(1)
p.Write("halle")
p.Formfeed()

p.SetUnderline(1)
p.SetFontSize(4, 4)
p.Write("halle")

p.SetReverse(1)
p.SetFontSize(2, 4)
p.Write("halle")
p.Formfeed()

p.FormfeedN(5)

p.Cut()

_,b:=p.Readbyte()

p.End()

Затем я записываю пойманный фрагмент b на устройство:

n,err:=f.Write(b)
if err != nil {
    panic(err)
}

В этот момент ничего не происходит, и мне потребовалось некоторое время, чтобы выяснить, что если я сделаю последний:

f.WriteString(" ")

Затем все последовательности печатаются как следует со всеми стилями, переводами строки и обрезкой. И все хорошо, но не без этого последнего WriteString. Ах, да, ему нужен пробел или другой символ, запись пустой строки не работает.

Я также пытался написать строку команд вместо байтового среза, но мне нужна та же вторая строка WriteString, иначе она не будет выводиться на бумажный рулон.

Ответы [ 4 ]

0 голосов
/ 12 июля 2018

Я собираюсь ответить на свой вопрос. Последние несколько дней я потратил на написание собственной реализации escpos в Голанге. Я узнал несколько вещей по пути. Главное, что термопринтер сам решит, что буферизовать и как это делать. Это означает, что вам нужно открыть устройство и без буферизации записывать на него команды.

В пакетах golang escpos на github (которые, на мой взгляд, являются неполными) io.Writer используется для потоковой передачи команд. Вместо этого вам нужно использовать * os.File и использовать его метод Write для потоковой передачи команды непосредственно на принтер. Это работает сразу и безупречно на моем термопринтере Epson TM-T88III.

В основном я изменил следующее ядро ​​кода escpos:

type Escpos struct {
    enc *encoding.Encoder
    w   io.Writer
}

func NewEscpos(w io.Writer) *Escpos {
    return &Escpos{
        enc: charmap.CodePage437.NewEncoder(),
        w:   w,
    }
}

func (e *Escpos) write(b []byte) error {
    _, err := e.w.Write(b)
    return err
}

В этот новый код, где я могу открыть устройство и дать указатель на дескриптор файла в качестве параметра ссылки типа Escpos, когда последовательность команд выполнена, я могу закрыть устройство. Между тем он выдает квитанцию ​​и печать, которую я хочу на нем.

type Escpos struct {
    enc *encoding.Encoder
    f   *os.File
}


func NewEscpos(f *os.File) *Escpos {
    return &Escpos{
        enc: charmap.CodePage437.NewEncoder(),
        f:   f,
    }
}

func (e *Escpos) write(b []byte) error {
    _, err := e.f.Write(b)
    return err
}
0 голосов
/ 10 июля 2018

Ваша проблема в том, что вы звоните

p.End()

после

p.Readbyte()

Хотя ты должен сделать это раньше. Я считаю, что ваш принтер рассматривает "" (пробел) как недопустимую команду и автоматически завершает предыдущую последовательность допустимых команд.

0 голосов
/ 10 июля 2018

Похоже, вы захватили фрагмент байта до того, как закончили запись в него.

p.Cut()

_,b:=p.Readbyte()

p.End()

Байт от вызова p.End() никогда не добавляется к вашим выходным данным, поэтому принтер ждет его вечно ...

Как показано в примере , это должно быть вместо:

p.Cut()

p.End()

_,b:=p.Readbyte()
0 голосов
/ 06 июля 2018

Вы должны сделать f.Sync(). Из документов: Sync commits the current contents of the file to stable storage. (https://golang.org/src/os/file_posix.go?s=3352:3379#L11). И после того, как вы закончите использовать устройство, вам, возможно, придется сделать f.Close().

...