using System; using System.Collections.Generic; using System.IO; using System.Reflection; namespace SickBlazorApp.Services { public class EdsParser { private readonly Dictionary> _sections = new(); public EdsParser(string edsPath) { LoadEds(edsPath); } private void LoadEds(string edsPath) { // Đọc embed resource var assembly = Assembly.GetExecutingAssembly(); using var stream = assembly.GetManifestResourceStream(edsPath); if (stream == null) throw new FileNotFoundException("EDS not found: " + edsPath); using var reader = new StreamReader(stream); string? line; string currentSection = string.Empty; var currentSub = new Dictionary(); while ((line = reader.ReadLine()) != null) { line = line.Trim(); if (string.IsNullOrEmpty(line) || line.StartsWith(";")) continue; if (line.StartsWith("[") && line.EndsWith("]")) { if (!string.IsNullOrEmpty(currentSection)) { _sections[currentSection] = currentSub; } currentSection = line[1..^1].ToLower(); // e.g. "1000" hoặc "1800sub1" currentSub = new Dictionary(); } else if (line.Contains("=")) { var parts = line.Split('=', 2); var key = parts[0].Trim().ToLower(); var value = parts[1].Trim(); currentSub[key] = value; } } if (!string.IsNullOrEmpty(currentSection)) { _sections[currentSection] = currentSub; } } // Helper lấy giá trị public string GetValue(string section, string key) { section = section.ToLower(); if (_sections.TryGetValue(section, out var sub) && sub.TryGetValue(key.ToLower(), out var value)) { return value; } return string.Empty; } // Ví dụ lấy TPDO1 COB-ID base (trả $nodeid + 0x180 → parse 0x180) public uint GetTpdo1BaseCobId() { var cob = GetValue("1800sub1", "defaultvalue"); // "$NodeID + 0x180" var hexPart = cob.Split('+')[1].Trim(); // "0x180" return Convert.ToUInt32(hexPart, 16); // 384 (0x180) } // Lấy access-code (EDS không default, nhưng manual 0x98127634 → hard-code tạm hoặc thêm param) public uint GetAccessCode() { // EDS không có default cho 0x2009sub1 → dùng từ manual return 0x98127634; // Cập nhật từ EDS/manual } // Tính scale (mm per count) public double GetPositionScale() { // Lấy resolution per revolution từ EDS (0x6001 default = 0x4000 = 16384 counts/rev) var resPerRevHex = GetValue("6001", "defaultvalue") ?? "0x4000"; var countsPerRev = Convert.ToUInt32(resPerRevHex, 16); // 16384 // Thông số dây kéo BCG08: 230 mm per revolution (từ datasheet SICK BCG08 series) const double mmPerRev = 230.0; // chuẩn từ datasheet wire draw // Scale = mm per count = mm/rev / counts/rev double scale = mmPerRev / countsPerRev; // Kết quả ≈ 230 / 16384 ≈ 0.014038 mm/count return scale; } // Lấy baudrate map (index → bitrate) public Dictionary GetBaudrateMap() { var map = new Dictionary(); byte index = 0; if (GetValue("deviceinfo", "baudrate_1000") == "1") map[index++] = 1000000; if (GetValue("deviceinfo", "baudrate_800") == "1") map[index++] = 800000; if (GetValue("deviceinfo", "baudrate_500") == "1") map[index++] = 500000; if (GetValue("deviceinfo", "baudrate_250") == "1") map[index++] = 250000; if (GetValue("deviceinfo", "baudrate_125") == "1") map[index++] = 125000; if (GetValue("deviceinfo", "baudrate_100") == "1") map[index++] = 100000; if (GetValue("deviceinfo", "baudrate_50") == "1") map[index++] = 50000; if (GetValue("deviceinfo", "baudrate_20") == "1") map[index++] = 20000; if (GetValue("deviceinfo", "baudrate_10") == "1") map[index++] = 10000; return map; } // Kiểm tra position mapping (byte 0-3 uint32?) public bool IsPositionMappedToTpdo1() { var mapping = GetValue("1a00sub1", "defaultvalue"); // 0x60040020 return mapping == "0x60040020"; // Position 32-bit } } }