From e0cceee4abad95179e693fb5fbc0345f52468de1 Mon Sep 17 00:00:00 2001
From: Callum Inglis <callum@4oh4.co>
Date: Sat, 30 Oct 2021 19:02:50 +0100
Subject: [PATCH] Display data on frontend. Accomodate ppm10 and ppm100 values.
 Fix EntityFrameworkCore version

---
 Public API/Client/Pages/LatestData.razor      | 60 +++++++++++++++++++
 Public API/Client/Shared/NavMenu.razor        |  5 ++
 .../Server/Controllers/APIController.cs       | 12 +---
 .../Server/Controllers/FrontendController.cs  | 24 ++++++++
 Public API/Server/DAL/ApiContext.cs           |  1 +
 Public API/Server/Public_API.Server.csproj    |  9 ++-
 .../Shared/Models/Tables/SensorValue.cs       |  6 +-
 .../Shared/Models/Views/vw_SensorData.cs      | 26 ++++++++
 Public API/Shared/Public_API.Shared.csproj    |  2 +-
 Public API/Shared/SQL/1. CREATE TABLES.sql    | 17 +++---
 Public API/Shared/SQL/2. CREATE VIEWS.sql     |  7 +++
 11 files changed, 150 insertions(+), 19 deletions(-)
 create mode 100644 Public API/Client/Pages/LatestData.razor
 create mode 100644 Public API/Server/Controllers/FrontendController.cs
 create mode 100644 Public API/Shared/Models/Views/vw_SensorData.cs
 create mode 100644 Public API/Shared/SQL/2. CREATE VIEWS.sql

diff --git a/Public API/Client/Pages/LatestData.razor b/Public API/Client/Pages/LatestData.razor
new file mode 100644
index 0000000..7cf171f
--- /dev/null
+++ b/Public API/Client/Pages/LatestData.razor	
@@ -0,0 +1,60 @@
+@page "/latestdata"
+@using Public_API.Shared.Models 
+@inject HttpClient http
+ 
+<h3>LatestData</h3>
+<p>View Most Recent Sensor Data!</p>
+
+@if (sensorData == null)
+{
+    <p><em>Loading...</em></p>
+} else
+{
+    <table class="table">
+        <thead>
+            <tr>
+                <th>Sensor UID</th>
+                <th>Friendly Name</th>
+                <th>Location</th>
+                <th>Date</th>
+                <th>Time</th>
+
+                <th>Temperature</th>
+                <th>Humidity</th>
+
+                <th>PPM 1.0</th>
+                <th>PPM 2.5</th>
+                <th>PPM 10</th>
+            </tr>
+        </thead>
+        <tbody>
+            @foreach (vw_SensorData data in sensorData)
+            {
+            <tr>
+                <td>@data.sensorUID</td>
+                <td>@data.friendlyName</td>
+                <td>@data.locationCity</td>
+                <td>@data.dateTime.ToShortDateString()</td>
+                <td>@data.dateTime.ToShortTimeString()</td>
+
+                <td>@data.temperature</td>
+                <td>@data.humidity</td>
+
+                <td>@data.ppm10</td>
+                <td>@data.ppm25</td>
+                <td>@data.ppm100</td>
+            </tr>
+
+            }
+        </tbody>
+    </table>
+}
+
+@code {
+    private vw_SensorData[] sensorData;
+
+    protected override async Task OnInitializedAsync()
+    {
+        sensorData = await http.GetFromJsonAsync<vw_SensorData[]>("frontend/LatestData");
+    }
+}
diff --git a/Public API/Client/Shared/NavMenu.razor b/Public API/Client/Shared/NavMenu.razor
index 24bf8cf..66bb2c3 100644
--- a/Public API/Client/Shared/NavMenu.razor	
+++ b/Public API/Client/Shared/NavMenu.razor	
@@ -22,6 +22,11 @@
                 <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
             </NavLink>
         </li>
+        <li class="nav-item px-3">
+            <NavLink class="nav-link" href="latestdata">
+                <span class="oi oi-list-rich" aria-hidden="true"></span> Latest Data
+            </NavLink>
+        </li>
     </ul>
 </div>
 
diff --git a/Public API/Server/Controllers/APIController.cs b/Public API/Server/Controllers/APIController.cs
index c25deb4..b10ddc8 100644
--- a/Public API/Server/Controllers/APIController.cs	
+++ b/Public API/Server/Controllers/APIController.cs	
@@ -24,14 +24,6 @@ namespace Public_API.Server.Controllers
             return db.Sensor.Where(s => s.sensorUID.Equals(sensorUID)).FirstOrDefault();
         }
 
-
-        // GET: api/<APIController>
-        [HttpGet]
-        public IEnumerable<string> Get()
-        {
-            return new string[] { "value1", "value2" };
-        }
-
         // TODO Post
         // TODO Auth required
         // GET api/sensor/logValue/...
@@ -65,7 +57,9 @@ namespace Public_API.Server.Controllers
                 (decimal)response.sensorReading.sht.temperature, // SHT
                 (decimal)response.sensorReading.sht.humidity, // SHT
                 0, // TODO C02
-                (decimal)response.sensorReading.ppm.p25 // PPM TODO ppm10 and ppm100
+                (decimal)response.sensorReading.ppm.p10, // PPM
+                (decimal)response.sensorReading.ppm.p25, // PPM 
+                (decimal)response.sensorReading.ppm.p100 // PPM
             );
 
             db.SensorValue.Add(sensorValue);
diff --git a/Public API/Server/Controllers/FrontendController.cs b/Public API/Server/Controllers/FrontendController.cs
new file mode 100644
index 0000000..e430fd3
--- /dev/null
+++ b/Public API/Server/Controllers/FrontendController.cs	
@@ -0,0 +1,24 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Public_API.Server.DAL;
+using Public_API.Shared.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Public_API.Server.Controllers
+{
+    [ApiController]
+    [Route("[controller]")]
+    public class FrontendController : Controller
+    {
+        private ApiContext db = new ApiContext();
+
+        [HttpGet("LatestData")]
+        public IEnumerable<vw_SensorData> Get()
+        {
+            return db.vw_SensorData.OrderByDescending(d => d.dateTime).Take(100).ToArray();
+        }
+    }
+}
diff --git a/Public API/Server/DAL/ApiContext.cs b/Public API/Server/DAL/ApiContext.cs
index a7ae2ff..b35243e 100644
--- a/Public API/Server/DAL/ApiContext.cs	
+++ b/Public API/Server/DAL/ApiContext.cs	
@@ -11,6 +11,7 @@ namespace Public_API.Server.DAL
     {
         public DbSet<Sensor> Sensor { get; set; } 
         public DbSet<SensorValue> SensorValue { get; set; }
+        public DbSet<vw_SensorData> vw_SensorData { get; set; }
 
         protected override void OnModelCreating(ModelBuilder modelBuilder)
         {
diff --git a/Public API/Server/Public_API.Server.csproj b/Public API/Server/Public_API.Server.csproj
index f2a65ff..de0ea30 100644
--- a/Public API/Server/Public_API.Server.csproj	
+++ b/Public API/Server/Public_API.Server.csproj	
@@ -8,7 +8,14 @@
 
   <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="3.2.1" />
-    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.11" />
+    <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="5.0.0" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.20" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.20" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.20">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.5" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/Public API/Shared/Models/Tables/SensorValue.cs b/Public API/Shared/Models/Tables/SensorValue.cs
index 65768a2..83b7efe 100644
--- a/Public API/Shared/Models/Tables/SensorValue.cs	
+++ b/Public API/Shared/Models/Tables/SensorValue.cs	
@@ -14,16 +14,20 @@ namespace Public_API.Shared.Models
         public decimal temperature { get; set; }
         public decimal humidity { get; set; }
         public decimal co2 { get; set; }
+        public decimal ppm10 { get; set; }
         public decimal ppm25 { get; set; }
+        public decimal ppm100 { get; set; }
 
-        public SensorValue(int sensorID, DateTime dateTime, decimal temperature, decimal humidity, decimal co2, decimal ppm25)
+        public SensorValue(int sensorID, DateTime dateTime, decimal temperature, decimal humidity, decimal co2, decimal ppm10, decimal ppm25, decimal ppm100)
         {
             this.sensorID = sensorID;
             this.dateTime = dateTime;
             this.temperature = temperature;
             this.humidity = humidity;
             this.co2 = co2;
+            this.ppm10 = ppm10;
             this.ppm25 = ppm25;
+            this.ppm100 = ppm100;
         }
     }
 }
diff --git a/Public API/Shared/Models/Views/vw_SensorData.cs b/Public API/Shared/Models/Views/vw_SensorData.cs
new file mode 100644
index 0000000..804b274
--- /dev/null
+++ b/Public API/Shared/Models/Views/vw_SensorData.cs	
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace Public_API.Shared.Models
+{
+    public class vw_SensorData
+    {
+        [Key]
+        public int valueID { get; set; }
+        public int sensorID { get; set; }
+        public string sensorUID { get; set; }
+        public decimal locationLong { get; set; }
+        public decimal locationLat { get; set; }
+        public string locationCity { get; set; }
+        public string friendlyName { get; set; }
+
+        public DateTime dateTime { get; set; }
+        public decimal? temperature { get; set; }
+        public decimal? humidity { get; set; }
+        public decimal? ppm10 { get; set; }
+        public decimal? ppm25 { get; set; }
+        public decimal? ppm100 { get; set; }
+    }
+}
diff --git a/Public API/Shared/Public_API.Shared.csproj b/Public API/Shared/Public_API.Shared.csproj
index b2b7d44..fce8eef 100644
--- a/Public API/Shared/Public_API.Shared.csproj	
+++ b/Public API/Shared/Public_API.Shared.csproj	
@@ -5,7 +5,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.20" />
   </ItemGroup>
 
 </Project>
diff --git a/Public API/Shared/SQL/1. CREATE TABLES.sql b/Public API/Shared/SQL/1. CREATE TABLES.sql
index 4acceb6..b6afd55 100644
--- a/Public API/Shared/SQL/1. CREATE TABLES.sql	
+++ b/Public API/Shared/SQL/1. CREATE TABLES.sql	
@@ -18,12 +18,15 @@ CREATE TABLE [dbo].[Sensor](
 ) ON [PRIMARY]
 GO
 
-CREATE TABLE [dbo].[Sensor](
-	[sensorID] [int] IDENTITY(1,1) NOT NULL,
-	[sensorUID] [nvarchar](50) NOT NULL,
-	[locationLong] [decimal](11, 8) NOT NULL,
-	[locationLat] [decimal](11, 8) NOT NULL,
-	[locationCity] [nvarchar](100) NOT NULL,
-	[friendlyName] [nvarchar](50) NULL
+CREATE TABLE [dbo].[SensorValue](
+	[valueID] [int] IDENTITY(1,1) NOT NULL,
+	[dateTime] [datetime] NOT NULL,
+	[sensorID] [int] NOT NULL,
+	[temperature] [decimal](14, 4) NULL,
+	[humidity] [decimal](14, 4) NULL,
+	[co2] [decimal](14, 4) NULL,
+	[ppm25] [decimal](14, 4) NULL,
+	[ppm10] [decimal](14, 4) NULL,
+	[ppm100] [decimal](14, 4) NULL
 ) ON [PRIMARY]
 GO
\ No newline at end of file
diff --git a/Public API/Shared/SQL/2. CREATE VIEWS.sql b/Public API/Shared/SQL/2. CREATE VIEWS.sql
new file mode 100644
index 0000000..f9fa448
--- /dev/null
+++ b/Public API/Shared/SQL/2. CREATE VIEWS.sql	
@@ -0,0 +1,7 @@
+CREATE VIEW [dbo].[vw_SensorData]
+AS
+SELECT        dbo.SensorValue.valueID, dbo.Sensor.sensorID, dbo.Sensor.sensorUID, dbo.Sensor.locationLong, dbo.Sensor.locationLat, dbo.Sensor.locationCity, dbo.Sensor.friendlyName, dbo.SensorValue.dateTime, dbo.SensorValue.temperature, 
+                         dbo.SensorValue.humidity, dbo.SensorValue.ppm10, dbo.SensorValue.ppm25, dbo.SensorValue.ppm100
+FROM            dbo.SensorValue LEFT OUTER JOIN
+                         dbo.Sensor ON dbo.SensorValue.sensorID = dbo.Sensor.sensorID
+GO
\ No newline at end of file
-- 
GitLab