Skip to content

Commit

Permalink
* menu actions for
Browse files Browse the repository at this point in the history
   background operation
  • Loading branch information
festo-i40 committed Jan 13, 2024
1 parent 61fcf7e commit c7ae335
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 40 deletions.
3 changes: 2 additions & 1 deletion src/AasxPackageLogic/ExplorerMenuFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public static AasxMenu CreateMainMenu()
.AddWpfBlazor(name: "LocationPush", header: "Push location", inputGesture: "Ctrl+Shift+P")
.AddWpfBlazor(name: "LocationPop", header: "Pop location", inputGesture: "Ctrl+Shift+O"))
.AddSeparator()
.AddMenu(header: "Create …", attachPoint: "Plugins", childs: (new AasxMenu())
.AddMenu(header: "Create …", attachPoint: "Create", childs: (new AasxMenu())
.AddWpfBlazor(name: "NewSubmodelFromPlugin", header: "New Submodel from plugin", inputGesture: "Ctrl+Shift+M",
help: "Creates a new Submodel based on defintions provided by plugin.",
args: new AasxMenuListOfArgDefs()
Expand Down Expand Up @@ -325,6 +325,7 @@ public static AasxMenu CreateMainMenu()
help: "Creates a new Submodel instance from an selected root given by accessible ConceptDescriptions.")
)
.AddMenu(header: "Visualize …", attachPoint: "Visualize")
.AddMenu(header: "Plugins …", attachPoint: "Plugins")
.AddSeparator()
.AddWpfBlazor(name: "ConvertElement", header: "Convert via plugin …",
help: "Asks plugins if these could make offers to convert the current elements and " +
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,17 @@
{
"Records": [
{
"RecordType": 0,
"IsDescription" : true,
"AllowSubmodelSemanticId": [
{
"type": "Submodel",
"local": false,
"value": "http://www.admin-shell.io/mtp/v1/submodel",
"index": 0,
"idType": "IRI"
"value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Submodel"
}
]
},
{
"RecordType": 1,
"AllowSubmodelSemanticId": [
{
"type": "Submodel",
"local": false,
"value": "http://www.admin-shell.io/mtp/v1/mtp-instance-submodel",
"index": 0,
"idType": "IRI"
}
]
}
],
"SymbolMappings": [
{
"EClassVersions": null,
"EClassClasses": "37010201",
"EClassIRDIs": null,
"SymbolDefault": "PNID_Festo.manual_valve_active-u-nozzled",
"SymbolActive": null,
"SymbolIntermediate": null,
"Comment": "V003,45fd1be7-d9fe-426a-aec7-ca16a09cb64b"
],
"UseHttp": true,
"UseModbus": false,
"UseMqtt": false,
"UseOpcUa": false
}
],
"VisuOptions": {
"Background": "#707070",
"StateColorActive": "#2020ff",
"StateColorNonActive": "#202020",
"StateColorForward": "#2020ff",
"StateColorReverse": "#20ff20"
}
]
}
4 changes: 4 additions & 0 deletions src/AasxPluginAssetInterfaceDesc/AidHttpConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ override public bool Open()
{
// pretty simple
Client = new HttpClient();

if (TimeOutMs >= 10)
Client.Timeout = new TimeSpan(0, 0, 0, 0, milliseconds: (int)TimeOutMs);

return true;
}

Expand Down
51 changes: 50 additions & 1 deletion src/AasxPluginAssetInterfaceDesc/AidInterfaceStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,13 @@ public class AidAllInterfaceStatus
/// </summary>
protected LogInstance _log = null;

/// <summary>
/// Holds a "pointer" to the "last current" Submodel defining the AID description.
/// Note: unlike most other plugins, this plugin is mostly intended to run in
/// the background.
/// </summary>
public Aas.ISubmodel SmAidDescription = null;

public bool[] UseTech = { false, false, false, true };

/// <summary>
Expand Down Expand Up @@ -330,6 +337,34 @@ public AidAllInterfaceStatus(LogInstance log = null)
_log = log;
}

public void RememberNothing()
{
SmAidDescription = null;
}

public bool EnoughMemories()
{
return SmAidDescription != null;
}

public void RememberSubmodel(Aas.ISubmodel sm, AssetInterfaceOptionsRecord optRec,
bool adoptUseFlags)
{
if (sm == null || optRec == null)
return;

if (optRec.IsDescription)
SmAidDescription = sm;

if (adoptUseFlags)
{
UseTech[(int)AidInterfaceTechnology.HTTP] = optRec.UseHttp;
UseTech[(int)AidInterfaceTechnology.Modbus] = optRec.UseModbus;
UseTech[(int)AidInterfaceTechnology.MQTT] = optRec.UseMqtt;
UseTech[(int)AidInterfaceTechnology.OPCUA] = optRec.UseOpcUa;
}
}

protected AidBaseConnection GetOrCreate(
AidInterfaceStatus ifcStatus,
string endpointBase,
Expand Down Expand Up @@ -580,7 +615,7 @@ await Parallel.ForEachAsync(
// Building, intake from Submodel
//

public void PrepareAidInformation(Aas.Submodel sm)
public void PrepareAidInformation(Aas.ISubmodel sm)
{
// access
InterfaceStatus.Clear();
Expand Down Expand Up @@ -678,6 +713,20 @@ public void SetAidInformationForUpdateAndTimeout(
double defaultUpdateFreqMs = 0,
double defaultTimeOutMs = 0)
{
// for Http, analyze update frequency and timeout
foreach (var ifc in InterfaceStatus.Where((i) => i.Technology == AidInterfaceTechnology.HTTP))
{
// polltimes
SetDoubleOnDefaultOrAvgOfIntList(
ref ifc.UpdateFreqMs, 10.0, defaultUpdateFreqMs,
SelectValuesToIntList(ifc?.Items?.Values, (it) => it.FormData?.Htv_pollingTime));

// time out
SetDoubleOnDefaultOrAvgOfIntList(
ref ifc.TimeOutMs, 10.0, defaultTimeOutMs,
SelectValuesToIntList(ifc?.Items?.Values, (it) => it.FormData?.Htv_timeout));
}

// for Modbus, analyze update frequency and timeout
foreach (var ifc in InterfaceStatus.Where((i) => i.Technology == AidInterfaceTechnology.Modbus))
{
Expand Down
6 changes: 6 additions & 0 deletions src/AasxPluginAssetInterfaceDesc/AssetInterfaceOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ namespace AasxPluginAssetInterfaceDescription
{
public class AssetInterfaceOptionsRecord : AasxPluginOptionsLookupRecordBase
{
public bool IsDescription = true;

public bool UseHttp = true;
public bool UseModbus = true;
public bool UseMqtt = true;
public bool UseOpcUa = true;
}

public class AssetInterfaceOptions : AasxPluginLookupOptionsBase
Expand Down
160 changes: 159 additions & 1 deletion src/AasxPluginAssetInterfaceDesc/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ This source code may use other Open Source software components (see LICENSE.txt)
using JetBrains.Annotations;
using Newtonsoft.Json;
using AasxPluginAssetInterfaceDescription;
using AnyUi;
using System.Windows.Controls;

namespace AasxIntegrationBase // the namespace has to be: AasxIntegrationBase
{
Expand All @@ -42,7 +44,7 @@ public class Session : PluginSessionBase
public new void InitPlugin(string[] args)
{
// start ..
PluginName = "AasxPluginAssetInterfaceDescription";
PluginName = "AasxPluginAssetInterfaceDesc";

// .. with built-in options
_options = AasxPluginAssetInterfaceDescription.AssetInterfaceOptions.CreateDefault();
Expand Down Expand Up @@ -84,6 +86,7 @@ public class Session : PluginSessionBase
enableLicenses: true,
enableEventsGet: true,
enableEventReturn: true,
enableMenuItems: true,
enablePanelAnyUi: true);
return res.ToArray();
}
Expand All @@ -107,6 +110,15 @@ public class Session : PluginSessionBase
if (!found)
return null;

// specifically find the record
var foundOptRec = _options.LookupAllIndexKey<AssetInterfaceOptionsRecord>(
sm.SemanticId.GetAsExactlyOneKey()).FirstOrDefault();
if (foundOptRec == null)
return null;

// remember for later / background
_allInterfaceStatus.RememberSubmodel(sm, foundOptRec, adoptUseFlags: true);

// success prepare record
var cve = new AasxPluginResultVisualExtension("AID", "Asset Interfaces Description");

Expand Down Expand Up @@ -177,6 +189,152 @@ public class Session : PluginSessionBase
// ReSharper enable UnusedVariable
}

if (action == "get-menu-items")
{
// result list
var res = new List<AasxPluginResultSingleMenuItem>();

// attach
// note: need to be single items, no childs allowed!
res.Add(new AasxPluginResultSingleMenuItem()
{
AttachPoint = "Plugins",
MenuItem = new AasxMenuItem()
{
Name = "AssetInterfaceOperationStart",
Header = "Asset Interfaces (AID): Start operations …",
HelpText = "Looks for a suitable Submodel with SMT Asset Interfaces Descriptions " +
"(AID) and mapping and starts operations in the background."
}
});
res.Add(new AasxPluginResultSingleMenuItem()
{
AttachPoint = "Plugins",
MenuItem = new AasxMenuItem()
{
Name = "AssetInterfaceOperationStop",
Header = "Asset Interfaces (AID): Stop operations …",
HelpText = "Stops all AID operations."
}
});

// return
return new AasxPluginResultProvideMenuItems()
{
MenuItems = res
};
}

// default
return null;
}

/// <summary>
/// Async variant of <c>ActivateAction</c>.
/// Note: for some reason of type conversion, it has to return <c>Task<object></c>.
/// </summary>
public new async Task<object> ActivateActionAsync(string action, params object[] args)
{
if (action == "call-menu-item")
{
if (args != null && args.Length >= 3
&& args[0] is string cmd
&& args[1] is AasxMenuActionTicket ticket
&& args[2] is AnyUiContextPlusDialogs displayContext
&& args[3] is DockPanel masterPanel)
{
try
{
if (cmd == "assetinterfaceoperationstart")
{
await Task.Yield();

// be safe
if (_allInterfaceStatus == null)
{
_log?.Error("Error accessing background all interface status! Aborting.");
return null;
}

try
{
// in (used!)Submodels of the respecitve AAS, find memories
_allInterfaceStatus.RememberNothing();
if (ticket.Env != null)
foreach (var sm in ticket.Env.FindAllSubmodelGroupedByAAS())
{
var foundOptRec = _options.LookupAllIndexKey<AssetInterfaceOptionsRecord>(
sm.SemanticId.GetAsExactlyOneKey()).FirstOrDefault();
if (foundOptRec == null)
continue;
_allInterfaceStatus.RememberSubmodel(sm, foundOptRec,
adoptUseFlags: true);
}

// start?
if (_allInterfaceStatus.EnoughMemories())
{
// switch off current?
if (_allInterfaceStatus.ContinousRun)
{
_log?.Info("Asset Interfaces: stopping current operation ..");
_allInterfaceStatus.StopContinousRun();
}

// (re-) init
_log?.Info("Asset Interfaces: starting new operation ..");
_allInterfaceStatus.PrepareAidInformation(_allInterfaceStatus.SmAidDescription);
_allInterfaceStatus.SetAidInformationForUpdateAndTimeout();
_allInterfaceStatus.StartContinousRun();
}

} catch (Exception ex)
{
_log?.Error(ex, "when starting Asset Interface operations");
}

// give object back
var res = new AasxPluginResultCallMenuItem();
return res;
}

if (cmd == "assetinterfaceoperationstop")
{
await Task.Yield();

// be safe
if (_allInterfaceStatus == null)
{
_log?.Error("Error accessing background all interface status! Aborting.");
return null;
}

try
{
// switch off current?
if (_allInterfaceStatus.ContinousRun)
{
_log?.Info("Asset Interfaces: stopping current operation ..");
_allInterfaceStatus.StopContinousRun();
}
}
catch (Exception ex)
{
_log?.Error(ex, "when starting Asset Interface operations");
}

// give object back
var res = new AasxPluginResultCallMenuItem();
return res;
}
}
catch (Exception ex)
{
_log?.Error(ex, "when executing plugin menu item " + cmd);
}
}
}

// default
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,12 @@ public class CD_Forms
[AasConcept(Cd = "https://www.w3.org/2011/http#headers", Card = AasxPredefinedCardinality.ZeroToOne)]
public CD_Htv_headers Htv_headers = null;

[AasConcept(Cd = "https://www.w3.org/2019/wot/http#pollingTime", Card = AasxPredefinedCardinality.ZeroToOne)]
public string Htv_pollingTime;

[AasConcept(Cd = "https://www.w3.org/2019/wot/http#timeout", Card = AasxPredefinedCardinality.ZeroToOne)]
public string Htv_timeout;

[AasConcept(Cd = "https://www.w3.org/2019/wot/modbus#Function", Card = AasxPredefinedCardinality.ZeroToOne)]
public string Modbus_function;

Expand Down

0 comments on commit c7ae335

Please sign in to comment.