Feed override
This commit is contained in:
@@ -134,7 +134,7 @@ namespace CMS_CORE_Application
|
||||
cmsError = N.AXES_RAxesNames(1, ref ax);
|
||||
|
||||
ICollection<CultureInfo> info = new List<CultureInfo>();
|
||||
cmsError = N.NC_GetAvailableLanguages(ref info);
|
||||
cmsError = N.NC_GetAvailableLanguages(ref info);
|
||||
|
||||
cmsError = N.NC_WLanguage(new CultureInfo("it"));
|
||||
if (cmsError.IsError())
|
||||
|
||||
@@ -104,6 +104,11 @@ namespace CMS_CORE_Library.Demo
|
||||
|
||||
public override CmsError NC_GetAvailableLanguages(ref ICollection<CultureInfo> languages)
|
||||
{
|
||||
|
||||
languages.Add(new CultureInfo("en"));
|
||||
languages.Add(new CultureInfo("it"));
|
||||
languages.Add(new CultureInfo("fr"));
|
||||
languages.Add(new CultureInfo("de"));
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace CMS_CORE_Library.Fanuc
|
||||
// Paths
|
||||
private const string NC_SUPPORT_FILE_PATH = "//CNC_MEM/USER/PATH1/CMS/";
|
||||
|
||||
private const string NC_PROGRAM_PATH = "//CNC_MEM/USER/PATH1/";
|
||||
private const string NC_PROGRAM_PATH = "//CNC_MEM/USER/";
|
||||
|
||||
private const string PLC_MESSAGE_PATH = "C:/CMS/FANUC/";
|
||||
|
||||
@@ -212,13 +212,11 @@ namespace CMS_CORE_Library.Fanuc
|
||||
foreach(string file in Directory.GetFiles(PLC_MESSAGE_PATH))
|
||||
{
|
||||
string fileName = Path.GetFileNameWithoutExtension(file);
|
||||
|
||||
var lang = CultureInfo
|
||||
.GetCultures(CultureTypes.NeutralCultures)
|
||||
.Where(ci => string.Equals(ci.ThreeLetterISOLanguageName, fileName.Split('_')[1], StringComparison.OrdinalIgnoreCase))
|
||||
.FirstOrDefault();
|
||||
|
||||
if(lang != null)
|
||||
// Get lang from threeletter
|
||||
var lang = GetCultureFromThreeLetter(fileName.Split('_')[1]);
|
||||
|
||||
if (lang != null)
|
||||
languages.Add(lang);
|
||||
}
|
||||
}
|
||||
@@ -279,8 +277,8 @@ namespace CMS_CORE_Library.Fanuc
|
||||
// return cmsError;
|
||||
|
||||
|
||||
/////// FANUC METODO
|
||||
//
|
||||
/////// FANUC METODO
|
||||
//
|
||||
//byte lang = ConvertToNCLanguage(Language, out bool isSpecial);
|
||||
//ushort hndl;
|
||||
|
||||
@@ -298,7 +296,6 @@ namespace CMS_CORE_Library.Fanuc
|
||||
//CmsError cmsError = MEM_RWBoolean(W, 0, SPECIAL_LANGUAGE_BIT.MemType, SPECIAL_LANGUAGE_BIT.Address, SPECIAL_LANGUAGE_BIT.SubAddress, ref isSpecial);
|
||||
//if (cmsError.IsError())
|
||||
// return cmsError;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -1165,7 +1162,7 @@ namespace CMS_CORE_Library.Fanuc
|
||||
|
||||
public override CmsError PLC_W154ManageAck(int processId)
|
||||
{
|
||||
return PLC_ManageActiveAck(M154_STROBE.Address, processId - 1, M154_ACK.Address, processId - 1, M154_STROBE.MemType);
|
||||
return PLC_ManageActiveAck(M154_STROBE.Address, processId - 1, M154_ACK.Address, processId - 1, M154_STROBE.MemType);
|
||||
}
|
||||
|
||||
public override CmsError PLC_RScadaValue(string memIndex, SCADA_MEM_TYPE memType, ref object value)
|
||||
@@ -1214,8 +1211,8 @@ namespace CMS_CORE_Library.Fanuc
|
||||
}
|
||||
else if (memType == SCADA_MEM_TYPE.WORD)
|
||||
{ // read WORD
|
||||
ushort val = 0;
|
||||
cmsError = MEM_RWWord(R, 0, Type, Convert.ToInt32(index[0]), ref val);
|
||||
short val = 0;
|
||||
cmsError = MEM_RWShort(R, 0, Type, Convert.ToInt32(index[0]), ref val);
|
||||
|
||||
value = val;
|
||||
}
|
||||
@@ -1277,8 +1274,8 @@ namespace CMS_CORE_Library.Fanuc
|
||||
}
|
||||
else if (memType == SCADA_MEM_TYPE.WORD)
|
||||
{ // WRITE WORD
|
||||
ushort val = Convert.ToUInt16(value);
|
||||
CmsError cmsError = MEM_RWWord(W, 0, fanucMemtype, Convert.ToInt32(index[0]), ref val);
|
||||
short val = Convert.ToInt16(value);
|
||||
CmsError cmsError = MEM_RWShort(W, 0, fanucMemtype, Convert.ToInt32(index[0]), ref val);
|
||||
if (cmsError.IsError())
|
||||
return cmsError;
|
||||
|
||||
@@ -1810,12 +1807,6 @@ namespace CMS_CORE_Library.Fanuc
|
||||
return cmsError;
|
||||
|
||||
byte rapid= 0, work = 0;
|
||||
bool jogIsActive = false;
|
||||
|
||||
//// read if jog is active
|
||||
//cmsError = MEM_RWBoolean(R, 0, MEMORY_TYPE.Fanuc_F, 3, 2, ref jogIsActive);
|
||||
//if (cmsError.IsError())
|
||||
// return cmsError;
|
||||
|
||||
// Choose & read work override // jogIsActive ? (processId - 1) * 1000 + 10 :
|
||||
int mem = (processId - 1) * 1000 + 12;
|
||||
@@ -1823,14 +1814,23 @@ namespace CMS_CORE_Library.Fanuc
|
||||
if (cmsError.IsError())
|
||||
return cmsError;
|
||||
|
||||
work = (byte)(((work - 256) + 1)* -1 );
|
||||
if (work != 0)
|
||||
work = (byte)(((work - 256) + 1)* -1 );
|
||||
|
||||
// Read rapid
|
||||
cmsError = MEM_RWByte(R, 0, MEMORY_TYPE.Fanuc_G, 96, 0, ref rapid);
|
||||
if (cmsError.IsError())
|
||||
return cmsError;
|
||||
|
||||
if(rapid != 0)
|
||||
rapid = (byte)(((rapid - 256) + 1) * -1);
|
||||
|
||||
rapid = (byte)(((rapid - 256) + 1) * -1);
|
||||
|
||||
ODBACT feed = new ODBACT();
|
||||
nReturn = Focas1.cnc_actf(nLibHandle[0], feed);
|
||||
// Check return value
|
||||
if (nReturn != 0)
|
||||
return GetNcError(nReturn);
|
||||
|
||||
processData = new SelectedProcessData()
|
||||
{
|
||||
@@ -1839,7 +1839,8 @@ namespace CMS_CORE_Library.Fanuc
|
||||
ProcessMessage = msg,
|
||||
OffsetData = offsetData,
|
||||
RapidOverride = rapid,
|
||||
WorkOverride = work
|
||||
WorkOverride = work,
|
||||
FeedOverride = (double)feed.data / 1000
|
||||
};
|
||||
|
||||
return NO_ERROR;
|
||||
@@ -3269,7 +3270,7 @@ namespace CMS_CORE_Library.Fanuc
|
||||
|
||||
try
|
||||
{
|
||||
string tmpM198FilePath = string.Format(NC_SUPPORT_FILE_PATH + CUSTOM_MAIN_PROGRAM, processId);
|
||||
string tmpM198FilePath = string.Format(NC_SUPPORT_FILE_PATH + CUSTOM_MAIN_PROGRAM, processId);
|
||||
|
||||
string fileName = string.Format(M198_FILE_NAME, processId);
|
||||
|
||||
@@ -4782,7 +4783,7 @@ namespace CMS_CORE_Library.Fanuc
|
||||
return cmsError;
|
||||
|
||||
short nReturn = 0;
|
||||
ulong SerialNumber = 0;
|
||||
string serialNumber = "";
|
||||
|
||||
//Read oly one time every 10 seconds
|
||||
if (DateTime.Now - Last_Static_Read > new TimeSpan(NC_MIN_SEC_READ_STATIC_DATA * TimeSpan.TicksPerSecond))
|
||||
@@ -4799,9 +4800,9 @@ namespace CMS_CORE_Library.Fanuc
|
||||
return GetNcError(nReturn);
|
||||
|
||||
// Read serial number
|
||||
nReturn = Focas1.cnc_rdcncid(nLibHandle[0], out SerialNumber);
|
||||
if (nReturn != 0 && nReturn != 1)
|
||||
return GetNcError(nReturn);
|
||||
cmsError = ReadSerialNumber(ref serialNumber);
|
||||
if (cmsError.IsError())
|
||||
return cmsError;
|
||||
|
||||
// Setup the name
|
||||
Cnc_name = GetName(node.cnc_type, node.addinfo);
|
||||
@@ -4810,7 +4811,7 @@ namespace CMS_CORE_Library.Fanuc
|
||||
Cnc_SftVersion = new string(node.version);
|
||||
|
||||
//Setup the Number Series
|
||||
Cnc_SeriesNum = SerialNumber.ToString();
|
||||
Cnc_SeriesNum = serialNumber;
|
||||
|
||||
Last_Static_Read = DateTime.Now;
|
||||
}
|
||||
@@ -4818,6 +4819,77 @@ namespace CMS_CORE_Library.Fanuc
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
private CmsError ReadSerialNumber(ref string serialNum)
|
||||
{
|
||||
|
||||
string partProgramPath = "";
|
||||
string partProgramContent = "";
|
||||
bool fileEnded = false;
|
||||
int lenght = 256;
|
||||
|
||||
|
||||
// Start read process
|
||||
short nReturn = Focas1.cnc_upstart4(nLibHandle[0], 8, partProgramPath); // 2 parameter = 8, means read maintenance FILE
|
||||
// Return if there's an error
|
||||
if (nReturn != 0)
|
||||
return GetNcError(nReturn);
|
||||
|
||||
do
|
||||
{
|
||||
// Local buffer
|
||||
char[] tmpContentBuffer = new char[256]; // TODO find function to read size file
|
||||
|
||||
// Read file
|
||||
nReturn = Focas1.cnc_upload4(nLibHandle[0], ref lenght, tmpContentBuffer);
|
||||
|
||||
// If File ended
|
||||
switch (nReturn)
|
||||
{
|
||||
case (short)Focas1.focas_ret.EW_RESET:
|
||||
{
|
||||
fileEnded = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case Focas1.EW_OK:
|
||||
{
|
||||
// Add the characters into string with all the content
|
||||
partProgramContent += new string(tmpContentBuffer);
|
||||
}
|
||||
break;
|
||||
|
||||
case (short)Focas1.focas_ret.EW_BUFFER:
|
||||
{
|
||||
continue;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return GetNcError(nReturn);
|
||||
}
|
||||
}
|
||||
|
||||
if (lenght <= 256)
|
||||
fileEnded = true;
|
||||
} while ((nReturn == (short)Focas1.focas_ret.EW_OK || nReturn == (short)Focas1.focas_ret.EW_BUFFER) && !fileEnded);
|
||||
|
||||
// End read
|
||||
nReturn = Focas1.cnc_upend4(nLibHandle[0]);
|
||||
|
||||
var lines = partProgramContent
|
||||
.Split('\n');
|
||||
|
||||
var line = lines
|
||||
.Where(x => x.IndexOf("serial", StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (line == null)
|
||||
return NO_ERROR;
|
||||
|
||||
serialNum = line.Split(':')[1];
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
// Manage the Exception Launch
|
||||
private CmsError GetNcError(short exNum)
|
||||
{
|
||||
|
||||
@@ -418,6 +418,8 @@ namespace CMS_CORE_Library.Models
|
||||
|
||||
public byte WorkOverride { get; set; }
|
||||
|
||||
public double FeedOverride { get; set; }
|
||||
|
||||
public OffsetModel OffsetData { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace CMS_CORE_Library.Osai
|
||||
|
||||
//private const string TOOL_MANAGER_DIRECTORY_PATH = @"active\OEM\CMS\SYS\ACTIVE\";
|
||||
|
||||
private static List<string> EXT_PP = new List<string>() { "", "TXT", "CNC", "INI" };
|
||||
private static List<string> EXT_PP = new List<string>() { "", "TXT", "CNC", "INI" };
|
||||
private static List<string> EXT_IMG = new List<string>() { "PNG", "JPG", "JPEG" };
|
||||
private const uint MAX_ROWS_FILE_PREVIEW = 10; // massimo 10 righe
|
||||
|
||||
@@ -197,6 +197,25 @@ namespace CMS_CORE_Library.Osai
|
||||
|
||||
public override CmsError NC_GetAvailableLanguages(ref ICollection<CultureInfo> languages)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (string file in Directory.GetFiles(PLC_MESSAGE_PATH))
|
||||
{
|
||||
string fileName = Path.GetFileNameWithoutExtension(file);
|
||||
|
||||
var lang = CultureInfo
|
||||
.GetCultures(CultureTypes.NeutralCultures)
|
||||
.Where(ci => string.Equals(ci.EnglishName, fileName.Split('_')[1], StringComparison.OrdinalIgnoreCase))
|
||||
.FirstOrDefault();
|
||||
|
||||
if (lang != null)
|
||||
languages.Add(lang);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return ManageException(ex);
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -1125,7 +1144,7 @@ namespace CMS_CORE_Library.Osai
|
||||
case "MD": Type = MEMORY_TYPE.Osai_MD; break;
|
||||
case "GD": Type = MEMORY_TYPE.Osai_GD; break;
|
||||
};
|
||||
|
||||
|
||||
index = index[1].Split('.');
|
||||
|
||||
try
|
||||
@@ -1142,8 +1161,8 @@ namespace CMS_CORE_Library.Osai
|
||||
}
|
||||
else if (memType == SCADA_MEM_TYPE.WORD)
|
||||
{ // read WORD
|
||||
ushort val = 0;
|
||||
cmsError = MEM_RWWord(R, 0, Type, Convert.ToInt32(index[0]), ref val);
|
||||
short val = 0;
|
||||
cmsError = MEM_RWShort(R, 0, Type, Convert.ToInt32(index[0]), ref val);
|
||||
|
||||
value = val;
|
||||
}
|
||||
@@ -1214,8 +1233,8 @@ namespace CMS_CORE_Library.Osai
|
||||
}
|
||||
else if (memType == SCADA_MEM_TYPE.WORD)
|
||||
{ // write WORD
|
||||
ushort val = Convert.ToUInt16(value);
|
||||
cmsError = MEM_RWWord(W, 0, type, Convert.ToInt32(index[0]), ref val);
|
||||
short val = Convert.ToInt16(value);
|
||||
cmsError = MEM_RWShort(W, 0, type, Convert.ToInt32(index[0]), ref val);
|
||||
}
|
||||
else if (memType == SCADA_MEM_TYPE.REAL)
|
||||
{ // write DOUBLE
|
||||
@@ -1842,7 +1861,8 @@ namespace CMS_CORE_Library.Osai
|
||||
ProcessMessage = message ?? "",
|
||||
RapidOverride = Convert.ToByte(info.rapfeedov / 100),
|
||||
WorkOverride = Convert.ToByte(info.manfeedov / 100),
|
||||
OffsetData = offsetData
|
||||
OffsetData = offsetData,
|
||||
FeedOverride = (double)info.feedov / 100
|
||||
};
|
||||
|
||||
return NO_ERROR;
|
||||
@@ -2583,6 +2603,10 @@ namespace CMS_CORE_Library.Osai
|
||||
if (cmsError.IsError())
|
||||
return cmsError;
|
||||
|
||||
// If i have to read convert the (2x) WORD list into UINT
|
||||
if (!bWrite)
|
||||
Value = ShortValue.ConvertAll(x => (short)x);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@@ -4869,12 +4893,12 @@ namespace CMS_CORE_Library.Osai
|
||||
internal static MEMORY_CELL SELF_ADAPTIVE_PATH = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 3472, 4);
|
||||
|
||||
// Assisted tooling
|
||||
internal static MEMORY_CELL ASSISTED_TOOLING_DATA = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 4512, 7);
|
||||
internal static MEMORY_CELL HMI_ASSISTED_TOOLING_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 4518, 0, 1);
|
||||
internal static MEMORY_CELL HMI_ASSISTED_TOOLING_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 4518, 1, 1);
|
||||
internal static MEMORY_CELL ASSISTED_TOOLING_DATA = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4512, 7);
|
||||
internal static MEMORY_CELL HMI_ASSISTED_TOOLING_STROBE = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4518, 0, 1);
|
||||
internal static MEMORY_CELL HMI_ASSISTED_TOOLING_ACK = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4518, 1, 1);
|
||||
|
||||
internal static MEMORY_CELL PLC_ASSISTED_TOOLING_ACK = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 4519, 1, 1);
|
||||
internal static MEMORY_CELL PLC_ASSISTED_TOOLING_STROBE = new MEMORY_CELL(MEMORY_TYPE.Fanuc_R, 4519, 1, 1);
|
||||
internal static MEMORY_CELL PLC_ASSISTED_TOOLING_ACK = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4519, 1, 1);
|
||||
internal static MEMORY_CELL PLC_ASSISTED_TOOLING_STROBE = new MEMORY_CELL(MEMORY_TYPE.Osai_MW, 4519, 1, 1);
|
||||
}
|
||||
|
||||
#endregion Memory addresses
|
||||
|
||||
@@ -241,7 +241,7 @@ namespace CMS_CORE_Library.Siemens
|
||||
// Machine
|
||||
axesData.Add(new Item() { Path = string.Format("/Nck/{0}[u{1},{2}]", "MachineAxis/actToolBasePos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
|
||||
// Programmed
|
||||
axesData.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", "GeometricAxis/actProgPos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
|
||||
axesData.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", "GeometricAxis/cmdProgPos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
|
||||
// Interp
|
||||
axesData.Add(new Item() { Path = string.Format("/Channel/{0}[u{1},{2}]", "GeometricAxis/actToolEdgeCenterPos", SelectedProcess, conf.Id), SymbolicName = conf.Id.ToString() });
|
||||
// Dist to go
|
||||
@@ -448,7 +448,11 @@ namespace CMS_CORE_Library.Siemens
|
||||
{
|
||||
string fileName = Path.GetFileNameWithoutExtension(file);
|
||||
|
||||
languages.Add(CultureInfo.CreateSpecificCulture(fileName.Split('_')[1]));
|
||||
// Get lang from threeletter
|
||||
var lang = GetCultureFromThreeLetter(fileName.Split('_')[1]);
|
||||
|
||||
if (lang != null)
|
||||
languages.Add(lang);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -1397,8 +1401,8 @@ namespace CMS_CORE_Library.Siemens
|
||||
}
|
||||
else if (memType == SCADA_MEM_TYPE.WORD)
|
||||
{ // read WORD
|
||||
ushort val = 0;
|
||||
cmsError = MEM_RWWord(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
|
||||
short val = 0;
|
||||
cmsError = MEM_RWShort(R, 0, MEMORY_TYPE.Siemens_DB, Convert.ToInt32(index[0]), Convert.ToInt32(index[1]), ref val);
|
||||
|
||||
value = val;
|
||||
}
|
||||
@@ -1449,8 +1453,8 @@ namespace CMS_CORE_Library.Siemens
|
||||
}
|
||||
else if (memType == SCADA_MEM_TYPE.WORD)
|
||||
{ // write WORD
|
||||
ushort val = 0;
|
||||
cmsError = MEM_RWWord(W, 0, MEMORY_TYPE.Osai_MW, Convert.ToInt32(index[0]), ref val);
|
||||
short val = 0;
|
||||
cmsError = MEM_RWShort(W, 0, MEMORY_TYPE.Osai_MW, Convert.ToInt32(index[0]), ref val);
|
||||
}
|
||||
else if (memType == SCADA_MEM_TYPE.REAL)
|
||||
{ // write DOUBLE
|
||||
@@ -1974,13 +1978,14 @@ namespace CMS_CORE_Library.Siemens
|
||||
|
||||
try
|
||||
{
|
||||
Item[] items = new Item[5]
|
||||
Item[] items = new Item[6]
|
||||
{
|
||||
new Item { Path = "/Channel/State/actTNumber[u" + processId + ",1]" }, // ActiveToolId
|
||||
new Item { Path = "/Channel/State/actDNumber[u" + processId + ",1]" }, // OffsetId
|
||||
new Item { Path = "/Channel/State/actFrameIndex[u" + processId + "]" }, // Origin
|
||||
new Item { Path = "DB21.DBB4"}, // Work override
|
||||
new Item { Path = "DB21.DBB5"} // Rapid override
|
||||
new Item { Path = "DB21.DBB5"}, // Rapid override,
|
||||
new Item { Path = "/Channel/State/actFeedRateIpo[u" + processId + ", 1]"}
|
||||
};
|
||||
|
||||
// Read data
|
||||
@@ -2027,7 +2032,8 @@ namespace CMS_CORE_Library.Siemens
|
||||
ProcessMessage = "",
|
||||
WorkOverride = Convert.ToByte(items[3].Value),
|
||||
RapidOverride = Convert.ToByte(items[4].Value),
|
||||
OffsetData = offset
|
||||
OffsetData = offset,
|
||||
FeedOverride = Convert.ToDouble(items[5].Value)
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
@@ -303,5 +304,14 @@ namespace CMS_CORE_Library.Utils
|
||||
{
|
||||
return (b & (1 << bitNumber)) != 0;
|
||||
}
|
||||
|
||||
public static CultureInfo GetCultureFromThreeLetter(string threeLetter)
|
||||
{
|
||||
// Get culture info from three letter iso standard
|
||||
return CultureInfo
|
||||
.GetCultures(CultureTypes.NeutralCultures)
|
||||
.Where(ci => string.Equals(ci.ThreeLetterISOLanguageName, threeLetter, StringComparison.OrdinalIgnoreCase))
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user