From 838f5445c090b85c1146c4b0aeab42009b271a0e Mon Sep 17 00:00:00 2001 From: zonyl Date: Thu, 8 Oct 2015 22:43:27 -0400 Subject: [PATCH] Add OWIN support, initial website with Razor Templating. Various Enhancements. --- BudMain/App.config | 10 +- BudMain/Program.cs | 10 +- BudProxy/App.config | 10 +- Netomity/Core/NetomityObjectType.cs | 1 + Netomity/Core/NetomitySystem.cs | 8 ++ Netomity/Devices/Scene.cs | 25 +++++ Netomity/Devices/StateDevice.cs | 45 +++++++- Netomity/Interfaces/Basic/BasicInterface.cs | 2 - Netomity/Interfaces/Basic/SerialIO.cs | 1 + Netomity/Interfaces/Basic/TCPClient.cs | 1 + Netomity/Netomity.csproj | 45 ++++++++ Netomity/Utility/Misc.cs | 11 ++ Netomity/Web/Content/devicecontrol.html | 87 ++++++++++++++++ Netomity/Web/Content/index.html | 70 +++++++++++++ Netomity/Web/HomeController.cs | 66 ++++++++++++ Netomity/Web/RestController.cs | 107 ++++++++++++++++++++ Netomity/Web/WebConfig.cs | 50 +++++++++ Netomity/Web/WebHost.cs | 26 +++++ Netomity/app.config | 11 ++ Netomity/packages.config | 11 ++ NetomityPS/NetomityPS.csproj | 3 + NetomityPS/app.config | 11 ++ NetomityTests/NetomityTests.csproj | 5 +- NetomityTests/Web/RestHostTests.cs | 6 ++ NetomityTests/Web/WebHostTests.cs | 37 +++++++ NetomityTests/app.config | 11 ++ 26 files changed, 659 insertions(+), 11 deletions(-) create mode 100644 Netomity/Devices/Scene.cs create mode 100644 Netomity/Utility/Misc.cs create mode 100644 Netomity/Web/Content/devicecontrol.html create mode 100644 Netomity/Web/Content/index.html create mode 100644 Netomity/Web/HomeController.cs create mode 100644 Netomity/Web/RestController.cs create mode 100644 Netomity/Web/WebConfig.cs create mode 100644 Netomity/Web/WebHost.cs create mode 100644 Netomity/app.config create mode 100644 NetomityPS/app.config create mode 100644 NetomityTests/Web/WebHostTests.cs create mode 100644 NetomityTests/app.config diff --git a/BudMain/App.config b/BudMain/App.config index 8e15646..03260cb 100644 --- a/BudMain/App.config +++ b/BudMain/App.config @@ -1,6 +1,14 @@ - + + + + + + + + + \ No newline at end of file diff --git a/BudMain/Program.cs b/BudMain/Program.cs index 3b40abd..1d820e8 100644 --- a/BudMain/Program.cs +++ b/BudMain/Program.cs @@ -24,13 +24,19 @@ static void Main(string[] args) var tp = new TCPClient(address: "192.168.12.161", port: 3333); var plm = new Insteon(iface: tp); - var test_tamp = new StateDevice(address: "00.5B.5d", iface: plm) + + var test_lamp = new StateDevice(address: "00.5B.5d", iface: plm) { Name = "TestLamp1" }; - var rh = new RestHost(address: BASE_ADDR); + var Bedtime = new Scene(devices: new List() { test_lamp }) + { + Name = "Bedtime" + }; + //var rh = new RestHost(address: BASE_ADDR); + var wh = new WebHost(address: "http://localhost:8083/"); ns.Run(); } diff --git a/BudProxy/App.config b/BudProxy/App.config index 8e15646..03260cb 100644 --- a/BudProxy/App.config +++ b/BudProxy/App.config @@ -1,6 +1,14 @@ - + + + + + + + + + \ No newline at end of file diff --git a/Netomity/Core/NetomityObjectType.cs b/Netomity/Core/NetomityObjectType.cs index 125a4de..310754d 100644 --- a/Netomity/Core/NetomityObjectType.cs +++ b/Netomity/Core/NetomityObjectType.cs @@ -14,6 +14,7 @@ public sealed class NetomityObjectType public static readonly NetomityObjectType Unknown = new NetomityObjectType("unknown"); public static readonly NetomityObjectType Device = new NetomityObjectType("device"); public static readonly NetomityObjectType Interface = new NetomityObjectType("interface"); + public static readonly NetomityObjectType Scene = new NetomityObjectType("scene"); private NetomityObjectType(String name) diff --git a/Netomity/Core/NetomitySystem.cs b/Netomity/Core/NetomitySystem.cs index 5a1e32c..771385c 100644 --- a/Netomity/Core/NetomitySystem.cs +++ b/Netomity/Core/NetomitySystem.cs @@ -43,5 +43,13 @@ public void Run() Thread.Sleep(1000); } } + + public IQueryable NetomityObjects + { + get + { + return c_objects.AsQueryable(); + } + } } } diff --git a/Netomity/Devices/Scene.cs b/Netomity/Devices/Scene.cs new file mode 100644 index 0000000..d3b9421 --- /dev/null +++ b/Netomity/Devices/Scene.cs @@ -0,0 +1,25 @@ +using Netomity.Core; +using Netomity.Interfaces.HA; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Netomity.Devices +{ + public class Scene: StateDevice + { + public Scene(string address = null, HAInterface iface = null, List devices = null): + base(address: address, iface: iface, devices: devices) + { + + } + + internal override void _Initialize() + { + base._Initialize(); + Type = NetomityObjectType.Scene; + } + } +} diff --git a/Netomity/Devices/StateDevice.cs b/Netomity/Devices/StateDevice.cs index 6cebb50..65e7706 100644 --- a/Netomity/Devices/StateDevice.cs +++ b/Netomity/Devices/StateDevice.cs @@ -22,25 +22,43 @@ public class StateDevice: NetomityObject List> _commandDelegates = null; List> _stateDelegates = null; List _devices = null; + List _commandsAvailable = null; public StateDevice(string address=null, HAInterface iface=null, List devices=null) { - Type = NetomityObjectType.Device; _iface = iface; _address = address; _commandDelegates = new List>(); _stateDelegates = new List>(); + _state = new State() + { + Primary = StateType.Unknown + }; + + _Initialize(); RegisterDevices(devices); - _state = new State(){ - Primary = StateType.Unknown - }; if(_iface !=null) _iface.OnCommand(source: _address, action: _CommandReceived); } + internal virtual void _Initialize() + { + Type = NetomityObjectType.Device; + + _commandsAvailable = new List() { + new Command() { + Primary = CommandType.On + }, + new Command() { + Primary = CommandType.Off + }, + }; + + } + private void RegisterDevices(List devices) { if (devices != null) @@ -64,6 +82,15 @@ public State State } } + [DataMember] + public List CommandsAvailable + { + get + { + return _commandsAvailable; + } + } + private void _CommandReceived(Command command) { State newState = null; @@ -176,5 +203,15 @@ public void OnStateChange(Action action) _stateDelegates.Add(action); } + public Task On() + { + return Command(commandT: CommandType.On); + } + + public Task Off() + { + return Command(commandT: CommandType.Off); + } + } } diff --git a/Netomity/Interfaces/Basic/BasicInterface.cs b/Netomity/Interfaces/Basic/BasicInterface.cs index be18b6c..01d1620 100644 --- a/Netomity/Interfaces/Basic/BasicInterface.cs +++ b/Netomity/Interfaces/Basic/BasicInterface.cs @@ -14,13 +14,11 @@ public BasicInterface(Logger logger=null) { if (logger != null) _logger = logger; - _Initialize(); } public BasicInterface() { - _Initialize(); } protected void _Initialize() diff --git a/Netomity/Interfaces/Basic/SerialIO.cs b/Netomity/Interfaces/Basic/SerialIO.cs index 9c90e28..46bd2b3 100644 --- a/Netomity/Interfaces/Basic/SerialIO.cs +++ b/Netomity/Interfaces/Basic/SerialIO.cs @@ -20,6 +20,7 @@ public SerialIO(string portName="COM4", int portSpeed = 9600) { _sp = new SerialPort(portName, portSpeed); _sp.DataReceived += _serialPort_DataReceived; + _Initialize(); } public override event DataReceivedHandler DataReceived; diff --git a/Netomity/Interfaces/Basic/TCPClient.cs b/Netomity/Interfaces/Basic/TCPClient.cs index 0c0fef0..12c29fe 100644 --- a/Netomity/Interfaces/Basic/TCPClient.cs +++ b/Netomity/Interfaces/Basic/TCPClient.cs @@ -21,6 +21,7 @@ public class TCPClient: BasicInterface public override event DataReceivedHandler DataReceived; public TCPClient(string address = null, int port = 0) { + Log("tcpconst"); _hostName = address; _portNumber = port; diff --git a/Netomity/Netomity.csproj b/Netomity/Netomity.csproj index 48e9481..f3cc205 100644 --- a/Netomity/Netomity.csproj +++ b/Netomity/Netomity.csproj @@ -33,6 +33,15 @@ false + + ..\packages\Microsoft.Owin.2.0.2\lib\net45\Microsoft.Owin.dll + + + ..\packages\Microsoft.Owin.Host.HttpListener.2.0.2\lib\net45\Microsoft.Owin.Host.HttpListener.dll + + + ..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll + ..\packages\CommonServiceLocator.1.0\lib\NET35\Microsoft.Practices.ServiceLocation.dll @@ -45,11 +54,36 @@ ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Owin.1.0\lib\net40\Owin.dll + + + ..\packages\RazorEngine.3.7.2\lib\net45\RazorEngine.dll + + + ..\packages\routedebugger.2.1.4.0\lib\net40\RouteDebugger.dll + + + + False + ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll + + + False + ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll + + + ..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3\lib\net45\System.Web.Http.Owin.dll + + + False + ..\packages\Microsoft.AspNet.Razor.3.0.0\lib\net45\System.Web.Razor.dll + @@ -66,6 +100,7 @@ + @@ -80,14 +115,24 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ + @foreach(var obj in @Model) + { + + + + + + } +
@obj.Name@obj.State.Primary + @foreach(var command in obj.CommandsAvailable) + { + + } +
+ @Model.ToString() + + @foreach(var obj in @Model) + { + @obj.Name + } + +
+ +

Netomity

+
+ +
+
+

+

Donec id elit non mi porta gravida at eget metus. Maecenas faucibus mollis interdum.

+ +

Subheading

+

Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum.

+ +

Subheading

+

Maecenas sed diam eget risus varius blandit sit amet non magna.

+
+ +
+

+

Donec id elit non mi porta gravida at eget metus. Maecenas faucibus mollis interdum.

+ +

Subheading

+

Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum.

+ +

Subheading

+

Maecenas sed diam eget risus varius blandit sit amet non magna.

+
+
+ +
+

© Company 2014

+
+ +
+ + + + \ No newline at end of file diff --git a/Netomity/Web/Content/index.html b/Netomity/Web/Content/index.html new file mode 100644 index 0000000..946711c --- /dev/null +++ b/Netomity/Web/Content/index.html @@ -0,0 +1,70 @@ +@* Generator : Template TypeVisibility : Internal *@ + + + + + + + + + + + + + + + + + + @Model.ToString() + + @foreach(var obj in @Model) + { + @obj.Name + } + +
+
+ +

Netomity

+
+ +
+
+

+

Donec id elit non mi porta gravida at eget metus. Maecenas faucibus mollis interdum.

+ +

Subheading

+

Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum.

+ +

Subheading

+

Maecenas sed diam eget risus varius blandit sit amet non magna.

+
+ +
+

+

Donec id elit non mi porta gravida at eget metus. Maecenas faucibus mollis interdum.

+ +

Subheading

+

Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum.

+ +

Subheading

+

Maecenas sed diam eget risus varius blandit sit amet non magna.

+
+
+ +
+

© Company 2014

+
+ +
+ + + + \ No newline at end of file diff --git a/Netomity/Web/HomeController.cs b/Netomity/Web/HomeController.cs new file mode 100644 index 0000000..51b94ed --- /dev/null +++ b/Netomity/Web/HomeController.cs @@ -0,0 +1,66 @@ +using Netomity.Core; +using Netomity.Devices; +using Netomity.Utility; +using Newtonsoft.Json; +using RazorEngine; +using RazorEngine.Templating; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using System.Web.Http; +using System.Web.Http.Results; + +namespace Netomity.Web +{ + [RoutePrefix("home")] + public class HomeController : ApiController + { + const string BASE_FOLDER = @"C:\projects\Netomity\Netomity\Web\Content\"; + [Route("")] + [HttpGet] + public HttpResponseMessage Get() + { + var objs = NetomitySystem.Factory().NetomityObjects; + + return RenderPage>(BASE_FOLDER + "index.html", objs); + } + + + [Route("devices")] + [HttpGet] + public HttpResponseMessage NetomityObjects2() + { + + var objs = NetomitySystem.Factory().NetomityObjects.Where(o => o.Type == NetomityObjectType.Device).Cast(); + +// return _JSONResponse>(true, objs); + return RenderPage>(BASE_FOLDER + "devicecontrol.html", objs); + } + + private HttpResponseMessage StringToHTMLResponse(string message) + { + var response = new HttpResponseMessage(); + response.Content = new StringContent(message); + response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html"); + return response; + } + + private string RazorToString(string templateText, T model) + { + string templateKeyName = Guid.NewGuid().ToString(); + string myParsedTemplate = Engine.Razor.RunCompile(templateText, templateKeyName, typeof(T), model); + + return myParsedTemplate; + } + + private HttpResponseMessage RenderPage(string filePath, T model) + { + string text = System.IO.File.ReadAllText(filePath); + return StringToHTMLResponse(RazorToString(text, model)); + } + } +} diff --git a/Netomity/Web/RestController.cs b/Netomity/Web/RestController.cs new file mode 100644 index 0000000..2399c1c --- /dev/null +++ b/Netomity/Web/RestController.cs @@ -0,0 +1,107 @@ +using Netomity.Core; +using Netomity.Devices; +using Netomity.Utility; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Web.Http; + +namespace Netomity.Web +{ + [RoutePrefix("net")] + public class RestController : ApiController + { + [Route("values")] + [HttpGet] + public IEnumerable Get() + { + return new string[] { "value1", "value2" }; + } + + [Route("objects/{type}")] + [HttpGet] + public IHttpActionResult NetomityObjects(string type) + { + + NetomityObjectType not = Conversions.ValueToStringEnum(type); + + var objs = NetomitySystem.Factory().NetomityObjects.Where(o => o.Type == not).ToList(); + +// return _JSONResponse>(true, objs); + return Json(objs); + } + + [Route("object/{id}/{property}/{primary}/{secondary?}")] + [HttpGet] + public IHttpActionResult SetNetomityObjectProperty(string id, string property, string primary, string secondary=null) + { + + Int32 iid = 0; + IQueryable nsojbs = null; + List objs = null; + NetomityObject obj = null; + bool status = false; + + nsojbs = NetomitySystem.Factory().NetomityObjects; + // var objs = c_objects.Where(o =>).ToList(); + if (Int32.TryParse(id, out iid)) + objs = nsojbs.Where(o => o.Id == iid).ToList(); + + if (iid == 0 || objs.Count() == 0) + objs = nsojbs.Where(o => o.Name != null && o.Name.ToLower() == id.ToLower()).ToList(); + + + if (objs.Count() > 0) + { + obj = objs.First(); + var sd = (StateDevice)obj; + switch (property.ToLower()) + { + case "command": + sd.Command(Conversions.ValueToStringEnum(primary), secondary); + status = true; + break; + case "state": + var state = new State() + { + Primary = Conversions.ValueToStringEnum(primary), + Secondary = secondary + }; + sd.State = state; + status = true; + break; + + } + + + } + + //return _JSONResponse(status, obj); + return Json(obj); + + } + + private string _JSONResponse(bool status, T obj) + { + var rObj = new RestResponse() + { + status = RestResponseStatusType.Success, + data = obj + }; + + string response = "[ "; + response = JsonConvert.SerializeObject(rObj, Formatting.Indented, + new JsonSerializerSettings + { + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }); + response = response.Replace("\r\n", ""); + + return response; + } + + } +} diff --git a/Netomity/Web/WebConfig.cs b/Netomity/Web/WebConfig.cs new file mode 100644 index 0000000..3fe649e --- /dev/null +++ b/Netomity/Web/WebConfig.cs @@ -0,0 +1,50 @@ +using Microsoft.Practices.Unity; +using Owin; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Http; + +namespace Netomity.Web +{ + public class WebConfig + { + Type RestControllerType = typeof(Netomity.Web.RestController); + + // This code configures Web API. The Startup class is specified as a type + // parameter in the WebApp.Start method. + public void Configuration(IAppBuilder appBuilder) + { + + // Configure Web API for self-host. + var config = new HttpConfiguration(); + + ThreadPool.SetMinThreads(50, 4); + + //config.Routes.MapHttpRoute("css", "css/{name}", new { controller = "Stylesheets" }); + //config.Routes.MapHttpRoute("js", "js/{name}", new { controller = "Javascript" }); + //config.Routes.MapHttpRoute("img", "img/{name}", new { controller = "Images" }); + //config.Routes.MapHttpRoute("defaultext", "{controller}.{ext}", new { ext = RouteParameter.Optional }); + //config.Routes.MapHttpRoute("default", "{controller}", new { controller = "Home" }); + + + + //config.MapHttpAttributeRoutes(); + config.MapHttpAttributeRoutes(); + + //config.Routes.MapHttpRoute( + // name: "DefaultApi", + // routeTemplate: "api/{controller}/{id}", + // defaults: new { id = RouteParameter.Optional } + //); + + + appBuilder.UseWebApi(config); + } + } +} diff --git a/Netomity/Web/WebHost.cs b/Netomity/Web/WebHost.cs new file mode 100644 index 0000000..e9b1100 --- /dev/null +++ b/Netomity/Web/WebHost.cs @@ -0,0 +1,26 @@ +using Microsoft.Owin.Hosting; +using Netomity.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Netomity.Web +{ + public class WebHost: NetomityObject + { + // netsh http add urlacl url=http://+:8082/ user=Everyone + public WebHost(string address) + { + var options = new StartOptions(address); + //options.Urls.Add("http://localhost:8083/"); + //options.Urls.Add("http://127.0.0.1:8083/"); + //options.Port = 8083; + Log(address); + options.Settings.Add("RouteDebugger:Enabled", "true"); +// WebApp.Start(url: address); + WebApp.Start(options); + } + } +} diff --git a/Netomity/app.config b/Netomity/app.config new file mode 100644 index 0000000..195db1f --- /dev/null +++ b/Netomity/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Netomity/packages.config b/Netomity/packages.config index 7c58563..91c01a0 100644 --- a/Netomity/packages.config +++ b/Netomity/packages.config @@ -1,6 +1,17 @@  + + + + + + + + + + + \ No newline at end of file diff --git a/NetomityPS/NetomityPS.csproj b/NetomityPS/NetomityPS.csproj index 78bb34f..7b31176 100644 --- a/NetomityPS/NetomityPS.csproj +++ b/NetomityPS/NetomityPS.csproj @@ -61,6 +61,9 @@ Netomity + + +