96 lines
3.2 KiB
C#
96 lines
3.2 KiB
C#
using System.Collections;
|
|
using System.Collections.Immutable;
|
|
using System.Diagnostics;
|
|
using System.Reactive.Subjects;
|
|
using InnovEnergy.Lib.Protocols.DBus.Protocol.DataTypes;
|
|
|
|
namespace InnovEnergy.Lib.Victron.VeDBus;
|
|
|
|
public class VeProperties : IEnumerable<VeProperty>
|
|
{
|
|
// Thread safe
|
|
|
|
private ImmutableDictionary<ObjectPath, VeProperty> _Dict = ImmutableDictionary<ObjectPath, VeProperty>.Empty;
|
|
|
|
private readonly Subject<VeProperty> _PropertyChanged = new();
|
|
private readonly Subject<ImmutableDictionary<ObjectPath, VeProperty>> _PropertiesChanged = new();
|
|
|
|
public IObservable<VeProperty> PropertyChanged => _PropertyChanged;
|
|
public IObservable<ImmutableDictionary<ObjectPath, VeProperty>> PropertiesChanged => _PropertiesChanged;
|
|
|
|
public Variant GetValueOfAllProperties(String prefix = "")
|
|
{
|
|
return _Dict
|
|
.Where(p => p.Key.Path.StartsWith(prefix))
|
|
.ToDictionary(p => p.Key.Path, p => p.Value.Value.Variant())
|
|
.Variant();
|
|
}
|
|
|
|
|
|
public Dictionary<String, String> GetTextOfAllProperties(String prefix = "")
|
|
{
|
|
return _Dict
|
|
.Where(p => p.Key.Path.StartsWith(prefix))
|
|
.ToDictionary(p => p.Key.Path, p => p.Value.Text);
|
|
}
|
|
|
|
|
|
public Dictionary<String, Dictionary<String, Variant>> GetAllItems(String prefix = "")
|
|
{
|
|
return _Dict
|
|
.Where(p => p.Key.Path.StartsWith(prefix))
|
|
.ToDictionary(p => p.Key.Path, p => p.Value.GetItem());
|
|
}
|
|
|
|
public VeProperty? Get(ObjectPath path)
|
|
{
|
|
return _Dict.TryGetValue(path, out var v) ? v : null;
|
|
}
|
|
|
|
public Boolean Set(ObjectPath path, Object value, String? text = null)
|
|
{
|
|
var txt = text ?? (value is Variant v ? v.Value.ToString() : value.ToString());
|
|
|
|
var p = new VeProperty(path, value, txt!);
|
|
return Set(p);
|
|
}
|
|
|
|
public Boolean Set(ObjectPath path, Object value, Boolean writable, String? text = null)
|
|
{
|
|
var txt = text ?? (value is Variant v ? v.Value.ToString() : value.ToString());
|
|
|
|
var p = new VeProperty(path, value, Text:txt!, writable);
|
|
return Set(p);
|
|
}
|
|
|
|
public Boolean Set(VeProperty prop)
|
|
{
|
|
|
|
// TODO: reenable optimization?
|
|
|
|
// var p = Get(prop.ObjectPath);
|
|
//
|
|
// if (p.HasValue && p.Value == prop)
|
|
// return false;
|
|
|
|
Debug.WriteLine($"Property changed: {prop.ObjectPath} {prop.Value} {prop.Text}");
|
|
|
|
_Dict = _Dict.SetItem(prop.ObjectPath, prop); // thread safe
|
|
|
|
_PropertiesChanged.OnNext(_Dict);
|
|
_PropertyChanged.OnNext(prop);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
#region Collection initializer
|
|
|
|
public Boolean Add(ObjectPath path, Object value, String? text = null) => Set(path, value, text:text);
|
|
public Boolean Add(VeProperty prop) => Set(prop);
|
|
public IEnumerator<VeProperty> GetEnumerator() => _Dict.Values.GetEnumerator();
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
|
|
#endregion Collection initializer
|
|
} |