From f087bc9f66f0e97fef050d0b9f29eba92634a8f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Patrik=20Pa=C5=A1ko?= <patrik.pasko@twinzo.eu>
Date: Thu, 30 Jan 2025 18:28:34 +0000
Subject: [PATCH] Develop

---
 Main/Program.cs                               |  8 +-
 README.md                                     |  3 +
 SDK/Connection/V3/Areas.cs                    |  2 +-
 SDK/Connection/V3/Beacons.cs                  | 11 +--
 SDK/Connection/V3/Devices.cs                  |  2 +-
 SDK/Connection/V3/Layers.cs                   | 18 +----
 SDK/Connection/V3/Log.cs                      |  2 +-
 SDK/Connection/V3/Paths.cs                    | 21 +++++
 SDK/Connection/V3/Quantities.cs               |  4 +-
 SDK/Connection/V3/Sectors.cs                  | 11 +--
 SDK/Connection/V3/Sensors.cs                  |  6 +-
 SDK/Connection/V3/Shifts.cs                   |  2 +-
 .../AddBeaconResponseContract.cs              | 72 -----------------
 SDK/Contracts/Communication/AddLogContract.cs | 31 ++++++++
 .../AddSectorResponseContract.cs              | 61 ---------------
 SDK/Contracts/Data/AccountContract.cs         |  6 +-
 SDK/Contracts/Data/AreaContract.cs            | 46 +++++++++++
 SDK/Contracts/Data/BeaconContract.cs          | 41 +++++++++-
 SDK/Contracts/Data/DeviceContract.cs          | 78 +++++++++++++++++++
 SDK/Contracts/Data/LayerContract.cs           | 59 ++++++++++++++
 SDK/Contracts/Data/LoginContract.cs           |  7 --
 SDK/Contracts/Data/PathContract.cs            | 47 +++++++++++
 SDK/Contracts/Data/QuantityContract.cs        | 20 +++++
 SDK/Contracts/Data/SectorContract.cs          | 57 ++++++++++++++
 SDK/Contracts/Data/SensorContract.cs          | 34 ++++++++
 SDK/Contracts/Data/SensorDataContract.cs      | 29 +++++++
 SDK/Contracts/Data/ShiftContract.cs           | 26 ++++++-
 SDK/Exceptions/ExceptionContent.cs            |  8 --
 SDK/Helpers/Address.cs                        |  2 +
 SDK/SDK.csproj                                |  2 +-
 Test/Test/TestData/Paths.cs                   | 47 +++++++++++
 Test/Test/V3/Areas.cs                         |  2 +-
 Test/Test/V3/Devices.cs                       |  9 ++-
 Test/Test/V3/Layers.cs                        | 16 +---
 Test/Test/V3/Log.cs                           |  2 +-
 Test/Test/V3/Paths.cs                         | 44 +++++++++++
 Test/Test/V3/Quantities.cs                    |  2 +-
 Test/Test/V3/Shifts.cs                        |  2 +-
 38 files changed, 619 insertions(+), 221 deletions(-)
 create mode 100644 SDK/Connection/V3/Paths.cs
 delete mode 100644 SDK/Contracts/Communication/AddBeaconResponseContract.cs
 delete mode 100644 SDK/Contracts/Communication/AddSectorResponseContract.cs
 delete mode 100644 SDK/Contracts/Data/LoginContract.cs
 create mode 100644 SDK/Contracts/Data/PathContract.cs
 delete mode 100644 SDK/Exceptions/ExceptionContent.cs
 create mode 100644 Test/Test/TestData/Paths.cs
 create mode 100644 Test/Test/V3/Paths.cs

diff --git a/Main/Program.cs b/Main/Program.cs
index 0cb61f6..5a405e7 100644
--- a/Main/Program.cs
+++ b/Main/Program.cs
@@ -48,7 +48,7 @@ namespace Main
                 // Define sensors data list of SensorDataContract
                 var dataList = new[]
                 {
-                    new SensorDataContract
+                    new SensorDataWriteContract
                     {
                         Quantity = "Voltage",
                         Value = "120",
@@ -56,7 +56,7 @@ namespace Main
                         DataType = SensorDataType.Decimal,
                         Index = 0,
                     },
-                    new SensorDataContract
+                    new SensorDataWriteContract
                     {
                         Quantity = "Frequency",
                         Value = "1",
@@ -64,7 +64,7 @@ namespace Main
                         DataType = SensorDataType.Decimal,
                         Index = 0,
                     },
-                    new SensorDataContract
+                    new SensorDataWriteContract
                     {
                         Quantity = "OK parts",
                         Value = "600",
@@ -75,7 +75,7 @@ namespace Main
                 };
 
                 // Create sensor contract with specific data
-                SensorContract sensor = new SensorContract
+                SensorWriteContract sensor = new SensorWriteContract
                 {
                     Login = "buffer",
                     SensorData = dataList.ToArray(),
diff --git a/README.md b/README.md
index 7a52bf1..618141f 100644
--- a/README.md
+++ b/README.md
@@ -270,6 +270,9 @@ await devkitConnector.AddSensorData(sensorContracts);
 		* `Post(string subUrl, object body)`
 		* `Patch(string subUrl, object body)`
 		* `Delete(string subUrl)`
+* **Paths**
+	* `GetPaths()` - Get all paths
+	* `GetPath(id)` - Get path by ID
 
 ## Future features
 - **protobuffers** serialization
diff --git a/SDK/Connection/V3/Areas.cs b/SDK/Connection/V3/Areas.cs
index c764679..f046941 100644
--- a/SDK/Connection/V3/Areas.cs
+++ b/SDK/Connection/V3/Areas.cs
@@ -18,7 +18,7 @@ namespace SDK
             return await GetRequest<AreaContract>(subUrl);
         }
 
-        public async Task<AreaContract> AddArea(AreaContract area)
+        public async Task<AreaContract> AddArea(AreaWriteContract area)
         {
             string subUrl = Address.UrlCombine(Address.Areas);
             return await PostRequest<AreaContract>(subUrl, area);
diff --git a/SDK/Connection/V3/Beacons.cs b/SDK/Connection/V3/Beacons.cs
index 4f7400f..9821923 100644
--- a/SDK/Connection/V3/Beacons.cs
+++ b/SDK/Connection/V3/Beacons.cs
@@ -23,17 +23,12 @@ namespace SDK
 
             return response;
         }
-        public async Task<BeaconContract> AddBeacon(BeaconContract beaconContract)
+        public async Task<BeaconContract> AddBeacon(BeaconWriteContract beaconContract)
         {
             string subUrl = Address.UrlCombine(Address.Beacons);
-            var response = await PostRequest<AddBeaconResponseContract>(subUrl, beaconContract);
+            var response = await PostRequest<BeaconContract>(subUrl, beaconContract);
 
-            if (response.ErrorMessage != null)
-            {
-                throw new ServerResponseException(ServerResponseException.message + " " + response.ErrorMessage);
-            }
-
-            return (BeaconContract)response;
+            return response;
         }
 
         public async Task UpdateBeacon(int id, object changes)
diff --git a/SDK/Connection/V3/Devices.cs b/SDK/Connection/V3/Devices.cs
index 1036ddb..88abc3f 100644
--- a/SDK/Connection/V3/Devices.cs
+++ b/SDK/Connection/V3/Devices.cs
@@ -50,7 +50,7 @@ namespace SDK
             return response;
         }
 
-        public async Task<DeviceContract> AddDevice(DeviceContract deviceContract)
+        public async Task<DeviceContract> AddDevice(DeviceWriteContract deviceContract)
         {
             string subUrl = Address.UrlCombine(Address.Devices);
             return await PostRequest<DeviceContract>(subUrl, deviceContract);
diff --git a/SDK/Connection/V3/Layers.cs b/SDK/Connection/V3/Layers.cs
index 181c470..a384e7b 100644
--- a/SDK/Connection/V3/Layers.cs
+++ b/SDK/Connection/V3/Layers.cs
@@ -24,14 +24,6 @@ namespace SDK
             return response;
         }
 
-        public async Task<LayerContract[]> GetNoGoLayers(string deviceLogin, string queryString = "")
-        {
-            string subUrl = Address.UrlCombine(Address.LayersNoGo, deviceLogin, queryString);
-            var response = await GetRequest<LayerContract[]>(subUrl);
-
-            return response;
-        }
-
         public async Task<LayerContract[]> GetLocalizationLayers(string deviceLogin, string queryString = "")
         {
             string subUrl = Address.UrlCombine(Address.Layerslocalization, deviceLogin, queryString);
@@ -40,15 +32,7 @@ namespace SDK
             return response;
         }
 
-        public async Task<LayerContract[]> GetLocalizationLayers(LoginContract loginContract, string queryString = "")
-        {
-            string subUrl = Address.UrlCombine(Address.Layerslocalization, queryString);
-            var response = await PostRequest<LayerContract[]>(subUrl, loginContract);
-
-            return response;
-        }
-
-        public async Task<LayerContract> AddLayer(LayerContract layer)
+        public async Task<LayerContract> AddLayer(LayerWriteContract layer)
         {
             string subUrl = Address.UrlCombine(Address.Layers);
             var response = await PostRequest<LayerContract>(subUrl, layer);
diff --git a/SDK/Connection/V3/Log.cs b/SDK/Connection/V3/Log.cs
index faf38e0..c6db1c4 100644
--- a/SDK/Connection/V3/Log.cs
+++ b/SDK/Connection/V3/Log.cs
@@ -7,7 +7,7 @@ namespace SDK
 {
     public partial class DevkitConnectorV3
     {
-        public async Task<LogContract> AddLog(LogContract logContract)
+        public async Task<LogContract> AddLog(LogWriteContract logContract)
         {
             string subUrl = Address.UrlCombine(Address.LogAdd);
             return await PostRequest<LogContract>(subUrl, logContract);
diff --git a/SDK/Connection/V3/Paths.cs b/SDK/Connection/V3/Paths.cs
new file mode 100644
index 0000000..78abea7
--- /dev/null
+++ b/SDK/Connection/V3/Paths.cs
@@ -0,0 +1,21 @@
+using SDK.Models;
+using System;
+using System.Threading.Tasks;
+
+namespace SDK
+{
+    public partial class DevkitConnectorV3
+    {
+        public async Task<PathContract[]> GetPaths(string queryString = "")
+        {
+            string subUrl = Address.UrlCombine(Address.Paths, queryString);
+            return await GetRequest<PathContract[]>(subUrl);
+        }
+
+        public async Task<PathContract> GetPath(int id, string queryString = "")
+        {
+            string subUrl = Address.UrlCombine(Address.Paths, Convert.ToString(id), queryString);
+            return await GetRequest<PathContract>(subUrl);
+        }
+    }
+}
\ No newline at end of file
diff --git a/SDK/Connection/V3/Quantities.cs b/SDK/Connection/V3/Quantities.cs
index 6cdae78..bd19070 100644
--- a/SDK/Connection/V3/Quantities.cs
+++ b/SDK/Connection/V3/Quantities.cs
@@ -18,7 +18,7 @@ namespace SDK
             return await GetRequest<QuantityContract>(subUrl);
         }
 
-        public async Task<QuantityContract> AddQuantity(QuantityContract Quantity)
+        public async Task<QuantityContract> AddQuantity(QuantityWriteContract Quantity)
         {
             string subUrl = Address.UrlCombine(Address.Quantities);
             return await PostRequest<QuantityContract>(subUrl, Quantity);
@@ -27,7 +27,7 @@ namespace SDK
         public async Task UpdateQuantity(QuantityContract Quantity)
         {
             string subUrl = Address.UrlCombine(Address.Quantities, Convert.ToString(Quantity.Id));
-            await PatchRequest<QuantityContract>(subUrl, Quantity);
+            await PatchRequest(subUrl, Quantity);
         }
 
         public async Task DeleteQuantity(int id)
diff --git a/SDK/Connection/V3/Sectors.cs b/SDK/Connection/V3/Sectors.cs
index a1b5391..0f0cde8 100644
--- a/SDK/Connection/V3/Sectors.cs
+++ b/SDK/Connection/V3/Sectors.cs
@@ -25,17 +25,12 @@ namespace SDK
             return response;
         }
 
-        public async Task<SectorContract> AddSector(SectorContract sectorContract)
+        public async Task<SectorContract> AddSector(SectorWriteContract sectorContract)
         {
             string subUrl = Address.UrlCombine(Address.Sectors);
-            var response = await PostRequest<AddSectorResponseContract>(subUrl, sectorContract);
+            var response = await PostRequest<SectorContract>(subUrl, sectorContract);
 
-            if (response.ErrorMessage != null)
-            {
-                throw new ServerResponseException(ServerResponseException.message + " " + response.ErrorMessage);
-            }
-
-            return (SectorContract)response;
+            return response;
         }
 
         public async Task UpdateSector(int id, object changes)
diff --git a/SDK/Connection/V3/Sensors.cs b/SDK/Connection/V3/Sensors.cs
index e3903a4..28571f5 100644
--- a/SDK/Connection/V3/Sensors.cs
+++ b/SDK/Connection/V3/Sensors.cs
@@ -31,7 +31,7 @@ namespace SDK
 
             return response;
         }
-        public async Task<SensorContract> AddSensor(SensorContract sensorContract)
+        public async Task<SensorContract> AddSensor(SensorWriteContract sensorContract)
         {
             string subUrl = Address.UrlCombine(Address.Sensors);
             var response = await PostRequest<AddSensorResponseContract>(subUrl, sensorContract);
@@ -53,7 +53,7 @@ namespace SDK
             string subUrl = Address.UrlCombine(Address.Sensors, Convert.ToString(id));
             await DeleteRequest(subUrl);
         }
-        public async Task<PostResponseContract[]> AddSensorData(SensorContract[] sensors)
+        public async Task<PostResponseContract[]> AddSensorData(SensorWriteContract[] sensors)
         {
             string subUrl = Address.UrlCombine(Address.SensorsAddDataBatch);
             var response = await PostRequest<AddSensorDataResponseContract[]>(subUrl, sensors);
@@ -82,7 +82,7 @@ namespace SDK
 
             return response;
         }
-        public async Task<PostResponseContract> AddSensorData(SensorDataContract[] sensorData)
+        public async Task<PostResponseContract> AddSensorData(SensorDataWriteContract[] sensorData)
         {
             string subUrl = Address.UrlCombine(Address.SensorsAddData);
             var response = await PostRequest<SensorDataResponseContract[]>(subUrl, sensorData); //AddSensorDataResponseContract
diff --git a/SDK/Connection/V3/Shifts.cs b/SDK/Connection/V3/Shifts.cs
index 1a6ec6f..60f7fc2 100644
--- a/SDK/Connection/V3/Shifts.cs
+++ b/SDK/Connection/V3/Shifts.cs
@@ -26,7 +26,7 @@ namespace SDK
             return response;
         }
 
-        public async Task<ShiftContract> AddShift(ShiftContract shiftContract)
+        public async Task<ShiftContract> AddShift(ShiftWriteContract shiftContract)
         {
             string subUrl = Address.UrlCombine(Address.Shifts);
             var response = await PostRequest<AddShiftResponseContract>(subUrl, shiftContract);
diff --git a/SDK/Contracts/Communication/AddBeaconResponseContract.cs b/SDK/Contracts/Communication/AddBeaconResponseContract.cs
deleted file mode 100644
index 3265af3..0000000
--- a/SDK/Contracts/Communication/AddBeaconResponseContract.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-using SDK.Communication;
-using SDK.Models;
-
-namespace SDK.Contracts.Communication
-{
-    public class AddBeaconResponseContract : PostResponseContract
-    {
-        public int Id { get; set; }
-
-        public int? SectorId { get; set; }
-
-        public int BranchId { get; set; }
-
-        public string Mac { get; set; }
-
-        public double? X { get; set; }
-
-        public double? Y { get; set; }
-
-        public double? Z { get; set; }
-
-        public string Title { get; set; }
-
-        public bool Active { get; set; }
-
-        public bool Position { get; set; }
-
-        public int? TypeId { get; set; }
-
-        public bool Geofence { get; set; }
-
-        public double? GeofenceRange { get; set; }
-
-        public string Cluster { get; set; }
-
-        public long? LastTimeOnline { get; set; }
-
-        public bool UseGps { get; set; }
-
-        public string CFUUID { get; set; }
-
-        public long Created { get; set; }
-
-        public long Update { get; set; }
-
-        public static explicit operator BeaconContract(AddBeaconResponseContract addBeaconResponseContract)
-        {
-            return new BeaconContract
-            {
-                Id = addBeaconResponseContract.Id,
-                SectorId = addBeaconResponseContract.SectorId,
-                BranchId = addBeaconResponseContract.BranchId,
-                Mac = addBeaconResponseContract.Mac,
-                X = addBeaconResponseContract.X,
-                Y = addBeaconResponseContract.Y,
-                Z = addBeaconResponseContract.Z,
-                Title = addBeaconResponseContract.Title,
-                Active = addBeaconResponseContract.Active,
-                Position = addBeaconResponseContract.Position,
-                TypeId = addBeaconResponseContract.TypeId,
-                Geofence = addBeaconResponseContract.Geofence,
-                GeofenceRange = addBeaconResponseContract.GeofenceRange,
-                Cluster = addBeaconResponseContract.Cluster,
-                LastTimeOnline = addBeaconResponseContract.LastTimeOnline,
-                UseGps = addBeaconResponseContract.UseGps,
-                CFUUID = addBeaconResponseContract.CFUUID,
-                Created = addBeaconResponseContract.Created,
-                Update = addBeaconResponseContract.Update,
-            };
-        }
-    }
-}
diff --git a/SDK/Contracts/Communication/AddLogContract.cs b/SDK/Contracts/Communication/AddLogContract.cs
index 8d05470..cc25898 100644
--- a/SDK/Contracts/Communication/AddLogContract.cs
+++ b/SDK/Contracts/Communication/AddLogContract.cs
@@ -1,6 +1,7 @@
 using SDK.Models;
 using System;
 using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
 using System.Linq;
 using System.Runtime.Serialization;
 using System.Text;
@@ -32,4 +33,34 @@ namespace SDK.Contracts.Communication
         [DataMember(Order = 8)]
         public string Login { get; set; }
     }
+
+    public class LogWriteContract
+    {
+        /// <summary>
+        /// If not provided, make sure to provide <b>Login</b> property, which is the <i>Login</i> of the <i>Account</i>
+        /// you want to associate this <i>Log</i> with. The system will find its AccountId.
+        /// </summary>
+        [DataMember(Order = 1)]
+        public int? AccountId { get; set; }
+
+        [DataMember(Order = 2)]
+        [StringLength(5000)]
+        public string Message { get; set; }
+
+        [DataMember(Order = 3)]
+        [StringLength(20)]
+        public string Level { get; set; }
+
+        /// <summary>
+        /// Provide a unix miliseconds UTC value. If not provided, current time will be used.
+        /// </summary>
+        [DataMember(Order = 4)]
+        public long? Timestamp { get; set; }
+
+        /// <summary>
+        /// If <b>AccountId</b> is not provided, this property is used to find the <i>Account</i> to associate this <i>Log</i> with.
+        /// </summary>
+        [DataMember(Order = 5)]
+        public string Login { get; set; }
+    }
 }
diff --git a/SDK/Contracts/Communication/AddSectorResponseContract.cs b/SDK/Contracts/Communication/AddSectorResponseContract.cs
deleted file mode 100644
index 09d9471..0000000
--- a/SDK/Contracts/Communication/AddSectorResponseContract.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using SDK.Communication;
-using SDK.Models;
-using System;
-
-namespace SDK.Contracts.Communication
-{
-    class AddSectorResponseContract : PostResponseContract
-    {
-        public int Id { get; set; }
-
-        public Guid Guid { get; set; }
-
-        public int BranchId { get; set; }
-
-        public string Title { get; set; }
-
-        public float BarrierWidth { get; set; }
-
-        public float BarrierHeight { get; set; }
-
-        public float SectorWidth { get; set; }
-
-        public float SectorHeight { get; set; }
-
-        public long Modified { get; set; }
-
-        public string Configuration { get; set; }
-
-        public GpsItemContract[] GpsItems { get; set; }
-
-        public AreaContract[] Areas { get; set; }
-
-        public BarrierContract[] Barriers { get; set; }
-
-        public BeaconContract[] Beacons { get; set; }
-
-        public SensorContract[] Sensors { get; set; }
-
-        public static explicit operator SectorContract(AddSectorResponseContract addSectorResponseContract)
-        {
-            return new SectorContract
-            {
-                Id = addSectorResponseContract.Id,
-                Guid = addSectorResponseContract.Guid,
-                BranchId = addSectorResponseContract.BranchId,
-                Title = addSectorResponseContract.Title,
-                BarrierHeight = addSectorResponseContract.BarrierHeight,
-                BarrierWidth = addSectorResponseContract.BarrierWidth,
-                SectorWidth = addSectorResponseContract.SectorWidth,
-                SectorHeight = addSectorResponseContract.SectorHeight,
-                Modified = addSectorResponseContract.Modified,
-                Configuration = addSectorResponseContract.Configuration,
-                GpsItems = addSectorResponseContract.GpsItems,
-                Areas = addSectorResponseContract.Areas,
-                Barriers = addSectorResponseContract.Barriers,
-                Beacons = addSectorResponseContract.Beacons,
-                Sensors = addSectorResponseContract.Sensors
-            };
-        }
-    }
-}
diff --git a/SDK/Contracts/Data/AccountContract.cs b/SDK/Contracts/Data/AccountContract.cs
index ef12094..b0cadea 100644
--- a/SDK/Contracts/Data/AccountContract.cs
+++ b/SDK/Contracts/Data/AccountContract.cs
@@ -1,7 +1,11 @@
-namespace SDK.Contracts.Data
+using System.ComponentModel.DataAnnotations;
+
+namespace SDK.Contracts.Data
 {
     public class AccountContract
     {
+        [Required]
+        [StringLength(255)]
         public string Login { get; set; }
 
         //public string Password { get; set; }
diff --git a/SDK/Contracts/Data/AreaContract.cs b/SDK/Contracts/Data/AreaContract.cs
index d52338e..1e2db0e 100644
--- a/SDK/Contracts/Data/AreaContract.cs
+++ b/SDK/Contracts/Data/AreaContract.cs
@@ -1,4 +1,5 @@
 using System;
+using System.ComponentModel.DataAnnotations;
 
 namespace SDK.Models
 {
@@ -26,6 +27,23 @@ namespace SDK.Models
 
         public long Updated { get; set; }
         public string ExternalId { get; set; }
+
+        public static explicit operator AreaWriteContract(AreaContract contract)
+        {
+            return new AreaWriteContract
+            {
+                Title = contract.Title,
+                Created = contract.Created,
+                Updated = contract.Updated,
+                ExternalId = contract.ExternalId,
+                Description = contract.Description,
+                Coordinates = contract.Coordinates,
+                Color = contract.Color,
+                LayerId = contract.LayerId,
+                SectorId = contract.SectorId,
+                Guid = contract.Guid,
+            };
+        }
     }
 
     public class PointContract
@@ -34,4 +52,32 @@ namespace SDK.Models
 
         public double Y { get; set; }
     }
+
+    public class AreaWriteContract
+    {
+        public Guid Guid { get; set; }
+
+        [Required]
+        public string Title { get; set; }
+
+        public int SectorId { get; set; }
+
+        public int? LayerId { get; set; }
+
+        [StringLength(25)]
+        public string Color { get; set; }
+
+        public PointContract[] Coordinates { get; set; }
+
+        public string Description { get; set; }
+
+        public long Created { get; set; }
+
+        public long Updated { get; set; }
+
+        public int? TargetBranchId { get; set; }
+
+        [StringLength(25)]
+        public string ExternalId { get; set; }
+    }
 }
diff --git a/SDK/Contracts/Data/BeaconContract.cs b/SDK/Contracts/Data/BeaconContract.cs
index fa166e6..f6ceb1e 100644
--- a/SDK/Contracts/Data/BeaconContract.cs
+++ b/SDK/Contracts/Data/BeaconContract.cs
@@ -1,4 +1,7 @@
-namespace SDK.Models
+using System.ComponentModel.DataAnnotations;
+using System.Runtime.Serialization;
+
+namespace SDK.Models
 {
     public class BeaconContract
     {
@@ -40,4 +43,40 @@
 
         public long Update { get; set; }
     }
+
+    public class BeaconWriteContract
+    {
+        public int? SectorId { get; set; }
+
+        [Required]
+        [StringLength(17)]
+        public string Mac { get; set; }
+
+        public float? X { get; set; }
+
+        public float? Y { get; set; }
+
+        public float? Z { get; set; }
+
+        [Required]
+        [StringLength(50)]
+        public string Title { get; set; }
+
+        public bool Active { get; set; }
+
+        public int? TypeId { get; set; }
+
+        public bool Position { get; set; }
+
+        public bool Geofence { get; set; }
+
+        public float? GeofenceRange { get; set; }
+
+        [StringLength(10)]
+        public string Cluster { get; set; }
+
+        public long? LastTimeOnline { get; set; }
+
+        public bool UseGps { get; set; }
+    }
 }
diff --git a/SDK/Contracts/Data/DeviceContract.cs b/SDK/Contracts/Data/DeviceContract.cs
index 1dd9d4d..1072085 100644
--- a/SDK/Contracts/Data/DeviceContract.cs
+++ b/SDK/Contracts/Data/DeviceContract.cs
@@ -1,5 +1,8 @@
 using Core.Enum;
 using SDK.Contracts.Data;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Runtime.Serialization;
 
 namespace SDK.Models
 {
@@ -48,5 +51,80 @@ namespace SDK.Models
         public bool Geofence { get; set; }
 
         public float? GeofenceRange { get; set; }
+
+        public static explicit operator DeviceWriteContract(DeviceContract contract)
+        {
+            return new DeviceWriteContract
+            {
+                Title = contract.Title,
+                Note = contract.Note,
+                Mac = contract.Mac,
+                SectorId = contract.SectorId,
+                LastTimeOnline = contract.LastTimeOnline,
+                X = (float)contract.X,
+                Y = (float)contract.Y,
+                AppVersion = contract.AppVersion,
+                IsMoving = contract.IsMoving,
+                FallStatus = contract.FallStatus,
+                Battery = contract.Battery,
+                DeviceTypeId = contract.DeviceTypeId,
+                Position = contract.Position,
+                Geofence = contract.Geofence,
+                GeofenceRange = contract.GeofenceRange,
+                Login = contract.Login,
+            };
+        }
+    }
+
+    public class DeviceWriteContract : AccountContract
+    {
+        [StringLength(17)]
+        public string Mac { get; set; }
+
+        public int? SectorId { get; set; }
+
+        [Required]
+        [StringLength(50)]
+        public string Title { get; set; }
+
+        public string Note { get; set; }
+
+        public long? LastTimeOnline { get; set; }
+
+        public float? X { get; set; }
+
+        public float? Y { get; set; }
+
+        public float? Z { get; set; }
+
+        [StringLength(17)]
+        public string AppVersion { get; set; }
+
+        public bool IsMoving { get; set; }
+
+        public FallType FallStatus { get; set; }
+
+        public float? Battery { get; set; }
+
+        public int? DeviceTypeId { get; set; }
+
+        public bool Position { get; set; }
+
+        public bool Geofence { get; set; }
+
+        public float? GeofenceRange { get; set; }
+
+        public string Password { get; set; }
+        /// <summary>
+        /// An array of <b>Layer Ids</b> that are NoGo Layers for this <b>Device</b>.
+        /// </summary>
+        public HashSet<int> Layers { get; set; }
+
+        [StringLength(17)]
+        public string DeviceStatus { get; set; }
+
+        public long? Heartbeat { get; set; }
+
+        public string Color { get; set; }
     }
 }
diff --git a/SDK/Contracts/Data/LayerContract.cs b/SDK/Contracts/Data/LayerContract.cs
index 4716d3e..f77364f 100644
--- a/SDK/Contracts/Data/LayerContract.cs
+++ b/SDK/Contracts/Data/LayerContract.cs
@@ -1,4 +1,8 @@
 using SDK.Models;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Runtime.Serialization;
 
 namespace SDK.Contracts.Data
 {
@@ -26,5 +30,60 @@ namespace SDK.Contracts.Data
 
         public bool IsNoGo { get; set; }
         public string ExternalId { get; set; }
+
+        public static explicit operator LayerWriteContract(LayerContract contract)
+        {
+            return new LayerWriteContract
+            {
+                Title = contract.Title,
+                Created = contract.Created,
+                Icon = contract.Icon,
+                Visible = contract.Visible,
+                Localization = contract.Localization,
+                Updated = contract.Updated,
+                ExternalId = contract.ExternalId,
+                Areas = contract.Areas.Select(area => area.Id).ToHashSet(),
+                Paths = contract.Devices.Select(device => device.Id).ToHashSet(),
+            };
+        }
+    }
+
+    public class LayerWriteContract
+    {
+        [Required]
+        [StringLength(255)]
+        public string Title { get; set; }
+
+        public string Icon { get; set; }
+
+        public bool Visible { get; set; }
+
+        public bool Localization { get; set; }
+
+        public long Created { get; set; }
+
+        public long Updated { get; set; }
+        /// <summary>
+        /// An array of <b>Area Ids</b> to associate with this <b>Layer</b>.
+        /// </summary>
+        public HashSet<int> Areas { get; set; }
+
+        /// <summary>
+        /// An array of <b>Device Ids</b> to associate with this <b>Layer</b>.
+        /// </summary>
+        public HashSet<int> Devices { get; set; }
+
+        /// <summary>
+        /// An array of <b>Path Ids</b> to associate with this <b>Layer</b>.
+        /// </summary>
+        public HashSet<int> Paths { get; set; }
+
+        /// <summary>
+        /// An array of <b>Layer Ids</b> that are children of this <b>Layer</b>.
+        /// </summary>
+        public HashSet<int> Children { get; set; }
+
+        [StringLength(255)]
+        public string ExternalId { get; set; }
     }
 }
diff --git a/SDK/Contracts/Data/LoginContract.cs b/SDK/Contracts/Data/LoginContract.cs
deleted file mode 100644
index 3fa8f4b..0000000
--- a/SDK/Contracts/Data/LoginContract.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace SDK.Contracts.Data
-{
-    public class LoginContract
-    {
-        public string Login { get; set; }
-    }
-}
diff --git a/SDK/Contracts/Data/PathContract.cs b/SDK/Contracts/Data/PathContract.cs
new file mode 100644
index 0000000..b74bc6b
--- /dev/null
+++ b/SDK/Contracts/Data/PathContract.cs
@@ -0,0 +1,47 @@
+using System;
+
+namespace SDK.Models
+{
+    public class PathContract
+    {
+        public int Id { get; set; }
+
+        public Guid Guid { get; set; }
+
+        public string Title { get; set; }
+
+        public int SectorId { get; set; }
+
+
+        public int BranchId { get; set; }
+
+
+        public int? LayerId { get; set; }
+
+
+        public string Color { get; set; }
+
+        public PathPointContract[] PathPoints { get; set; }
+
+        public string Description { get; set; }
+
+        public long Created { get; set; }
+
+        public long Updated { get; set; }
+    }
+
+    public class PathPointContract
+    {
+        public int Id { get; set; }
+
+        public int PathId { get; set; }
+
+        public int BranchId { get; set; }
+
+        public int Index { get; set; }
+
+        public float X { get; set; }
+
+        public float Y { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/SDK/Contracts/Data/QuantityContract.cs b/SDK/Contracts/Data/QuantityContract.cs
index 5433bd2..bf7086e 100644
--- a/SDK/Contracts/Data/QuantityContract.cs
+++ b/SDK/Contracts/Data/QuantityContract.cs
@@ -18,6 +18,15 @@ namespace SDK.Models
 
         [DataMember(Order = 4)]
         public RangeContract Range { get; set; }
+
+        public static explicit operator QuantityWriteContract(QuantityContract contract)
+        {
+            return new QuantityWriteContract
+            {
+                Title = contract.Title,
+                Range = contract.Range,
+            };
+        }
     }
 
     [DataContract]
@@ -44,4 +53,15 @@ namespace SDK.Models
         [DataMember(Order = 2)]
         public string value { get; set; }
     }
+
+    public class QuantityWriteContract
+    {
+        [DataMember(Order = 1)]
+        [Required]
+        [StringLength(255)]
+        public string Title { get; set; }
+
+        [DataMember(Order = 2)]
+        public RangeContract Range { get; set; }
+    }
 }
diff --git a/SDK/Contracts/Data/SectorContract.cs b/SDK/Contracts/Data/SectorContract.cs
index 50b77a4..d944755 100644
--- a/SDK/Contracts/Data/SectorContract.cs
+++ b/SDK/Contracts/Data/SectorContract.cs
@@ -1,4 +1,7 @@
 using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Runtime.Serialization;
 
 namespace SDK.Models
 {
@@ -33,6 +36,8 @@ namespace SDK.Models
         public BeaconContract[] Beacons { get; set; }
 
         public SensorContract[] Sensors { get; set; }
+
+        public int? Floor { get; set; }
     }
 
     public class BarrierContract
@@ -60,4 +65,56 @@ namespace SDK.Models
 
         public double Longitude { get; set; }
     }
+
+    public class SectorWriteContract
+    {
+        public Guid Guid { get; set; }
+
+        [Required]
+        [StringLength(50)]
+        public string Title { get; set; }
+
+        public float BarrierHeight { get; set; }
+
+        public float BarrierWidth { get; set; }
+
+        public float SectorWidth { get; set; }
+
+        public float SectorHeight { get; set; }
+
+        public long Modified { get; set; }
+
+        /// <summary>
+        /// An Array of <b>GpsItem Ids</b> that are in this sector.
+        /// </summary>
+        public HashSet<int> GpsItems { get; set; }
+
+        /// <summary>
+        /// An Array of <b>Area Ids</b> that are in this sector.
+        /// </summary>
+        public HashSet<int> Areas { get; set; }
+
+        /// <summary>
+        /// An Array of <b>Barrier Ids</b> that are in this sector.
+        /// </summary>
+        public HashSet<int> Barriers { get; set; }
+
+        /// <summary>
+        /// An Array of <b>Beacon Ids</b> that are in this sector.
+        /// </summary>
+        public HashSet<int> Beacons { get; set; }
+
+        /// <summary>
+        /// An Array of <b>Sensor Ids</b> that are in this sector.
+        /// </summary>
+        public HashSet<int> Sensors { get; set; }
+
+        public string Configuration { get; set; }
+        /// <summary>
+        /// An Array of <b>Path Ids</b> that are in this sector.
+        /// </summary>
+        public HashSet<int> Paths { get; set; }
+
+        public int? Floor { get; set; }
+    }
 }
diff --git a/SDK/Contracts/Data/SensorContract.cs b/SDK/Contracts/Data/SensorContract.cs
index 277a0a8..f600141 100644
--- a/SDK/Contracts/Data/SensorContract.cs
+++ b/SDK/Contracts/Data/SensorContract.cs
@@ -1,4 +1,6 @@
 using SDK.Contracts.Data;
+using System.ComponentModel.DataAnnotations;
+using System.Runtime.Serialization;
 
 namespace SDK.Models
 {
@@ -25,4 +27,36 @@ namespace SDK.Models
         public int? AreaId { get; set; }
         public string ExternalId { get; set; }
     }
+
+    public class SensorWriteContract : AccountContract
+    {
+        [Required]
+        [StringLength(50)]
+        public string Title { get; set; }
+
+        [StringLength(17)]
+        public string Mac { get; set; }
+
+        public string Note { get; set; }
+
+        public float? X { get; set; }
+
+        public float? Y { get; set; }
+
+        public float? Battery { get; set; }
+
+        public int? SectorId { get; set; }
+
+        public SensorDataWriteContract[] SensorData { get; set; }
+
+        public int? AreaId { get; set; }
+
+        public string Password { get; set; }
+
+        [StringLength(25)]
+        public string Color { get; set; }
+
+        [StringLength(50)]
+        public string ExternalId { get; set; }
+    }
 }
diff --git a/SDK/Contracts/Data/SensorDataContract.cs b/SDK/Contracts/Data/SensorDataContract.cs
index 328ecbe..640c43e 100644
--- a/SDK/Contracts/Data/SensorDataContract.cs
+++ b/SDK/Contracts/Data/SensorDataContract.cs
@@ -1,4 +1,6 @@
 using SDK.Enum;
+using System.ComponentModel.DataAnnotations;
+using System.Runtime.Serialization;
 
 namespace SDK.Models
 {
@@ -24,4 +26,31 @@ namespace SDK.Models
 
         public RangeContract Range { get; set; }
     }
+
+    public class SensorDataWriteContract
+    {
+        [Required]
+        [StringLength(255)]
+        public string Quantity { get; set; }
+
+        [Required]
+        [StringLength(1000)]
+        public string Value { get; set; }
+
+        [StringLength(15)]
+        public string Unit { get; set; }
+
+        [Required]
+        public SensorDataType DataType { get; set; }
+
+        public long Timestamp { get; set; }
+
+        public RangeContract Range { get; set; }
+
+        public int Index { get; set; }
+
+        public bool VisibleInApp { get; set; }
+
+        public int SensorId { get; set; }
+    }
 }
diff --git a/SDK/Contracts/Data/ShiftContract.cs b/SDK/Contracts/Data/ShiftContract.cs
index fe4cc98..2f70892 100644
--- a/SDK/Contracts/Data/ShiftContract.cs
+++ b/SDK/Contracts/Data/ShiftContract.cs
@@ -1,4 +1,7 @@
-namespace SDK.Contracts.Data
+using System.ComponentModel.DataAnnotations;
+using System.Runtime.Serialization;
+
+namespace SDK.Contracts.Data
 {
     public class ShiftContract
     {
@@ -11,5 +14,26 @@
         public long StartTime { get; set; }
 
         public long StopTime { get; set; }
+
+        public static explicit operator ShiftWriteContract(ShiftContract contract)
+        {
+            return new ShiftWriteContract
+            {
+                Title = contract.Title,
+                StartTime = contract.StartTime,
+                StopTime = contract.StopTime,
+            };
+        }
+    }
+
+    public class ShiftWriteContract
+    {
+        [Required]
+        [StringLength(255)]
+        public string Title { get; set; }
+
+        public long StartTime { get; set; }
+
+        public long StopTime { get; set; }
     }
 }
diff --git a/SDK/Exceptions/ExceptionContent.cs b/SDK/Exceptions/ExceptionContent.cs
deleted file mode 100644
index 27be96e..0000000
--- a/SDK/Exceptions/ExceptionContent.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace SDK.Exceptions
-{
-    public class ExceptionContent
-    {
-        public string Code { get; set; }
-        public string Message { get; set; }
-    }
-}
diff --git a/SDK/Helpers/Address.cs b/SDK/Helpers/Address.cs
index 16c08ad..2e85813 100644
--- a/SDK/Helpers/Address.cs
+++ b/SDK/Helpers/Address.cs
@@ -50,6 +50,8 @@ namespace SDK.Models
 
         public const string LogAdd = "logs";
 
+        public const string Paths = "paths/";
+
         public const string Sectors = "sectors/";
 
         public const string Sensors = "sensors/";
diff --git a/SDK/SDK.csproj b/SDK/SDK.csproj
index b7429ea..59235ec 100644
--- a/SDK/SDK.csproj
+++ b/SDK/SDK.csproj
@@ -13,7 +13,7 @@
     <TargetFrameworks Condition="'$(TargetFrameworkOverride)' != ''">$(TargetFrameworkOverride)</TargetFrameworks>
     <AssemblyVersion>2021.6.28.25</AssemblyVersion>
     <FileVersion>2021.6.28.25</FileVersion>
-    <Version>5.7.0</Version>
+    <Version>5.8.0</Version>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
   </PropertyGroup>
 
diff --git a/Test/Test/TestData/Paths.cs b/Test/Test/TestData/Paths.cs
new file mode 100644
index 0000000..6da71df
--- /dev/null
+++ b/Test/Test/TestData/Paths.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using SDK.Models;
+
+namespace Test.TestData
+{
+    public static class Paths
+    {
+        public static readonly Guid TestPathId1 = new Guid("11111111-1111-1111-1111-111111111111");
+        public static readonly Guid TestPathId2 = new Guid("22222222-2222-2222-2222-222222222222");
+
+        public static PathContract GetTestPath(Guid guid) => new PathContract
+        {
+            Id = 1,
+            Title = $"Test Path 1",
+            Description = "A test path for unit testing",
+            BranchId = 1,
+            SectorId = 1,
+            LayerId = 1,
+            Guid = guid,
+            PathPoints = new [] 
+            { 
+                new PathPointContract
+                {
+                    Id = 1,
+                    X = 0,
+                    Y = 0,
+                }, 
+                new PathPointContract
+                {
+                    Id = 2,
+                    X = 10,
+                    Y = 10,
+                } 
+            }
+        };
+
+        public static IEnumerable<PathContract> GetTestPaths()
+        {
+            return new List<PathContract>
+            {
+                GetTestPath(TestPathId1),
+                GetTestPath(TestPathId2)
+            };
+        }
+    }
+}
diff --git a/Test/Test/V3/Areas.cs b/Test/Test/V3/Areas.cs
index 076800e..7edb16d 100644
--- a/Test/Test/V3/Areas.cs
+++ b/Test/Test/V3/Areas.cs
@@ -47,7 +47,7 @@ namespace Test.V3
             server.Given(Request.Create().WithPath(PATH_BASE + AREAS).UsingPost())
                     .RespondWith(Response.Create().WithStatusCode(200).WithBodyAsJson(bodyContent));
 
-            AreaContract response = await devkitConnector.AddArea(bodyContent);
+            AreaContract response = await devkitConnector.AddArea((AreaWriteContract)bodyContent);
             Assert.IsInstanceOfType(response, typeof(AreaContract));
         }
 
diff --git a/Test/Test/V3/Devices.cs b/Test/Test/V3/Devices.cs
index 472750a..0046c4b 100644
--- a/Test/Test/V3/Devices.cs
+++ b/Test/Test/V3/Devices.cs
@@ -1,4 +1,5 @@
 using Core.Enum;
+using Microsoft.AspNetCore.Mvc;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using SDK.Contracts.Communication;
 using SDK.Contracts.Data;
@@ -20,10 +21,10 @@ namespace Test.V3
         [TestMethod]
         public async Task GetDevices_ErrorHandling_ShouldThrowsException()
         {
-            var bodyContent = new ExceptionContent
+            var bodyContent = new ProblemDetails
             {
-                Code = "10",
-                Message = "Error"
+                Title = "Specify the Error from Type property more.",
+                Detail = "How to solve error."
             };
 
             server.Reset();
@@ -87,7 +88,7 @@ namespace Test.V3
             server.Given(Request.Create().WithPath(PATH_BASE + DEVICES).UsingPost())
                     .RespondWith(Response.Create().WithStatusCode(200).WithBodyAsJson(bodyContent));
 
-            DeviceContract response = await devkitConnector.AddDevice(bodyContent);
+            DeviceContract response = await devkitConnector.AddDevice((DeviceWriteContract)bodyContent);
 
             Assert.IsInstanceOfType(response, typeof(DeviceContract));
         }
diff --git a/Test/Test/V3/Layers.cs b/Test/Test/V3/Layers.cs
index 7e536cc..12c1d3f 100644
--- a/Test/Test/V3/Layers.cs
+++ b/Test/Test/V3/Layers.cs
@@ -25,20 +25,6 @@ namespace Test.V3
             Assert.IsInstanceOfType(response, typeof(LayerContract[]));
         }
 
-        [TestCategory("Layer")]
-        [TestMethod]
-        public async Task GetNoGoLayersForDevice_ShouldReturnLayers()
-        {
-            var deviceLogin = "device1";
-
-            server.Given(Request.Create().WithPath(PATH_BASE + LAYERS + $"/device/{deviceLogin}").UsingGet())
-                .RespondWith(Response.Create().WithStatusCode(200)
-                .WithBodyAsJson(TestData.Layers.GetLayers()));
-
-            var response = await devkitConnector.GetNoGoLayers(deviceLogin);
-            Assert.IsInstanceOfType(response, typeof(LayerContract[]));
-        }
-
         [TestCategory("Layer")]
         [TestMethod]
         public async Task GetLayers_ShouldReturnLayers()
@@ -72,7 +58,7 @@ namespace Test.V3
                 .RespondWith(Response.Create().WithStatusCode(200)
                 .WithBodyAsJson(layer));
 
-            var response = await devkitConnector.AddLayer(layer);
+            var response = await devkitConnector.AddLayer((LayerWriteContract) layer);
             Assert.IsInstanceOfType(response, typeof(LayerContract));
         }
 
diff --git a/Test/Test/V3/Log.cs b/Test/Test/V3/Log.cs
index b934e4b..075a298 100644
--- a/Test/Test/V3/Log.cs
+++ b/Test/Test/V3/Log.cs
@@ -15,7 +15,7 @@ namespace Test.V3
         [TestMethod]
         public async Task PostLog_ShouldReturnLogContract()
         {
-            var bodyContent = new LogContract()
+            var bodyContent = new LogWriteContract()
             {
                 Login = "login",
                 AccountId = 1,
diff --git a/Test/Test/V3/Paths.cs b/Test/Test/V3/Paths.cs
new file mode 100644
index 0000000..a0bd496
--- /dev/null
+++ b/Test/Test/V3/Paths.cs
@@ -0,0 +1,44 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using SDK.Models;
+using System;
+using System.Threading.Tasks;
+using WireMock.RequestBuilders;
+using WireMock.ResponseBuilders;
+
+namespace Test.V3
+{
+    [TestClass]
+    public class Paths : Requests
+    {
+        const string PATHS = "paths";
+
+        [TestCategory("Path")]
+        [TestMethod]
+        public async Task GetPaths_ShouldReturnPaths()
+        {
+            var bodyContent = TestData.Paths.GetTestPaths();
+
+            server.Given(Request.Create().WithPath(PATH_BASE + PATHS).UsingGet())
+                    .RespondWith(Response.Create().WithStatusCode(200).WithBodyAsJson(bodyContent));
+
+            var response = await devkitConnector.GetPaths();
+
+            Assert.IsInstanceOfType(response, typeof(PathContract[]));
+        }
+
+        [TestCategory("Path")]
+        [TestMethod]
+        public async Task GetPath_ShouldReturnPath()
+        {
+            const int pathId = 1;
+            var bodyContent = TestData.Paths.GetTestPath(TestData.Paths.TestPathId1);
+
+            server.Given(Request.Create().WithPath(PATH_BASE + PATHS + "/" + pathId).UsingGet())
+                .RespondWith(Response.Create().WithStatusCode(200)
+                .WithBodyAsJson(bodyContent));
+
+            var response = await devkitConnector.GetPath(pathId);
+            Assert.IsInstanceOfType(response, typeof(PathContract));
+        }
+    }
+}
diff --git a/Test/Test/V3/Quantities.cs b/Test/Test/V3/Quantities.cs
index 9eadc3c..bfbbd2b 100644
--- a/Test/Test/V3/Quantities.cs
+++ b/Test/Test/V3/Quantities.cs
@@ -48,7 +48,7 @@ namespace Test.V3
             server.Given(Request.Create().WithPath(PATH_BASE + QUANTITIES).UsingPost())
                 .RespondWith(Response.Create().WithStatusCode(200).WithBodyAsJson(bodyContent));
 
-            QuantityContract response = await devkitConnector.AddQuantity(bodyContent);
+            QuantityContract response = await devkitConnector.AddQuantity((QuantityWriteContract)bodyContent);
             Assert.IsInstanceOfType(response, typeof(QuantityContract));
         }
 
diff --git a/Test/Test/V3/Shifts.cs b/Test/Test/V3/Shifts.cs
index 824ac50..51e8f5d 100644
--- a/Test/Test/V3/Shifts.cs
+++ b/Test/Test/V3/Shifts.cs
@@ -48,7 +48,7 @@ namespace Test.V3
             server.Given(Request.Create().WithPath(PATH_BASE + SHIFTS).UsingPost())
                 .RespondWith(Response.Create().WithStatusCode(200).WithBodyAsJson(bodyContent));
 
-            ShiftContract response = await devkitConnector.AddShift(bodyContent);
+            ShiftContract response = await devkitConnector.AddShift((ShiftWriteContract)bodyContent);
             Assert.IsInstanceOfType(response, typeof(ShiftContract));
         }
 
-- 
GitLab