1using CommunityToolkit.Mvvm.ComponentModel;
2using CommunityToolkit.Mvvm.Input;
9using System.Collections.ObjectModel;
10using System.ComponentModel;
36 this.thing = Args?.
Thing;
40 if (this.thing is not
null)
42 if (
string.IsNullOrEmpty(this.thing.NodeId) &&
string.IsNullOrEmpty(
this.thing.SourceId) &&
string.IsNullOrEmpty(
this.thing.Partition))
45 this.thingRef =
new ThingReference(this.thing.NodeId,
this.thing.SourceId,
this.thing.Partition);
47 if (this.thing.MetaData is not
null &&
this.thing.MetaData.Length > 0)
51 foreach (
Property Tag
in this.thing.MetaData)
55 this.SupportsSensorEvents = this.thing.SupportsSensorEvents ??
false;
62 await base.OnInitialize();
64 this.CalcThingIsOnline();
66 ServiceRef.XmppService.OnPresence += this.Xmpp_OnPresence;
67 ServiceRef.TagProfile.Changed += this.TagProfile_Changed;
69 string? FullJid = this.GetFullJid();
71 if (!
string.IsNullOrEmpty(FullJid))
73 if (this.thingRef is
null)
78 this.request.OnStateChanged += this.Request_OnStateChanged;
79 this.request.OnFieldsReceived += this.Request_OnFieldsReceived;
80 this.request.OnErrorsReceived += this.Request_OnErrorsReceived;
88 this.Status = NewState
switch
90 SensorDataReadoutState.Requested =>
ServiceRef.
Localizer[nameof(AppResources.SensorDataRequested)],
91 SensorDataReadoutState.Accepted =>
ServiceRef.
Localizer[nameof(AppResources.SensorDataAccepted)],
92 SensorDataReadoutState.Cancelled =>
ServiceRef.
Localizer[nameof(AppResources.SensorDataCancelled)],
94 SensorDataReadoutState.Failure =>
ServiceRef.
Localizer[nameof(AppResources.SensorDataFailure)],
95 SensorDataReadoutState.Receiving =>
ServiceRef.
Localizer[nameof(AppResources.SensorDataReceiving)],
96 SensorDataReadoutState.Started =>
ServiceRef.
Localizer[nameof(AppResources.SensorDataStarted)],
100 return Task.CompletedTask;
103 private static string GetFieldTypeString(
FieldType Type)
109 else if (Type.HasFlag(
FieldType.Momentary))
113 else if (Type.HasFlag(
FieldType.Computed))
115 else if (Type.HasFlag(
FieldType.Historical))
121 private Task Request_OnFieldsReceived(
object? Sender, IEnumerable<Field> NewFields)
123 return this.NewFieldsReported(NewFields);
126 private Task NewFieldsReported(IEnumerable<Field> NewFields)
128 MainThread.BeginInvokeOnMainThread(() =>
133 int CategoryIndex = 0;
147 if (FieldName.EndsWith(
", Min", StringComparison.InvariantCultureIgnoreCase))
149 FieldName = FieldName[0..^5];
152 else if (FieldName.EndsWith(
", Max", StringComparison.InvariantCultureIgnoreCase))
154 FieldName = FieldName[0..^5];
158 Category = FieldName;
162 Category = GetFieldTypeString(
Field.
Type);
163 IsMin = IsMax =
false;
166 if (CategoryHeader is
null || CategoryHeader.Label != Category)
168 CategoryHeader =
null;
173 if (Item is
HeaderModel Header && Header.Label == Category)
175 CategoryHeader = Header;
182 if (CategoryHeader is
null)
185 this.SensorData.Add(CategoryHeader);
191 for (i = CategoryIndex + 1, c = this.SensorData.Count; i < c; i++)
193 object Obj = this.SensorData[i];
211 else if (j > 0 && !IsMin && !IsMax)
229 for (i = CategoryIndex + 1, c = this.SensorData.Count; i < c; i++)
231 object Obj = this.SensorData[i];
233 if (Obj is FieldModel FieldModel)
235 j =
string.Compare(FieldName, FieldModel.Name, StringComparison.OrdinalIgnoreCase);
241 FieldModel.Field =
Field;
243 this.SensorData.Insert(i,
new FieldModel(
Field));
250 this.SensorData.Insert(i,
new FieldModel(
Field));
256 this.SensorData.Add(
new FieldModel(
Field));
261 return Task.CompletedTask;
264 private Task Request_OnErrorsReceived(
object? Sender, IEnumerable<ThingError> NewErrors)
266 return this.NewErrorsReported(NewErrors);
269 private Task NewErrorsReported(IEnumerable<ThingError> NewErrors)
271 MainThread.BeginInvokeOnMainThread(() =>
275 int CategoryIndex = 0;
278 foreach (
object Item
in this.SensorData)
280 if (Item is
HeaderModel Header && Header.Label == Errors)
282 CategoryHeader = Header;
289 if (CategoryHeader is
null)
292 this.SensorData.Add(CategoryHeader);
295 for (i = CategoryIndex + 1, c = this.SensorData.Count; i < c; i++)
297 object Obj = this.SensorData[i];
299 if (Obj is ErrorModel ErrorModel)
305 this.SensorData.Insert(i++,
new ErrorModel(Error));
316 this.SensorData.Add(
new ErrorModel(Error));
320 return Task.CompletedTask;
323 private async Task SensorDataPersonalEventHandler(
object? Sender, PersonalEventNotificationEventArgs e)
326 !
string.IsNullOrEmpty(
this.thing?.BareJid) &&
327 string.Equals(
this.thing.BareJid, e.Publisher, StringComparison.OrdinalIgnoreCase) &&
328 string.IsNullOrEmpty(
this.thing.SourceId) &&
329 string.IsNullOrEmpty(
this.thing.NodeId) &&
330 string.IsNullOrEmpty(
this.thing.Partition))
345 ServiceRef.XmppService.OnPresence -= this.Xmpp_OnPresence;
346 ServiceRef.TagProfile.Changed -= this.TagProfile_Changed;
348 if (this.request is not
null &&
354 await this.request.
Cancel();
357 await base.OnDispose();
360 private Task Xmpp_OnPresence(
object? Sender, PresenceEventArgs e)
362 this.CalcThingIsOnline();
363 return Task.CompletedTask;
366 private void CalcThingIsOnline()
368 if (this.thing is
null)
369 this.IsThingOnline =
false;
373 this.IsThingOnline = Item is not
null && Item.HasLastPresence && Item.
LastPresence.IsOnline;
377 private string? GetFullJid()
379 if (this.thing is
null)
392 private void TagProfile_Changed(
object? Sender, PropertyChangedEventArgs e)
394 MainThread.BeginInvokeOnMainThread(this.CalcThingIsOnline);
408 private bool isThingOnline;
414 private bool supportsSensorEvents;
420 private bool hasStatus;
426 private string? status;
431 base.OnPropertyChanged(e);
433 switch (e.PropertyName)
435 case nameof(this.Status):
436 this.HasStatus = !
string.IsNullOrEmpty(this.Status);
439 case nameof(this.IsConnected):
440 this.CalcThingIsOnline();
451 private static Task Click(
object obj)
455 else if (obj is FieldModel
Field)
457 else if (obj is ErrorModel Error)
459 else if (obj is
string s)
462 return Task.CompletedTask;
Base class that references services in the app.
static IStringLocalizer Localizer
Localization service
static IXmppService XmppService
The XMPP service for XMPP communication.
Class used to present a meta-data tag in a human interface.
Represents a set of historical field values.
void Add(Field Field)
Adds a historical field value.
string FieldName
Field Name
void AddMax(Field Field)
Adds a historical maximum field value.
void AddMin(Field Field)
Adds a historical minimum field value.
The view model to bind to when displaying a thing.
override async Task OnDispose()
Method called when the view is disposed, and will not be used more. Use this method to unregister eve...
ReadSensorViewModel(ViewThingNavigationArgs? Args)
Creates an instance of the ReadSensorViewModel class.
override void OnPropertyChanged(PropertyChangedEventArgs e)
override async Task OnInitialize()
Method called when view is initialized for the first time. Use this method to implement registration ...
The view model to bind to for when displaying thing claim information.
static async Task LabelClicked(string Name, string Value, string LocalizedValue)
Processes the click of a localized meta-data label.
Holds navigation parameters specific to viewing things.
ContactInfo? Thing
Thing information.
A view model that holds the XMPP state.
Maintains information about an item in the roster.
bool HasLastPresence
If the roster item has received presence from an online resource having the given bare JID.
string LastPresenceFullJid
Full JID of last resource sending online presence.
PresenceEventArgs LastPresence
Last presence received from a resource having this bare JID.
Manages a sensor data client request.
virtual Task Cancel()
Cancels the readout.
SensorDataReadoutState State
Current state of readout.
Contains personal sensor data.
IEnumerable< ThingError > Errors
Thing errors.
IEnumerable< Field > Fields
Sensor data fields.
Base class for all sensor data fields.
FieldType Type
Field Type flags.
abstract string ValueString
String representation of field value.
string Name
Unlocalized field name.
Contains information about an error on a thing
Contains a reference to a thing
class HeaderModel(string Label)
Represents a header
SensorDataReadoutState
Sensor Data Readout States.
FieldType
Field Type flags