/// <summary> /// Возвращает версию файла сессии /// </summary> /// <param name="fileName">Имя файла сессии</param> /// <returns>-1 - файл не поддреживается, 0 - файл старого формата, 1 - нового</returns> public int GetSessionVersion(string fileName) { byte[] zipHeader = { 0x1F, 0x8B, 0x08 }; byte[] packageHeader = { 0x50, 0x4B, 0x03, 0x04, 0x14 }; if (Path.GetExtension(fileName) == SESSION_FILE_EXTENSION) { byte[] bytes = new byte[5]; using (System.IO.FileStream fs = new System.IO.FileStream(fileName, System.IO.FileMode.Open, System.IO.FileAccess.Read)) using (System.IO.MemoryStream mso = new System.IO.MemoryStream()) { fs.Read(bytes, 0, bytes.Length); mso.Write(bytes, 0, bytes.Length); } if (bytes.Take(3).SequenceEqual(zipHeader)) { return(IsSupportedSessionVersion(LoadVersionFromZip(fileName)) ? 0 : -1); } else if (bytes.Take(5).SequenceEqual(packageHeader)) { try { BalanceSessionInfo info = LoadSessionInfo(fileName); return(IsSupportedSessionVersion(info.Version) ? 1 : -1); } catch (IOException ioe) { EmcosSiteWrapperApp.LogException(ioe); return(-1); } catch (FileFormatException ffe) { EmcosSiteWrapperApp.LogException(ffe); return(-1); } catch { return(-1); } } else { return(-1); } } else { return(-1); } }
/// <summary> /// Создание списка сессий /// </summary> public void FillSessionsList() { SessionsInfoList = new List <BalanceSessionInfo>(); var di = new DirectoryInfo(SESSIONS_FOLDER); try { var files = di.GetFiles().OrderByDescending(p => p.LastWriteTime).ToArray(); foreach (FileInfo fi in files) { int versionNumber = GetSessionVersion(fi.FullName); if (versionNumber >= 0) { BalanceSessionInfo balanceSessionInfo = LoadSessionInfo(fi.FullName, versionNumber); SessionsInfoList.Add(balanceSessionInfo); } } } catch (Exception e) { _callBackAction(e); } }
/// <summary> /// Загрузка файла сессии версии 1.0 /// </summary> /// <remarks> /// Файл сессии версии 1.0 представляет собой сериализованный в json объект BalanceSession дополнительно сжатый gzip /// </remarks> /// <param name="fileName">Имя файла</param> /// <param name="balanceSession">Ссылка на сессию</param> /// <returns>Сессия</returns> private BalanceSession LoadDataFromFileVersion_1_0(string fileName) { const string UNKNOWN_DEPARTAMENT_NAME = "<неизвестно>"; BalanceSession balanceSession = new BalanceSession(); try { dynamic obj = ParseJsonFromFile(fileName); if (obj != null) { var fi = new FileInfo(fileName); BalanceSessionInfo balanceSessionInfo = LoadSessionInfoFromOldFileFormat(obj); balanceSessionInfo.FileSize = fi.Length; balanceSession.Info = balanceSessionInfo; if (obj.Substations != null) { balanceSession.BalancePoints.Clear(); // создание списка департаментов (рэс) HashSet <string> departamentsSet = new HashSet <string>(); foreach (var item in obj.Substations) { string departament = item?.Departament?.ToString(); if (String.IsNullOrWhiteSpace(departament) == false && departamentsSet.Contains(departament) == false) { departamentsSet.Add(departament); } } Dictionary <string, IHierarchicalEmcosPoint> departamentsDictionary = new Dictionary <string, IHierarchicalEmcosPoint>(); foreach (var item in departamentsSet) { departamentsDictionary.Add(item, new EmcosPoint() { ElementType = ElementTypes.DEPARTAMENT, TypeCode = "RES", Name = item }); } departamentsDictionary.Add("?", new EmcosPoint() { ElementType = ElementTypes.DEPARTAMENT, TypeCode = "RES", Name = UNKNOWN_DEPARTAMENT_NAME }); System.Collections.IList parentList = departamentsDictionary["?"].Children; void parseBase(IHierarchicalEmcosPoint source, dynamic data) { try { source.Id = data.Id ?? 0; source.Code = data.Code; source.Name = data.Title; source.Status = data.Status; source.Description = data.Description; if (String.IsNullOrEmpty(source.Description) == false) { balanceSession.DescriptionsById.Add(source.Id, source.Description); } } catch (Exception e) { _callBackAction(e); } } object getPropertyValue(string propertyName, dynamic jObject) { if ((jObject is Newtonsoft.Json.Linq.JObject o) && (o.Property(propertyName) != null)) { return(o.Property(propertyName).Value); } else { return(null); } } double?getDoubleValue(string propertyName, dynamic jObject) { object value = getPropertyValue(propertyName, jObject); if (value == null) { return(null); } else { return(Convert.ToDouble(value)); } } bool getBoolValue(string propertyName, dynamic jObject) { object value = getPropertyValue(propertyName, jObject); if (value == null) { return(false); } else { return(Convert.ToBoolean(value)); } } void parseTokens(IEnumerable <Newtonsoft.Json.Linq.JToken> tokens) { foreach (Newtonsoft.Json.Linq.JToken jobj in tokens) { if (jobj.Children().Where(i => (i is Newtonsoft.Json.Linq.JProperty p) && p.Name == "$type").FirstOrDefault() is Newtonsoft.Json.Linq.JProperty typeProperty) { string tokenType = typeProperty.Value.ToString(); if (String.IsNullOrWhiteSpace(tokenType) == false) { string t = tokenType.Split(new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries)[0]; string[] parts = t.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length > 1 && parts[0] == "TMP") { string part = parts[parts.Length - 1]; IBalanceGroupItem group = null; dynamic data = jobj; switch (part) { case "Substation": group = new Substation { Departament = data.Departament, Voltage = data.Voltage }; break; case "SubstationSection": group = new SubstationSection { Voltage = data.Voltage }; break; case "SubstationPowerTransformers": group = new SubstationPowerTransformers(); break; case "SubstationAuxiliary": group = new SubstationAuxiliary(); break; default: { IBalanceItem item = null; switch (part) { case "Fider": item = new Fider(); break; case "PowerTransformer": item = new PowerTransformer(); break; case "UnitTransformer": item = new UnitTransformer(); break; case "UnitTransformerBus": item = new UnitTransformerBus(); break; default: System.Diagnostics.Debugger.Break(); break; } if (item != null) { parseBase(item, data); } object value = getPropertyValue("DailyEplus", data); string daysValues = value?.ToString(); item.ActiveEnergy.Plus.DaysValues = (daysValues != null && daysValues.StartsWith("<")) ? null : (value as Newtonsoft.Json.Linq.JToken)?.ToObject <List <double?> >(); value = getPropertyValue("DailyEminus", data); daysValues = value?.ToString(); item.ActiveEnergy.Minus.DaysValues = (daysValues != null && daysValues.StartsWith("<")) ? null : (value as Newtonsoft.Json.Linq.JToken)?.ToObject <List <double?> >(); item.ActiveEnergy.Plus.MonthValue = getDoubleValue("MonthEplus", data); item.ActiveEnergy.Minus.MonthValue = getDoubleValue("MonthEminus", data); item.ActiveEnergy.Plus.CorrectionValue = getDoubleValue("Eplus", data) - getDoubleValue("DayEplusValue", data); item.ActiveEnergy.Minus.CorrectionValue = getDoubleValue("Eminus", data) - getDoubleValue("DayEminusValue", data); item.ActiveEnergy.Plus.UseMonthValue = getBoolValue("UseMonthValue", data); item.ActiveEnergy.Minus.UseMonthValue = getBoolValue("UseMonthValue", data); if (group != null) { group.Children.Add(item); } if (item == null && group == null) { System.Diagnostics.Debugger.Break(); } } break; } if (group != null) { parseBase(group, data); if (group is Substation substation) { departamentsDictionary[substation.Departament].Children.Add(substation); } else { parentList.Add(group); } var childrenProperty = jobj.Children() .Where(i => (i is Newtonsoft.Json.Linq.JProperty p) && p.Name == "Children") .FirstOrDefault() as Newtonsoft.Json.Linq.JProperty; if (childrenProperty != null && childrenProperty.Value != null && childrenProperty.Value is Newtonsoft.Json.Linq.JArray childrenArray) { System.Collections.IList oldParentList = parentList; parentList = group.Children; parseTokens(childrenArray); parentList = oldParentList; } else { System.Diagnostics.Debugger.Break(); } } } } // значение типа токена пустое else { System.Diagnostics.Debugger.Break(); } } // не найден тип токена else { System.Diagnostics.Debugger.Break(); } }
/// <summary> /// Загрузка сессии /// </summary> /// <param name="fileName">Имя файла, если не указано, то загрузка из стандартного файла <see cref="BALANCE_SESSION_FILENAME"/></param> /// <returns>True если загрузка произошла успешно</returns> private bool LoadSessionData(string fileName = null) { bool mustStoreLastSessionFileName = true; try { if (String.IsNullOrWhiteSpace(fileName)) { fileName = BALANCE_SESSION_FILENAME + SESSION_FILE_EXTENSION; mustStoreLastSessionFileName = false; } else if (Path.GetExtension(fileName).ToLowerInvariant() != SESSION_FILE_EXTENSION) { fileName = fileName + SESSION_FILE_EXTENSION; } var fi = new FileInfo(Path.Combine(SESSIONS_FOLDER, fileName)); if (fi.Exists == false) { return(false); } BalanceSession balanceSession = null; bool isOldVersionFile = false; try { if (Path.IsPathRooted(fileName) == false) { fileName = Path.Combine(SESSIONS_FOLDER, fileName); } // попытка прочитать файл как пакет using (System.IO.Packaging.Package package = System.IO.Packaging.Package.Open(fileName, FileMode.Open, FileAccess.Read)) { BalanceSessionInfo info = LoadSessionInfoFromPackage(package.GetPart(System.IO.Packaging.PackUriHelper.CreatePartUri(new Uri(PART_Info, UriKind.Relative)))); if (IsSupportedSessionVersion(info.Version)) { void unknownVersion() { string msg = String.Format("Файл '{1}'\nнеизвестной версии - {0}\nЗагрузка невозможна.\nОбновите программу или обратитесь к разработчику.", info.Version, fi.FullName); EmcosSiteWrapperApp.LogError(msg); EmcosSiteWrapperApp.ShowError(msg); } switch (info.Version.Major) { case 1: switch (info.Version.Minor) { case 0: isOldVersionFile = true; break; case 1: balanceSession = LoadDataFromFileVersion_1_1(package); break; default: unknownVersion(); return(false); } break; default: unknownVersion(); return(false); } } } } catch (IOException ioe) { EmcosSiteWrapperApp.LogException(ioe); isOldVersionFile = true; } catch (Exception e) { isOldVersionFile = true; } if (isOldVersionFile) { balanceSession = LoadDataFromFileVersion_1_0(fi.FullName); } if (mustStoreLastSessionFileName) { File.WriteAllText(Path.Combine(SESSIONS_FOLDER, "lastsession"), fileName); } ActiveSession = balanceSession; return(balanceSession != null); } catch (Exception ex) { _callBackAction(ex); ActiveSession = null; return(false); } }