private void CalculateTxtData() { System.Data.DataTable dtInfo = new System.Data.DataTable(); System.Data.DataTable dtMatrix = new System.Data.DataTable(); ipList = new List <InfoParser>(); mpList = new List <MatrixParser>(); if (File.Exists(infoFile) && File.Exists(matrixFile)) { splashScreenManager1.ShowWaitForm(); splashScreenManager1.SetWaitFormCaption("正在加载数据"); splashScreenManager1.SetWaitFormDescription(" 请等待。。。"); dtInfo = OpenCSV(infoFile, 0, 0, 0, 0, true); dtMatrix = OpenCSV(matrixFile, 0, 0, 0, 0, true); foreach (DataRow dr in dtInfo.Rows) { if (dr[0].ToString() == "0") { continue; } else { InfoParser ip = new InfoParser(); ip.No = dr[0].ToString(); ip.Value = dr[1].ToString(); ip.Name = dr[2].ToString(); ipList.Add(ip); } } foreach (DataRow dr in dtMatrix.Rows) { MatrixParser mp = new MatrixParser(); mp.No = dr[0].ToString(); mp.Value = dr[1].ToString(); mp.Name = dr[2].ToString(); mp.OldValue = dr[3].ToString(); mpList.Add(mp); } splashScreenManager1.SetWaitFormCaption("正在计算"); FrmCalculation frmCal = new FrmCalculation(mpList, ipList); splashScreenManager1.CloseWaitForm(); frmCal.Show(); } else { MessageBox.Show("CSV文件不存在"); } }
private int SaveFileToDB(bool hasTitle, string fileName, string password) { Microsoft.Office.Interop.Excel.Application app = new Microsoft.Office.Interop.Excel.Application(); Sheets sheets; object oMissiong = System.Reflection.Missing.Value; Workbook workbook = null; System.Data.DataTable dt = new System.Data.DataTable(); try { if (app == null) { return(0); } workbook = app.Workbooks.Open(fileName, oMissiong, oMissiong, oMissiong, password, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong, oMissiong); sheets = workbook.Worksheets; //将数据读入 //worksheet 1 Excel.Worksheet ws = (Worksheet)sheets.get_Item(1); if (ws == null) { return(0); } string machineSourceCode = ((Excel.Range)ws.Cells[1, 1]).Text.ToString(); string machineCode = ""; if (machineSourceCode.IndexOf("=") > 0) { string[] machineCodes = machineSourceCode.Split('='); if (machineCodes.Length == 2) { machineCode = machineCodes[1]; } } ws = (Worksheet)sheets.get_Item(2); string serialCode = ((Excel.Range)ws.Cells[3, 3]).Text.ToString(); if (serialCode.IndexOf("_") > 0) { string[] serialCodes = serialCode.Split('_'); if (serialCodes.Length == 2) { serialCode = serialCodes[1]; } } string sex = ((Excel.Range)ws.Cells[11, 3]).Text.ToString().ToLower(); int iRowCount = ws.UsedRange.Rows.Count; int iColCount = ws.UsedRange.Columns.Count; //生成行数据 info List <InfoParser> ipList = new List <InfoParser>(); Range range; int rowIdx = hasTitle ? 2 : 1; for (int iRow = rowIdx; iRow <= iRowCount; iRow++) { InfoParser ip = new InfoParser(); range = (Range)ws.Cells[iRow, 1]; ip.No = (range.Value2 == null) ? "" : range.Text.ToString(); range = (Range)ws.Cells[iRow, 2]; ip.Value = (range.Value2 == null) ? "" : range.Text.ToString(); range = (Range)ws.Cells[iRow, 3]; ip.Name = (range.Value2 == null) ? "" : range.Text.ToString(); ipList.Add(ip); } //生成行数据 matrix ws = (Worksheet)sheets.get_Item(3); iRowCount = ws.UsedRange.Rows.Count; iColCount = ws.UsedRange.Columns.Count; List <MatrixParser> mpList = new List <MatrixParser>(); for (int iRow = rowIdx; iRow <= iRowCount; iRow++) { MatrixParser mp = new MatrixParser(); range = (Range)ws.Cells[iRow, 1]; mp.No = (range.Value2 == null) ? "" : range.Text.ToString(); range = (Range)ws.Cells[iRow, 2]; mp.Value = (range.Value2 == null) ? "" : range.Text.ToString(); range = (Range)ws.Cells[iRow, 3]; mp.Name = (range.Value2 == null) ? "" : range.Text.ToString(); range = (Range)ws.Cells[iRow, 4]; mp.OldValue = (range.Value2 == null) ? "" : range.Text.ToString(); mpList.Add(mp); } string info = JsonConvert.SerializeObject(ipList); string matrix = JsonConvert.SerializeObject(mpList); modelSourceData.infoData = info; modelSourceData.matrixData = matrix; modelSourceData.serialCode = serialCode; modelSourceData.machineCode = machineCode; modelSourceData.sex = sex; int ret = dalSourceData.Add(modelSourceData); return(ret); } catch { return(0); } finally { workbook.Close(false, oMissiong, oMissiong); System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook); workbook = null; app.Workbooks.Close(); app.Quit(); System.Runtime.InteropServices.Marshal.ReleaseComObject(app); } }
static async Task Main() { //Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new InvalidOperationException()); Log.Logger = new LoggerConfiguration() .WriteTo.Console() .Enrich.FromLogContext() .MinimumLevel.Information() .CreateLogger(); var c = await JsonReader.ReadConfigAsync(); foreach (var cfg in c) { Log.Logger.Information("Loading version configration: {0}", cfg.Version); //初始化parser var parser = new InfoParser(cfg.Configuration, cfg.CustomConfigurations); if (cfg.Configuration is not null) { var dict = await JsonReader.ReadIntroAsync(cfg.Configuration.Version, cfg.Version); var root = Directory.CreateDirectory( $"{Directory.GetCurrentDirectory()}\\projects\\{cfg.Version}\\assets"); var names = root.GetDirectories().Select(_ => _.Name).ToList(); if (cfg.CustomConfigurations is not null) { foreach (var configuration in cfg.CustomConfigurations) { if (!names.Contains(configuration.ProjectName)) { names.Add(configuration.ProjectName); } } } if (cfg.Count is not null) { var allMods = await UrlLib.GetModInfoAsync(cfg.Count.Value, cfg.Configuration.Version); foreach (var modInfo in allMods) { if (dict.ContainsKey(modInfo.Slug) || dict.ContainsValue(modInfo.Id)) { continue; } dict.Add(modInfo.Slug, modInfo.Id); } if (names.Count > cfg.Count) { var bin = allMods.Where(_ => !names.Contains(_.Slug)); var l = allMods.ToList(); foreach (var info in bin) { l.Remove(info); } allMods = l.ToArray(); } var allNames = allMods.ToList().Select(_ => _.Slug).Distinct().ToList(); var l1 = parser.SerializeAll(allMods).Distinct().ToList(); var pending = new List <string>(); foreach (var str in names) { if (!allNames.Contains(str)) { pending.Add(str); } } Log.Logger.Information($"该版本[assets]文件夹下含有 {names.Count} 个mod,有 {pending.Count} 要单独处理"); var semaphore = new SemaphoreSlim(16, 16); var tasks = l1.Select(async mod => { try { await semaphore.WaitAsync(); await Utils.ParseModsAsync(mod, cfg); } catch (Exception e) { Log.Logger.Error(e.Message); } finally { semaphore.Release(); } }); await Task.WhenAll(tasks); if (!Directory.Exists(@$ "{Directory.GetCurrentDirectory()}\config\spider\{cfg.Configuration.Version}")) { Directory.CreateDirectory( @$ "{Directory.GetCurrentDirectory()}\config\spider\{cfg.Configuration.Version}"); } var inf = new List <ModIntro>(); foreach (var(key, value) in dict) { inf.Add(new ModIntro() { Name = key, Id = value }); } await File.WriteAllTextAsync(@$ "{Directory.GetCurrentDirectory()}\config\spider\{cfg.Version}\intro.json", JsonSerializer.Serialize(inf, new JsonSerializerOptions() { WriteIndented = true })); var ids = pending.Where(name => dict.ContainsKey(name)).Select(name => dict[name].ToString()); var infos = await UrlLib.GetModInfosAsync(ids); var cfgs = parser.SerializeAll(infos); var semaphore2 = new SemaphoreSlim(16, 16); var postTask = cfgs.Select(async _ => { try { await semaphore2.WaitAsync(); await Utils.ParseModsAsync(_, cfg); } catch (Exception e) { Log.Logger.Error(e.Message); } finally { semaphore2.Release(); } }); await Task.WhenAll(postTask); }
/// <summary> /// Retrieves file information from the given filename /// </summary> /// <returns>File info</returns> public override Task <ParsedFileInfo> Execute() => InfoParser.Parse(FileName);
static async Task Main(string[] args) { //Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new InvalidOperationException()); Log.Logger = new LoggerConfiguration() .WriteTo.Console() .CreateLogger(); var c = await JsonReader.ReadConfigAsync(); foreach (var cfg in c) { var parser = new InfoParser(cfg.Configuration, cfg.CustomConfigurations); var root = Directory.CreateDirectory( $"{Directory.GetCurrentDirectory()}\\projects\\{cfg.Version}\\assets"); var names = root.GetDirectories().Select(_ => _.Name).ToList(); foreach (var configuration in cfg.CustomConfigurations) { if (!names.Contains(configuration.ProjectName)) { names.Add(configuration.ProjectName); } } var allM = await UrlLib.GetModInfoAsync(cfg.Count, cfg.Version); var allN = allM.ToList().Select(_ => _.ShortWebsiteUrl).ToList(); var pending = new List <string>(); foreach (var info in names) { if (!allN.Contains(info)) { pending.Add(info); } } Log.Logger.Information($"该版本[assets]文件夹下含有 {names.Count} 个mod,{pending.Count} 个mod需要单独处理"); var dict = await JsonReader.ReadIntroAsync(cfg.Version); if (names.Count > cfg.Count) { var bin = allM.Where(_ => !names.Contains(_.ShortWebsiteUrl)); var l = allM.ToList(); foreach (var info in bin) { l.Remove(info); } allM = l.ToArray(); } parser.Infos = allM.ToList(); var l1 = parser.SerializeAll(); var semaphore = new Semaphore(32, 40); foreach (var l in l1) { try { semaphore.WaitOne(); await Utils.ParseModsAsync(l); } catch (Exception e) { Log.Logger.Error(e.Message); } finally { semaphore.Release(); } } foreach (var name in pending) { if (dict.ContainsKey(name)) { var m = await UrlLib.GetModInfoAsync(dict[name]); var i = parser.Serialize(m); try { await Utils.ParseModsAsync(i); } catch (Exception e) { Log.Logger.Error(e.Message); } Thread.Sleep(5000); } } } }
/// <summary> /// Process an M-code that should be interpreted by the control server /// </summary> /// <param name="code">Code to process</param> /// <returns>Result of the code if the code completed, else null</returns> public static async Task <CodeResult> Process(Commands.Code code) { if (code.Channel == CodeChannel.File && FileExecution.Job.IsSimulating) { // Ignore M-codes from files in simulation mode... return(null); } switch (code.MajorNumber) { // Stop or Unconditional stop // Sleep or Conditional stop case 0: case 1: if (await SPI.Interface.Flush(code)) { using (await FileExecution.Job.LockAsync()) { if (FileExecution.Job.IsFileSelected) { // M0/M1 may be used in a print file to terminate it if (code.Channel != CodeChannel.File && !FileExecution.Job.IsPaused) { return(new CodeResult(MessageType.Error, "Pause the print before attempting to cancel it")); } code.CancellingPrint = true; } } break; } throw new OperationCanceledException(); // List SD card case 20: if (await SPI.Interface.Flush(code)) { // Resolve the directory string virtualDirectory = code.Parameter('P'); if (virtualDirectory == null) { using (await Model.Provider.AccessReadOnlyAsync()) { virtualDirectory = Model.Provider.Get.Directories.GCodes; } } string physicalDirectory = await FilePath.ToPhysicalAsync(virtualDirectory); // Make sure to stay within limits if it is a request from the firmware int maxSize = -1; if (code.Flags.HasFlag(CodeFlags.IsFromFirmware)) { maxSize = SPI.Communication.Consts.MaxMessageLength; } // Check if JSON file lists were requested int startAt = Math.Max(code.Parameter('R') ?? 0, 0); CodeParameter sParam = code.Parameter('S', 0); if (sParam == 2) { string json = FileLists.GetFiles(virtualDirectory, physicalDirectory, startAt, true, maxSize); return(new CodeResult(MessageType.Success, json)); } if (sParam == 3) { string json = FileLists.GetFileList(virtualDirectory, physicalDirectory, startAt, maxSize); return(new CodeResult(MessageType.Success, json)); } // Print standard G-code response Compatibility compatibility; using (await Model.Provider.AccessReadOnlyAsync()) { compatibility = Model.Provider.Get.Inputs[code.Channel].Compatibility; } StringBuilder result = new StringBuilder(); if (compatibility == Compatibility.Default || compatibility == Compatibility.RepRapFirmware) { result.AppendLine("GCode files:"); } else if (compatibility == Compatibility.Marlin || compatibility == Compatibility.NanoDLP) { result.AppendLine("Begin file list:"); } int numItems = 0; bool itemFound = false; foreach (string file in Directory.EnumerateFileSystemEntries(physicalDirectory)) { if (numItems++ >= startAt) { string filename = Path.GetFileName(file); if (compatibility == Compatibility.Marlin || compatibility == Compatibility.NanoDLP) { result.AppendLine(filename); } else { if (itemFound) { result.Append(','); } result.Append($"\"{filename}\""); } itemFound = true; } } if (compatibility == Compatibility.Marlin || compatibility == Compatibility.NanoDLP) { if (!itemFound) { result.AppendLine("NONE"); } result.Append("End file list"); } return(new CodeResult(MessageType.Success, result.ToString())); } throw new OperationCanceledException(); // Initialize SD card case 21: throw new NotSupportedException(); // Release SD card case 22: throw new NotSupportedException(); // Select a file to print case 23: case 32: if (await SPI.Interface.Flush(code)) { string file = code.GetUnprecedentedString(); if (string.IsNullOrWhiteSpace(file)) { return(new CodeResult(MessageType.Error, "Filename expected")); } string physicalFile = await FilePath.ToPhysicalAsync(file, FileDirectory.GCodes); if (!File.Exists(physicalFile)) { return(new CodeResult(MessageType.Error, $"Could not find file {file}")); } using (await FileExecution.Job.LockAsync()) { if (code.Channel != CodeChannel.File && FileExecution.Job.IsProcessing) { return(new CodeResult(MessageType.Error, "Cannot set file to print, because a file is already being printed")); } await FileExecution.Job.SelectFile(physicalFile); } if (await code.EmulatingMarlin()) { return(new CodeResult(MessageType.Success, "File opened\nFile selected")); } return(new CodeResult(MessageType.Success, $"File {file} selected for printing")); } throw new OperationCanceledException(); // Resume a file print case 24: if (await SPI.Interface.Flush(code)) { using (await FileExecution.Job.LockAsync()) { if (!FileExecution.Job.IsFileSelected) { return(new CodeResult(MessageType.Error, "Cannot print, because no file is selected!")); } } // Let RepRapFirmware process this request so it can invoke resume.g. When M24 completes, the file is resumed break; } throw new OperationCanceledException(); // Set SD position case 26: if (await SPI.Interface.Flush(code)) { using (await FileExecution.Job.LockAsync()) { if (!FileExecution.Job.IsFileSelected) { return(new CodeResult(MessageType.Error, "Not printing a file")); } CodeParameter sParam = code.Parameter('S'); if (sParam != null) { if (sParam < 0L || sParam > FileExecution.Job.FileLength) { return(new CodeResult(MessageType.Error, "Position is out of range")); } await FileExecution.Job.SetFilePosition(sParam); } } // P is not supported yet return(new CodeResult()); } throw new OperationCanceledException(); // Report SD print status case 27: if (await SPI.Interface.Flush(code)) { using (await FileExecution.Job.LockAsync()) { if (FileExecution.Job.IsFileSelected) { long filePosition = await FileExecution.Job.GetFilePosition(); return(new CodeResult(MessageType.Success, $"SD printing byte {filePosition}/{FileExecution.Job.FileLength}")); } return(new CodeResult(MessageType.Success, "Not SD printing.")); } } throw new OperationCanceledException(); // Begin write to SD card case 28: if (await SPI.Interface.Flush(code)) { int numChannel = (int)code.Channel; using (await Commands.Code.FileLocks[numChannel].LockAsync(code.CancellationToken)) { if (Commands.Code.FilesBeingWritten[numChannel] != null) { return(new CodeResult(MessageType.Error, "Another file is already being written to")); } string file = code.GetUnprecedentedString(); if (string.IsNullOrWhiteSpace(file)) { return(new CodeResult(MessageType.Error, "Filename expected")); } string prefix = (await code.EmulatingMarlin()) ? "ok\n" : string.Empty; string physicalFile = await FilePath.ToPhysicalAsync(file, FileDirectory.GCodes); try { FileStream fileStream = new FileStream(physicalFile, FileMode.Create, FileAccess.Write); StreamWriter writer = new StreamWriter(fileStream); Commands.Code.FilesBeingWritten[numChannel] = writer; return(new CodeResult(MessageType.Success, prefix + $"Writing to file: {file}")); } catch (Exception e) { _logger.Debug(e, "Failed to open file for writing"); return(new CodeResult(MessageType.Error, prefix + $"Can't open file {file} for writing.")); } } } throw new OperationCanceledException(); // End write to SD card case 29: if (await SPI.Interface.Flush(code)) { int numChannel = (int)code.Channel; using (await Commands.Code.FileLocks[numChannel].LockAsync(code.CancellationToken)) { if (Commands.Code.FilesBeingWritten[numChannel] != null) { Stream stream = Commands.Code.FilesBeingWritten[numChannel].BaseStream; Commands.Code.FilesBeingWritten[numChannel].Dispose(); Commands.Code.FilesBeingWritten[numChannel] = null; stream.Dispose(); if (await code.EmulatingMarlin()) { return(new CodeResult(MessageType.Success, "Done saving file.")); } return(new CodeResult()); } break; } } throw new OperationCanceledException(); // Delete a file on the SD card case 30: if (await SPI.Interface.Flush(code)) { string file = code.GetUnprecedentedString(); string physicalFile = await FilePath.ToPhysicalAsync(file); try { File.Delete(physicalFile); } catch (Exception e) { _logger.Debug(e, "Failed to delete file"); return(new CodeResult(MessageType.Error, $"Failed to delete file {file}: {e.Message}")); } } throw new OperationCanceledException(); // For case 32, see case 23 // Return file information case 36: if (code.Parameters.Count > 0) { if (await SPI.Interface.Flush(code)) { string file = await FilePath.ToPhysicalAsync(code.GetUnprecedentedString(), FileDirectory.GCodes); try { ParsedFileInfo info = await InfoParser.Parse(file); string json = JsonSerializer.Serialize(info, JsonHelper.DefaultJsonOptions); return(new CodeResult(MessageType.Success, "{\"err\":0," + json.Substring(1))); } catch (Exception e) { _logger.Debug(e, "Failed to return file information"); return(new CodeResult(MessageType.Success, "{\"err\":1}")); } } throw new OperationCanceledException(); } break; // Simulate file case 37: if (await SPI.Interface.Flush(code)) { CodeParameter pParam = code.Parameter('P'); if (pParam != null) { string file = pParam; if (string.IsNullOrWhiteSpace(file)) { return(new CodeResult(MessageType.Error, "Filename expected")); } string physicalFile = await FilePath.ToPhysicalAsync(file, FileDirectory.GCodes); if (!File.Exists(physicalFile)) { return(new CodeResult(MessageType.Error, $"GCode file \"{file}\" not found\n")); } using (await FileExecution.Job.LockAsync()) { if (code.Channel != CodeChannel.File && FileExecution.Job.IsProcessing) { return(new CodeResult(MessageType.Error, "Cannot set file to simulate, because a file is already being printed")); } await FileExecution.Job.SelectFile(physicalFile, true); // Simulation is started when M37 has been processed by the firmware } } break; } throw new OperationCanceledException(); // Compute SHA1 hash of target file case 38: if (await SPI.Interface.Flush(code)) { string file = code.GetUnprecedentedString(); string physicalFile = await FilePath.ToPhysicalAsync(file); try { using FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read); byte[] hash; using System.Security.Cryptography.SHA1 sha1 = System.Security.Cryptography.SHA1.Create(); hash = await Task.Run(() => sha1.ComputeHash(stream), code.CancellationToken); return(new CodeResult(MessageType.Success, BitConverter.ToString(hash).Replace("-", string.Empty))); } catch (Exception e) { _logger.Debug(e, "Failed to compute SHA1 checksum"); if (e is AggregateException ae) { e = ae.InnerException; } return(new CodeResult(MessageType.Error, $"Could not compute SHA1 checksum for file {file}: {e.Message}")); } } throw new OperationCanceledException(); // Report SD card information case 39: if (await SPI.Interface.Flush(code)) { using (await Model.Provider.AccessReadOnlyAsync()) { int index = code.Parameter('P', 0); if (code.Parameter('S', 0) == 2) { if (index < 0 || index >= Model.Provider.Get.Volumes.Count) { return(new CodeResult(MessageType.Success, $"{{\"SDinfo\":{{\"slot\":{index},present:0}}}}")); } Volume storage = Model.Provider.Get.Volumes[index]; var output = new { SDinfo = new { slot = index, present = 1, capacity = storage.Capacity, free = storage.FreeSpace, speed = storage.Speed } }; return(new CodeResult(MessageType.Success, JsonSerializer.Serialize(output, JsonHelper.DefaultJsonOptions))); } else { if (index < 0 || index >= Model.Provider.Get.Volumes.Count) { return(new CodeResult(MessageType.Error, $"Bad SD slot number: {index}")); } Volume storage = Model.Provider.Get.Volumes[index]; return(new CodeResult(MessageType.Success, $"SD card in slot {index}: capacity {storage.Capacity / (1000 * 1000 * 1000):F2}Gb, free space {storage.FreeSpace / (1000 * 1000 * 1000):F2}Gb, speed {storage.Speed / (1000 * 1000):F2}MBytes/sec")); } } } throw new OperationCanceledException(); // Emergency Stop - unconditional and interpreteted immediately when read case 112: await SPI.Interface.EmergencyStop(); using (await Model.Provider.AccessReadWriteAsync()) { Model.Provider.Get.State.Status = MachineStatus.Halted; } return(new CodeResult()); // Immediate DSF diagnostics case 122: if (code.Parameter('B', 0) == 0 && code.GetUnprecedentedString() == "DSF") { CodeResult result = new CodeResult(); await Diagnostics(result); return(result); } break; // Save heightmap case 374: if (await SPI.Interface.Flush(code)) { string file = code.Parameter('P', FilePath.DefaultHeightmapFile); string physicalFile = await FilePath.ToPhysicalAsync(file, FileDirectory.System); try { if (await SPI.Interface.LockMovementAndWaitForStandstill(code.Channel)) { Heightmap map; try { map = await SPI.Interface.GetHeightmap(); } finally { await SPI.Interface.UnlockAll(code.Channel); } if (map.NumX * map.NumY > 0) { await map.Save(physicalFile); string virtualFile = await FilePath.ToVirtualAsync(physicalFile); using (await Model.Provider.AccessReadWriteAsync()) { Model.Provider.Get.Move.Compensation.File = virtualFile; } return(new CodeResult(MessageType.Success, $"Height map saved to file {file}")); } return(new CodeResult()); } } catch (Exception e) { _logger.Debug(e, "Failed to save height map"); if (e is AggregateException ae) { e = ae.InnerException; } return(new CodeResult(MessageType.Error, $"Failed to save height map to file {file}: {e.Message}")); } } throw new OperationCanceledException(); // Load heightmap case 375: if (await SPI.Interface.Flush(code)) { string file = code.Parameter('P', FilePath.DefaultHeightmapFile); string physicalFile = await FilePath.ToPhysicalAsync(file, FileDirectory.System); try { Heightmap map = new Heightmap(); await map.Load(physicalFile); if (await SPI.Interface.LockMovementAndWaitForStandstill(code.Channel)) { try { await SPI.Interface.SetHeightmap(map); } finally { await SPI.Interface.UnlockAll(code.Channel); } string virtualFile = await FilePath.ToVirtualAsync(physicalFile); using (await Model.Provider.AccessReadWriteAsync()) { Model.Provider.Get.Move.Compensation.File = virtualFile; } CodeResult result = new CodeResult(); using (await Model.Provider.AccessReadOnlyAsync()) { if (Model.Provider.Get.Move.Axes.Any(axis => axis.Letter == 'Z' && !axis.Homed)) { result.Add(MessageType.Warning, "The height map was loaded when the current Z=0 datum was not determined. This may result in a height offset."); } } result.Add(MessageType.Success, $"Height map loaded from file {file}"); return(result); } } catch (Exception e) { _logger.Debug(e, "Failed to load height map"); if (e is AggregateException ae) { e = ae.InnerException; } return(new CodeResult(MessageType.Error, $"Failed to load height map from file {file}: {e.Message}")); } } throw new OperationCanceledException(); // Create Directory on SD-Card case 470: if (await SPI.Interface.Flush(code)) { string path = code.Parameter('P'); if (path == null) { return(new CodeResult(MessageType.Error, "Missing directory name")); } string physicalPath = await FilePath.ToPhysicalAsync(path); try { Directory.CreateDirectory(physicalPath); } catch (Exception e) { _logger.Debug(e, "Failed to create directory"); return(new CodeResult(MessageType.Error, $"Failed to create directory {path}: {e.Message}")); } } throw new OperationCanceledException(); // Rename File/Directory on SD-Card case 471: if (await SPI.Interface.Flush(code)) { string from = code.Parameter('S'); string to = code.Parameter('T'); try { string source = await FilePath.ToPhysicalAsync(from); string destination = await FilePath.ToPhysicalAsync(to); if (File.Exists(source)) { if (File.Exists(destination) && code.Parameter('D', false)) { File.Delete(destination); } File.Move(source, destination); } else if (Directory.Exists(source)) { if (Directory.Exists(destination) && code.Parameter('D', false)) { // This could be recursive but at the moment we mimic RRF's behaviour Directory.Delete(destination); } Directory.Move(source, destination); } throw new FileNotFoundException(); } catch (Exception e) { _logger.Debug(e, "Failed to rename file or directory"); return(new CodeResult(MessageType.Error, $"Failed to rename file or directory {from} to {to}: {e.Message}")); } } throw new OperationCanceledException(); // Store parameters case 500: if (await SPI.Interface.Flush(code)) { await ConfigOverride.Save(code); return(new CodeResult()); } throw new OperationCanceledException(); // Print settings case 503: if (await SPI.Interface.Flush(code)) { string configFile = await FilePath.ToPhysicalAsync(FilePath.ConfigFile, FileDirectory.System); if (File.Exists(configFile)) { string content = await File.ReadAllTextAsync(configFile); return(new CodeResult(MessageType.Success, content)); } string configFileFallback = await FilePath.ToPhysicalAsync(FilePath.ConfigFileFallback, FileDirectory.System); if (File.Exists(configFileFallback)) { string content = await File.ReadAllTextAsync(configFileFallback); return(new CodeResult(MessageType.Success, content)); } return(new CodeResult(MessageType.Error, "Configuration file not found")); } throw new OperationCanceledException(); // Set configuration file folder case 505: if (await SPI.Interface.Flush(code)) { string directory = code.Parameter('P'); if (!string.IsNullOrEmpty(directory)) { string physicalDirectory = await FilePath.ToPhysicalAsync(directory, "sys"); if (Directory.Exists(physicalDirectory)) { string virtualDirectory = await FilePath.ToVirtualAsync(physicalDirectory); using (await Model.Provider.AccessReadWriteAsync()) { Model.Provider.Get.Directories.System = virtualDirectory; } return(new CodeResult()); } return(new CodeResult(MessageType.Error, "Directory not found")); } using (await Model.Provider.AccessReadOnlyAsync()) { return(new CodeResult(MessageType.Success, $"Sys file path is {Model.Provider.Get.Directories.System}")); } } throw new OperationCanceledException(); // Set Name case 550: if (await SPI.Interface.Flush(code)) { // Verify the P parameter string pParam = code.Parameter('P'); if (!string.IsNullOrEmpty(pParam)) { if (pParam.Length > 40) { return(new CodeResult(MessageType.Error, "Machine name is too long")); } // Strip letters and digits from the machine name string machineName = string.Empty; foreach (char c in Environment.MachineName) { if (char.IsLetterOrDigit(c)) { machineName += c; } } // Strip letters and digits from the desired name string desiredName = string.Empty; foreach (char c in pParam) { if (char.IsLetterOrDigit(c)) { desiredName += c; } } // Make sure the subset of letters and digits is equal if (!machineName.Equals(desiredName, StringComparison.CurrentCultureIgnoreCase)) { return(new CodeResult(MessageType.Error, "Machine name must consist of the same letters and digits as configured by the Linux hostname")); } // Hostname is legit - pretend we didn't see this code so RRF can interpret it } break; } throw new OperationCanceledException(); // Configure filament case 703: if (await SPI.Interface.Flush(code)) { await Model.Updater.WaitForFullUpdate(Program.CancellationToken); break; } throw new OperationCanceledException(); // Set current RTC date and time case 905: if (await SPI.Interface.Flush(code)) { bool seen = false; CodeParameter pParam = code.Parameter('P'); if (pParam != null) { if (DateTime.TryParseExact(pParam, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date)) { System.Diagnostics.Process.Start("timedatectl", $"set-time {date:yyyy-MM-dd}").WaitForExit(); seen = true; } else { return(new CodeResult(MessageType.Error, "Invalid date format")); } } CodeParameter sParam = code.Parameter('S'); if (sParam != null) { if (DateTime.TryParseExact(sParam, "HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime time)) { System.Diagnostics.Process.Start("timedatectl", $"set-time {time:HH:mm:ss}").WaitForExit(); seen = true; } else { return(new CodeResult(MessageType.Error, "Invalid time format")); } } if (!seen) { return(new CodeResult(MessageType.Success, $"Current date and time: {DateTime.Now:yyyy-MM-dd HH:mm:ss}")); } } throw new OperationCanceledException(); // Start/stop event logging to SD card case 929: if (await SPI.Interface.Flush(code)) { CodeParameter sParam = code.Parameter('S'); if (sParam == null) { using (await Model.Provider.AccessReadOnlyAsync()) { return(new CodeResult(MessageType.Success, $"Event logging is {(Model.Provider.Get.State.LogFile != null ? "enabled" : "disabled")}")); } } if (sParam > 0) { string file = code.Parameter('P', Utility.Logger.DefaultLogFile); if (string.IsNullOrWhiteSpace(file)) { return(new CodeResult(MessageType.Error, "Missing filename in M929 command")); } string physicalFile = await FilePath.ToPhysicalAsync(file, FileDirectory.System); await Utility.Logger.Start(physicalFile); } else { await Utility.Logger.Stop(); } return(new CodeResult()); } throw new OperationCanceledException(); // Update the firmware case 997: if (((int[])code.Parameter('S', new int[] { 0 })).Contains(0) && code.Parameter('B', 0) == 0) { if (await SPI.Interface.Flush(code)) { string iapFile, firmwareFile; using (await Model.Provider.AccessReadOnlyAsync()) { if (Model.Provider.Get.Boards.Count == 0) { return(new CodeResult(MessageType.Error, "No boards have been detected")); } // There are now two different IAP binaries, check which one to use iapFile = Model.Provider.Get.Boards[0].IapFileNameSBC; firmwareFile = Model.Provider.Get.Boards[0].FirmwareFileName; } iapFile = await FilePath.ToPhysicalAsync(iapFile, FileDirectory.Firmware); if (!File.Exists(iapFile)) { return(new CodeResult(MessageType.Error, $"Failed to find IAP file {iapFile}")); } firmwareFile = await FilePath.ToPhysicalAsync(firmwareFile, FileDirectory.Firmware); if (!File.Exists(firmwareFile)) { return(new CodeResult(MessageType.Error, $"Failed to find firmware file {firmwareFile}")); } using FileStream iapStream = new FileStream(iapFile, FileMode.Open, FileAccess.Read); using FileStream firmwareStream = new FileStream(firmwareFile, FileMode.Open, FileAccess.Read); await SPI.Interface.UpdateFirmware(iapStream, firmwareStream); return(new CodeResult()); } throw new OperationCanceledException(); } break; // Request resend of line case 998: throw new NotSupportedException(); // Reset controller - unconditional and interpreteted immediately when read case 999: if (code.Parameters.Count == 0) { await SPI.Interface.Reset(); return(new CodeResult()); } break; } return(null); }
/// <summary> /// Process an M-code that should be interpreted by the control server /// </summary> /// <param name="code">Code to process</param> /// <returns>Result of the code if the code completed, else null</returns> public static async Task <CodeResult> Process(Commands.Code code) { if (code.Channel == CodeChannel.File && FileExecution.Job.IsSimulating) { // Ignore M-codes from files in simulation mode... return(null); } switch (code.MajorNumber) { // Stop or Unconditional stop // Sleep or Conditional stop case 0: case 1: if (await SPI.Interface.Flush(code)) { using (await FileExecution.Job.LockAsync()) { if (FileExecution.Job.IsFileSelected) { // M0/M1 may be used in a print file to terminate it if (code.Channel != CodeChannel.File && !FileExecution.Job.IsPaused) { return(new CodeResult(MessageType.Error, "Pause the print before attempting to cancel it")); } } } break; } throw new OperationCanceledException(); // List SD card case 20: if (await SPI.Interface.Flush(code)) { // Resolve the directory string virtualDirectory = code.Parameter('P'); if (virtualDirectory == null) { using (await Model.Provider.AccessReadOnlyAsync()) { virtualDirectory = Model.Provider.Get.Directories.GCodes; } } string physicalDirectory = await FilePath.ToPhysicalAsync(virtualDirectory); // Make sure to stay within limits if it is a request from the firmware int maxSize = -1; if (code.Flags.HasFlag(CodeFlags.IsFromFirmware)) { maxSize = Settings.MaxMessageLength; } // Check if JSON file lists were requested int startAt = Math.Max(code.Parameter('R') ?? 0, 0); CodeParameter sParam = code.Parameter('S', 0); if (sParam == 2) { string json = FileLists.GetFiles(virtualDirectory, physicalDirectory, startAt, true, maxSize); return(new CodeResult(MessageType.Success, json)); } if (sParam == 3) { string json = FileLists.GetFileList(virtualDirectory, physicalDirectory, startAt, maxSize); return(new CodeResult(MessageType.Success, json)); } // Print standard G-code response Compatibility compatibility; using (await Model.Provider.AccessReadOnlyAsync()) { compatibility = Model.Provider.Get.Inputs[code.Channel].Compatibility; } StringBuilder result = new StringBuilder(); if (compatibility == Compatibility.Default || compatibility == Compatibility.RepRapFirmware) { result.AppendLine("GCode files:"); } else if (compatibility == Compatibility.Marlin || compatibility == Compatibility.NanoDLP) { result.AppendLine("Begin file list:"); } int numItems = 0; bool itemFound = false; foreach (string file in Directory.EnumerateFileSystemEntries(physicalDirectory)) { if (numItems++ >= startAt) { string filename = Path.GetFileName(file); if (compatibility == Compatibility.Marlin || compatibility == Compatibility.NanoDLP) { result.AppendLine(filename); } else { if (itemFound) { result.Append(','); } result.Append($"\"{filename}\""); } itemFound = true; } } if (compatibility == Compatibility.Marlin || compatibility == Compatibility.NanoDLP) { if (!itemFound) { result.AppendLine("NONE"); } result.Append("End file list"); } return(new CodeResult(MessageType.Success, result.ToString())); } throw new OperationCanceledException(); // Initialize SD card case 21: if (await SPI.Interface.Flush(code)) { if (code.Parameter('P', 0) == 0) { // M21 (P0) will always work because it's always mounted return(new CodeResult()); } throw new NotSupportedException(); } throw new OperationCanceledException(); // Release SD card case 22: throw new NotSupportedException(); // Select a file to print case 23: case 32: if (await SPI.Interface.Flush(code)) { string file = code.GetUnprecedentedString(); if (string.IsNullOrWhiteSpace(file)) { return(new CodeResult(MessageType.Error, "Filename expected")); } string physicalFile = await FilePath.ToPhysicalAsync(file, FileDirectory.GCodes); if (!File.Exists(physicalFile)) { return(new CodeResult(MessageType.Error, $"Could not find file {file}")); } using (await FileExecution.Job.LockAsync()) { if (code.Channel != CodeChannel.File && FileExecution.Job.IsProcessing) { return(new CodeResult(MessageType.Error, "Cannot set file to print, because a file is already being printed")); } await FileExecution.Job.SelectFile(physicalFile); } if (await code.EmulatingMarlin()) { return(new CodeResult(MessageType.Success, "File opened\nFile selected")); } return(new CodeResult(MessageType.Success, $"File {file} selected for printing")); } throw new OperationCanceledException(); // Resume a file print case 24: if (await SPI.Interface.Flush(code)) { using (await FileExecution.Job.LockAsync()) { if (!FileExecution.Job.IsFileSelected) { return(new CodeResult(MessageType.Error, "Cannot print, because no file is selected!")); } } // Let RepRapFirmware process this request so it can invoke resume.g. When M24 completes, the file is resumed break; } throw new OperationCanceledException(); // Set SD position case 26: if (await SPI.Interface.Flush(code)) { using (await FileExecution.Job.LockAsync()) { if (!FileExecution.Job.IsFileSelected) { return(new CodeResult(MessageType.Error, "Not printing a file")); } CodeParameter sParam = code.Parameter('S'); if (sParam != null) { if (sParam < 0L || sParam > FileExecution.Job.FileLength) { return(new CodeResult(MessageType.Error, "Position is out of range")); } await FileExecution.Job.SetFilePosition(sParam); } } // P is not supported yet return(new CodeResult()); } throw new OperationCanceledException(); // Report SD print status case 27: if (await SPI.Interface.Flush(code)) { using (await FileExecution.Job.LockAsync()) { if (FileExecution.Job.IsFileSelected) { long filePosition = await FileExecution.Job.GetFilePosition(); return(new CodeResult(MessageType.Success, $"SD printing byte {filePosition}/{FileExecution.Job.FileLength}")); } return(new CodeResult(MessageType.Success, "Not SD printing.")); } } throw new OperationCanceledException(); // Begin write to SD card case 28: if (await SPI.Interface.Flush(code)) { int numChannel = (int)code.Channel; using (await Commands.Code.FileLocks[numChannel].LockAsync(Program.CancellationToken)) { if (Commands.Code.FilesBeingWritten[numChannel] != null) { return(new CodeResult(MessageType.Error, "Another file is already being written to")); } string file = code.GetUnprecedentedString(); if (string.IsNullOrWhiteSpace(file)) { return(new CodeResult(MessageType.Error, "Filename expected")); } string prefix = (await code.EmulatingMarlin()) ? "ok\n" : string.Empty; string physicalFile = await FilePath.ToPhysicalAsync(file, FileDirectory.GCodes); try { FileStream fileStream = new FileStream(physicalFile, FileMode.Create, FileAccess.Write); StreamWriter writer = new StreamWriter(fileStream); Commands.Code.FilesBeingWritten[numChannel] = writer; return(new CodeResult(MessageType.Success, prefix + $"Writing to file: {file}")); } catch (Exception e) { _logger.Debug(e, "Failed to open file for writing"); return(new CodeResult(MessageType.Error, prefix + $"Can't open file {file} for writing.")); } } } throw new OperationCanceledException(); // End write to SD card case 29: if (await SPI.Interface.Flush(code)) { int numChannel = (int)code.Channel; using (await Commands.Code.FileLocks[numChannel].LockAsync(Program.CancellationToken)) { if (Commands.Code.FilesBeingWritten[numChannel] != null) { Stream stream = Commands.Code.FilesBeingWritten[numChannel].BaseStream; Commands.Code.FilesBeingWritten[numChannel].Dispose(); Commands.Code.FilesBeingWritten[numChannel] = null; stream.Dispose(); if (await code.EmulatingMarlin()) { return(new CodeResult(MessageType.Success, "Done saving file.")); } return(new CodeResult()); } break; } } throw new OperationCanceledException(); // Delete a file on the SD card case 30: if (await SPI.Interface.Flush(code)) { string file = code.GetUnprecedentedString(); string physicalFile = await FilePath.ToPhysicalAsync(file); try { File.Delete(physicalFile); } catch (Exception e) { _logger.Debug(e, "Failed to delete file"); return(new CodeResult(MessageType.Error, $"Failed to delete file {file}: {e.Message}")); } } throw new OperationCanceledException(); // For case 32, see case 23 // Return file information case 36: if (code.Parameters.Count > 0) { if (await SPI.Interface.Flush(code)) { string file = await FilePath.ToPhysicalAsync(code.GetUnprecedentedString(), FileDirectory.GCodes); try { ParsedFileInfo info = await InfoParser.Parse(file); string json = JsonSerializer.Serialize(info, JsonHelper.DefaultJsonOptions); return(new CodeResult(MessageType.Success, "{\"err\":0," + json[1..]));
static async Task Main() { //Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new InvalidOperationException()); Log.Logger = new LoggerConfiguration() .WriteTo.Console() .Enrich.FromLogContext() .MinimumLevel.Information() .CreateLogger(); var c = await JsonReader.ReadConfigAsync(); foreach (var cfg in c) { var parser = new InfoParser(cfg.Configuration, cfg.CustomConfigurations); if (cfg.Configuration != null) { var dict = await JsonReader.ReadIntroAsync(cfg.Configuration.Version, cfg.Version); var pending = new List <string>(); var root = Directory.CreateDirectory( $"{Directory.GetCurrentDirectory()}\\projects\\{cfg.Version}\\assets"); var names = root.GetDirectories().Select(_ => _.Name).ToList(); if (cfg.CustomConfigurations != null) { foreach (var configuration in cfg.CustomConfigurations) { if (!names.Contains(configuration.ProjectName)) { names.Add(configuration.ProjectName); } } } if (cfg.Count != null) { var allM = await UrlLib.GetModInfoAsync(cfg.Count.Value, cfg.Configuration.Version); if (names.Count > cfg.Count) { var bin = allM.Where(_ => !names.Contains(_.Slug)); var l = allM.ToList(); foreach (var info in bin) { l.Remove(info); } allM = l.ToArray(); } var allN = allM.ToList().Select(_ => _.Slug).Distinct().ToList(); var l1 = parser.SerializeAll(allM).Distinct().ToList(); //var parallelOption = new ParallelOptions { // MaxDegreeOfParallelism = 16 //}; foreach (var str in names) { if (!allN.Contains(str)) { pending.Add(str); } } Log.Logger.Information($"该版本[assets]文件夹下含有 {names.Count} 个mod,有 {pending.Count} 要单独处理"); var semaphore = new SemaphoreSlim(16, 16); //Parallel.ForEach(l1, parallelOption, (async tuple => { // try { // semaphore.WaitOne(); // await Utils.ParseModsAsync(tuple, cfg); // } // catch (Exception e) { // Log.Logger.Error(e.Message); // } // finally { // semaphore.Release(); // } //})); var tasks = l1.Select(async _ => { try { await semaphore.WaitAsync(); await Utils.ParseModsAsync(_, cfg); } catch (Exception e) { Log.Logger.Error(e.Message); } finally { semaphore.Release(); } }); await Task.WhenAll(tasks); } foreach (var name in pending) { if (dict.ContainsKey(name)) { var m = await UrlLib.GetModInfoAsync(dict[name]); var i = parser.Serialize(m); try { var task = new Task(async() => { try { await Utils.ParseModsAsync(i, cfg); } catch (Exception e) { Log.Logger.Error(e.Message); } }); task.Start(); //await Utils.ParseModsAsync(i,cfg); } catch (Exception e) { Log.Logger.Error(e.Message); } Thread.Sleep(5000); } } } //var semaphore = new Semaphore(32, 40); //foreach (var l in l1) { // try { // semaphore.WaitOne(); // await Utils.ParseModsAsync(l,cfg); // } // catch (Exception e) { // Log.Logger.Error(e.Message); // } // finally { // semaphore.Release(); // } //} } }