176 lines
6.9 KiB
C#
176 lines
6.9 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Hermes;
|
|
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace VisionCommon {
|
|
/// <summary>
|
|
/// 현재 실행 중인 SW의 Recipe 구성에 맞게
|
|
/// 장비에 저장된 Recipe 파일을 업데이트 한다.
|
|
/// </summary>
|
|
public static class RecipeUpdater {
|
|
private const string KEY_UNIT_RECIPES = nameof(VisionDef.UnitRecipes);
|
|
private const string KEY_SUB_SYS_RECIPES = nameof(UnitRecipe.SubSysRecipes);
|
|
private const string KEY_FOV_RECIPES = nameof(SubSysRecipe.FovRecipes);
|
|
private const string KEY_ALIGN_RECIPES = nameof(SubSysRecipe.AlignRecipes);
|
|
|
|
private static Logger _logger = new Logger(nameof(RecipeUpdater));
|
|
|
|
/// <summary>
|
|
/// 레시피 업데이트를 실행한다.
|
|
/// </summary>
|
|
/// <param name="recipeModelType">레시피 또는 모델</param>
|
|
/// <returns>실행 결과</returns>
|
|
public static int Run(eRecipeModelType recipeModelType) {
|
|
var recipeDirectories = RecipeUpdaterUtil.GetDataDirectories(recipeModelType);
|
|
var updaters = GetRecipeUpdaters();
|
|
|
|
foreach (var recipeDir in recipeDirectories) {
|
|
var recipeFilePath = Path.Combine(recipeDir, $"{VisionKeys.VisionRecipeKey}.json");
|
|
|
|
if (File.Exists(recipeFilePath)) {
|
|
JToken machineRecipeOriginal = JsonManager.ParseFromFile(recipeFilePath);
|
|
if (machineRecipeOriginal == null) {
|
|
_logger.E($"Read recipe file error : {recipeFilePath}");
|
|
continue;
|
|
}
|
|
|
|
JToken machineRecipe = machineRecipeOriginal.DeepClone();
|
|
|
|
SetInitialVersion(machineRecipe);
|
|
var machineRecipeVersion = GetRecipeVersion(machineRecipe);
|
|
if (!IsUpdatable(machineRecipeVersion)) {
|
|
continue;
|
|
}
|
|
|
|
var result = Update(machineRecipe, machineRecipeVersion, VisionDef.RECIPE_VERSION_CURRENT, updaters);
|
|
if (result == E1.OK) {
|
|
SaveBackupFile(machineRecipeOriginal, machineRecipeVersion, recipeDir);
|
|
SaveUpdateFile(machineRecipe, recipeDir);
|
|
}
|
|
}
|
|
}
|
|
|
|
return E1.OK;
|
|
}
|
|
|
|
private static List<Updater> GetRecipeUpdaters() {
|
|
var updaters = new List<Updater>();
|
|
|
|
Type targetType = typeof(Updater);
|
|
Assembly assembly = Assembly.GetExecutingAssembly();
|
|
var types = assembly.GetTypes();
|
|
foreach (var type in types) {
|
|
if (targetType.IsAssignableFrom(type)) {
|
|
ConstructorInfo ctor = type.GetConstructor(new Type[] { });
|
|
if (ctor != null) {
|
|
updaters.Add((Updater)ctor.Invoke(new object[] { }));
|
|
}
|
|
}
|
|
}
|
|
return updaters;
|
|
}
|
|
|
|
private static void SetInitialVersion(JToken machineRecipe) {
|
|
var machineRecipeVersion = GetRecipeVersion(machineRecipe);
|
|
if (machineRecipeVersion == 0) {
|
|
SetRecipeVersion(machineRecipe, VisionDef.RECIPE_VERSION_INITIAL);
|
|
}
|
|
}
|
|
|
|
private static bool IsUpdatable(double machineRecipeVersion) {
|
|
return !MathUtil.Equals(machineRecipeVersion, VisionDef.RECIPE_VERSION_CURRENT, 0.01);
|
|
}
|
|
|
|
private static double GetRecipeVersion(JToken machineRecipe) {
|
|
try {
|
|
var versionToken = machineRecipe.SelectToken(nameof(VisionDef.Version));
|
|
if (versionToken != null) {
|
|
return Math.Round(versionToken.ToObject<double>(), 1);
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
_logger.E(e.Message);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
private static int SetRecipeVersion(JToken machineRecipe, double version) {
|
|
try {
|
|
var versionToken = machineRecipe.SelectToken(nameof(VisionDef.Version));
|
|
if (versionToken == null) {
|
|
machineRecipe[nameof(VisionDef.Version)] = version;
|
|
}
|
|
else {
|
|
versionToken.Replace(new JValue(Math.Round(version, 1)));
|
|
}
|
|
}
|
|
catch (Exception e) {
|
|
_logger.E(e.Message);
|
|
return E1.GENERIC;
|
|
}
|
|
|
|
return E1.OK;
|
|
}
|
|
|
|
private static int Update(JToken machineRecipe, double machineRecipeVersion, double swVersion, List<Updater> updaters) {
|
|
if (machineRecipeVersion < VisionDef.RECIPE_VERSION_CURRENT) {
|
|
return Upgrade(machineRecipe, machineRecipeVersion, VisionDef.RECIPE_VERSION_CURRENT, updaters);
|
|
}
|
|
else if (VisionDef.RECIPE_VERSION_CURRENT < machineRecipeVersion) {
|
|
return Downgrade(machineRecipe, machineRecipeVersion, VisionDef.RECIPE_VERSION_CURRENT, updaters);
|
|
}
|
|
|
|
return E1.GENERIC;
|
|
}
|
|
|
|
private static int Upgrade(JToken machineRecipe, double machineRecipeVersion, double swVersion, List<Updater> updaters) {
|
|
for (double curVer = machineRecipeVersion; curVer < swVersion; curVer += 0.1) {
|
|
double nextVer = curVer + 0.1;
|
|
foreach (var updater in updaters) {
|
|
updater.Update(machineRecipe, curVer, nextVer);
|
|
}
|
|
SetRecipeVersion(machineRecipe, nextVer);
|
|
}
|
|
|
|
return E1.OK;
|
|
}
|
|
|
|
private static int Downgrade(JToken machineRecipe, double machineRecipeVersion, double swVersion, List<Updater> updaters) {
|
|
for (double curVer = machineRecipeVersion; swVersion < curVer; curVer -= 0.1) {
|
|
double nextVer = curVer - 0.1;
|
|
foreach (var updater in updaters) {
|
|
updater.Update(machineRecipe, curVer, nextVer);
|
|
}
|
|
SetRecipeVersion(machineRecipe, nextVer);
|
|
}
|
|
|
|
return E1.OK;
|
|
}
|
|
|
|
private static int SaveBackupFile(
|
|
JToken machineRecipeOriginal, double machineRecipeVersion, string recipeDir) {
|
|
string datetimeStr = DateTime.Now.ToString("yyyyMMdd_hhmmss");
|
|
string backupFileName = $"{VisionKeys.VisionRecipeKey}_{datetimeStr}_v{machineRecipeVersion}.json";
|
|
|
|
return JsonManager.SaveToFile(
|
|
machineRecipeOriginal,
|
|
Path.Combine(recipeDir, backupFileName));
|
|
}
|
|
|
|
private static int SaveUpdateFile(JToken machineRecipe, string recipeDir) {
|
|
return JsonManager.SaveToFile(
|
|
machineRecipe,
|
|
Path.Combine(recipeDir, $"{VisionKeys.VisionRecipeKey}.json"));
|
|
}
|
|
}
|
|
}
|