Skip to content

Commit

Permalink
Merge pull request #84 from PHOENIXCONTACT/upgrade/instruction-and-lo…
Browse files Browse the repository at this point in the history
…cations

Upgrade future and clean up instruction result object
  • Loading branch information
Toxantron authored Jul 2, 2024
2 parents a90bdf3 + 07bb264 commit bf12e8d
Show file tree
Hide file tree
Showing 13 changed files with 108 additions and 35 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ on:
env:
dotnet_sdk_version: '8.0.100'
REPOSITORY_NAME: ${{ github.event.repository.name }}
MORYX_PACKAGE_TARGET_DEV: 'https://www.myget.org/F/moryx/api/v2/package'
MORYX_PACKAGE_TARGET_V3_DEV: 'https://www.myget.org/F/moryx/api/v3/index.json'
MORYX_PACKAGE_TARGET_FUTURE: 'https://www.myget.org/F/moryx-future/api/v2/package'
MORYX_PACKAGE_TARGET_V3_FUTURE: 'https://www.myget.org/F/moryx-future/api/v3/index.json'
MORYX_PACKAGE_TARGET_DEV: 'https://www.myget.org/F/moryx-oss-ci/api/v2/package'
MORYX_PACKAGE_TARGET_V3_DEV: 'https://www.myget.org/F/moryx-oss-ci/api/v3/index.json'
MORYX_PACKAGE_TARGET_FUTURE: 'https://www.myget.org/F/moryx-oss-ci/api/v2/package'
MORYX_PACKAGE_TARGET_V3_FUTURE: 'https://www.myget.org/F/moryx-oss-ci/api/v3/index.json'
MORYX_PACKAGE_TARGET_RELEASE: 'https://api.nuget.org/v3/index.json'
MORYX_PACKAGE_TARGET_V3_RELEASE: 'https://api.nuget.org/v3/index.json'

Expand Down
20 changes: 13 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
</a>
</p>

<p align="center">
<a href="https://www.nuget.org/packages/Moryx/">
<img alt="NuGet Release" src="https://img.shields.io/nuget/v/Moryx.ControlSystem?color=0098A1">
</a>
</p>

# MORYX Factory

**Public API definitions for MORYX Factory applications.**
Expand All @@ -25,13 +31,13 @@ This repository contains the APIs, domain objects and developer documentation fo

## Packages

| Package | Stable | Preview | Future |
|--|--|--|--|
| `Moryx.ControlSystem` | [![NuGet](https://img.shields.io/nuget/v/Moryx.ControlSystem.svg)](https://www.nuget.org/packages/Moryx.ControlSystem/) | [![MyGet](https://img.shields.io/myget/moryx/vpre/Moryx.ControlSystem)](https://www.myget.org/feed/moryx/package/nuget/Moryx.ControlSystem) | [![MyGet-Release](https://img.shields.io/myget/moryx-future/vpre/Moryx.ControlSystem)](https://www.myget.org/feed/moryx-future/package/nuget/Moryx.ControlSystem) |
| `Moryx.Orders` | [![NuGet](https://img.shields.io/nuget/v/Moryx.Orders.svg)](https://www.nuget.org/packages/Moryx.Orders/) | [![MyGet](https://img.shields.io/myget/moryx/vpre/Moryx.Orders)](https://www.myget.org/feed/moryx/package/nuget/Moryx.Orders) | [![MyGet-Release](https://img.shields.io/myget/moryx-future/vpre/Moryx.Orders)](https://www.myget.org/feed/moryx-future/package/nuget/Moryx.Orders) |
| `Moryx.Users` | [![NuGet](https://img.shields.io/nuget/v/Moryx.Users.svg)](https://www.nuget.org/packages/Moryx.Users/) | [![MyGet](https://img.shields.io/myget/moryx/vpre/Moryx.Users)](https://www.myget.org/feed/moryx/package/nuget/Moryx.Users) | [![MyGet-Release](https://img.shields.io/myget/moryx-future/vpre/Moryx.Users)](https://www.myget.org/feed/moryx-future/package/nuget/Moryx.USers) |
| `Moryx.ProcessData` | [![NuGet](https://img.shields.io/nuget/v/Moryx.ProcessData.svg)](https://www.nuget.org/packages/Moryx.ProcessData/) | [![MyGet](https://img.shields.io/myget/moryx/vpre/Moryx.ProcessData)](https://www.myget.org/feed/moryx/package/nuget/Moryx.ProcessData) | [![MyGet-Release](https://img.shields.io/myget/moryx-future/vpre/Moryx.ProcessData)](https://www.myget.org/feed/moryx-future/package/nuget/Moryx.ProcessData) |
| `Moryx.Simulation` | [![NuGet](https://img.shields.io/nuget/v/Moryx.Simulation.svg)](https://www.nuget.org/packages/Moryx.Simulation/) | [![MyGet](https://img.shields.io/myget/moryx/vpre/Moryx.Simulation)](https://www.myget.org/feed/moryx/package/nuget/Moryx.Simulation) | [![MyGet-Release](https://img.shields.io/myget/moryx-future/vpre/Moryx.Simulation)](https://www.myget.org/feed/moryx-future/package/nuget/Moryx.Simulation) |
| Package | |
|--|--|
| `Moryx.ControlSystem` | |
| `Moryx.Orders` | |
| `Moryx.Users` | |
| `Moryx.ProcessData` | |
| `Moryx.Simulation` | |
## Contribute

You can contribute to the MORYX Factory Domain by reporting bugs and suggesting extensions to APIs.
5 changes: 5 additions & 0 deletions docs/migrations/v8_to_v10.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Factory 6.x to 8.x

## Replaced result of visual instructions with dedicated result object

In *Moryx.Factory* **6.3** and **8.1** we introduced the new result object and optional extended APIs. The result object solved issues caused by localization of the different results. With **Moryx 10** we remove all old APIs based on strings.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2022, Phoenix Contact GmbH & Co. KG
// Licensed under the Apache License, Version 2.0

using System;
using System.Collections.Generic;

namespace Moryx.ControlSystem.VisualInstructions
Expand Down Expand Up @@ -31,8 +32,8 @@ public class ActiveInstruction
public object Inputs { get; set; }

/// <summary>
/// Results of the instruction
/// Possible results of the instruction
/// </summary>
public IReadOnlyList<string> PossibleResults { get; set; } = new string[0];
public IReadOnlyList<InstructionResult> Results { get; set; } = Array.Empty<InstructionResult>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace Moryx.ControlSystem.VisualInstructions
/// Response of the client for an <see cref="ActiveInstruction"/>
/// </summary>
public class ActiveInstructionResponse

{
/// <summary>
/// Runtime unique identifier of this instruction per client-identifier
Expand All @@ -26,6 +25,6 @@ public class ActiveInstructionResponse
/// <summary>
/// Selected result option by the user
/// </summary>
public string Result { get; set; }
public InstructionResult SelectedResult { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,40 @@ public static class EnumInstructionResult
/// <summary>
/// Determine possbile string buttons from enum result
/// </summary>
public static IReadOnlyList<string> PossibleResults(Type resultEnum, params string[] exceptions)
public static IReadOnlyList<InstructionResult> PossibleResults(Type resultEnum, params string[] exceptions)
{
return ParseEnum(resultEnum, exceptions).Keys.ToList();
return ParseEnum(resultEnum, exceptions).Select(pair => new InstructionResult
{
Key = pair.Value.ToString("D"),
DisplayValue = pair.Key
}).ToList();
}

/// <summary>
/// Determine possible string buttons from enum result
/// </summary>
[Obsolete("Method took over the previous signature, use 'PossibleResults' instead")]
public static IReadOnlyList<InstructionResult> PossibleInstructionResults(Type resultEnum, params string[] exceptions)
{
return PossibleResults(resultEnum, exceptions);
}

/// <summary>
/// Parse the given result back to an enum value
/// </summary>
public static int ResultToEnumValue(Type resultEnum, string result)
public static int ResultToEnumValue(Type resultEnum, InstructionResult result)
{
return ParseEnum(resultEnum)[result];
return int.Parse(result.Key);
}

/// <summary>
/// Convert string result to typed enum
/// </summary>
public static TEnum ResultToGenericEnumValue<TEnum>(InstructionResult result)
where TEnum : Enum
{
var numeric = int.Parse(result.Key);
return (TEnum)Enum.ToObject(typeof(TEnum), numeric);
}

/// <summary>
Expand Down Expand Up @@ -70,7 +93,7 @@ private static IDictionary<string, int> ParseEnum(Type resultEnum, params string
{
return allValues;
}

// Case 3: All values are explicitly hidden => display nothing
if (allValues.Count == hiddenValues.Count)
{
Expand Down
22 changes: 22 additions & 0 deletions src/Moryx.ControlSystem/VisualInstructions/InstructionResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Moryx.ControlSystem.VisualInstructions
{
/// <summary>
/// Object representing a possible result for an instructions
/// </summary>
public class InstructionResult
{
/// <summary>
/// Key of the result. This value needs to be unique for the instruction the result is used for.
/// </summary>
public string Key { get; set; }

/// <summary>
/// Human readable value of the result
/// </summary>
public string DisplayValue { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@ public static long Display(this IVisualInstructor instructor, string title, Acti
/// Execute these instructions based on the given activity and report the result on completion
/// Can (but must not) be cleared with the <see cref="IVisualInstructor.Clear"/> method
/// </summary>
public static long Execute(this IVisualInstructor instructor, string title, IVisualInstructions parameter, IReadOnlyList<string> results, Action<ActiveInstructionResponse> callback)
public static long Execute(this IVisualInstructor instructor, string title, IVisualInstructions parameter, IReadOnlyList<InstructionResult> results, Action<ActiveInstructionResponse> callback)
{
return instructor.Execute(new ActiveInstruction
{
Title = title,
Instructions = parameter.Instructions,
PossibleResults = results
Results = results
}, callback);
}

Expand All @@ -77,20 +77,20 @@ public static long Execute<T>(this IVisualInstructor instructor, string title, I
title,
parameter,
EnumInstructionResult.PossibleResults(typeof(T)),
result => { callback(EnumInstructionResult.ResultToEnumValue(typeof(T), result.Result)); });
result => callback(EnumInstructionResult.ResultToGenericEnumValue<T>(result.SelectedResult)));
}

/// <summary>
/// Executes the instructions of an activity with defining own results
/// </summary>
public static long Execute(this IVisualInstructor instructor, string title, ActivityStart activityStart, IReadOnlyList<string> results, Action<ActiveInstructionResponse> callback)
public static long Execute(this IVisualInstructor instructor, string title, ActivityStart activityStart, IReadOnlyList<InstructionResult> results, Action<ActiveInstructionResponse> callback)
{
var instructions = GetInstructions(activityStart);
return instructor.Execute(new ActiveInstruction
{
Title = title,
Instructions = instructions,
PossibleResults = results
Results = results
}, callback);
}

Expand Down Expand Up @@ -159,9 +159,9 @@ private static long ExecuteWithEnum(this IVisualInstructor instructor, string ti
{
Title = title,
Instructions = parameters,
PossibleResults = results,
Results = results,
Inputs = inputs
}, instructionResponse => callback(EnumInstructionResult.ResultToEnumValue(attr.ResultEnum, instructionResponse.Result), instructionResponse.Inputs, activityStart));
}, instructionResponse => callback(EnumInstructionResult.ResultToEnumValue(attr.ResultEnum, instructionResponse.SelectedResult), instructionResponse.Inputs, activityStart));
}

private static VisualInstruction[] GetInstructions(ActivityStart activity)
Expand Down
2 changes: 1 addition & 1 deletion src/Moryx.Orders/Facade/IOrderManagement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public interface IOrderManagement

/// <summary>
/// Tries to advise the <see cref="Operation"/>.
/// The returned advice result contains information regarding the successful or unsuccesful attempt.
/// The returned advice result contains information regarding the successful or unsuccessful attempt.
/// </summary>
/// <param name="operation">The <see cref="Operation"/> to advice.</param>
/// <param name="advice">The <see cref="OperationAdvice"/> to apply on the <see cref="Operation"/>.</param>
Expand Down
12 changes: 11 additions & 1 deletion src/Moryx.Orders/Operation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,23 @@ public class Operation
/// <summary>
/// Current state classification of this operation
/// </summary>
public virtual OperationClassification State { get => (OperationClassification)((int)FullState & 0xFF); protected set => FullState = value; }
public virtual OperationClassification State
{
get => (OperationClassification)((int)FullState & 0xFF);
protected set => FullState = value;
}

/// <summary>
/// Current state classification of this operation
/// </summary>
public virtual OperationClassification FullState { get; protected set; }

/// <summary>
/// Detailed display name of the state
/// TODO: Remove this property in next major and replace rework OperationClassification
/// </summary>
public virtual string StateDisplayName { get; protected set; }

/// <summary>
/// Source information of the operation
/// </summary>
Expand Down
10 changes: 7 additions & 3 deletions src/Moryx.Orders/OperationClassification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace Moryx.Orders
/// <summary>
/// Enum providing the classification of the internal state machine of the operation for an external representation
/// The lowest 8 bits define the state of the operation. The following 16 bits contain flags for the executable
/// actions on the operation and the trailing 8 bits overal classification information.
/// actions on the operation and the trailing 8 bits overall classification information.
/// Bit: 31 - 24 | 23 - 8 | 7 - 0 |
/// Flag: Type | Usage | State |
/// </summary>
Expand Down Expand Up @@ -60,7 +60,6 @@ public enum OperationClassification
/// </summary>
Failed = 11,


/// <summary>
/// Flag if the operation can be reloaded
/// </summary>
Expand All @@ -84,6 +83,11 @@ public enum OperationClassification
/// <summary>
/// Flag if the operation can be adviced
/// </summary>
CanAdvice = (1 << 20)
CanAdvice = (1 << 20),

/// <summary>
/// Flag if the operation is running but has no process
/// </summary>
IsAmountReached = (1 << 22),
}
}
1 change: 0 additions & 1 deletion src/Moryx.Orders/OperationLogMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System;
using Microsoft.Extensions.Logging;
using Moryx.Logging;

namespace Moryx.Orders
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ public void GetAllValuesIfNoResultIsDecorated()
{
// Act
var instructionResult = EnumInstructionResult.PossibleResults(typeof(TestResults1));
var possibleResults = EnumInstructionResult.PossibleInstructionResults(typeof(TestResults1));

Check warning on line 25 in src/Tests/Moryx.ControlSystem.Tests/EnumInstructionResultTests.cs

View workflow job for this annotation

GitHub Actions / Build / Build

'EnumInstructionResult.PossibleInstructionResults(Type, params string[])' is obsolete: 'Method took over the previous signature, use 'PossibleResults' instead'

Check warning on line 25 in src/Tests/Moryx.ControlSystem.Tests/EnumInstructionResultTests.cs

View workflow job for this annotation

GitHub Actions / IntegrationTests / IntegrationTests

'EnumInstructionResult.PossibleInstructionResults(Type, params string[])' is obsolete: 'Method took over the previous signature, use 'PossibleResults' instead'

// Assert
Assert.AreEqual(2, instructionResult.Count, "There should be 2 results because all of the results are not decorated");
Assert.AreEqual(2, instructionResult.Count(), "There should be 2 results because all of the results are not decorated");
Assert.AreEqual(2, possibleResults.Count(), "There should be 2 results because all of the results are not decorated");
}

private enum TestResults2
Expand Down Expand Up @@ -106,9 +108,11 @@ public void ParseResponse()

// Act
var enumValue = (TestResults1)EnumInstructionResult.ResultToEnumValue(typeof(TestResults1), instructionResult[1]);
var directValue = EnumInstructionResult.ResultToGenericEnumValue<TestResults1>(instructionResult[1]);

// Assert
Assert.AreEqual(TestResults1.Value2, enumValue);
Assert.AreEqual(TestResults1.Value2, directValue);
}

private class MyInput
Expand All @@ -132,7 +136,7 @@ public void UsesDisplayResultsWhereFound()

// Assert
Assert.AreEqual(1, instructionResult.Count(), "There should be two results, because one does not have the EnumInstruction attribute");
Assert.AreEqual("Value 1", instructionResult[0]);
Assert.AreEqual("Value 1", instructionResult[0].DisplayValue);
}
}
}

0 comments on commit bf12e8d

Please sign in to comment.