package main import ( "fmt" "github.com/kenshaw/escpos" "math" "net/http" "os" "time" ) const ESC = byte(27) func pageWidth(widht int) []byte { return []byte{escpos.GS, 87, byte(widht), 0} } func pageMargin(margin int) []byte { return []byte{escpos.GS, 76, byte(margin), 0} } func pageMode() []byte { return []byte{ESC, 'L'} } func pageDirection(direction uint8) []byte { // https://www.epson-biz.com/modules/ref_escpos/index.php?content_id=55 return []byte{ESC, 'T', direction} } func pagePrintArea(x, y, width, height int) []byte { return []byte{ESC, 'W', byte(x & 255), byte(x >> 8 & 255), byte(y & 255), byte(y >> 8 & 255), byte(width & 255), byte(width >> 8 & 255), byte(height & 255), byte(height >> 8 & 255)} } func offsetY(offset int) []byte { // A positive number specifies movement downward, and a negative number specifies movement upward. // The horizontal or vertical motion unit is used for the print direction set by ESC T. // When the starting position is set to the upper left or lower right of the print area using ESC T, the vertical motion unit is used. // When the starting position is set to the upper right or lower left of the print area using ESC T, the horizontal motion unit is used. return []byte{escpos.GS, '\\', byte(offset & 255), byte(offset >> 8 & 255)} } func offsetX(offset int) []byte { // A positive number specifies movement to the right, and a negative number specifies movement to the left. // When Standard mode is selected, the horizontal motion unit is used. // when Page mode is selected, the horizontal or vertical motion unit is used for the print direction set by ESC T. // When the starting position is set to the upper left or lower right of the print area using ESC T, the horizontal motion unit is used. // When the starting position is set to the upper right or lower left of the print area using ESC T, the vertical motion unit is used. return []byte{ESC, '\\', byte(offset & 255), byte(offset >> 8 & 255)} } func invert(n int) []byte { //When the LSB of n is 0, white/black reverse print mode is turned off. //n = 0 – 255 return []byte{escpos.GS, byte('B'), byte(n)} } func disableSensors() []byte { return []byte{ESC, 'c', '3', 0} } func printSpeed(m int) []byte { // m = 0 – 9, 48 – 57 : slowest - fastest // [Default] 0 = Setting value of GS ( E customize value (a = 6) // m = 0 //Slower print speed seems to retain a bit more quality in dithered images. pure B/W images do not have a noticable difference return []byte{escpos.GS, '(', 'K', 2, 0, 50, byte(m & 255), byte(m >> 8 & 255)} } func main() { f, err := os.OpenFile("/dev/usb/lp0", os.O_WRONLY|os.O_CREATE, 0) if err != nil { panic(err) } defer f.Close() ep := escpos.New(f) ep.Init() http.HandleFunc("/create_dnh_label", func(w http.ResponseWriter, r *http.Request) { createDnhLabelHandler(w, r, ep) }) http.HandleFunc("/create_generic_label", func(w http.ResponseWriter, r *http.Request) { createGenericLabelHandler(w, r, ep) }) http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "index.html") }) fmt.Println("Server starting on port 8080") if err := http.ListenAndServe(":8080", nil); err != nil { panic(err) } } func createDnhLabelHandler(w http.ResponseWriter, r *http.Request, ep *escpos.Escpos) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } name := r.FormValue("name") date := r.FormValue("date") // Check if name is blank if name == "" { http.Error(w, "Name cannot be blank", http.StatusBadRequest) return } // Set date to today if not defined if date == "" { date = time.Now().Format("2006-01-02") } // Here you can add the logic for creating a label using the POST data text := fmt.Sprintf("%s - %s \n", name, date) ep.Init() ep.WriteRaw(pageMode()) ep.WriteRaw(pageDirection(1)) ep.WriteRaw(pagePrintArea(0, 0, int(math.Round((29.0/80.0)*512)), 850)) ep.WriteRaw(offsetY(30)) ep.SetFontSize(1, 1) ep.Write("Technologia Incognita\n") ep.WriteRaw(offsetY(35)) ep.SetFontSize(3, 2) ep.SetEmphasize(1) ep.Write("Do Not Hack\n") ep.SetEmphasize(0) ep.WriteRaw(offsetY(15)) ep.SetFontSize(1, 1) ep.Write(text) ep.WriteRaw([]byte{12}) // FF: in Page mode, prints all the data in the print buffer collectively and switches from Page mode to Standard mode. ep.Cut() ep.End() w.WriteHeader(http.StatusOK) } func createGenericLabelHandler(w http.ResponseWriter, r *http.Request, ep *escpos.Escpos) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } text := r.FormValue("text") // Check if name is blank if text == "" { http.Error(w, "Text cannot be blank", http.StatusBadRequest) return } // Here you can add the logic for creating a label using the POST data ep.Init() ep.WriteRaw(pageMode()) ep.WriteRaw(pageDirection(1)) ep.WriteRaw(pagePrintArea(0, 0, int(math.Round((29.0/80.0)*512)), 850)) ep.WriteRaw(offsetY(30)) ep.SetFontSize(1, 1) ep.Write("Technologia Incognita\n") ep.WriteRaw(offsetY(35)) ep.SetFontSize(1, 2) ep.Write(text) ep.WriteRaw([]byte{12}) // FF: in Page mode, prints all the data in the print buffer collectively and switches from Page mode to Standard mode. ep.Cut() ep.End() w.WriteHeader(http.StatusOK) }