|
|
|
using EyesAndEars.UWP.Models;
|
|
|
|
using System;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Text.Json;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using Windows.Storage;
|
|
|
|
using Windows.UI;
|
|
|
|
using Windows.UI.Xaml.Media;
|
|
|
|
using Windows.UI.Xaml.Controls;
|
|
|
|
using Windows.UI.Xaml.Documents;
|
|
|
|
using Windows.UI.Text;
|
|
|
|
using Windows.Media.SpeechSynthesis;
|
|
|
|
|
|
|
|
namespace EyesAndEars.UWP.Services {
|
|
|
|
public static class DataServices {
|
|
|
|
|
|
|
|
static SpeechSynthesizer _synth = new SpeechSynthesizer();
|
|
|
|
|
|
|
|
public static string SetCurrentTime() {
|
|
|
|
var zone = TimeZoneInfo.Local;
|
|
|
|
var britishZone = TimeZoneInfo.FindSystemTimeZoneById(zone.Id);
|
|
|
|
var newDate = TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.Local, britishZone);
|
|
|
|
return newDate.ToShortTimeString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async Task<Device> UpdateDevice(string url, int deviceId,
|
|
|
|
RichTextBlock logs, string currentStatus, MediaElement audioUpdater, bool _logData) {
|
|
|
|
try {
|
|
|
|
var id = MapFactoryDeviceToGalleyDevice(deviceId); // Has note.
|
|
|
|
var readingAPI = $"{url}/api/readings/latest/{id}";
|
|
|
|
var statusAPI = $"{url}/api/status/latest/{deviceId}";
|
|
|
|
var readingJSON = await WebServices.GetJSON(readingAPI);
|
|
|
|
var statusJSON = await WebServices.GetJSON(statusAPI);
|
|
|
|
var r = MapToLightReading(readingJSON);
|
|
|
|
var s = MapToDeviceStatus(statusJSON);
|
|
|
|
var c = UpdateStatusColour(deviceId, s.status, r.reading);
|
|
|
|
var dev = new Device(deviceId, r, s, c);
|
|
|
|
if(_logData == true) LogUpdate(logs, dev);
|
|
|
|
NotifyAnyStatusChanges(currentStatus, dev, audioUpdater);
|
|
|
|
return dev;
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
Debug.WriteLine(e.Message);
|
|
|
|
return CreateFallBackDevice(deviceId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static async void NotifyAnyStatusChanges(string currentStatus,
|
|
|
|
Device dev, MediaElement audioUpdater) {
|
|
|
|
if (currentStatus.Equals
|
|
|
|
(dev.LatestStatus.status, StringComparison.InvariantCulture)
|
|
|
|
!= true) {
|
|
|
|
var stream = await _synth.SynthesizeTextToStreamAsync
|
|
|
|
($"{TranslateDeviceIdToDeviceName(dev)} {dev.LatestStatus.status}");
|
|
|
|
audioUpdater.SetSource(stream, stream.ContentType);
|
|
|
|
audioUpdater.Play();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static string TranslateDeviceIdToDeviceName(Device dev) {
|
|
|
|
if (dev.Id == 1) return "factory1";
|
|
|
|
else if (dev.Id == 2) return "factory2";
|
|
|
|
else if (dev.Id == 4) return "gallery1";
|
|
|
|
else return "gallery2";
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void LogUpdate(RichTextBlock logs, Device dev) {
|
|
|
|
// Devices 3 and 6 are not in use.
|
|
|
|
// string device = TranslateDeviceIdToDeviceName(dev);
|
|
|
|
Paragraph paragraph = new Paragraph();
|
|
|
|
var run1 = new Run {
|
|
|
|
FontWeight = FontWeights.Bold,
|
|
|
|
Text = $"{DateTime.Now} | "
|
|
|
|
};
|
|
|
|
var run2 = new Run {
|
|
|
|
Foreground = dev.StatusColour,
|
|
|
|
FontWeight = FontWeights.Bold,
|
|
|
|
Text = TranslateDeviceIdToDeviceName(dev)
|
|
|
|
};
|
|
|
|
var run3 = new Run {
|
|
|
|
Foreground = dev.StatusColour,
|
|
|
|
Text = $" | {dev.LatestReading.id} | {dev.LatestReading.reading} | " +
|
|
|
|
$"{dev.LatestStatus.status} | {dev.LatestReading.time}"
|
|
|
|
};
|
|
|
|
paragraph.Inlines.Add(run1);
|
|
|
|
paragraph.Inlines.Add(run2);
|
|
|
|
paragraph.Inlines.Add(run3);
|
|
|
|
logs.Blocks.Insert(0, paragraph);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static SolidColorBrush UpdateStatusColour(int device, string status, int reading) {
|
|
|
|
try {
|
|
|
|
if (status.Equals("on", StringComparison.OrdinalIgnoreCase)) {
|
|
|
|
|
|
|
|
/* Note: 'Negative Light' Levels.
|
|
|
|
* ========================================================
|
|
|
|
* The light meters will record 'negative light' values
|
|
|
|
* when the factory lights are off. This does not mean
|
|
|
|
* the light meters are not functioning properly. With that
|
|
|
|
* said, this dashboard make it look like they are. Because
|
|
|
|
* of this, the blocks in the dashboard will change to
|
|
|
|
* 'LightSkyBlue' to help indicate the change is something
|
|
|
|
* the system knows about and everything is fine -- nothing
|
|
|
|
* is broken.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (device == 1) {
|
|
|
|
if (reading > 0 && reading <= 39) // No weld detected.
|
|
|
|
return new SolidColorBrush(Colors.LightSeaGreen);
|
|
|
|
if (reading > 38) // Weld detected.
|
|
|
|
return new SolidColorBrush(Colors.DarkSeaGreen);
|
|
|
|
}
|
|
|
|
else if (device == 2) {
|
|
|
|
if (reading > 0 && reading <= 48) // No weld detected.
|
|
|
|
return new SolidColorBrush(Colors.LightSeaGreen);
|
|
|
|
if (reading > 48) // Weld detected.
|
|
|
|
return new SolidColorBrush(Colors.DarkSeaGreen);
|
|
|
|
}
|
|
|
|
else if (reading < 0) {
|
|
|
|
// The device is on but factory lights are off.
|
|
|
|
return new SolidColorBrush(Colors.LightSkyBlue);
|
|
|
|
}
|
|
|
|
// Indicate the gallery relays are on.
|
|
|
|
return new SolidColorBrush(Colors.LightSeaGreen);
|
|
|
|
}
|
|
|
|
// The device is off.
|
|
|
|
return new SolidColorBrush(Colors.DarkRed);
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
// Extra protection to if-check at top of this try block.
|
|
|
|
Debug.WriteLine(e.Message);
|
|
|
|
return new SolidColorBrush(Colors.DarkOrange);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Note: The Purpose of Mapping a Factory to a Gallery Device.
|
|
|
|
* ================================================================
|
|
|
|
* Every device in the project is paired up with another.
|
|
|
|
* Factory1 => Gallery1 | Device1 => Device4
|
|
|
|
* Factory2 => Gallery2 | Device2 => Device5
|
|
|
|
* Factory3 => Gallery3 | Device3 => Device6 (Note in use at this time)
|
|
|
|
* At the moment, when a device completes a status update, each one
|
|
|
|
* is ran throught the "UpdateDevice" function (above). This means
|
|
|
|
* the latest light reading for a light meter (factory) must be
|
|
|
|
* retrieved when a galley-based device's status is updated.
|
|
|
|
* From a strict point-of-view, the gallery device does not need it
|
|
|
|
* so I should/could seperate out this functionality into seperate
|
|
|
|
* functions. For now though, a light reading is still needed to be
|
|
|
|
* retrieved because of the way the functions are called.
|
|
|
|
* This function just maps/pairs the (factory) light reading to the
|
|
|
|
* appropriate gallery device. By doing this, the gallery device
|
|
|
|
* has extra information on its paired up light meter. One way I
|
|
|
|
* have used that information is to show a small piece of text in
|
|
|
|
* the gallery status box to quickly check the accuracy of the
|
|
|
|
* synchronisation between the factory and gallery devices.
|
|
|
|
*/
|
|
|
|
static int MapFactoryDeviceToGalleyDevice(int deviceId) {
|
|
|
|
int id = 0;
|
|
|
|
if (deviceId > 3) {
|
|
|
|
switch (deviceId) {
|
|
|
|
case 4:
|
|
|
|
id = 1;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
id = 2;
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
id = 3;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
id = deviceId;
|
|
|
|
}
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LightReading MapToLightReading(string json) {
|
|
|
|
try {
|
|
|
|
var reading = JsonSerializer.Deserialize<LightReading>(json);
|
|
|
|
return reading;
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
Debug.WriteLine(e.Message);
|
|
|
|
return CreateDefaultLightReading();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static DeviceStatus MapToDeviceStatus(string json) {
|
|
|
|
try {
|
|
|
|
var status = JsonSerializer.Deserialize<DeviceStatus>(json);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
Debug.WriteLine(e.Message);
|
|
|
|
return CreateDefaultDeviceStatus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Device CreateFallBackDevice(int deviceId) {
|
|
|
|
// "999" and "err" are acting as sentinals in this context.
|
|
|
|
var r = new LightReading { id = 0, reading = 999, time = DateTime.Now };
|
|
|
|
var s = new DeviceStatus { id = 0, status = "err", time = DateTime.Now };
|
|
|
|
var c = new SolidColorBrush(Colors.DarkOrange);
|
|
|
|
var d = new Device(deviceId, r, s, c);
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
static LightReading CreateDefaultLightReading() =>
|
|
|
|
new LightReading { id = 0, reading = 999, time = DateTime.Now };
|
|
|
|
|
|
|
|
static DeviceStatus CreateDefaultDeviceStatus() =>
|
|
|
|
new DeviceStatus { id = 0, status = "err", time = DateTime.Now };
|
|
|
|
|
|
|
|
public static async Task SaveBaseURLAsync(string contents) {
|
|
|
|
try {
|
|
|
|
var storageFolder = ApplicationData.Current.LocalFolder;
|
|
|
|
var baseURLFile = await storageFolder.CreateFileAsync("baseURL.txt",
|
|
|
|
CreationCollisionOption.ReplaceExisting);
|
|
|
|
await FileIO.WriteTextAsync(baseURLFile, contents);
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
Debug.WriteLine(e.Message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async Task<string> GetBaseURLAsync() {
|
|
|
|
try {
|
|
|
|
var storageFolder = ApplicationData.Current.LocalFolder;
|
|
|
|
var baseURLFile = await storageFolder.GetFileAsync("baseURL.txt");
|
|
|
|
var text = await FileIO.ReadTextAsync(baseURLFile);
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
catch (Exception e) {
|
|
|
|
Debug.WriteLine(e.Message);
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|