Updated JsonToSimpMaster.cs and EventArgs and Constants.cs to implement passing resolved file path and filename to SIMPL. All edits are flagged with TODO: pdc-20 for easier review.

This commit is contained in:
Jason DeVito
2019-09-29 08:28:18 -05:00
parent 41b79cc639
commit 0ade04d0c7
2 changed files with 320 additions and 299 deletions

View File

@@ -1,125 +1,129 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
/// <summary> /// <summary>
/// Constants for Simpl modules /// Constants for Simpl modules
/// </summary> /// </summary>
public class JsonToSimplConstants public class JsonToSimplConstants
{ {
public const ushort JsonIsValidBoolChange = 2; public const ushort JsonIsValidBoolChange = 2;
public const ushort BoolValueChange = 1; public const ushort BoolValueChange = 1;
public const ushort UshortValueChange = 101; public const ushort UshortValueChange = 101;
public const ushort StringValueChange = 201; public const ushort StringValueChange = 201;
public const ushort FullPathToArrayChange = 202; public const ushort FullPathToArrayChange = 202;
public const ushort ActualFilePathChange = 203; public const ushort ActualFilePathChange = 203;
}
// TODO: pdc-20: Added below constants for passing file path and filename back to S+
//**************************************************************************************************// public const ushort FilenameResolvedChange = 204;
public delegate void SPlusValuesDelegate(); public const ushort FilePathResolvedChange = 205;
}
public class SPlusValueWrapper
{ //**************************************************************************************************//
public SPlusType ValueType { get; private set; } public delegate void SPlusValuesDelegate();
public ushort Index { get; private set; }
public ushort BoolUShortValue { get; set; } public class SPlusValueWrapper
public string StringValue { get; set; } {
public SPlusType ValueType { get; private set; }
public SPlusValueWrapper() { } public ushort Index { get; private set; }
public ushort BoolUShortValue { get; set; }
public SPlusValueWrapper(SPlusType type, ushort index) public string StringValue { get; set; }
{
ValueType = type; public SPlusValueWrapper() { }
Index = index;
} public SPlusValueWrapper(SPlusType type, ushort index)
} {
ValueType = type;
public enum SPlusType Index = index;
{ }
Digital, Analog, String }
}
public enum SPlusType
{
//**************************************************************************************************// Digital, Analog, String
public class BoolChangeEventArgs : EventArgs }
{
public bool State { get; set; }
public ushort IntValue { get { return (ushort)(State ? 1 : 0); } } //**************************************************************************************************//
public ushort Type { get; set; } public class BoolChangeEventArgs : EventArgs
public ushort Index { get; set; } {
public bool State { get; set; }
public BoolChangeEventArgs() public ushort IntValue { get { return (ushort)(State ? 1 : 0); } }
{ public ushort Type { get; set; }
} public ushort Index { get; set; }
public BoolChangeEventArgs(bool state, ushort type) public BoolChangeEventArgs()
{ {
State = state; }
Type = type;
} public BoolChangeEventArgs(bool state, ushort type)
{
public BoolChangeEventArgs(bool state, ushort type, ushort index) State = state;
{ Type = type;
State = state; }
Type = type;
Index = index; public BoolChangeEventArgs(bool state, ushort type, ushort index)
} {
} State = state;
Type = type;
//**************************************************************************************************// Index = index;
public class UshrtChangeEventArgs : EventArgs }
{ }
public ushort IntValue { get; set; }
public ushort Type { get; set; } //**************************************************************************************************//
public ushort Index { get; set; } public class UshrtChangeEventArgs : EventArgs
{
public UshrtChangeEventArgs() public ushort IntValue { get; set; }
{ public ushort Type { get; set; }
} public ushort Index { get; set; }
public UshrtChangeEventArgs(ushort intValue, ushort type) public UshrtChangeEventArgs()
{ {
IntValue = intValue; }
Type = type;
} public UshrtChangeEventArgs(ushort intValue, ushort type)
{
public UshrtChangeEventArgs(ushort intValue, ushort type, ushort index) IntValue = intValue;
{ Type = type;
IntValue = intValue; }
Type = type;
Index = index; public UshrtChangeEventArgs(ushort intValue, ushort type, ushort index)
} {
} IntValue = intValue;
Type = type;
//**************************************************************************************************// Index = index;
public class StringChangeEventArgs : EventArgs }
{ }
public string StringValue { get; set; }
public ushort Type { get; set; } //**************************************************************************************************//
public ushort Index { get; set; } public class StringChangeEventArgs : EventArgs
{
public StringChangeEventArgs() public string StringValue { get; set; }
{ public ushort Type { get; set; }
} public ushort Index { get; set; }
public StringChangeEventArgs(string stringValue, ushort type) public StringChangeEventArgs()
{ {
StringValue = stringValue; }
Type = type;
} public StringChangeEventArgs(string stringValue, ushort type)
{
public StringChangeEventArgs(string stringValue, ushort type, ushort index) StringValue = stringValue;
{ Type = type;
StringValue = stringValue; }
Type = type;
Index = index; public StringChangeEventArgs(string stringValue, ushort type, ushort index)
} {
StringValue = stringValue;
} Type = type;
Index = index;
}
}
} }

View File

@@ -1,178 +1,195 @@
using System; using System;
//using System.IO; //using System.IO;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Crestron.SimplSharp; using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO; using Crestron.SimplSharp.CrestronIO;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
namespace PepperDash.Core.JsonToSimpl namespace PepperDash.Core.JsonToSimpl
{ {
public class JsonToSimplFileMaster : JsonToSimplMaster public class JsonToSimplFileMaster : JsonToSimplMaster
{ {
/// <summary> /// <summary>
/// Sets the filepath as well as registers this with the Global.Masters list /// Sets the filepath as well as registers this with the Global.Masters list
/// </summary> /// </summary>
public string Filepath { get; private set; } public string Filepath { get; private set; }
public string ActualFilePath { get; private set; } public string ActualFilePath { get; private set; }
/*****************************************************************************************/ // TODO: pdc-20: added to return filename back to SIMPL
/** Privates **/ public string Filename { get; private set; }
public string FilePathName { get; private set; }
// The JSON file in JObject form /*****************************************************************************************/
// For gathering the incoming data /** Privates **/
object StringBuilderLock = new object();
// To prevent multiple same-file access
static object FileLock = new object(); // The JSON file in JObject form
// For gathering the incoming data
/*****************************************************************************************/ object StringBuilderLock = new object();
// To prevent multiple same-file access
/// <summary> static object FileLock = new object();
/// SIMPL+ default constructor.
/// </summary> /*****************************************************************************************/
public JsonToSimplFileMaster()
{ /// <summary>
} /// SIMPL+ default constructor.
/// </summary>
/// <summary> public JsonToSimplFileMaster()
/// Read, evaluate and udpate status {
/// </summary> }
public void EvaluateFile(string filepath)
{ /// <summary>
Filepath = filepath; /// Read, evaluate and udpate status
/// </summary>
OnBoolChange(false, 0, JsonToSimplConstants.JsonIsValidBoolChange); public void EvaluateFile(string filepath)
if (string.IsNullOrEmpty(Filepath)) {
{ Filepath = filepath;
CrestronConsole.PrintLine("Cannot evaluate file. JSON file path not set");
return; OnBoolChange(false, 0, JsonToSimplConstants.JsonIsValidBoolChange);
} if (string.IsNullOrEmpty(Filepath))
{
// Resolve wildcard CrestronConsole.PrintLine("Cannot evaluate file. JSON file path not set");
var dir = Path.GetDirectoryName(Filepath); return;
Debug.Console(1, "Checking directory {0}", dir); }
var fileName = Path.GetFileName(Filepath);
var directory = new DirectoryInfo(dir); // Resolve wildcard
var dir = Path.GetDirectoryName(Filepath);
var actualFile = directory.GetFiles(fileName).FirstOrDefault(); Debug.Console(1, "Checking directory {0}", dir);
if(actualFile == null) var fileName = Path.GetFileName(Filepath);
{ var directory = new DirectoryInfo(dir);
var msg = string.Format("JSON file not found: {0}", Filepath);
CrestronConsole.PrintLine(msg); var actualFile = directory.GetFiles(fileName).FirstOrDefault();
ErrorLog.Error(msg); if (actualFile == null)
return; {
} var msg = string.Format("JSON file not found: {0}", Filepath);
//var actualFileName = actualFile.FullName; CrestronConsole.PrintLine(msg);
ErrorLog.Error(msg);
return;
}
// \xSE\xR\PDT000-Template_Main_Config-Combined_DSP_v00.02.json
// \USER\PDT000-Template_Main_Config-Combined_DSP_v00.02.json
ActualFilePath = actualFile.FullName; ActualFilePath = actualFile.FullName;
OnStringChange(ActualFilePath, 0, JsonToSimplConstants.ActualFilePathChange); OnStringChange(ActualFilePath, 0, JsonToSimplConstants.ActualFilePathChange);
Debug.Console(1, "Actual JSON file is {0}", ActualFilePath); Debug.Console(1, "Actual JSON file is {0}", ActualFilePath);
string json = File.ReadToEnd(ActualFilePath, System.Text.Encoding.ASCII); // TODO: pdc-20: added to retrun filename to SIMPL
Filename = actualFile.Name;
try OnStringChange(Filename, 0, JsonToSimplConstants.FilenameResolvedChange);
{ Debug.Console(1, "JSON Filename is {0}", Filename);
JsonObject = JObject.Parse(json);
foreach (var child in Children) // TODO: pdc-20: added to return the file path to SIMPL
child.ProcessAll(); FilePathName = string.Format(@"{0}\", actualFile.DirectoryName);
OnBoolChange(true, 0, JsonToSimplConstants.JsonIsValidBoolChange); OnStringChange(FilePathName, 0, JsonToSimplConstants.FilePathResolvedChange);
} Debug.Console(1, "JSON File Path is {0}", FilePathName);
catch (Exception e)
{ string json = File.ReadToEnd(ActualFilePath, System.Text.Encoding.ASCII);
var msg = string.Format("JSON parsing failed:\r{0}", e);
CrestronConsole.PrintLine(msg); try
ErrorLog.Error(msg); {
return; JsonObject = JObject.Parse(json);
} foreach (var child in Children)
} child.ProcessAll();
public void setDebugLevel(int level) { OnBoolChange(true, 0, JsonToSimplConstants.JsonIsValidBoolChange);
Debug.SetDebugLevel(level); }
} catch (Exception e)
public override void Save() {
{ var msg = string.Format("JSON parsing failed:\r{0}", e);
// this code is duplicated in the other masters!!!!!!!!!!!!! CrestronConsole.PrintLine(msg);
UnsavedValues = new Dictionary<string, JValue>(); ErrorLog.Error(msg);
// Make each child update their values into master object return;
foreach (var child in Children) }
{ }
Debug.Console(1, "Master [{0}] checking child [{1}] for updates to save", UniqueID, child.Key); public void setDebugLevel(int level)
child.UpdateInputsForMaster(); {
} Debug.SetDebugLevel(level);
}
if (UnsavedValues == null || UnsavedValues.Count == 0) public override void Save()
{ {
Debug.Console(1, "Master [{0}] No updated values to save. Skipping", UniqueID); // this code is duplicated in the other masters!!!!!!!!!!!!!
return; UnsavedValues = new Dictionary<string, JValue>();
} // Make each child update their values into master object
lock (FileLock) foreach (var child in Children)
{ {
Debug.Console(1, "Saving"); Debug.Console(1, "Master [{0}] checking child [{1}] for updates to save", UniqueID, child.Key);
foreach (var path in UnsavedValues.Keys) child.UpdateInputsForMaster();
{ }
var tokenToReplace = JsonObject.SelectToken(path);
if (tokenToReplace != null) if (UnsavedValues == null || UnsavedValues.Count == 0)
{// It's found {
tokenToReplace.Replace(UnsavedValues[path]); Debug.Console(1, "Master [{0}] No updated values to save. Skipping", UniqueID);
Debug.Console(1, "JSON Master[{0}] Updating '{1}'", UniqueID, path); return;
} }
else // No token. Let's make one lock (FileLock)
{ {
//http://stackoverflow.com/questions/17455052/how-to-set-the-value-of-a-json-path-using-json-net Debug.Console(1, "Saving");
Debug.Console(1, "JSON Master[{0}] Cannot write value onto missing property: '{1}'", UniqueID, path); foreach (var path in UnsavedValues.Keys)
{
// JContainer jpart = JsonObject; var tokenToReplace = JsonObject.SelectToken(path);
// // walk down the path and find where it goes if (tokenToReplace != null)
//#warning Does not handle arrays. {// It's found
// foreach (var part in path.Split('.')) tokenToReplace.Replace(UnsavedValues[path]);
// { Debug.Console(1, "JSON Master[{0}] Updating '{1}'", UniqueID, path);
}
// var openPos = part.IndexOf('['); else // No token. Let's make one
// if (openPos > -1) {
// { //http://stackoverflow.com/questions/17455052/how-to-set-the-value-of-a-json-path-using-json-net
// openPos++; // move to number Debug.Console(1, "JSON Master[{0}] Cannot write value onto missing property: '{1}'", UniqueID, path);
// var closePos = part.IndexOf(']');
// var arrayName = part.Substring(0, openPos - 1); // get the name // JContainer jpart = JsonObject;
// var index = Convert.ToInt32(part.Substring(openPos, closePos - openPos)); // // walk down the path and find where it goes
//#warning Does not handle arrays.
// // Check if the array itself exists and add the item if so // foreach (var part in path.Split('.'))
// if (jpart[arrayName] != null) // {
// {
// var arrayObj = jpart[arrayName] as JArray; // var openPos = part.IndexOf('[');
// var item = arrayObj[index]; // if (openPos > -1)
// if (item == null) // {
// arrayObj.Add(new JObject()); // openPos++; // move to number
// } // var closePos = part.IndexOf(']');
// var arrayName = part.Substring(0, openPos - 1); // get the name
// Debug.Console(0, "IGNORING MISSING ARRAY VALUE FOR NOW"); // var index = Convert.ToInt32(part.Substring(openPos, closePos - openPos));
// continue;
// } // // Check if the array itself exists and add the item if so
// // Build the // if (jpart[arrayName] != null)
// if (jpart[part] == null) // {
// jpart.Add(new JProperty(part, new JObject())); // var arrayObj = jpart[arrayName] as JArray;
// jpart = jpart[part] as JContainer; // var item = arrayObj[index];
// } // if (item == null)
// jpart.Replace(UnsavedValues[path]); // arrayObj.Add(new JObject());
} // }
}
using (StreamWriter sw = new StreamWriter(ActualFilePath)) // Debug.Console(0, "IGNORING MISSING ARRAY VALUE FOR NOW");
{ // continue;
try // }
{ // // Build the
sw.Write(JsonObject.ToString()); // if (jpart[part] == null)
sw.Flush(); // jpart.Add(new JProperty(part, new JObject()));
} // jpart = jpart[part] as JContainer;
catch (Exception e) // }
{ // jpart.Replace(UnsavedValues[path]);
string err = string.Format("Error writing JSON file:\r{0}", e); }
Debug.Console(0, err); }
ErrorLog.Warn(err); using (StreamWriter sw = new StreamWriter(ActualFilePath))
return; {
} try
} {
} sw.Write(JsonObject.ToString());
} sw.Flush();
} }
} catch (Exception e)
{
string err = string.Format("Error writing JSON file:\r{0}", e);
Debug.Console(0, err);
ErrorLog.Warn(err);
return;
}
}
}
}
}
}