SickApp/SickBlazorApp/Services/EdsParser.cs
2026-02-02 10:00:26 +07:00

124 lines
4.9 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
namespace SickBlazorApp.Services
{
public class EdsParser
{
private readonly Dictionary<string, Dictionary<string, string>> _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<string, string>();
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<string, string>();
}
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<byte, int> GetBaudrateMap()
{
var map = new Dictionary<byte, int>();
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
}
}
}