Compare commits

..

1 Commits

Author SHA1 Message Date
jtalborough
83c76340fc fix: reapply fixes for fileIO 4 series 2023-05-09 09:08:28 -04:00
5 changed files with 248 additions and 498 deletions

View File

@@ -1,10 +1,11 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Crestron.SimplSharp;
using Crestron.SimplSharp.Net.Http;
using Crestron.SimplSharp.Ssh;
using Crestron.SimplSharpPro.EthernetCommunication;
using PepperDash.Core;
using PepperDash.Core.DebugThings;
namespace PepperDash.Essentials.Core
{
@@ -16,130 +17,52 @@ namespace PepperDash.Essentials.Core
public GenericHttpClient(string key, string name, string hostname)
: base(key, name)
{
Client = new HttpClient {HostName = hostname};
Client = new HttpClient();
Client.HostName = hostname;
}
public GenericHttpClient(string key, string name, string hostname, GenericHttpClientConnectionOptions options)
: base(key, name)
{
Client = new HttpClient
{
HostName = hostname,
Accept = options.Accept,
KeepAlive = options.KeepAlive,
Password = options.Password,
Timeout = options.Timeout,
TimeoutEnabled = options.TimeoutEnabled,
UserAgent = options.UserAgent,
UserName = options.UserName,
Version = options.Version
};
if (options.Port > 0) Client.Port = options.Port;
}
/// <summary>
/// Send a HTTP Get Request to a client
/// <summary>
///
/// </summary>
/// <param name="path">Path to request node</param>
public void SendText(string path)
{
var url = string.Format("http://{0}/{1}", Client.HostName, path);
var request = new HttpClientRequest()
{
Url = new UrlParser(url)
};
var error = Client.DispatchAsyncEx(request, Response, request);
}
/// <param name="path"></param>
public void SendText(string path)
{
HttpClientRequest request = new HttpClientRequest();
string url = string.Format("http://{0}/{1}", Client.HostName, path);
request.Url = new UrlParser(url);
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
}
public void SendText(string format, params object[] items)
{
HttpClientRequest request = new HttpClientRequest();
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
request.Url = new UrlParser(url);
HttpClient.DISPATCHASYNC_ERROR error = Client.DispatchAsyncEx(request, Response, request);
}
/// <summary>
/// Send a HTTP Get Request to a client using a formatted string
/// </summary>
/// <param name="format">Path</param>
/// <param name="items">Parameters for Path String Formatting</param>
public void SendText(string format, params object[] items)
{
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
var request = new HttpClientRequest()
{
Url = new UrlParser(url)
};
var error = Client.DispatchAsyncEx(request, Response, request);
}
/// <summary>
/// Send a unidirectional HTTP Get Request to a client using a formatted string
/// </summary>
/// <param name="format">Path</param>
/// <param name="items">Parameters for Path String Formatting</param>
public void SendTextNoResponse(string format, params object[] items)
{
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
var request = new HttpClientRequest()
{
Url = new UrlParser(url)
};
Client.Dispatch(request);
}
/// <summary>
/// Send an HTTP Request of a specific request type
/// </summary>
/// <param name="requestType">HTTP Request Type</param>
/// <param name="path">Path to request node</param>
public void SendText(RequestType requestType, string path)
{
var url = string.Format("http://{0}/{1}", Client.HostName, path);
var request = new HttpClientRequest()
{
Url = new UrlParser(url),
RequestType = requestType
};
var error = Client.DispatchAsyncEx(request, Response, request);
}
/// <summary>
/// Send an HTTP Request of a specific request type using a formatted string
/// </summary>
/// <param name="requestType">HTTP Request Type</param>
/// <param name="format">Path</param>
/// <param name="items">Parameters for Path String Formatting</param>
public void SendText(RequestType requestType, string format, params object[] items)
{
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
var request = new HttpClientRequest()
{
Url = new UrlParser(url),
RequestType = requestType
};
var error = Client.DispatchAsyncEx(request, Response, request);
}
/// <summary>
/// Send a unidirectional HTTP Request of a specific request type using a formatted string
/// </summary>
/// <param name="requestType">HTTP Request Type</param>
/// <param name="format">Path</param>
/// <param name="items">Parameters for Path String Formatting</param>
public void SendTextNoResponse(RequestType requestType, string format, params object[] items)
{
var url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
var request = new HttpClientRequest()
{
Url = new UrlParser(url)
};
Client.Dispatch(request);
}
public void SendTextNoResponse(string format, params object[] items)
{
HttpClientRequest request = new HttpClientRequest();
string url = string.Format("http://{0}/{1}", Client.HostName, string.Format(format, items));
request.Url = new UrlParser(url);
Client.Dispatch(request);
}
private void Response(HttpClientResponse response, HTTP_CALLBACK_ERROR error, object request)
{
if (error != HTTP_CALLBACK_ERROR.COMPLETED) return;
var responseReceived = response;
if (error == HTTP_CALLBACK_ERROR.COMPLETED)
{
var responseReceived = response;
if (responseReceived.ContentString.Length > 0)
{
if (ResponseRecived != null)
ResponseRecived(this, new GenericHttpClientEventArgs(responseReceived.ContentString, (request as HttpClientRequest).Url.ToString(), error));
}
}
if (responseReceived.ContentString.Length <= 0) return;
if (ResponseRecived == null) return;
var httpClientRequest = request as HttpClientRequest;
if (httpClientRequest != null)
ResponseRecived(this, new GenericHttpClientEventArgs(responseReceived.ContentString, httpClientRequest.Url.ToString(), error));
}
@@ -177,8 +100,6 @@ namespace PepperDash.Essentials.Core
#endregion
}
public class GenericHttpClientEventArgs : EventArgs
{
public string ResponseText { get; private set; }
@@ -191,84 +112,4 @@ namespace PepperDash.Essentials.Core
Error = error;
}
}
/// <summary>
/// Objedct to set parameters for HTTP Requests
/// </summary>
public class GenericHttpClientConnectionOptions
{
/// <summary>
/// Gets or sets content types that are acceptable for the response. The default
/// value is "text/html, image/gif, image/jpeg, image/png, */*".
/// </summary>
[DefaultValue("text/html, image/gif, image/jpeg, image/png")]
public string Accept { get; set; }
/// <summary>
/// Controls whether to use HTTP Keep-Alive to keep the connection alive between
/// requests. If enabled (true) , once a request is made and a connection is
/// established, this connection is kept open and used for future requests. If
/// disabled, the connection is closed, and a new connection is created for future
/// requests.
/// </summary>
[DefaultValue(true)]
public bool KeepAlive { get; set; }
/// <summary>
/// This property controls whether the request operation will do an automatic
/// timeout checking. If timeout handling is turned on (i.e. this property is
/// set to true) and a request takes longer than Timeout, it will be terminated.
/// </summary>
[DefaultValue(true)]
public bool TimeoutEnabled { get; set; }
/// <summary>
/// Gets or sets the maximum amount of time (in seconds) that a client will wait
/// for a server response within a single request. The default value is 60 seconds
/// (1 minute). The timeout handling can be activated via the TimeoutEnabled
/// property.
/// </summary>
[DefaultValue(60)]
public int Timeout { get; set; }
/// <summary>
/// Gets or sets the version identifier of the UserAgent. Can be used to mimic
/// particular browsers like Internet Explorer 6.0
/// </summary>
[DefaultValue("1.1")]
public string Version { get; set; }
/// <summary>
/// Gets or sets the identifier of the software being used to retrieve data via
/// the URL. Some custom HTTP servers check this HTTP header to provide content
/// optimized for particular HTTP browsers.
/// </summary>
[DefaultValue("Crestron SimplSharp HTTP Client")]
public string UserAgent { get; set; }
/// <summary>
/// Name that will be inserted into the Authorization HTTP header in the request
/// to the server.
/// </summary>
public string UserName { get; set; }
/// <summary>
/// Password that will be inserted into the Authorization HTTP header in the
/// request to the server.
/// </summary>
public string Password { get; set; }
/// <summary>
/// The server Port that you intend the client to connect to. If you do not
/// assign a port number on this property, the port number in the parsed URL
/// will be used. If a port number is assigned in the parsed URL, it will take
/// precedence over this property.
/// </summary>
/// <remarks>
/// If you do not assign a port number on this property, the port number in the
/// parsed URL will be used.
/// </remarks>
///
public int Port { get; set; }
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using Crestron.SimplSharp;
using PepperDash.Core;
using PepperDash.Essentials.Core;
@@ -9,7 +8,6 @@ namespace PepperDash_Essentials_Core.Devices
/// <summary>
/// Interface for any device that is able to control it'spower and has a configurable reboot time
/// </summary>
[Obsolete("PepperDash_Essentials_Core.Devices is Deprecated - use PepperDash.Essentials.Core")]
public interface IHasPowerCycle : IKeyName, IHasPowerControlWithFeedback
{
/// <summary>
@@ -26,7 +24,6 @@ namespace PepperDash_Essentials_Core.Devices
/// <summary>
/// Interface for any device that contains a collection of IHasPowerReboot Devices
/// </summary>
[Obsolete("PepperDash_Essentials_Core.Devices is Deprecated - use PepperDash.Essentials.Core")]
public interface IHasControlledPowerOutlets : IKeyName
{
/// <summary>

View File

@@ -1,87 +0,0 @@
using Crestron.SimplSharp;
using PepperDash.Core;
namespace PepperDash.Essentials.Core
{
/// <summary>
/// Interface for any device that has a battery that can be monitored
/// </summary>
public interface IHasBatteryStats : IKeyName
{
int BatteryPercentage { get; }
int BatteryCautionThresholdPercentage { get; }
int BatteryWarningThresholdPercentage { get; }
BoolFeedback BatteryIsWarningFeedback { get; }
BoolFeedback BatteryIsCautionFeedback { get; }
BoolFeedback BatteryIsOkFeedback { get; }
IntFeedback BatteryPercentageFeedback { get; }
}
/// <summary>
/// Interface for any device that has a battery that can be monitored and the ability to charge and discharge
/// </summary>
public interface IHasBatteryCharging : IHasBatteryStats
{
BoolFeedback BatteryIsCharging { get; }
}
/// <summary>
/// Interface for any device that has multiple batteries that can be monitored
/// </summary>
public interface IHasBatteries : IKeyName
{
ReadOnlyDictionary<string, IHasBatteryStats> Batteries { get; }
}
public interface IHasBatteryStatsExtended : IHasBatteryStats
{
int InputVoltage { get; }
int OutputVoltage { get; }
int InptuCurrent { get; }
int OutputCurrent { get; }
IntFeedback InputVoltageFeedback { get; }
IntFeedback OutputVoltageFeedback { get; }
IntFeedback InputCurrentFeedback { get; }
IntFeedback OutputCurrentFeedback { get; }
}
/// <summary>
/// Interface for any device that is able to control its power, has a configurable reboot time, and has batteries that can be monitored
/// </summary>
public interface IHasPowerCycleWithBattery : IHasPowerCycle, IHasBatteryStats
{
}
/// <summary>
/// Interface for any device that is able to control it's power and has a configurable reboot time
/// </summary>
public interface IHasPowerCycle : IKeyName, IHasPowerControlWithFeedback
{
/// <summary>
/// Delay between power off and power on for reboot
/// </summary>
int PowerCycleTimeMs { get; }
/// <summary>
/// Reboot outlet
/// </summary>
void PowerCycle();
}
/// <summary>
/// Interface for any device that contains a collection of IHasPowerReboot Devices
/// </summary>
public interface IHasControlledPowerOutlets : IKeyName
{
/// <summary>
/// Collection of IPduOutlets
/// </summary>
ReadOnlyDictionary<int, IHasPowerCycle> PduOutlets { get; }
}
}

View File

@@ -9,18 +9,18 @@ using Crestron.SimplSharpPro.CrestronThread;
namespace PepperDash.Essentials.Core
{
public static class FileIO
{
public static class FileIO
{
static CCriticalSection fileLock = new CCriticalSection();
public delegate void GotFileEventHandler(object sender, FileEventArgs e);
public static event GotFileEventHandler GotFileEvent;
static CCriticalSection fileLock = new CCriticalSection();
public delegate void GotFileEventHandler(object sender, FileEventArgs e);
public static event GotFileEventHandler GotFileEvent;
/// <summary>
/// Get the full file info from a path/filename, can include wildcards.
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
/// <summary>
/// Get the full file info from a path/filename, can include wildcards.
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static FileInfo[] GetFiles(string fileName)
{
string fullFilePath = Global.FilePathPrefix + fileName;
@@ -54,228 +54,228 @@ namespace PepperDash.Essentials.Core
}
/// <summary>
/// Get the data from string path/filename
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string ReadDataFromFile(string fileName)
{
try
{
return ReadDataFromFile(GetFile(fileName));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
return "";
}
}
/// <summary>
/// Get the data from string path/filename
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string ReadDataFromFile(string fileName)
{
try
{
return ReadDataFromFile(GetFile(fileName));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
return "";
}
}
/// <summary>
/// Get the data with fileInfo object
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string ReadDataFromFile(FileInfo file)
{
try
{
if (fileLock.TryEnter())
{
DirectoryInfo dirInfo = new DirectoryInfo(file.DirectoryName);
Debug.Console(2, "FileIO Getting Data {0}", file.FullName);
/// <summary>
/// Get the data with fileInfo object
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string ReadDataFromFile(FileInfo file)
{
try
{
if (fileLock.TryEnter())
{
DirectoryInfo dirInfo = new DirectoryInfo(file.DirectoryName);
Debug.Console(2, "FileIO Getting Data {0}", file.FullName);
if (File.Exists(file.FullName))
{
using (StreamReader r = new StreamReader(file.FullName))
{
return r.ReadToEnd();
}
}
else
{
Debug.Console(2, "File {0} does not exsist", file.FullName);
return "";
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
return "";
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
return "";
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
if (File.Exists(file.FullName))
{
using (StreamReader r = new StreamReader(file.FullName))
{
return r.ReadToEnd();
}
}
else
{
Debug.Console(2, "File {0} does not exsist", file.FullName);
return "";
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
return "";
}
}
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
return "";
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
public static void ReadDataFromFileASync(string fileName)
{
try
{
ReadDataFromFileASync(GetFile(fileName));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
}
}
public static void ReadDataFromFileASync(string fileName)
{
try
{
ReadDataFromFileASync(GetFile(fileName));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
}
}
public static void ReadDataFromFileASync(FileInfo file)
{
try
{
CrestronInvoke.BeginInvoke(o => _ReadDataFromFileASync(file));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
}
}
public static void ReadDataFromFileASync(FileInfo file)
{
try
{
CrestronInvoke.BeginInvoke(o => _ReadDataFromFileASync(file));
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
}
}
private static void _ReadDataFromFileASync(FileInfo file)
{
string data;
try
{
if (fileLock.TryEnter())
{
DirectoryInfo dirInfo = new DirectoryInfo(file.Name);
Debug.Console(2, "FileIO Getting Data {0}", file.FullName);
private static void _ReadDataFromFileASync(FileInfo file)
{
string data;
try
{
if (fileLock.TryEnter())
{
DirectoryInfo dirInfo = new DirectoryInfo(file.Name);
Debug.Console(2, "FileIO Getting Data {0}", file.FullName);
if (File.Exists(file.FullName))
{
using (StreamReader r = new StreamReader(file.FullName))
{
data = r.ReadToEnd();
}
}
else
{
Debug.Console(2, "File {0} Does not exsist", file.FullName);
data = "";
}
GotFileEvent.Invoke(null, new FileEventArgs(data));
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
}
if (File.Exists(file.FullName))
{
using (StreamReader r = new StreamReader(file.FullName))
{
data = r.ReadToEnd();
}
}
else
{
Debug.Console(2, "File {0} Does not exsist", file.FullName);
data = "";
}
GotFileEvent.Invoke(null, new FileEventArgs(data));
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
data = "";
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO read failed: \r{0}", e);
data = "";
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
}
}
}
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="filePath"></param>
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="filePath"></param>
public static void WriteDataToFile(string data, string filePath)
{
Thread _WriteFileThread;
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="filePath"></param>
/// <summary>
///
/// </summary>
/// <param name="data"></param>
/// <param name="filePath"></param>
public static void WriteDataToFile(string data, string filePath)
{
Thread _WriteFileThread;
_WriteFileThread = new Thread((O) => _WriteFileMethod(data, Global.FilePathPrefix + "/" + filePath), null, Thread.eThreadStartOptions.CreateSuspended);
_WriteFileThread.Priority = Thread.eThreadPriority.LowestPriority;
_WriteFileThread.Start();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "New WriteFile Thread");
_WriteFileThread.Priority = Thread.eThreadPriority.LowestPriority;
_WriteFileThread.Start();
Debug.Console(0, Debug.ErrorLogLevel.Notice, "New WriteFile Thread");
}
}
static object _WriteFileMethod(string data, string filePath)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write file: '{0}'", filePath);
static object _WriteFileMethod(string data, string filePath)
{
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Attempting to write file: '{0}'", filePath);
try
{
if (fileLock.TryEnter())
{
try
{
if (fileLock.TryEnter())
{
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.Write(data);
sw.Flush();
}
{
sw.Write(data);
sw.Flush();
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
}
}
else
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "FileIO Unable to enter FileLock");
}
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO write failed: \r{0}", e);
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
catch (Exception e)
{
Debug.Console(0, Debug.ErrorLogLevel.Error, "Error: FileIO write failed: \r{0}", e);
}
finally
{
if (fileLock != null && !fileLock.Disposed)
fileLock.Leave();
}
return null;
}
return null;
}
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public static bool FileIoUnitTest()
{
var testData = "Testing FileIO";
FileIO.WriteDataToFile(testData, "\\user\\FileIOTest.pdt");
/// <summary>
///
/// </summary>
/// <returns></returns>
public static bool FileIoUnitTest()
{
var testData = "Testing FileIO";
FileIO.WriteDataToFile(testData, "\\user\\FileIOTest.pdt");
var file = FileIO.GetFile("\\user\\*FileIOTest*");
var readData = FileIO.ReadDataFromFile(file);
Debug.Console(0, "Returned {0}", readData);
File.Delete(file.FullName);
if (testData == readData)
{
return true;
}
else
{
return false;
}
}
var file = FileIO.GetFile("\\user\\*FileIOTest*");
}
public class FileEventArgs
{
public FileEventArgs(string data) { Data = data; }
public string Data { get; private set; } // readonly
var readData = FileIO.ReadDataFromFile(file);
Debug.Console(0, "Returned {0}", readData);
File.Delete(file.FullName);
if (testData == readData)
{
return true;
}
else
{
return false;
}
}
}
}
public class FileEventArgs
{
public FileEventArgs(string data) { Data = data; }
public string Data { get; private set; } // readonly
}
}

View File

@@ -200,7 +200,6 @@
<Compile Include="Crestron IO\Relay\GenericRelayDevice.cs" />
<Compile Include="Crestron IO\Relay\ISwitchedOutput.cs" />
<Compile Include="Crestron IO\StatusSign\StatusSignController.cs" />
<Compile Include="Devices\PowerInterfaces.cs" />
<Compile Include="Web\RequestHandlers\AppDebugRequestHandler.cs" />
<Compile Include="Web\RequestHandlers\GetFeedbacksForDeviceRequestHandler.cs" />
<Compile Include="Web\EssentialsWebApiHelpers.cs" />