Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Development of Initial CUSTOM Printer Implementation #105

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 49 additions & 23 deletions ESCPOS_NET.ConsoleTest/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,48 @@ namespace ESCPOS_NET.ConsoleTest
internal class Program
{
private static BasePrinter printer;
private static ICommandEmitter e;
private static ICommandEmitter emitter;

static void Main(string[] args)
{

Console.WriteLine("ESCPOS_NET Test Application...");

Console.WriteLine($"{(int)PrinterTypeOption.EPSON} {PrinterTypeOption.EPSON} Printer");
Console.WriteLine($"{(int)PrinterTypeOption.CUSTOM} {PrinterTypeOption.CUSTOM} Printer");
Console.Write("Choice: ");
var response = Console.ReadLine();
var valid = new List<string> { ((int)PrinterTypeOption.EPSON).ToString(), ((int)PrinterTypeOption.CUSTOM).ToString() };
if (!valid.Contains(response))
{
response = ((int)PrinterTypeOption.EPSON).ToString();
}
int choice = int.Parse(response);
switch((PrinterTypeOption)choice)
{
case PrinterTypeOption.EPSON:
emitter = new EPSON();
break;
case PrinterTypeOption.CUSTOM:
emitter = new CUSTOM();
break;
}

Console.WriteLine("1 ) Test Serial Port");
Console.WriteLine("2 ) Test Network Printer");
Console.Write("Choice: ");
string comPort = "";
string baudRate;
string ip;
string networkPort;
var response = Console.ReadLine();
var valid = new List<string> { "1", "2" };
response = Console.ReadLine();
valid = new List<string> { "1", "2" };
if (!valid.Contains(response))
{
response = "1";
}

int choice = int.Parse(response);
choice = int.Parse(response);

if (choice == 1)
{
Expand Down Expand Up @@ -88,7 +109,6 @@ static void Main(string[] args)
monitor = true;
}

e = new EPSON();
var testCases = new Dictionary<Option, string>()
{
{ Option.Printing, "Printing" },
Expand Down Expand Up @@ -134,61 +154,61 @@ static void Main(string[] args)
}
Setup(monitor);

printer?.Write(e.PrintLine($"== [ Start {testCases[enumChoice]} ] =="));
printer?.Write(emitter.PrintLine($"== [ Start {testCases[enumChoice]} ] =="));

switch (enumChoice)
{
case Option.Printing:
printer.Write(Tests.Printing(e));
printer.Write(Tests.Printing(emitter));
break;
case Option.LineSpacing:
printer.Write(Tests.LineSpacing(e));
printer.Write(Tests.LineSpacing(emitter));
break;
case Option.BarcodeStyles:
printer.Write(Tests.BarcodeStyles(e));
printer.Write(Tests.BarcodeStyles(emitter));
break;
case Option.BarcodeTypes:
printer.Write(Tests.BarcodeTypes(e));
printer.Write(Tests.BarcodeTypes(emitter));
break;
case Option.TwoDimensionCodes:
printer.Write(Tests.TwoDimensionCodes(e));
printer.Write(Tests.TwoDimensionCodes(emitter));
break;
case Option.TextStyles:
printer.Write(Tests.TextStyles(e));
printer.Write(Tests.TextStyles(emitter));
break;
case Option.FullReceipt:
printer.Write(Tests.Receipt(e));
printer.Write(Tests.Receipt(emitter));
break;
case Option.Images:
printer.Write(Tests.Images(e, false));
printer.Write(Tests.Images(emitter, false));
break;
case Option.LegacyImages:
printer.Write(Tests.Images(e, true));
printer.Write(Tests.Images(emitter, true));
break;
case Option.LargeByteArrays:
try
{
printer.Write(Tests.TestLargeByteArrays(e));
printer.Write(Tests.TestLargeByteArrays(emitter));
}
catch (Exception e)
{
Console.WriteLine($"Aborting print due to test failure. Exception: {e?.Message}, Stack Trace: {e?.GetBaseException()?.StackTrace}");
}
break;
case Option.CashDrawerPin2:
printer.Write(Tests.CashDrawerOpenPin2(e));
printer.Write(Tests.CashDrawerOpenPin2(emitter));
break;
case Option.CashDrawerPin5:
printer.Write(Tests.CashDrawerOpenPin5(e));
printer.Write(Tests.CashDrawerOpenPin5(emitter));
break;
default:
Console.WriteLine("Invalid entry.");
break;
}

Setup(monitor);
printer?.Write(e.PrintLine($"== [ End {testCases[enumChoice]} ] =="));
printer?.Write(e.PartialCutAfterFeed(5));
printer?.Write(emitter.PrintLine($"== [ End {testCases[enumChoice]} ] =="));
printer?.Write(emitter.PartialCutAfterFeed(5));

// TODO: write a sanitation check.
// TODO: make DPI to inch conversion function
Expand All @@ -199,6 +219,12 @@ static void Main(string[] args)
}
}

public enum PrinterTypeOption
{
EPSON = 1,
CUSTOM = 2,
}

public enum Option
{
Printing = 1,
Expand Down Expand Up @@ -234,11 +260,11 @@ private static void Setup(bool enableStatusBackMonitoring)
printer.StatusChanged += StatusChanged;
_hasEnabledStatusMonitoring = true;
}
printer?.Write(e.Initialize());
printer?.Write(e.Enable());
printer?.Write(emitter.Initialize());
printer?.Write(emitter.Enable());
if (enableStatusBackMonitoring)
{
printer.Write(e.EnableAutomaticStatusBack());
printer.Write(emitter.EnableAutomaticStatusBack());
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions ESCPOS_NET.UnitTest/GlobalTests/Barcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public class Barcode
[InlineData("EPSON", TwoDimensionCodeType.QRCODE_MODEL2)]
[InlineData("EPSON", TwoDimensionCodeType.QRCODE_MICRO)]
[InlineData("EPSON", null)]
[InlineData("CUSTOM", TwoDimensionCodeType.QRCODE_MODEL1)]
[InlineData("CUSTOM", TwoDimensionCodeType.QRCODE_MODEL2)]
[InlineData("CUSTOM", TwoDimensionCodeType.QRCODE_MICRO)]
[InlineData("CUSTOM", null)]
public void PrintQRCode_Success(string emitter, TwoDimensionCodeType? codeType)
{
var type = Assembly.LoadFrom("ESCPOS_NET").GetType($"ESCPOS_NET.Emitters.{emitter}", true);
Expand All @@ -30,6 +34,7 @@ public void PrintQRCode_Success(string emitter, TwoDimensionCodeType? codeType)

[Theory]
[InlineData("EPSON", TwoDimensionCodeType.PDF417)]
[InlineData("CUSTOM", TwoDimensionCodeType.PDF417)]
public void PrintQRCode_Failure(string emitter, TwoDimensionCodeType codeType)
{
var type = Assembly.LoadFrom("ESCPOS_NET").GetType($"ESCPOS_NET.Emitters.{emitter}", true);
Expand Down
10 changes: 10 additions & 0 deletions ESCPOS_NET/Emitters/CUSTOM.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace ESCPOS_NET.Emitters
{
/// <summary>
/// CUSTOM Printer (https://www.custom.biz/) implementation of the ESC \ POS protocol. The majority of the commands are identical. However, a small
/// number of them are unique to the CUSTOM implementation.
/// </summary>
public class CUSTOM : CustomCommandEmitter
{
}
}
61 changes: 61 additions & 0 deletions ESCPOS_NET/Emitters/CustomCommandEmitter/BarcodeCommands.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using ESCPOS_NET.DataValidation;
using ESCPOS_NET.Emitters.BaseCommandValues;
using ESCPOS_NET.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ESCPOS_NET.Emitters
{
public abstract partial class CustomCommandEmitter
{
public override byte[] Print2DCode(TwoDimensionCodeType type, string data, Size2DCode size = Size2DCode.NORMAL, CorrectionLevel2DCode correction = CorrectionLevel2DCode.PERCENT_7)
{
DataValidator.Validate2DCode(type, data);
List<byte> command = new List<byte>();
byte[] initial = { Cmd.GS, Barcodes.Set2DCode, Barcodes.PrintBarcode };
switch (type)
{
case TwoDimensionCodeType.PDF417:
command.AddRange(initial, Barcodes.SetPDF417NumberOfColumns, Barcodes.AutoEnding);
command.AddRange(initial, Barcodes.SetPDF417NumberOfRows, Barcodes.AutoEnding);
command.AddRange(initial, Barcodes.SetPDF417DotSize, (byte)size);
command.AddRange(initial, Barcodes.SetPDF417CorrectionLevel, (byte)correction);

// k = (pL + pH * 256) - 3 --> But pH is always 0.
int k = data.Length;
int l = k + 3;
command.AddRange(initial, (byte)l, Barcodes.StorePDF417Data);
command.AddRange(data.ToCharArray().Select(x => (byte)x));

// Prints stored PDF417
command.AddRange(initial, Barcodes.PrintPDF417);
break;

case TwoDimensionCodeType.QRCODE_MODEL1:
case TwoDimensionCodeType.QRCODE_MODEL2:
case TwoDimensionCodeType.QRCODE_MICRO:
command.AddRange(initial, Barcodes.SelectQRCodeModel, (byte)type, Barcodes.AutoEnding);
command.AddRange(initial, Barcodes.SetQRCodeDotSize, (byte)size);
command.AddRange(initial, Barcodes.SetQRCodeCorrectionLevel, (byte)correction);
int num = data.Length + 3;
int pL = num % 256;
int pH = num / 256;

// NOTE: StoreQRCodeData is using CUSTOM Printer override
command.AddRange(initial, (byte)pL, (byte)pH, CustomCommandValues.Barcodes.StoreQRCodeData);
command.AddRange(data.ToCharArray().Select(x => (byte)x));

// Prints stored QRCode
// NOTE: PrintQRCode is using CUSTOM Printer override
command.AddRange(initial, CustomCommandValues.Barcodes.PrintQRCode);
break;

default:
throw new NotImplementedException($"2D Code '{type}' was not implemented yet.");
}

return command.ToArray();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace ESCPOS_NET.Emitters
{
public abstract partial class CustomCommandEmitter : BaseCommandEmitter
{
}
}
15 changes: 15 additions & 0 deletions ESCPOS_NET/Emitters/CustomCommandValues/Barcodes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace ESCPOS_NET.Emitters.CustomCommandValues
{
public static class Barcodes
{
/// <summary>
/// CUSTOM implements the Store QR Code Data slightly differently than the base implementation
/// </summary>
public static readonly byte[] StoreQRCodeData = { 0x31, 0x50, 0x31 };

/// <summary>
/// CUSTOM implements the Print QR Code slightly differently than the base implementation
/// </summary>
public static readonly byte[] PrintQRCode = { 0x03, 0x00, 0x31, 0x51, 0x31 };
}
}