using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
class Focas : IDisposable
const ushort FocasPort = 8193;
readonly TimeSpan ConnectionTimeout = TimeSpan.FromSeconds(6);
public bool Ready { get { return FlibHndl != 0; } }
internal void ConnectAsync()
short ret = Focas1.cnc_allclibhndl3(Ip, FocasPort, (int)ConnectionTimeout.TotalSeconds, out FlibHndl);
throw new ApplicationException($"Errore su connessione FOCAS {Ip}:{FocasPort}\n{ret} - {convert.ResultToString(ret)}");
internal void Disconnect()
Focas1.cnc_freelibhndl(FlibHndl);
internal Focas1.ODBST GetStatInfo()
var buf = new Focas1.ODBST();
short ret = Focas1.cnc_statinfo(FlibHndl, buf);
throw new ApplicationException($"Errore su cnc_statinfo: {ret} - {convert.ResultToString(ret)}");
internal Focas1.ODBDY2_1 GetDynamicData()
var buf = new Focas1.ODBDY2_1();
short ret = Focas1.cnc_rddynamic2(FlibHndl, Focas1.ALL_AXES, (short)Marshal.SizeOf(buf), buf);
throw new ApplicationException($"Errore su cnc_rddynamic2: {ret} - {convert.ResultToString(ret)}");
internal Focas1.LOADELM[] GetServo()
var sv = new Focas1.LOADELM();
byte[] bytes = new byte[Marshal.SizeOf(sv) * Focas1.MAX_AXIS];
IntPtr ptrWork = IntPtr.Zero;
ptrWork = Marshal.AllocCoTaskMem(Marshal.SizeOf(sv));
short num = Focas1.MAX_AXIS;
short ret = Focas1.cnc_rdsvmeter(FlibHndl, ref num, bytes);
throw new ApplicationException($"Errore su cnc_rdsvmeter: {ret} - {convert.ResultToString(ret)}");
var buf = new Focas1.LOADELM[num];
for (int i = 0; i < num; i++)
sv = new Focas1.LOADELM();
Marshal.Copy(bytes, i * Marshal.SizeOf(sv), ptrWork, Marshal.SizeOf(sv));
Marshal.PtrToStructure(ptrWork, sv);
Marshal.FreeCoTaskMem(ptrWork);
internal Focas1.ODBSPLOAD_data[] GetSpindle()
var sp = new Focas1.ODBSPLOAD_data();
byte[] bytes = new byte[Marshal.SizeOf(sp) * num];
IntPtr ptrWork = IntPtr.Zero;
ptrWork = Marshal.AllocCoTaskMem(Marshal.SizeOf(sp));
short ret = Focas1.cnc_rdspmeter(FlibHndl, Type, ref num, bytes);
return new Focas1.ODBSPLOAD_data[0];
var buf = new Focas1.ODBSPLOAD_data[num];
for (int i = 0; i < num; i++)
sp = new Focas1.ODBSPLOAD_data();
Marshal.Copy(bytes, i * Marshal.SizeOf(sp), ptrWork, Marshal.SizeOf(sp));
Marshal.PtrToStructure(ptrWork, sp);
Marshal.FreeCoTaskMem(ptrWork);
var info = new Focas1.ODBSYS();
short ret = Focas1.cnc_sysinfo(FlibHndl, info);
throw new ApplicationException($"Errore su cnc_sysinfo: {ret} - {convert.ResultToString(ret)}");
return short.Parse(new string(info.axes));
internal Focas1.IODBPSD[] GetParameters(short start, short end, short axis = 0)
var param = new Focas1.IODBPSD();
short length = (short)(Marshal.SizeOf(param) * (end - start + 1));
var bytes = new byte[length];
IntPtr ptrWork = IntPtr.Zero;
ptrWork = Marshal.AllocCoTaskMem(Marshal.SizeOf(param));
short ret = Focas1.cnc_rdparar(FlibHndl, ref start, axis, ref end, ref length, bytes);
throw new ApplicationException($"Errore su cnc_rdparar: {ret} - {convert.ResultToString(ret)}");
var buf = new List<Focas1.IODBPSD>();
for (short idx1 = start; idx1 <= end; idx1++)
param = new Focas1.IODBPSD();
Marshal.Copy(bytes, pos, ptrWork, Marshal.SizeOf(param));
Marshal.PtrToStructure(ptrWork, param);
if ((start != 0) && (param.datano == 0)) break;
switch (param.type & 0xff)
for (short idx2 = 0; idx2 < axno; idx2++)
pos += (short)(4 + Focas1.MAX_AXIS * inc);
case 1: inc = 1 + 3; break;
case 2: inc = 2 + 2; break;
default: throw new NotImplementedException();
Marshal.FreeCoTaskMem(ptrWork);
internal Focas1.ODBALMMSG2_data[] GetAlarms()
var buf = new Focas1.ODBALMMSG2();
short ret = Focas1.cnc_rdalmmsg2(FlibHndl, type, ref num, buf);
throw new ApplicationException($"Errore su cnc_sysinfo: {ret} - {convert.ResultToString(ret)}");
var list = new List<Focas1.ODBALMMSG2_data>();
for (int i = 1; i <= num; i++)
list.Add(GetAlarmMessage(buf, i));
private Focas1.ODBALMMSG2_data GetAlarmMessage(Focas1.ODBALMMSG2 buf, int i)
case 10: return buf.msg10;
default: throw new NotImplementedException();
private bool disposedValue;
protected virtual void Dispose(bool disposing)
Dispose(disposing: true);
GC.SuppressFinalize(this);