initialize

This commit is contained in:
Pruefer
2025-06-06 09:15:13 +02:00
commit fa7c2730f1
5817 changed files with 1339670 additions and 0 deletions

View File

@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<appSettings>
<!-- The name or the IP address of the OIB Core Host -->
<add key="OIBCoreHostName" value="192.168.5.51" />
<!-- define the factory element for the MES SiMM Application.
Find the value for this configuration in the ASM Studio - Factory Layout.
Typically use here the main area. -->
<add key="factoryElementPathMes" value="Enterprise:Site_327811073"/>
<!-- the port of the endpoint. please note that port sharing is not enabled;
every application MUST have it's own port
the resulting endpoint looks like this
http://host:port/iTAC.SIMMApplication/SetupCenterExtCrtl/SIMM
You may browse this port via a web browser and you will get an overview page
It is required to assign this endpoint manually to the Factory
-->
<add key="SetupCenterExternalControlPort" value="35331"/>
<!-- define to which server this iTAC.SIMM.Application should connect to -->
<add key="itac.artes.clusternodes" value="http://itacsv103:10080/mes"/>
<!-- define the client
this is required for registration of the process -->
<add key="client" value="01"/>
<!-- use this movement code for any material quantity change
because the client just provides the current filling level it is not possible to
distinguish between positive and negative movements -->
<add key="transactionCode" value="122" />
<!-- define which station number should be used to call IMSAPI for Material verification
a verification will fail if the station is not existent or not TR-licensed -->
<add key="stationNumber" value="01010010"/>
<!-- define which system leads for maintaining the quantities of containers
available values are off, MES, SIMM
see flows for description-->
<add key="QuantityMaster" value="off"/>
<!-- define which system leads for maintaining the msl-Values of containers
available values are off, MES, SIMM (not case-sensitive)
see flows for description-->
<add key="MSLMaster" value="SIMM"/>
<!-- define which system leads for maintaining the expiration of containers
available values are off, MES, SIMM (not case-sensitive)
see flows for description-->
<add key="ExpirationMaster" value="simm"/>
<!-- define the interval the application check s the MES for empty containers
and report them to the SiMM
Format: hr:mi:secs, invalid values are reported at start time
Option is disabled if value is 00:00:00 -->
<add key="emptyContainerCheckInterval" value="00:00:15"/>
<!-- optional parameters to enable/disable some features
by default this check is disabled!-->
<add key="mslLevelCheck" value="false"/>
</appSettings>
<log4net>
<appender name="LogFileAppenderFull" type="log4net.Appender.RollingFileAppender">
<file value=".\log\itac.simm.full.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<header value="" />
<footer value="" />
<conversionPattern value="%date{dd.MM.yyyy HH:mm:ss,f} %8.10c %-5p %m%n" />
</layout>
</appender>
<appender name="LogFileAppenderError" type="log4net.Appender.RollingFileAppender">
<file value=".\log\itac.simm.error.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="3" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="WARN" />
<levelMax value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<header value="" />
<footer value="" />
<conversionPattern value="%date{dd.MM.yyyy HH:mm:ss,f} %8.10c %-5p %m%n" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
<layout type="log4net.Layout.PatternLayout">
<header value="[Header]\r\n" />
<footer value="[Footer]\r\n" />
<conversionPattern value="%date{dd.MM.yyyy HH:mm:ss,f} %8.10c %-5p %m%n" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppenderFull" />
<appender-ref ref="LogFileAppenderError" />
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
</configuration>

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Itac.Oib
{
public interface IReceiver
{
void StartReceiver();
void StopReceiver();
}
}

View File

@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("SimmApplication3x")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SimmApplication3x")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("561159ec-a9b8-48c7-8fe2-09428c10d1f0")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,6 @@
Version 3.2.0.1 (20161124)
----------------------------------------------------------------------------------------
- Initial Version
- no automatic registration of the endpoint for SiMM
- start as administrator required
- basic functionality adjusting material quantity

View File

@@ -0,0 +1,151 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{561159EC-A9B8-48C7-8FE2-09428C10D1F0}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>com.itac.mes.proxy</RootNamespace>
<AssemblyName>SimmApplication3x</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject>com.itac.mes.proxy.winservice.WindowsService</StartupObject>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>icon_oib_simm.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="ASM.AS.OIB.Client">
<HintPath>..\libs\asm3client\ASM.AS.OIB.Client.dll</HintPath>
</Reference>
<Reference Include="ASM.AS.OIB.Client.CustomExtensions">
<HintPath>..\libs\asm3client\ASM.AS.OIB.Client.CustomExtensions.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.Common">
<HintPath>..\libs\oib3\Asm.As.Oib.Common.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.Common.Proxy">
<HintPath>..\libs\oib3\Asm.As.Oib.Common.Proxy.dll</HintPath>
</Reference>
<Reference Include="ASM.AS.OIB.DisplayService.Contracts">
<HintPath>..\libs\oib3\ASM.AS.OIB.DisplayService.Contracts.dll</HintPath>
</Reference>
<Reference Include="ASM.AS.OIB.DisplayService.Proxy">
<HintPath>..\libs\oib3\ASM.AS.OIB.DisplayService.Proxy.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.Monitoring.Contracts">
<HintPath>..\libs\oib3\Asm.As.Oib.Monitoring.Contracts.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.Monitoring.Proxy">
<HintPath>..\libs\oib3\Asm.As.Oib.Monitoring.Proxy.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.SIPLACEPro.Contracts">
<HintPath>..\libs\oib3\Asm.As.Oib.SIPLACEPro.Contracts.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.SIPLACEPro.LineControl.Contracts">
<HintPath>..\libs\oib3\Asm.As.Oib.SIPLACEPro.LineControl.Contracts.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.SIPLACEPro.LineControl.Proxy">
<HintPath>..\libs\oib3\Asm.As.Oib.SIPLACEPro.LineControl.Proxy.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.SIPLACEPro.Proxy">
<HintPath>..\libs\oib3\Asm.As.Oib.SIPLACEPro.Proxy.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.SIPLACESetupCenter.Contracts">
<HintPath>..\libs\oib3\Asm.As.Oib.SIPLACESetupCenter.Contracts.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.SiplaceSetupCenter.Proxy">
<HintPath>..\libs\oib3\Asm.As.Oib.SiplaceSetupCenter.Proxy.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.WS.Common">
<HintPath>..\libs\oib3\Asm.As.Oib.WS.Common.dll</HintPath>
</Reference>
<Reference Include="Asm.As.Oib.WS.Eventing.Contracts">
<HintPath>..\libs\oib3\Asm.As.Oib.WS.Eventing.Contracts.dll</HintPath>
</Reference>
<Reference Include="IMSApiDotNet">
<HintPath>..\libs\itac\IMSApiDotNet.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Itac.Oib\IReceiver.cs" />
<Compile Include="com.itac.mes.proxy.winservice\WindowsService.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="com.itac.mes.proxy.winservice\WindowsServiceInstaller.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="com.itac.mes.simm\ConfigCode.cs" />
<Compile Include="com.itac.mes.simm\ContainerCheckThread.cs" />
<Compile Include="com.itac.mes.simm\MaterialBinBooking.cs" />
<Compile Include="com.itac.mes.simm\MslLevel.cs" />
<Compile Include="com.itac.mes.simm\SetupCenterExternalControlReceiver.cs" />
<Compile Include="com.itac.mes.simm\SmtContainer.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<Content Include="icon_oib_simm.ico" />
<Content Include="Readme.txt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ItacTools\ItacTools.csproj">
<Project>{db6626c3-81a3-49f4-9117-b20c9b87a2c4}</Project>
<Name>ItacTools</Name>
</ProjectReference>
<ProjectReference Include="..\MesTools\ItacMesTools.csproj">
<Project>{886de482-89c0-4f56-b699-27c63f8255d5}</Project>
<Name>ItacMesTools</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="resources\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,442 @@
#region Namespace
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Security.Principal;
using System.ServiceProcess;
using System.Threading;
using Asm.As.Oib.Client;
using com.itac.mes.imsapi;
using com.itac.mes.imsapi.client.dotnet;
using com.itac.mes.imsapi.domain.container;
using com.itac.mes.simm;
using com.itac.mes.tools;
using Itac.Oib.Simm;
#endregion
namespace com.itac.mes.proxy.winservice
{
public class WindowsService : ServiceBase
{
#region Fields
/// <summary>
/// Der Linienname ergibt sich aus der SetupCenter Konfiguration. Es darf nur eine Linie geben.
/// </summary>
private OibClient _oibClient;
private static List<tools.KeyValue> versionList;
private static IMSApiDotNet imsapi = null;
private IMSApiSessionValidationStruct sessValData = new IMSApiSessionValidationStruct();
private IMSApiSessionContextStruct newSessionContext = null;
private IIMSApiDotNet imsapiproxy = null;
#endregion
#region Static Methods
private static string GetVersionNr()
{
var asm = Assembly.GetExecutingAssembly();
var asmName = asm.GetName();
object[] attribs = asm.GetCustomAttributes(typeof(AssemblyProductAttribute), true);
string productName = String.Empty;
if (attribs.Length > 0)
{
var asmProduct = attribs[0] as AssemblyProductAttribute;
productName = asmProduct.Product;
}
string aVersion = String.Format("{1}.{2}.{3}.{4}",
productName, asmName.Version.Major, asmName.Version.Minor, asmName.Version.Build, asmName.Version.Revision);
string vers = String.Format("{0} - Version: {1}", productName, aVersion);
return (vers);
}
private static string GetFileVersionNr()
{
var asm = Assembly.GetExecutingAssembly();
object[] attribs = asm.GetCustomAttributes(typeof(AssemblyProductAttribute), true);
string productName = String.Empty;
var assembly = Assembly.GetExecutingAssembly();
if (attribs.Length > 0)
{
var asmProduct = attribs[0] as AssemblyProductAttribute;
productName = asmProduct.Product;
}
var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
// string version = fvi.ProductVersion;
versionList.Add(new tools.KeyValue() { key = productName, value = fvi.ProductVersion });
string version = String.Format("FileVersion: {1}", productName, fvi.ProductVersion);
try
{
String[] xVersion = fvi.Comments.Split();
String[] mesVersion = xVersion[3].Split('=');
versionList.Add(new tools.KeyValue() { key = mesVersion[0], value = mesVersion[1] });
String[] intfVersion = xVersion[4].Split('=');
versionList.Add(new tools.KeyValue() { key = intfVersion[0], value = intfVersion[1] });
}
catch (Exception)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Warning, "unable to extract version information from assembly " + assembly.GetName());
}
return (version);
}
#endregion
/// <summary>
/// Public Constructor for WindowsService.
/// - Put all of your Initialization code here.
/// </summary>
public WindowsService()
{
ServiceName = Constants.SERVICE_NAME;
EventLog.Log = Constants.LOGGER;
// These Flags set whether or not to handle that specific
// type of event. Set to true if you need it, false otherwise.
CanHandlePowerEvent = true;
CanHandleSessionChangeEvent = true;
CanPauseAndContinue = true;
CanShutdown = true;
CanStop = true;
}
/// <summary>
/// The Main Thread: This is where your Service is Run.
/// </summary>
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += (sender, e) =>
{
if (e.IsTerminating)
{
object o = e.ExceptionObject;
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "### general exception handling ###");
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, o.ToString());
}
};
var service = new WindowsService();
#if (SERVICE)
ServiceBase.Run(service);
#else
service.OnStart(null);
Console.ReadLine();
service.OnStop();
#endif
}
/// <summary>
/// OnStart(): Put startup code here
/// - Start threads, get inital data, etc.
/// </summary>
/// <param name="args"></param>
protected override void OnStart(string[] args)
{
InitService();
base.OnStart(args);
}
/// <summary>
/// OnStop(): Put your stop code here
/// - Stop threads, set final data, etc.
/// </summary>
protected override void OnStop()
{
ShutdownService();
base.OnStop();
}
/// <summary>
/// OnShutdown(): Called when the System is shutting down
/// - Put code here when you need special handling
/// of code that deals with a system shutdown, such
/// as saving special data before shutdown.
/// </summary>
protected override void OnShutdown()
{
ShutdownService();
base.OnShutdown();
}
/// <summary>
/// Dieser Adapter übernimmt die Steuerung der Subscriptions und der Endpoints
/// </summary>
private StatisticWorker statisticWorker;
private Thread statisticThread;
private void InitService()
{
// Ausgabe hilfe für xml-Messages
var config = new AppSettingsReader();
try
{
#if (SERVICE)
TraceListener eventLogTraceListener = new EventLogTraceListener(Constants.SERVICE_NAME);
eventLogTraceListener.Filter = new EventTypeFilter(SourceLevels.Information);
LogHandler.addListener(eventLogTraceListener);
#endif
// Der Port an dem der Adapter auf eingehende Verbindungen des iTAC DataInterface lauscht
var clusterNodes = (String)config.GetValue("itac.artes.clusterNodes", typeof(String));
var stationNumber = (String)config.GetValue("stationNumber", typeof(String));
var client = (String)config.GetValue("client", typeof(String));
var transactionCode = (int)config.GetValue("transactionCode", typeof(int));
var factoryElementPathMes = (String)config.GetValue("factoryElementPathMes", typeof(String));
// diese Werte werden alle benötigt...
var oibCoreComuputerName = (String)config.GetValue("OIBCoreHostName", typeof(String));
var setupCenterExternalControlPort = (int)config.GetValue("SetupCenterExternalControlPort", typeof(int));
// check values for those 3 settings (off, MES, SiMM);
ConfigCode quantityMaster = ConfigCode.OFF;
ConfigCode mslMaster = ConfigCode.OFF;
ConfigCode expirationMaster = ConfigCode.OFF;
try
{
quantityMaster = GetCode((String)config.GetValue("QuantityMaster", typeof(String)), "QuantityMaster");
mslMaster = GetCode((String)config.GetValue("MSLMaster", typeof(String)), "MSLMaster");
expirationMaster = GetCode((String)config.GetValue("ExpirationMaster", typeof(String)), "ExpirationMaster");
}
catch (ArgumentException ae)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, ae.Message);
return;
}
string sEmptyContainerCheckInterval = (string)config.GetValue("emptyContainerCheckInterval", typeof(string));
TimeSpan emptyContainerCheckInterval = new TimeSpan(0);
try
{
emptyContainerCheckInterval = TimeSpan.Parse(sEmptyContainerCheckInterval);
}
catch (FormatException)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "invalid value " + sEmptyContainerCheckInterval + " for configParameter emptyContainerCheckInterval");
return;
}
catch (OverflowException)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "invalid value " + sEmptyContainerCheckInterval + " for configParameter emptyContainerCheckInterval");
return;
}
if (emptyContainerCheckInterval.Ticks == 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "checking MES for empty containers switched OFF by configuration value");
}
else
{
if (emptyContainerCheckInterval.TotalSeconds < ContainerCheckThread.MIN_INTERVAL_SECONDS)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "minimum value for checking MES for empty containers is " + ContainerCheckThread.MIN_INTERVAL_SECONDS
+ " seconds, but configured is " + emptyContainerCheckInterval.ToString());
return;
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "checking MES for empty containers " + emptyContainerCheckInterval.ToString());
// create and start appropriate thread
}
// check that the process is started as administrator or end process with message
WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, getHeadertext("iTAC.SiMM.Application Startup Problem"));
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "");
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Insufficient privileges!");
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "This process needs to be started with administrative privileges.");
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Right click on the executable file and select \"Run As Administrator\"");
return;
}
versionList = new List<tools.KeyValue>();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("iTAC.SIMM.Application"));
LogHandler.log(Constants.LOGGER, TraceEventType.Information, GetVersionNr() + " / " + GetFileVersionNr());
IMSApiDotNet.setProperty("itac.appid", "iTAC_SIMM_Application");
IMSApiDotNet.setProperty("itac.artes.clusternodes", clusterNodes);
imsapi = IMSApiDotNet.loadLibrary();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("IMS API"));
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "start Initializing IMS API " + clusterNodes);
int result = imsapi.imsapiInit();
if (result != IMSApiDotNetConstants.RES_OK)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "IMS API initialization failed " + clusterNodes + ": " + result);
return;
}
// read values for 'in' and 'inout' arguments
sessValData.stationNumber = stationNumber;
sessValData.stationPassword = "";
sessValData.user = "";
sessValData.password = "";
sessValData.client = client;
sessValData.registrationType = "S";
sessValData.systemIdentifier = "iTAC.SIMM";
result = imsapi.regLogin(sessValData, out newSessionContext);
if (result != IMSApiDotNetConstants.RES_OK)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "IMS API regLogin failed: " + result);
return;
}
ImsApiProxy proxy = new ImsApiProxy(imsapi);
imsapiproxy = (IIMSApiDotNet)proxy.GetTransparentProxy();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "IMS API initialized");
var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in loadedAssemblies)
{
if (assembly.FullName.StartsWith("AsmApi"))
{
AssemblyProductAttribute adAttr = (AssemblyProductAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyProductAttribute));
versionList.Add(new tools.KeyValue() { key = "AsmApi", value = adAttr.Product });
Console.WriteLine("AsmApi" + adAttr.Product);
}
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("Simm Application Startup"));
_oibClient = new OibClient("iTAC", "SIMMApplication", oibCoreComuputerName, factoryElementPathMes, true);
/// listener auf externalcontrol bauen
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("SetupCenterExternalControl"));
var oibSetupCenterExternalControlEvents = _oibClient.GetOibSetupCenterExternalControlEvents(setupCenterExternalControlPort, PortsharingMode.WithoutTcpPortsharing);
var setupCenterNotificationClient = _oibClient.GetSetupCenterNotificationClient();
SetupCenterExternalControlReceiver externalcontrolReceiver = new SetupCenterExternalControlReceiver(oibSetupCenterExternalControlEvents, imsapiproxy, newSessionContext,
stationNumber, transactionCode, quantityMaster, mslMaster, expirationMaster);
externalcontrolReceiver.StartReceiver();
// create and start appropriate thread
if (emptyContainerCheckInterval.TotalSeconds >= 10)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("iTAC.SiMM.Application startup container check thread"));
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "checking MES for empty containers interval: " + emptyContainerCheckInterval.ToString());
ContainerCheckThread ctt = new ContainerCheckThread(emptyContainerCheckInterval, imsapiproxy, newSessionContext, setupCenterNotificationClient, stationNumber);
ctt.Start();
}
try
{
HashSet<string> versionKeySet = new HashSet<string>();
versionKeySet.Add("ServiceLocator");
versionKeySet.Add("SIPLACE.SetupCenter.MaterialControl");
var serviceLocator = _oibClient.GetSeriviceLocatorClient();
var allServices = serviceLocator.GetAllServices();
for (int i = 0; i < allServices.Length; i++)
{
var sd = allServices[i];
if (versionKeySet.Contains(sd.ServiceName) && sd.Configuration != null)
{
versionList.Add(new tools.KeyValue() { key = sd.ServiceName, value = sd.ServiceVersion });
}
}
}
catch (Exception)
{
throw;
}
String currentPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "current path = " + currentPath);
var proxyVersions = _oibClient.GetOibProxyVersions();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("SIMM Proxy Versions"));
foreach (var keyValuePair in proxyVersions)
{
if (!keyValuePair.Key.Equals("AsmApi"))
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, string.Format("{0,-50} {1,10}", keyValuePair.Key, keyValuePair.Value));
}
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("Statistic Thread"));
try
{
statisticWorker = new StatisticWorker();
statisticWorker.setVersionList(versionList);
statisticThread = new Thread(statisticWorker.DoWork);
statisticThread.Start();
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "Statistic thread started! ");
}
catch (Exception e)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Statistic thread NOT started!", e);
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, getHeadertext("Initialization completed"));
}
catch (Exception e)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "Initialization failed! " + e.Message, e);
}
}
private ConfigCode GetCode(string sCodeValue, string sParameterName)
{
foreach (ConfigCode configCode in Enum.GetValues(typeof(ConfigCode)))
{
if (configCode.ToString().Equals(sCodeValue.ToUpper()))
{
return configCode;
}
}
throw new ArgumentException("The value " + sCodeValue + " is invalid for the parameter " + sParameterName);
}
private string getHeadertext(string v)
{
String separator = "-----------------------------------------------------------------------";
if (separator.Length < v.Length)
{
return separator.Substring(0, 10) + " " + v;
}
else
{
return separator.Substring(0, 10) + " " + v + " " + separator.Substring(0, separator.Length - v.Length);
}
}
private void ShutdownService()
{
statisticWorker.RequestStop();
statisticThread.Join();
if (_oibClient != null)
_oibClient.Dispose();
}
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.ServiceProcess;
using com.itac.mes.tools;
namespace com.itac.mes.proxy.winservice
{
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer
{
/// <summary>
/// Public Constructor for WindowsServiceInstaller.
/// - Put all of your Initialization code here.
/// </summary>
public WindowsServiceInstaller()
{
ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
ServiceInstaller serviceInstaller = new ServiceInstaller();
//# Service Account Information
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
serviceProcessInstaller.Username = null;
serviceProcessInstaller.Password = null;
//# Service Information
serviceInstaller.DisplayName = Constants.SERVICE_NAME;
serviceInstaller.StartType = ServiceStartMode.Automatic;
//# This must be identical to the WindowsService.ServiceBase name
//# set in the constructor of WindowsService.cs
serviceInstaller.ServiceName = Constants.SERVICE_NAME;
this.Installers.Add(serviceProcessInstaller);
this.Installers.Add(serviceInstaller);
}
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
ServiceController controller = new ServiceController(Constants.SERVICE_NAME);
try
{
controller.Start();
}
catch (Exception e)
{
if (!EventLog.SourceExists(Constants.SERVICE_NAME))
{
EventLog.CreateEventSource(Constants.SERVICE_NAME, Constants.LOGGER);
}
EventLog.WriteEntry(Constants.SERVICE_NAME, "@The service could not be started. Error: " + e.Message, EventLogEntryType.Error);
}
}
}
}

View File

@@ -0,0 +1,14 @@
namespace com.itac.mes.simm
{
/// <summary>
/// possible values for the configuration settings
/// </summary>
public enum ConfigCode
{
OFF = 0,
MES = 1,
SIMM = 2
}
}

View File

@@ -0,0 +1,189 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Asm.As.Oib.Client;
using com.itac.mes.imsapi.client.dotnet;
using com.itac.mes.tools;
using com.itac.mes.imsapi.domain.container;
using KeyValue = com.itac.mes.imsapi.domain.container.KeyValue;
using www.siplace.com.OIB._2008._05.SetupCenter.Contracts.Data;
using com.itac.mes.imsapi;
namespace com.itac.mes
{
class ContainerCheckThread
{
private static string attributeName = "SIMM-ManualSetToZero";
public static int MIN_INTERVAL_SECONDS = 10;
private TimeSpan interval;
private Thread thread;
private IIMSApiDotNet imsapi;
private SetupCenterNotificationClient setupCenterNotificationClient;
private string stationNumber;
private IMSApiSessionContextStruct sessionContext;
private KeyValue[] materialBinFilters = new KeyValue[] { new KeyValue("MATERIAL_BIN_NUMBER", "*") };
private AttributeInfo[] attributes = new AttributeInfo[] { new AttributeInfo(attributeName, "1") };
private string[] materialBinResultKeys = new string[] { "MATERIAL_BIN_NUMBER" };
public ContainerCheckThread(TimeSpan interval, IIMSApiDotNet imsapi, IMSApiSessionContextStruct sessionContext, SetupCenterNotificationClient setupCenterNotificationClient, String stationNumber)
{
// none of those values must be null
this.interval = interval;
this.imsapi = imsapi;
this.setupCenterNotificationClient = setupCenterNotificationClient;
this.stationNumber = stationNumber;
this.sessionContext = sessionContext;
if (interval.TotalSeconds >= MIN_INTERVAL_SECONDS)
{
thread = new Thread(CheckContainers);
}
}
public void Start()
{
if (thread != null)
{
thread.Start();
}
}
public void CheckContainers()
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "start checking empty containers in MES (having attribute " + attributeName + "==1)");
while (true)
{
try
{
string[] resultValues;
int objectType = 2;
string attributeValue = "1";
int maxRows = 100;
KeyValue[] attributeFilters = new KeyValue[0];
// getContainers with attribute
int returnCode = imsapi.attribGetObjectsForAttributeValues(sessionContext, stationNumber, objectType, attributeName, attributeValue, maxRows, attributeFilters, materialBinResultKeys, out resultValues);
if (returnCode == 0 || returnCode == 3)
{
// for every container:
// send this info to setupCenter and close them within SC
// if OK remove the attribute from the container, otherwise set appropriate attribute value
foreach (String containerId in resultValues)
{
consumePackagingUnitInSetupCenter(containerId);
}
}
else if (returnCode == -932 || returnCode > 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "no empty containers found");
}
else if (returnCode < 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "failed to retrieve empty containers from MES, apiRet Code=" + returnCode);
}
}
catch (Exception exception)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Critical, "processing empty containers failed", exception);
}
finally
{
DateTime nextRun = DateTime.Now + interval;
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "next run for checking empty containers (having attribute " + attributeName + "==1) in " + interval + " at " + nextRun.ToLongTimeString());
Thread.Sleep(interval);
}
}
}
protected void consumePackagingUnitInSetupCenter(string containerId)
{
// create an ASM packaging unit; for delete it is sufficient to have an UID only
PackagingUnit packagingUnit = new PackagingUnit();
packagingUnit.UID = containerId;
PackagingUnitConsumedReport packUnitConsumedReport = new PackagingUnitConsumedReport();
packUnitConsumedReport.PackagingUnits = new PackagingUnit[] { packagingUnit };
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "raise delete packagingUnit " + containerId + " in SetupCenter");
try
{
setupCenterNotificationClient.RaisePackagingUnitConsumed(packUnitConsumedReport);
// delete Packaging unite succeeded
// remove attribute from container
/* example call:
attribRemoveAttributeValue()
stationNumber= 01010010
objectType= 2
objectNumber= 000197630005
objectDetail= -1
attributeCode= SIMM - ManualSetToZero
attributeValueKey= 1
------------------------------------------------------------------
Result_attribRemoveAttributeValue
.return_value= 0 ''
*/
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "remove attribute " + attributeName + " from container " + containerId);
int objectType = 2;
string objectDetail = "-1";
string attributeValueKey = "1";
int retValue = imsapi.attribRemoveAttributeValue(sessionContext, stationNumber, objectType, containerId, objectDetail, attributeName, attributeValueKey);
if (retValue != 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "removing attribute " + attributeName + " from container " + containerId + " failed");
}
else
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "removing attribute " + attributeName + " from container " + containerId + " succeded");
}
}
catch (Exception e)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "raise consumed event for packagingUnit " + containerId + " failed", e);
// modify attribute value
/* example call
attribAppendAttributeValues()
stationNumber= 01010010
objectType= 2
objectNumber= 000197630005
objectDetail= -1
bookDate= -1
allowOverWrite= 1
attributeUploadKeys.length= 3
attributeUploadKeys[0]= ATTRIBUTE_CODE
attributeUploadKeys[1]= ATTRIBUTE_VALUE
attributeUploadKeys[2]= ERROR_CODE
attributeUploadValues.length= 3
attributeUploadValues[0]= SIMM - ManualSetToZero
attributeUploadValues[1]= 3
attributeUploadValues[2]= 0
------------------------------------------------------------------
Result_attribAppendAttributeValues
.return_value= 0 ''
.attributeResultValues[] empty
*/
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "update attribute " + attributeName + " from container " + containerId + " to value 2");
int objectType = 2;
string objectDetail = "-1";
long bookDate = -1;
int allowOverwrite = 1;
string[] attributeUploadKeys = new string[] { "ATTRIBUTE_CODE", "ATTRIBUTE_VALUE", "ERROR_CODE" };
string[] attributeUploadValues = new string[] { attributeName, "2", "0" };
string[] attributeResultValues = null;
int retValue = imsapi.attribAppendAttributeValues(sessionContext, stationNumber, objectType, containerId, objectDetail,
bookDate, allowOverwrite, attributeUploadKeys, attributeUploadValues, out attributeResultValues);
if (retValue != 0)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "setting attribute " + attributeName + " from container " + containerId + " to value 2 failed");
}
}
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.itac.mes.imsapi;
namespace com.itac.mes.imsapi.data
{
public class MaterialBinBooking
{
public static string[] MAXIMAL_INFORMATION = new string[] { "ERROR_CODE", "MATERIAL_BIN_NUMBER", "MATERIAL_BIN_QTY_ACTUAL", "QUANTITY", "TRANSACTION_CODE" };
[ImsApiKey(Key = "MATERIAL_BIN_NUMBER")]
public string materialBinNumber;
[ImsApiKey(Key = "MATERIAL_BIN_QTY_ACTUAL")]
public int materialBinQuantityActual = 0;
[ImsApiKey(Key = "QUANTITY")]
public int quantity = 0;
[ImsApiKey(Key = "TRANSACTION_CODE")]
public string transactionCode;
[ImsApiKey(Key = "ERROR_CODE")]
public int errorCode = 0;
public int CompareTo(MaterialBinBooking obj)
{
if (materialBinNumber == null) return -1;
if (obj == null) return 1;
return materialBinNumber.CompareTo(obj.materialBinNumber);
}
}
}

View File

@@ -0,0 +1,49 @@
namespace com.itac.mes.proxy
{
public class MslLevel
{
/// <summary>
/// SetupCenter has it's own values for the MSL Levels. These are defined as constants
/// This function returns the value from MsdLevel as a String (lower case);
/// </summary>
/// <param name="mslLevel"></param>
/// <returns></returns>
public static string toString(int msdLevel)
{
switch (msdLevel)
{
case 1: return "1";
case 2: return "2";
case 3: return "2a";
case 4: return "3";
case 5: return "4";
case 6: return "5";
case 7: return "5a";
case 8: return "6";
default: return "1";
}
}
/// <summary>
/// convert a level as it is used in iTAC.MES.Suite to a value used in SetupCenter
/// </summary>
/// <param name="itacLevel"></param>
/// <returns></returns>
public static int toCode(string itacLevel)
{
switch (itacLevel)
{
case "1": return 1;
case "2": return 2;
case "2a": case "2A": return 3;
case "3": return 4;
case "4": return 5;
case "5": return 6;
case "5a": case "5A": return 7;
case "6": return 8;
default:
return 1;
}
}
}
}

View File

@@ -0,0 +1,584 @@
#region Namespace
using System;
using System.Diagnostics;
using System.Reflection;
using System.ServiceModel;
using com.itac.mes.proxy;
using www.siplace.com.OIB._2008._05.SetupCenter.Contracts.Data;
using www.siplace.com.OIB._2008._05.SetupCenter.Contracts.Service;
using OibClient = Asm.As.Oib.Client;
using com.itac.mes.imsapi.domain.container;
using System.Collections.Generic;
using com.itac.mes.imsapi;
using KeyValue = com.itac.mes.imsapi.domain.container.KeyValue;
using com.itac.mes.imsapi.data;
using System.Configuration;
using com.itac.mes.simm;
using com.itac.mes.tools;
using com.itac.mes.imsapi.client.dotnet;
#endregion
namespace Itac.Oib.Simm
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class SetupCenterExternalControlReceiver : ISiplaceSetupCenterExternalControl, IDisposable, IReceiver
{
#region Fields
private readonly OibClient.OibSetupCenterExternalControlEvents _oibSetupCenterExternalControlEvents;
private IIMSApiDotNet imsapi;
private IMSApiSessionContextStruct sessionContext;
private ItacXmlSerializer serializer;
private long firstASMTime = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
private long msdOpenTime = DateTime.MinValue.Ticks;
private long lastItacTimeTicks = new DateTime(3000, 12, 31, 23, 59, 59, DateTimeKind.Utc).Ticks;
private long firstItacTimeTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
/// <summary>
/// the station Number is configured, must not be empty and MUST exist and valid!!!
/// if the stationNumber is not valid (licensed etc) all requests are rejected!!
/// </summary>
private string stationNumber;
private int transactionCode;
// some optional values, default false
private bool mslLevelCheck;
private ConfigCode expirationMaster;
private ConfigCode mslMaster;
private ConfigCode quantityMaster;
#endregion
#region Constructor
public SetupCenterExternalControlReceiver(OibClient.OibSetupCenterExternalControlEvents oibSetupCenterExternalControlEvents, IIMSApiDotNet imsapi, IMSApiSessionContextStruct newSessionContext,
String stationNumber, int transactionCode,
ConfigCode quantityMaster, ConfigCode mslMaster, ConfigCode expirationMaster)
{
_oibSetupCenterExternalControlEvents = oibSetupCenterExternalControlEvents;
if (oibSetupCenterExternalControlEvents != null)
{
oibSetupCenterExternalControlEvents.Ping = Ping;
oibSetupCenterExternalControlEvents.GetNewPackagingUnitData = GetNewPackagingUnitData;
oibSetupCenterExternalControlEvents.GetPackagingUnitControlStatus = GetPackagingUnitControlStatus;
}
this.imsapi = imsapi;
this.sessionContext = newSessionContext;
this.stationNumber = stationNumber;
this.transactionCode = transactionCode;
this.quantityMaster = quantityMaster;
this.mslMaster = mslMaster;
this.expirationMaster = expirationMaster;
serializer = new ItacXmlSerializer();
// evaluate some optional parameters from appConfig file
if (!String.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings["mslLevelCheck"]))
{
mslLevelCheck = bool.Parse(ConfigurationManager.AppSettings["mslLevelCheck"].ToString());
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "optional parameter 'mslLevelCheck' set '" + mslLevelCheck.ToString() + "'");
}
}
public void Dispose()
{
if (_oibSetupCenterExternalControlEvents != null)
_oibSetupCenterExternalControlEvents.Dispose();
}
#endregion
#region Start/Stop
public void StartReceiver()
{
_oibSetupCenterExternalControlEvents.Start();
}
public void StopReceiver()
{
_oibSetupCenterExternalControlEvents.Stop();
}
#endregion
#region toolFunctions
// muss noch weiter getestet werden...
public void DeepCopy(object sourceObject, object destObject)
{
Type sourceType = sourceObject.GetType();
Type destType = destObject.GetType();
MemberInfo[] sourceMbrInfoArray = sourceType.GetMembers();
MemberInfo[] destMbrInfoArray = destType.GetMembers();
foreach (MemberInfo sourceMbrInfo in sourceMbrInfoArray)
{
if (sourceMbrInfo.MemberType == MemberTypes.Property)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Error, "" + sourceMbrInfo + " is a " + sourceMbrInfo.MemberType);
// alle einfachen TypeNameConverter direkt prüfen (int, String, bool)
// komplexe Typen ???
PropertyInfo sourcePropInfo = sourceType.GetProperty(sourceMbrInfo.Name);
// gibt es das Property auch im Zielobjekt
foreach (MemberInfo destMbrInfo in destMbrInfoArray)
{
// identischer Name, identischerr Typ
if (destMbrInfo.MemberType == sourceMbrInfo.MemberType && destMbrInfo.Name == sourceMbrInfo.Name)
{
PropertyInfo destPropInfo = destType.GetProperty(destMbrInfo.Name);
object sourceValue = sourcePropInfo.GetValue(sourceObject, null);
object destValue = destPropInfo.GetValue(destObject, null);
if (sourcePropInfo.PropertyType == typeof(String) || sourcePropInfo.PropertyType == typeof(int)
|| sourcePropInfo.PropertyType == typeof(Int32) || sourcePropInfo.PropertyType == typeof(Int64)
|| sourcePropInfo.PropertyType == typeof(long) || sourcePropInfo.PropertyType == typeof(bool)
|| sourcePropInfo.PropertyType == typeof(Boolean))
{
if (sourceValue != destValue)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "primitive type copy value");
destPropInfo.SetValue(destObject, sourceValue, null);
}
}
else if (!sourceType.IsArray)
{
// komplexer Typ, kein Array
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, sourceMbrInfo.Name + " is complex type ");
if (sourceValue != null)
{
DeepCopy(sourceValue, destValue);
}
else
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, sourceMbrInfo.Name + " is complex type, sourceValue is null");
}
}
}
}
}
}
}
public void applyToPackagingUnit(SmtContainer container, ref PackagingUnit p)
{
p.BatchId = container.supplierChargeNumber;
// p.BatchPackagingUnit=
p.BrightnessClass = container.classification; ;
// p.Comment="";
p.ComponentBarcode = "";
p.ComponentName = container.materialBinPartNumber;
// p.ConsumptionDate = getDateValue(resultValues[indexMap[""]]);
// special case: itac 31.12.3000 is unexpired, in ASM 31.12.9999
if (container.expirationDate >= new DateTime(2037, 12, 31))
{
p.ExpiryDate = DateTime.MaxValue.ToUniversalTime();
}
else
{
p.ExpiryDate = container.expirationDate; // getDateValue(resultValues[indexMap["EXPIRATION_DATE"]]);
}
// p.Extra1="";
// p.Extra2="";
// p.Extra3="";
// p.GreyZone=
if (p.LastProductionDate <= new DateTime(1901, 01, 01, 00, 00, 00, DateTimeKind.Utc))
{
p.LastProductionDate = DateTime.MinValue.ToUniversalTime();
}
// p.ManufactureLocation
// p.ManufacturePartNumber
p.Manufacturer = container.supplierName;
p.ManufacturerDate = container.dateCreated;
p.MsdLevel = MslLevel.toCode(container.mslLevel);
string mslState = container.mslState;
if ("C".Equals(mslState))
{
p.MsdOpenDate = DateTime.MinValue.ToUniversalTime();
}
else
{
// take open date from MES
p.MsdOpenDate = container.mslOpenDate;
// correction of MSD open Date when unopened
if (p.MsdOpenDate <= new DateTime(1901, 01, 01, 00, 00, 00, DateTimeKind.Utc))
{
p.MsdOpenDate = DateTime.MinValue.ToUniversalTime();
}
}
// p.OrderingCode = ;
p.OriginalQuantity = container.quantity;// Convert.ToInt32(double.Parse(resultValues[indexMap["MATERIAL_BIN_QTY_TOTAL"]]));
p.PurchaseOrderNumber = container.huNumber;
p.Quantity = container.materialBinQuantityActual; // Convert.ToInt32(Double.Parse(resultValues[indexMap["MATERIAL_BIN_QTY_ACTUAL"]]));
// p.RevisionLevel;
// p.RoHS
// p.Serial
// p.ShippingNoteNumber
// p.SplicedPackagingUnit
p.Supplier = container.supplierName;
// p.SupplierData
// p.UID;
}
public void mapValues(PackagingUnit pu, string[] materialBinUploadKeys, ref string[] result, int index)
{
foreach (string s in materialBinUploadKeys)
{
switch (s)
{
case "ERROR_CODE": result[index++] = "0"; break;
case "MATERIAL_BIN_NUMBER": result[index++] = pu.UID; break;
default: result[index++] = "0"; break;
}
}
}
public void deepAddUnit(PackagingUnit packUnit, ref Dictionary<string, PackagingUnit> packagingUnitMap)
{
packagingUnitMap.Add(packUnit.UID, packUnit);
if (packUnit.SplicedPackagingUnit != null)
{
deepAddUnit(packUnit.SplicedPackagingUnit, ref packagingUnitMap);
}
}
#endregion toolFunctions
#region ISiplaceSetupCenterExternalControl Members
/// <summary>
/// Check for the client if this service is available.
/// </summary>
/// <returns></returns>
public bool Ping()
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "SetupCenterExternalControl.Ping");
return true;
}
/// <summary>
/// Gets the packaging unit control status.
/// </summary>
/// <param name="packagingUnitLocations">The packaging unit locations.</param>
/// <returns>List of ExternalControlResults for reading the data</returns>
/// ResultState UNKNOWN=0;OK = 1;NOT_OK=2;
public ExternalControlResult[] GetNewPackagingUnitData(PackagingUnitLocation[] packagingUnitLocations)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "SetupCenterExternalControl.GetNewPackagingUnit()\n"
+ serializer.serialize(packagingUnitLocations).ToString());
KeyValue[] matBinfilters = new KeyValue[] { new KeyValue("MATERIAL_BIN_NUMBER", "") };
AttributeInfo[] attributes = new AttributeInfo[0];
string[] resultValues;
try
{
ExternalControlResult[] result = new ExternalControlResult[packagingUnitLocations.Length];
for (int i = 0; i < packagingUnitLocations.Length; i++)
{
result[i] = new ExternalControlResult();
result[i].PackagingUnit = packagingUnitLocations[i].PackagingUnit;
matBinfilters[0].value = packagingUnitLocations[i].PackagingUnit.UID;
int imsapiResult = imsapi.mlGetMaterialBinData(sessionContext, stationNumber, matBinfilters, attributes, SmtContainer.MAXIMAL_INFORMATION, out resultValues);
// return all relevant PackagingUnit infos known in iTAC.MES.Suite
if (imsapiResult < 0 || imsapiResult == 1) // 1 = no data found
{
result[i].ResultState = 2;
result[i].Messages = new ExternalControlResultMessage[] { new ExternalControlResultMessage() };
result[i].Messages[0].Message = "UID " + packagingUnitLocations[i].PackagingUnit.UID + " unknown in iTAC.MES.Suite";
}
else
{
// OK, Info gathered
result[i].ResultState = 1;
result[i].Messages = new ExternalControlResultMessage[] { };
PackagingUnit p = result[i].PackagingUnit;
try
{
SmtContainer knownContainer = new ImsApiMapTool<SmtContainer>().getStruct(typeof(SmtContainer), SmtContainer.MAXIMAL_INFORMATION, resultValues);
applyToPackagingUnit(knownContainer, ref p);
}
catch (Exception e)
{
result[i].ResultState = 2;
result[i].Messages = new ExternalControlResultMessage[] { new ExternalControlResultMessage() };
result[i].Messages[0].Message = e.Message.ToString();
}
}
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, serializer.serialize(result).ToString());
return result;
}
catch (Exception)
{
// Fehler, keine weitere info vorhanden, da die Applikation nicht läuft
return new ExternalControlResult[0];
}
}
/// <summary>
/// Gets the packaging unit control status.
/// </summary>
/// <param name="packagingUnitLocations">The packaging unit locations.</param>
/// <returns>List of ExternalControlResults for reading the data</returns>
public ExternalControlResult[] GetPackagingUnitControlStatus(PackagingUnitLocation[] packagingUnitLocations)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Information, "SetupCenterExternalControl.GetPackagingUnitControlStatus:\n"
+ serializer.serialize(packagingUnitLocations).ToString());
if (!mslLevelCheck)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "mslLevel check switched off by confguration");
}
KeyValue[] matBinfilters = new KeyValue[] { new KeyValue("MATERIAL_BIN_NUMBER", "") };
AttributeInfo[] attributes = new AttributeInfo[0];
// flag wether to update any qty or not.
LinkedList<MaterialBinBooking> updateQtyList = new LinkedList<MaterialBinBooking>();
try
{
ExternalControlResult[] result = new ExternalControlResult[packagingUnitLocations.Length];
for (int resultIndex = 0; resultIndex < packagingUnitLocations.Length; resultIndex++)
{
result[resultIndex] = new ExternalControlResult();
result[resultIndex].PackagingUnit = packagingUnitLocations[resultIndex].PackagingUnit;
PackagingUnit packagingUnit = packagingUnitLocations[resultIndex].PackagingUnit;
// ResultState UNKNOWN = 0; OK = 1; NOT_OK = 2;
result[resultIndex].ResultState = 1;
result[resultIndex].Messages = new ExternalControlResultMessage[] { };
string[] resultValues;
matBinfilters[0].value = packagingUnitLocations[resultIndex].PackagingUnit.UID;
int imsapiResult = imsapi.mlGetMaterialBinData(sessionContext, stationNumber, matBinfilters, attributes, SmtContainer.MINIMAL_INFORMATION, out resultValues);
if (imsapiResult < 0 || imsapiResult == 1) // 1 = no data found
{
// Packaging Units unknown in MES.Suite must be rejected
// Error, Packaging Unit not found in mes.suite
result[resultIndex].ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = "PackagingUnit '" + packagingUnitLocations[resultIndex].PackagingUnit.UID + "' unknown in iTAC.MES.Suite";
result[resultIndex].Messages = new ExternalControlResultMessage[] { message };
}
else
{
// find any differences in quantities and update the values in MES.Suite
SmtContainer knownContainer = new ImsApiMapTool<SmtContainer>().getStruct(typeof(SmtContainer), SmtContainer.MINIMAL_INFORMATION, resultValues);
LogHandler.log(Constants.LOGGER, TraceEventType.Information, serializer.serialize(knownContainer).ToString());
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "quantityMaster=" + quantityMaster);
adjustQuantity(quantityMaster, ref knownContainer, ref packagingUnit, ref updateQtyList);
// any differences in mslLevel?
if (mslLevelCheck)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "mslLevelCheck=true");
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} MsdLevel(ASM): {1}, MslLevel(iTAC): {2}", packagingUnit.UID, packagingUnit.MsdLevel, knownContainer.mslLevel));
if (!knownContainer.mslLevel.ToLower().Equals(MslLevel.toString(packagingUnit.MsdLevel)))
{
// failure, wrong MslLevel
result[resultIndex].ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = String.Format("PackagingUnit {0} has MsdLevel {1} in SetupCenter, but Level {2} in iTAC.MES.Suite",
packagingUnit.UID, MslLevel.toString(packagingUnit.MsdLevel), knownContainer.mslLevel);
result[resultIndex].Messages = new ExternalControlResultMessage[] { message };
}
// continue with next container
continue;
}
// any differences in msl state?
if (mslMaster == ConfigCode.SIMM)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "mslMaster=" + mslMaster.ToString());
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} MsdOpen(ASM): {1}, MslState(iTAC): {2}", packagingUnit.UID, isMsdOpen(packagingUnit.MsdOpenDate), knownContainer.mslState));
// iTAC states : C = geschützt / verschweißt(Closed) O = ungeschützt / offen(Open) B = in der Rücktrocknung (Baking)
// ASM closed: MsdOpenDate = 2.1.1900
KeyValue[] mslEventParams = new KeyValue[] { new KeyValue("BOOK_DATE", getImsApiDateString(packagingUnit.MsdOpenDate)) };
KeyValue[] mslStopEventParams = new KeyValue[] { new KeyValue("BOOK_DATE", "-1") };
string[] mslObjectKeys = new String[] { "ERROR_CODE", "MATERIAL_BIN_NUMBER" };
string[] mslObjectValues = new String[] { "0", packagingUnit.UID };
string[] mslResultValues = new String[] { };
if (knownContainer.mslState.Equals("C") && isMsdOpen(packagingUnit.MsdOpenDate))
{
// closed in iTAC, open in ASM--> required to open in iTAC!!!
int mslStartExpirationCode = imsapi.mslStartObjectExpiration(sessionContext, stationNumber, mslEventParams, mslObjectKeys, mslObjectValues, out mslResultValues);
if (mslStartExpirationCode < 0)
{
result[resultIndex].ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = String.Format("PackagingUnit {0} not opened in iTAC.MES.Suite", packagingUnit.UID);
result[resultIndex].Messages = new ExternalControlResultMessage[] { message };
continue;
}
}
else if (knownContainer.mslState.Equals("O") && !isMsdOpen(packagingUnit.MsdOpenDate) && packagingUnit.MsdOpenDate.Ticks > DateTime.MinValue.Ticks)
{
// open in iTAC, closed in ASM--> required to close in iTAC!!!
int mslStopExpirationCode = imsapi.mslStopObjectExpiration(sessionContext, stationNumber, mslStopEventParams, mslObjectKeys, mslObjectValues, out mslResultValues);
if (mslStopExpirationCode < 0)
{
result[resultIndex].ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = String.Format("PackagingUnit {0} not closed in iTAC.MES.Suite", packagingUnit.UID);
result[resultIndex].Messages = new ExternalControlResultMessage[] { message };
continue;
}
}
}
else if (mslMaster == ConfigCode.MES)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Warning, "this mode is currently not supported!");
}
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, "expirationMaster=" + expirationMaster.ToString());
if (!adjustExpiration(expirationMaster, ref knownContainer, ref packagingUnit, ref imsapi, ref result[resultIndex]))
{
continue;
}
// SiMM-Corrections
if (packagingUnit.MsdOpenDate <= new DateTime(1900, 01, 01)) { packagingUnit.MsdOpenDate = DateTime.MinValue.ToUniversalTime(); }
if (packagingUnit.ConsumptionDate <= new DateTime(1900, 01, 01)) { packagingUnit.ConsumptionDate = DateTime.MinValue.ToUniversalTime(); }
if (packagingUnit.ExpiryDate <= new DateTime(1900, 01, 01)) { packagingUnit.ExpiryDate = DateTime.MinValue.ToUniversalTime(); }
if (packagingUnit.LastProductionDate <= new DateTime(1900, 01, 01)) { packagingUnit.LastProductionDate = DateTime.MinValue.ToUniversalTime(); }
if (packagingUnit.ManufacturerDate <= new DateTime(1900, 01, 01)) { packagingUnit.ManufacturerDate = DateTime.MinValue.ToUniversalTime(); }
}
}
if (quantityMaster == ConfigCode.SIMM && updateQtyList.Count > 0)
{
MaterialBinBooking[] matBinBookingArray = new MaterialBinBooking[updateQtyList.Count];
updateQtyList.CopyTo(matBinBookingArray, 0);
string[] materialBinBookingUploadValues = new ImsApiMapTool<MaterialBinBooking>().getValueArray(matBinBookingArray, MaterialBinBooking.MAXIMAL_INFORMATION); ;
string[] materialBinBookingsResultValues = null;
int retUpdateQty = imsapi.mlUploadMaterialBinBooking(sessionContext, stationNumber, MaterialBinBooking.MAXIMAL_INFORMATION, materialBinBookingUploadValues, out materialBinBookingsResultValues);
}
LogHandler.log(Constants.LOGGER, TraceEventType.Information, serializer.serialize(result).ToString());
return result;
}
catch (Exception)
{
// Fehler, keine weitere info vorhanden, da die Applikation nicht läuft
return new ExternalControlResult[0];
}
}
public void adjustQuantity(ConfigCode quantityMaster, ref SmtContainer knownContainer, ref PackagingUnit packagingUnit, ref LinkedList<MaterialBinBooking> updateQtyList)
{
if (quantityMaster == ConfigCode.SIMM)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} Qty(ASM): {1}, Qty(iTAC): {2}", packagingUnit.UID, packagingUnit.Quantity, knownContainer.materialBinQuantityActual));
if (packagingUnit.Quantity != knownContainer.materialBinQuantityActual)
{
// udpate the MES with the quantity from ASM
MaterialBinBooking matBinBooking = new MaterialBinBooking();
matBinBooking.materialBinNumber = packagingUnit.UID;
matBinBooking.transactionCode = transactionCode.ToString();
matBinBooking.materialBinQuantityActual = packagingUnit.Quantity;
updateQtyList.AddLast(matBinBooking);
}
}
else if (quantityMaster == ConfigCode.MES)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} Qty(ASM): {1}, Qty(iTAC): {2}", packagingUnit.UID, packagingUnit.Quantity, knownContainer.materialBinQuantityActual));
if (packagingUnit.Quantity != knownContainer.materialBinQuantityActual)
{
packagingUnit.Quantity = knownContainer.materialBinQuantityActual;
}
}
}
public bool adjustExpiration(ConfigCode expirationMaster, ref SmtContainer knownContainer, ref PackagingUnit packagingUnit, ref IIMSApiDotNet imsapi, ref ExternalControlResult result)
{
if (expirationMaster == ConfigCode.SIMM)
{
if (packagingUnit.ExpiryDate == DateTime.MinValue)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} no expiration set", packagingUnit.UID));
return true;
}
LogHandler.log(Constants.LOGGER, TraceEventType.Verbose, String.Format("UID: {0} expiryDate(ASM): {1}, expirationDate(iTAC): {2}", packagingUnit.UID, packagingUnit.ExpiryDate, knownContainer.expirationDate));
if (expirationDateDifferent(packagingUnit.ExpiryDate, knownContainer.expirationDate))
{
// update expirationDate in iTAC
KeyValue[] keyValueArray = new KeyValue[1];
keyValueArray[0] = new KeyValue("EXPIRATION_DATE_FINAL", getImsApiDateString(packagingUnit.ExpiryDate));
int changeBinResult = imsapi.mlChangeMaterialBinData(sessionContext, stationNumber, packagingUnit.UID, keyValueArray);
if (changeBinResult < 0)
{
// reject container
result.ResultState = 2;
ExternalControlResultMessage message = new ExternalControlResultMessage();
message.Message = String.Format("PackagingUnit {0} expiration date final not updated in iTAC.MES.Suite", packagingUnit.UID);
result.Messages = new ExternalControlResultMessage[] { message };
return false;
}
}
}
else if (expirationMaster == ConfigCode.MES)
{
LogHandler.log(Constants.LOGGER, TraceEventType.Warning, "this mode is currently not supported!");
return true;
}
return true;
}
public string getImsApiDateString(DateTime expiryDate)
{
if (expiryDate.Ticks >= lastItacTimeTicks)
{
return "32535212399000";
}
if (expiryDate.Ticks <= firstItacTimeTicks)
{
return "0";
}
return expiryDate.ToUniversalTime().Subtract(
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
).TotalMilliseconds.ToString();
}
public bool expirationDateDifferent(DateTime expiryDate, DateTime expirationDate)
{
// both values after 30.12.3000 00:00:00 --> same...
if (expiryDate.Day >= 30 && expiryDate.Month >= 12 && expiryDate.Year >= 3000 &&
expirationDate.Day >= 30 && expirationDate.Month >= 12 && expirationDate.Year >= 3000) { return false; }
return expiryDate.Ticks != expirationDate.Ticks;
}
public bool isMsdOpen(DateTime msdOpenDate)
{
return (msdOpenDate.Ticks > msdOpenTime);
}
#endregion
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using com.itac.mes.imsapi;
namespace com.itac.mes.imsapi.data
{
public class SmtContainer
{
public static string[] MAXIMAL_INFORMATION = new string[] { "MATERIAL_BIN_NUMBER", "EXPIRATION_DATE", "MATERIAL_BIN_DATE_CODE",
"MATERIAL_BIN_PART_NUMBER", "MATERIAL_BIN_STATE", "SUPPLIER_CHARGE_NUMBER", "DATE_CREATED",
"PART_COST", "PART_COST_BASE", "STORAGE_DESC", "STORAGE_NUMBER", "RECEIVING_NUMBER", "SUPPLIER_NAME", "SUPPLIER_NUMBER",
"CLASSIFICATION", "MSL_STATE", "MSL_LEVEL", "MSL_DRY_END_DATE", "MSL_OPEN_DATE", "HU_NUMBER",
"MATERIAL_BIN_QTY_ACTUAL", "MATERIAL_BIN_QTY_TOTAL"};
public static string[] MINIMAL_INFORMATION = new string[] { "MATERIAL_BIN_NUMBER", "EXPIRATION_DATE", "MATERIAL_BIN_STATE",
"MSL_STATE", "MSL_LEVEL", "MSL_DRY_END_DATE", "MSL_OPEN_DATE", "MATERIAL_BIN_QTY_ACTUAL" };
[ImsApiKey(Key = "MATERIAL_BIN_NUMBER")]
public string materialBinNumber { get; set; }
[ImsApiKey(Key = "MATERIAL_BIN_QTY_ACTUAL")]
public int materialBinQuantityActual = 0;
[ImsApiKey(Key = "MATERIAL_BIN_QTY_TOTAL")]
public int quantity = 0;
[ImsApiKey(Key = "ERROR_CODE")]
public int errorCode = 0;
[ImsApiKey(Key = "EXPIRATION_DATE")]
public DateTime expirationDate;
[ImsApiKey(Key = "DATE_CREATED")]
public DateTime dateCreated;
[ImsApiKey(Key = "MSL_DRY_END_DATE")]
public DateTime mslDryEndDate;
[ImsApiKey(Key = "MSL_OPEN_DATE")]
public DateTime mslOpenDate;
[ImsApiKey(Key = "MATERIAL_BIN_DATE_CODE")]
public string materialBinDateCode;
[ImsApiKey(Key = "MATERIAL_BIN_PART_NUMBER")]
public string materialBinPartNumber;
[ImsApiKey(Key = "MATERIAL_BIN_STATE")]
public string materialBinState;
[ImsApiKey(Key = "SUPPLIER_CHARGE_NUMBER")]
public string supplierChargeNumber;
[ImsApiKey(Key = "PART_COST")]
public string partCost;
[ImsApiKey(Key = "PART_COST_BASE")]
public string partCostBase;
[ImsApiKey(Key = "STORAGE_DESC")]
public string storageDesc;
[ImsApiKey(Key = "STORAGE_NUMBER")]
public string storageNumber;
[ImsApiKey(Key = "RECEIVING_NUMBER")]
public string receivingNumber;
[ImsApiKey(Key = "SUPPLIER_NAME")]
public string supplierName;
[ImsApiKey(Key = "SUPPLIER_NUMBER")]
public string supplierNumber;
[ImsApiKey(Key = "CLASSIFICATION")]
public string classification;
[ImsApiKey(Key = "MSL_STATE")]
public string mslState;
[ImsApiKey(Key = "MSL_LEVEL")]
public string mslLevel;
[ImsApiKey(Key = "HU_NUMBER")]
public string huNumber;
public int CompareTo(MaterialBinBooking obj)
{
if (materialBinNumber == null) return -1;
if (obj == null) return 1;
return materialBinNumber.CompareTo(obj.materialBinNumber);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB