Checking for loops in foldertree, getting only unique children now.
Small Stability changes to VrmGrabber
This commit is contained in:
parent
731587ac77
commit
b727ef765a
|
@ -31,13 +31,22 @@ public static class FolderMethods
|
|||
.NotNull();
|
||||
}
|
||||
|
||||
public static IEnumerable<Folder> ChildFolders(this Folder parent)
|
||||
private static IEnumerable<Folder> ChildFolders(this Folder parent)
|
||||
{
|
||||
// Unsafe can give back loops
|
||||
return Db
|
||||
.Folders
|
||||
.Where(f => f.ParentId == parent.Id);
|
||||
}
|
||||
|
||||
public static IEnumerable<Folder> UniqueChildFolders(this Folder parent)
|
||||
{
|
||||
|
||||
var set = new HashSet<Folder>(Db.Folders, EqualityComparer<Folder>.Default);
|
||||
|
||||
return ChildFolders(parent).Where(set.Add);
|
||||
}
|
||||
|
||||
public static IEnumerable<Installation> ChildInstallations(this Folder parent)
|
||||
{
|
||||
return Db
|
||||
|
@ -48,14 +57,14 @@ public static class FolderMethods
|
|||
public static IEnumerable<Folder> DescendantFolders(this Folder parent)
|
||||
{
|
||||
return parent
|
||||
.TraverseDepthFirstPreOrder(ChildFolders)
|
||||
.TraverseDepthFirstPreOrder(UniqueChildFolders)
|
||||
.Skip(1); // skip self
|
||||
}
|
||||
|
||||
public static IEnumerable<Folder> DescendantFoldersAndSelf(this Folder parent)
|
||||
{
|
||||
return parent
|
||||
.TraverseDepthFirstPreOrder(ChildFolders);
|
||||
.TraverseDepthFirstPreOrder(UniqueChildFolders);
|
||||
}
|
||||
public static Boolean IsDescendantOf(this Folder folder, Folder ancestor)
|
||||
{
|
||||
|
|
|
@ -138,7 +138,7 @@ public static class InstallationMethods
|
|||
|
||||
public static String GetOrderNumbers(this Installation installation)
|
||||
{
|
||||
return string.Join(", ", Db.OrderNumber2Installation
|
||||
return String.Join(", ", Db.OrderNumber2Installation
|
||||
.Where(i => i.InstallationId == installation.Id)
|
||||
.Select(i => i.OrderNumber)
|
||||
.ToReadOnlyList());
|
||||
|
|
|
@ -13,10 +13,10 @@ public static class UserMethods
|
|||
{
|
||||
public static IEnumerable<Installation> AccessibleInstallations(this User user)
|
||||
{
|
||||
var direct = user.DirectlyAccessibleInstallations();
|
||||
var direct = user.DirectlyAccessibleInstallations().ToList();
|
||||
var fromFolders = user
|
||||
.AccessibleFolders()
|
||||
.SelectMany(u => u.ChildInstallations());
|
||||
.SelectMany(u => u.ChildInstallations()).ToList();
|
||||
|
||||
return direct
|
||||
.Concat(fromFolders)
|
||||
|
@ -35,7 +35,7 @@ public static class UserMethods
|
|||
{
|
||||
var folders = user.AccessibleFolders() as IEnumerable<TreeNode>;
|
||||
|
||||
// user.AccessibleInstallations().ForEach(i => i.FillOrderNumbers());
|
||||
user.AccessibleInstallations().ForEach(i => i.FillOrderNumbers());
|
||||
var installations = user.AccessibleInstallations();
|
||||
|
||||
return folders.Concat(installations);
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace InnovEnergy.App.Backend.DataTypes;
|
||||
|
||||
public abstract partial class TreeNode
|
||||
{
|
||||
private sealed class IdEqualityComparer : IEqualityComparer<TreeNode>
|
||||
{
|
||||
public Boolean Equals(TreeNode x, TreeNode y)
|
||||
{
|
||||
if (ReferenceEquals(x, y)) return true;
|
||||
if (ReferenceEquals(x, null)) return false;
|
||||
if (ReferenceEquals(y, null)) return false;
|
||||
if (x.GetType() != y.GetType()) return false;
|
||||
return x.Id == y.Id;
|
||||
}
|
||||
|
||||
public Int32 GetHashCode(TreeNode obj)
|
||||
{
|
||||
return obj.Id.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
public static IEqualityComparer<TreeNode> IdComparer { get; } = new IdEqualityComparer();
|
||||
}
|
|
@ -195,7 +195,7 @@ th { /* header cell */
|
|||
for (var batteryId = 3; batteryId < Int64.Parse(numberOfBatteries) + 2; batteryId++)
|
||||
{
|
||||
localCommand = localCommand.Append(
|
||||
$" && /opt/innovenergy/scripts/upload-bms-firmware {batteryTtyName} {batteryId} /opt/innovenergy/{FirmwareVersion}.bin");
|
||||
$" && sleep 3m && /opt/innovenergy/scripts/upload-bms-firmware {batteryTtyName} {batteryId} /opt/innovenergy/{FirmwareVersion}.bin");
|
||||
}
|
||||
#pragma warning disable CS4014
|
||||
Db.ExecuteBufferedAsyncCommandOnIp(installationIp, localCommand)
|
||||
|
|
|
@ -153,7 +153,7 @@ public static partial class Db
|
|||
var command = $"dbus-send --system --dest={pathToBattery.Split('"')[1]} --type=method_call --print-reply /FirmwareVersion com.victronenergy.BusItem.GetText";
|
||||
var returnString = await ExecuteBufferedAsyncCommandOnIp(ip, command);
|
||||
var returnStringShortened = returnString.Split('"')[1];
|
||||
return returnStringShortened.Length > 5 ? "Unknown" : returnStringShortened;
|
||||
return returnStringShortened.Length > 10 ? "Unknown" : returnStringShortened;
|
||||
}
|
||||
|
||||
private static async Task<String> NumberOfBatteries(String? ip, String? online)
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace InnovEnergy.Lib.Utils;
|
||||
|
||||
public static class GraphTraversal
|
||||
{
|
||||
public static IEnumerable<T> TraverseDepthFirstPreOrder<T>(T root,
|
||||
Func<T, IEnumerable<T>> getChildren,
|
||||
IEqualityComparer<T>? comparer = null)
|
||||
{
|
||||
return Traverse(root, TreeTraversal.TraverseDepthFirstPreOrder, getChildren, comparer);
|
||||
}
|
||||
|
||||
|
||||
public static IEnumerable<T> TraverseDepthFirstPostOrder<T>(T root,
|
||||
Func<T, IEnumerable<T>> getChildren,
|
||||
IEqualityComparer<T>? comparer = null)
|
||||
{
|
||||
return Traverse(root, TreeTraversal.TraverseDepthFirstPostOrder, getChildren, comparer);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> TraverseBreadthFirst<T>(T root,
|
||||
Func<T, IEnumerable<T>> getChildren,
|
||||
IEqualityComparer<T>? comparer = null)
|
||||
{
|
||||
return Traverse(root, TreeTraversal.TraverseBreadthFirst, getChildren, comparer);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> TraverseDepthFirstPreOrder<T>(IEnumerable<T> sources,
|
||||
Func<T, IEnumerable<T>> getChildren,
|
||||
IEqualityComparer<T>? comparer = null)
|
||||
{
|
||||
return Traverse(sources, TreeTraversal.TraverseDepthFirstPreOrder, getChildren, comparer);
|
||||
}
|
||||
|
||||
|
||||
public static IEnumerable<T> TraverseDepthFirstPostOrder<T>(IEnumerable<T> sources,
|
||||
Func<T, IEnumerable<T>> getChildren,
|
||||
IEqualityComparer<T>? comparer = null)
|
||||
{
|
||||
return Traverse(sources, TreeTraversal.TraverseDepthFirstPostOrder, getChildren, comparer);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> TraverseBreadthFirst<T>(IEnumerable<T> sources,
|
||||
Func<T, IEnumerable<T>> getChildren,
|
||||
IEqualityComparer<T>? comparer = null)
|
||||
{
|
||||
return Traverse(sources, TreeTraversal.TraverseBreadthFirst, getChildren, comparer);
|
||||
}
|
||||
|
||||
|
||||
private static IEnumerable<T> Traverse<T>(T root,
|
||||
Func<T , Func<T, IEnumerable<T>>,IEnumerable<T>> traversor,
|
||||
Func<T, IEnumerable<T>> getChildren,
|
||||
IEqualityComparer<T>? comparer = null)
|
||||
{
|
||||
var getUniqueChildren = GetUniqueChildren(getChildren, root, comparer);
|
||||
return traversor(root, getUniqueChildren);
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
||||
private static IEnumerable<T> Traverse<T>(IEnumerable<T> sources,
|
||||
Func<T , Func<T, IEnumerable<T>>,IEnumerable<T>> traversor,
|
||||
Func<T, IEnumerable<T>> getChildren,
|
||||
IEqualityComparer<T>? comparer = null)
|
||||
{
|
||||
var set = new HashSet<T>(sources, comparer ?? EqualityComparer<T>.Default);
|
||||
IEnumerable<T> GetUniqueChildren(T n) => getChildren(n).Where(set.Add);
|
||||
|
||||
return from s in sources
|
||||
from e in traversor(s, GetUniqueChildren)
|
||||
select e;
|
||||
}
|
||||
|
||||
// TODO: IEqualityComparer
|
||||
public static IEnumerable<(T source, T target)> Edges<T>(T node, Func<T, IEnumerable<T>> getChildren)
|
||||
{
|
||||
return Edges(node.AsSingleEnumerable(), getChildren);
|
||||
}
|
||||
|
||||
|
||||
// TODO: IEqualityComparer
|
||||
public static IEnumerable<(T source, T target)> Edges<T>(IEnumerable<T> sources,
|
||||
Func<T, IEnumerable<T>> getChildren)
|
||||
{
|
||||
var hs = new HashSet<(T source, T target)>();
|
||||
|
||||
IEnumerable<(T source, T target)> GetChildEdges((T source, T target) edge)
|
||||
{
|
||||
return getChildren(edge.target)
|
||||
.Select(c => (edge.target, c))
|
||||
.Where(hs!.Add);
|
||||
}
|
||||
|
||||
return from src in sources.Select(s => (s, s))
|
||||
from e in TreeTraversal.TraverseDepthFirstPreOrder(src, GetChildEdges).Skip(1)
|
||||
select e;
|
||||
}
|
||||
|
||||
private static Func<T, IEnumerable<T>> GetUniqueChildren<T>(Func<T, IEnumerable<T>> getChildren,
|
||||
T root,
|
||||
IEqualityComparer<T>? comparer)
|
||||
{
|
||||
return GetUniqueChildren(getChildren, root.AsSingleEnumerable(), comparer);
|
||||
}
|
||||
|
||||
private static Func<T, IEnumerable<T>> GetUniqueChildren<T>(Func<T, IEnumerable<T>> getChildren,
|
||||
IEnumerable<T> sources,
|
||||
IEqualityComparer<T>? comparer)
|
||||
{
|
||||
var set = new HashSet<T>(sources, comparer ?? EqualityComparer<T>.Default);
|
||||
return n => getChildren(n).Where(set.Add);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
using InnovEnergy.Lib.Utils.Reflection;
|
||||
|
||||
namespace InnovEnergy.Lib.Utils;
|
||||
|
||||
public static class TreeTraversal
|
||||
|
|
Loading…
Reference in New Issue