App.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. using Edge.Core.Processor;
  2. using Edge.Core.IndustryStandardInterface.Pump;
  3. using Microsoft.Extensions.DependencyInjection;
  4. using Microsoft.Extensions.Logging;
  5. using MQTTnet;
  6. using MQTTnet.Client;
  7. using MQTTnet.Diagnostics;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Drawing;
  11. using System.Drawing.Printing;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading.Tasks;
  15. namespace XinHua_XPrinter_WindowsPrinter_App
  16. {
  17. public class App : IAppProcessor
  18. {
  19. private ILogger logger = new LoggerFactory().CreateLogger("no exists");
  20. private IMqttClient mqttClient;
  21. private string mqttServerUrl;
  22. private int mqttServerPort;
  23. private string mqttClientId;
  24. private string mqttClientUsername;
  25. private string mqttClientPassword;
  26. private string topic_PrintingRequest;
  27. private string topic_PrintRequestReply;
  28. private string printerName;
  29. private string printingContent;
  30. private bool shouldReconnect = true;
  31. public string MetaConfigName { get; set; }
  32. public App(string mqttServerUrl, int mqttServerPort, string mqttClientId,
  33. string mqttClientUsername, string mqttClientPassword,
  34. string topic_PrintingRequest, string topic_PrintRequestReply, string printerName, IServiceProvider services)
  35. {
  36. if (services != null)
  37. {
  38. var loggerFactory = services.GetRequiredService<ILoggerFactory>();
  39. this.logger = loggerFactory.CreateLogger("Application");
  40. }
  41. this.mqttServerUrl = mqttServerUrl;
  42. this.mqttServerPort = mqttServerPort;
  43. this.mqttClientId = mqttClientId;
  44. this.mqttClientUsername = mqttClientUsername;
  45. this.mqttClientPassword = mqttClientPassword;
  46. this.topic_PrintingRequest = topic_PrintingRequest;
  47. this.topic_PrintRequestReply = topic_PrintRequestReply;
  48. this.printerName = printerName;
  49. }
  50. public async void Init(IEnumerable<IProcessor> processors)
  51. {
  52. //https://docs.microsoft.com/en-us/dotnet/api/system.drawing.graphics.drawstring?view=netcore-3.0
  53. PrintDocument printDocument = new PrintDocument();
  54. var installedPrinters = PrinterSettings.InstalledPrinters.Cast<string>();
  55. this.logger.LogInformation("System installed printers are: "
  56. + installedPrinters.Aggregate((acc, n) => acc + ", " + n)
  57. + Environment.NewLine
  58. + "now the printer with name: " + printDocument.PrinterSettings.PrinterName + " is defaultly chosen.");
  59. if (!string.IsNullOrEmpty(this.printerName))
  60. {
  61. this.logger.LogInformation(" will switch to printer with name: " + this.printerName);
  62. printDocument.PrinterSettings.PrinterName = this.printerName;
  63. }
  64. printDocument.PrintPage += Pd_PrintPage;
  65. //MqttNetGlobalLogger.LogMessagePublished += (s, e) =>
  66. //{
  67. // //var trace = $">> [{e.TraceMessage.ThreadId}] [{e.TraceMessage.Source}] [{e.TraceMessage.Level}]: {e.TraceMessage.Message}";
  68. // if (this.logger.IsEnabled(LogLevel.Trace))
  69. // {
  70. // var trace = $"MQTTnet - {e.TraceMessage.Message}";
  71. // if (e.TraceMessage.Exception != null)
  72. // trace += Environment.NewLine + e.TraceMessage.Exception.ToString();
  73. // this.logger.LogTrace(trace);
  74. // }
  75. //};
  76. // Create a new MQTT client.
  77. var factory = new MqttFactory();
  78. this.mqttClient = factory.CreateMqttClient();
  79. this.mqttClient.ApplicationMessageReceivedAsync += e =>
  80. {
  81. if (this.logger.IsEnabled(LogLevel.Trace))
  82. {
  83. this.logger.LogTrace("### Received Messages from Topic ###");
  84. this.logger.LogTrace($" Topic = {e.ApplicationMessage.Topic}");
  85. this.logger.LogTrace($" Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
  86. this.logger.LogTrace($" QoS = {e.ApplicationMessage.QualityOfServiceLevel}");
  87. this.logger.LogTrace($" Retain = {e.ApplicationMessage.Retain}");
  88. }
  89. if (e.ApplicationMessage.Topic == this.topic_PrintingRequest)
  90. {
  91. this.printingContent = this.ParseToPrinterStringData(e.ApplicationMessage.Payload);
  92. printDocument.Print();
  93. if (!string.IsNullOrEmpty(this.topic_PrintRequestReply))
  94. this.mqttClient.PublishAsync(new MqttApplicationMessage()
  95. {
  96. Topic = this.topic_PrintRequestReply,
  97. Payload = new byte[] { }
  98. });
  99. }
  100. return Task.CompletedTask;
  101. };
  102. this.mqttClient.DisconnectedAsync += arg =>
  103. {
  104. this.shouldReconnect = true;
  105. this.logger.LogInformation(" Mqtt connection disconnected, " +
  106. "AuthenticateResult: " + (arg.ReasonString ?? "") +
  107. ", ClientWasConnected: " + arg.ClientWasConnected +
  108. ", exception: " + arg.Exception);
  109. return Task.CompletedTask;
  110. };
  111. // Create TCP based options using the builder.
  112. var options = new MqttClientOptionsBuilder()
  113. .WithClientId(this.mqttClientId)
  114. .WithTcpServer(this.mqttServerUrl, this.mqttServerPort)
  115. .WithCredentials(this.mqttClientUsername, this.mqttClientPassword)
  116. .WithKeepAlivePeriod(new TimeSpan(0, 0, 30))
  117. .WithCleanSession(true)
  118. .Build();
  119. await Task.Run(async () =>
  120. {
  121. while (true)
  122. {
  123. if (!this.shouldReconnect) { await Task.Delay(30000); continue; }
  124. this.logger.LogDebug("Connecting to mqtt server...");
  125. try
  126. {
  127. try
  128. {
  129. // always try to close previous conn.
  130. await mqttClient.DisconnectAsync();
  131. }
  132. catch { }
  133. var result = await mqttClient.ConnectAsync(options);
  134. if (result.ResultCode == MqttClientConnectResultCode.Success)
  135. {
  136. this.logger.LogInformation(" Successfully connected to mqtt server.");
  137. var subResult = await this.mqttClient.SubscribeAsync(this.topic_PrintingRequest,
  138. MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce);
  139. if (subResult.Items.Any())
  140. {
  141. if ((int)(subResult.Items.First().ResultCode) <= 2)
  142. {
  143. this.logger.LogInformation(" Successfully subscribed on topic.");
  144. this.shouldReconnect = false;
  145. }
  146. else
  147. {
  148. this.logger.LogInformation(" Failed on subscribe on topic with Sub resultCode: "
  149. + subResult.Items.First().ResultCode);
  150. }
  151. }
  152. else
  153. this.logger.LogInformation(" Failed on subscribe on topic by generic error.");
  154. }
  155. else
  156. {
  157. this.logger.LogInformation(" Failed connecting to mqtt server with returned ResultCode: "
  158. + result.ResultCode
  159. + ", ReasonString:" + (result.ReasonString ?? ""));
  160. }
  161. }
  162. catch (Exception exx)
  163. {
  164. this.logger.LogError(" Connecting to mqtt server exceptioned: " + exx);
  165. }
  166. }
  167. });
  168. }
  169. private void Pd_PrintPage(object sender, PrintPageEventArgs e)
  170. {
  171. //string drawString = "hello world this is my test line0"
  172. // + Environment.NewLine + "line1"
  173. // + Environment.NewLine + "line2";
  174. // Create font and brush.
  175. Font drawFont = new Font("Arial", 10);//, FontStyle.Bold);
  176. SolidBrush drawBrush = new SolidBrush(Color.Black);
  177. // Create point for upper-left corner of drawing.
  178. float x = 0.00F;
  179. float y = 0.00F;
  180. // Set format of string.
  181. StringFormat drawFormat = new StringFormat();
  182. //drawFormat.FormatFlags = StringFormatFlags.DirectionVertical;
  183. //drawFormat.FormatFlags = StringFormatFlags.DisplayFormatControl;
  184. e.Graphics.DrawString(this.printingContent, drawFont, drawBrush, x, y, drawFormat);
  185. //e.Graphics.DrawString("\x1b\x69", drawFont, drawBrush, x, y + 40, drawFormat);
  186. //string GS = Convert.ToString((char)29);
  187. //string ESC = Convert.ToString((char)27);
  188. //string COMMAND = "";
  189. //COMMAND = ESC + "@";
  190. //COMMAND += GS + "V" + (char)1;
  191. //e.Graphics.DrawString(COMMAND, drawFont, drawBrush, x, y + 60, drawFormat);
  192. //e.Graphics.DrawString("\x1B@\x1DV1", drawFont, drawBrush, x, y + 80, drawFormat);
  193. }
  194. public async Task<bool> Start()
  195. {
  196. return true;
  197. }
  198. public async Task<bool> Stop()
  199. {
  200. return true;
  201. }
  202. /// <summary>
  203. /// parse the bytes from remote which most likely with format control chars included.
  204. /// </summary>
  205. /// <param name="remoteContent"></param>
  206. /// <returns>a string that the device can read and operate</returns>
  207. private string ParseToPrinterStringData(byte[] rawContent)
  208. {
  209. return Encoding.UTF8.GetString(rawContent);
  210. }
  211. }
  212. }