Skip to content

Instantly share code, notes, and snippets.

@jenikm
Last active August 29, 2015 14:13
Show Gist options
  • Save jenikm/a6d73fe74d9c1c2bbe5e to your computer and use it in GitHub Desktop.
Save jenikm/a6d73fe74d9c1c2bbe5e to your computer and use it in GitHub Desktop.
Exposes Zebra printer and scale connected via serial port to http port
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Web;
using System.Collections.Specialized;
using ITDM;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Printing;
using Microsoft.Win32.SafeHandles;
using System.Globalization;
namespace HardwareIO
{
class HardwareIO
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern SafeFileHandle CreateFile(string lpFileName, FileAccess dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, FileMode dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile);
public static SerialPort p;
public static SafeFileHandle label_printer;
public static void ConfigureScalePort(String port){
p = new SerialPort(port);
p.ReadBufferSize = 14;
try
{
p.Open();
}
catch (IOException e)
{
AlertAndWrite("Invalid COM port specified. Please use device manager to determine correct COM port. Should be between COM1 - COM4");
return;
}
catch (UnauthorizedAccessException e){
AlertAndWrite("COM PORT '" + port + "' is in use. Make sure that another instance of Scale Server is not running.");
return;
}
}
public static void TestPrinter() {
String label = @"
N
A20,10,0,4,1,2,N,""248964-20130131-1923-ЗАЙЦЕ@S4-5-21""
A610,10,0,4,1,1,N,""2013-07-01""
A720,70,0,5,2,2,N,""P""
X710,60,2,790,180
A20,70,0,2,2,2,N,""Uzlovaya""
A320,115,0,4,2,2,N,""10 of 10""
A600,70,0,4,3,3,N,""*""
A500,10,0,3,2,2,N,""""
A500,70,0,2,2,2,N,""RU""
A20,165,0,4,1,1,N,""170979297210""
B20,115,0,1,2,0,45,N,""669851:N""
A500,165,0,4,1,1,N,""669851:N""
A340,165,0,4,1,1,N,""q1""
P1,1";
//RawPrinterHelper.SendStringToPrinter(@"EPL_2844", label);
PrintLabel(label, "1234", @"\\WIN-QU4U0SFT8SR\EPL_2844", true);
}
//First argument must be a communication port (COM3)
static void Main(string[] args){
//TestPrinter();
if (args.Length == 0) {
String instructions = @"
You ran HarwdareIO without command arguments, you probably don't know what you are doing.
0. Create Shortcut on Desktop to Hardware IO
----INSTRUCTIONS FOR LABLER----
1. Install printer (Ex. EPL2844)
2. Share printer (printer -> printer properties -> sharing)
3. Configure printer. (printer -> printer preferences)
3.1 Item Labels: Width 3, Height: 2
3.2 Custom Commands tab -> Send command:
3.2.1 I8,C,001
3.2.2 q800
3.2.3 D15
5. Configure shortcut
5.1 -printer_port \\computer_name\printer_name
----Scale Server Instructions----
1. Configure scale into mode 1.0 (press AND hold 'm')
2. Figure out COM port (device manager -> com ports)
3. Configure shortcut
3.1 -scale_port COM_NUMBER
";
AlertAndWrite(instructions);
return;
}
ConsoleCmdLine c = new ConsoleCmdLine();
CmdLineString scale_port = new CmdLineString("scale_port", false, "Scale port name.");
CmdLineString printer_port = new CmdLineString("printer_port", false, "Printer port.");
c.RegisterParameter(scale_port);
c.RegisterParameter(printer_port);
c.Parse(args);
bool scale_setup = scale_port.Value.Length > 0;
bool label_printer_setup = printer_port.Value.Length > 0;
if(scale_setup)
ConfigureScalePort(scale_port);
TcpListener tcpListener = new TcpListener(IPAddress.Any, 3000);
try{
tcpListener.Start();
}
catch (SocketException e){
AlertAndWrite("Port 3000 is already in use. Make sure that another instance of Scale Server is not running.");
return;
}
bool send_formatting_command_to_epl = true;
//Listens for incoming connections
while (true){
TcpClient client = tcpListener.AcceptTcpClient();
NetworkStream clientStream = client.GetStream();
byte[] message = new byte[4096];
int bytesRead;
UTF8Encoding encoder = new UTF8Encoding();
bytesRead = 0;
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
String incoming_headers = encoder.GetString(message, 0, bytesRead);
Console.WriteLine(incoming_headers);
String incoming_url_string = ExtractUrlString(incoming_headers);
Console.WriteLine("URL QUERY STRING: " + incoming_url_string);
if (incoming_url_string.Length == 0)
continue;
NameValueCollection parsedUrl = HttpUtility.ParseQueryString(incoming_url_string);
String action = parsedUrl.Get("action");
if (action == null)
continue;
String result = "{}";
Console.WriteLine("ACTION: " + action);
if(action.Equals("read_weight")){
if (scale_setup)
result = ReadWeight();
else
AlertAndWrite("Scale not setup");
}
else if(action.Equals("print_item_label")){
if (label_printer_setup) {
String label = Uri.UnescapeDataString(Uri.UnescapeDataString(parsedUrl.Get("label"))).Replace("+", " ");
String order_item_id = parsedUrl.Get("order_item_id");
result = PrintLabel(label, order_item_id, printer_port, send_formatting_command_to_epl);
send_formatting_command_to_epl = false;
} else {
AlertAndWrite("Printer port not configured");
}
}
String headers = "HTTP/1.0 200 OK\r\n";
headers += "Content-Type: text/javascript;charset=UTF-8\r\n\r\n";
String callback = parsedUrl.Get("callback");
result = headers + callback + "(" + result + ")";
Console.WriteLine(result);
byte[] buffer = encoder.GetBytes(result);
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
clientStream.Close();
client.Close();
}
}
//THINGS TO CONSIDER: I8,c,001 - Make Russian
//q800 - fix margins
//D15 - make dark
public static String PrintLabel(String label, String order_item_id, String port, bool send_formatting_command){
try{
label_printer = CreateFile(port, FileAccess.Write, 0, IntPtr.Zero, FileMode.OpenOrCreate, 0, IntPtr.Zero);
if (label_printer.IsInvalid) {
AlertAndWrite("Printer is Invalid");
}
} catch (Exception ex) {
AlertAndWrite("Error happened configuring printer port: '" + ex.Message + "'");
return "{\"STATUS\": \"FAILURE\"}";
}
try{
if (send_formatting_command) {
label = "q800\nI8,C,001\nD15\n" + label;
}
Console.WriteLine("===========LABEL BEGIN===========");
Console.WriteLine(label);
Console.WriteLine("===========LABEL END===========");
Encoding ANSI = Encoding.GetEncoding(1251);
byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(label);
byte[] ansiBytes = Encoding.Convert(Encoding.UTF8, ANSI, utf8Bytes);
FileStream lpt1 = new FileStream(label_printer, FileAccess.ReadWrite);
lpt1.Write(ansiBytes, 0, ansiBytes.Length);
lpt1.Close();
return "{\"STATUS\": \"SUCCESS\", \"ORDER_ITEM_ID\": \"" + order_item_id + "\"}";
}
catch(Exception ex){
String err = "Error happened configuring printer port: '" + ex.Message + "'";
Console.WriteLine(err);
return "{\"STATUS\": \"FAILURE\"}";
}
}
public static String ReadWeight()
{
p.WriteLine("\r\n");
System.Threading.Thread.Sleep(200);
String data = p.ReadExisting();
if (data.Length != 14){
Console.WriteLine("ERROR");
return "{\"ERROR\": \"There is an error reading scale, please try again\"}";
}
String weight_seg = data.Substring(2, 7);
weight_seg = System.Text.RegularExpressions.Regex.Replace(weight_seg, @"\s+", "");
Console.WriteLine(weight_seg);
float weight = float.Parse(weight_seg);
char c = data[11];
if (c == 'S'){
return "{\"WEIGHT\":" + weight + "}";
}
else{
return "{\"ERROR\": \"Scale is not stable\"}";
}
}
public static void AlertAndWrite(String message){
Console.WriteLine(message);
MessageBox.Show(message);
}
public static String ExtractUrlString(String headers) {
Match m = Regex.Match(headers, @"/(\S+)\s+HTTP");
String val = "";
if (m.Groups.Count == 2)
val = m.Groups[1].Value;
return val;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment