V0.6.0 Apalone
This commit is contained in:
parent
84c1058e83
commit
5d5cc7ef0a
@ -10,8 +10,8 @@
|
|||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"sswg.swift-lang",
|
"sswg.swift-lang",
|
||||||
//"fabiospampinato.vscode-highlight",
|
"fabiospampinato.vscode-highlight",
|
||||||
//"fabiospampinato.vscode-todo-plus"
|
"fabiospampinato.vscode-todo-plus"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "Sources/DataAcquisition"]
|
||||||
|
path = Sources/DataAcquisition
|
||||||
|
url = https://repositories.communitynotfound.work/PoliBa-Software-Architecture/embeddedLibrary.git
|
||||||
@ -15,6 +15,10 @@ let package = Package(
|
|||||||
name: "RandomCpp",
|
name: "RandomCpp",
|
||||||
targets: ["RandomCpp"]
|
targets: ["RandomCpp"]
|
||||||
),
|
),
|
||||||
|
.library(
|
||||||
|
name: "DataAcquisition",
|
||||||
|
targets: ["DataAcquisition"]
|
||||||
|
),
|
||||||
|
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
@ -27,21 +31,29 @@ let package = Package(
|
|||||||
name: "RandomCpp"
|
name: "RandomCpp"
|
||||||
),
|
),
|
||||||
|
|
||||||
|
.target(
|
||||||
|
name: "DataAcquisition"
|
||||||
|
),
|
||||||
|
|
||||||
.target(
|
.target(
|
||||||
name: "IoT-Simulator-Core",
|
name: "IoT-Simulator-Core",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"RandomCpp",
|
"RandomCpp",
|
||||||
|
"DataAcquisition",
|
||||||
.product(name: "Crypto", package: "swift-crypto"),
|
.product(name: "Crypto", package: "swift-crypto"),
|
||||||
|
|
||||||
],
|
],
|
||||||
swiftSettings: [
|
swiftSettings: [
|
||||||
.interoperabilityMode(.Cxx)
|
.interoperabilityMode(.Cxx),
|
||||||
|
.interoperabilityMode(.C)
|
||||||
]),
|
]),
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "IoT-Simulator-CoreTests",
|
name: "IoT-Simulator-CoreTests",
|
||||||
dependencies: ["IoT-Simulator-Core"],
|
dependencies: ["IoT-Simulator-Core"],
|
||||||
swiftSettings: [
|
swiftSettings: [
|
||||||
.interoperabilityMode(.Cxx)
|
.interoperabilityMode(.C),
|
||||||
|
.interoperabilityMode(.Cxx),
|
||||||
|
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
1
Sources/DataAcquisition
Submodule
1
Sources/DataAcquisition
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit a9ba49505e8d77e5bdc759914d23540b77fa7b84
|
||||||
@ -1,73 +1,90 @@
|
|||||||
public class EdgeDevice : EdgeDeviceP {
|
import Crypto
|
||||||
|
import DataAcquisition
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public class EdgeDevice: EdgeDeviceP {
|
||||||
|
|
||||||
public let deviceID: String
|
public let deviceID: String
|
||||||
public let deviceType: DeviceType
|
public let deviceType: DeviceType
|
||||||
public let dataType: DataType
|
public let dataType: DataType
|
||||||
public var disconnected: Bool
|
public var disconnected: Bool
|
||||||
public var compromised: Bool
|
public var compromised: Bool
|
||||||
|
public var location: Location3D
|
||||||
public var dutyCicle: UInt
|
public var dutyCicle: UInt
|
||||||
public var sensors: [Int: Sensor]
|
public var sensors: [Int: Sensor]
|
||||||
public var privateKey: [UInt8]
|
public var privateKey: P521.Signing.PrivateKey
|
||||||
|
|
||||||
private var numberOfSensors: Int {
|
private var numberOfSensors: Int {
|
||||||
get{
|
return sensors.count
|
||||||
return sensors.count
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
deviceID: String,
|
deviceID: String,
|
||||||
dataType: DataType,
|
dataType: DataType,
|
||||||
disconnected: Bool,
|
disconnected: Bool,
|
||||||
|
location: Location3D,
|
||||||
dutyCicle: UInt,
|
dutyCicle: UInt,
|
||||||
sensors: [Int: Sensor]
|
sensors: [Int: Sensor],
|
||||||
|
privateKey: P521.Signing.PrivateKey
|
||||||
) {
|
) {
|
||||||
self.deviceID = deviceID
|
self.deviceID = deviceID
|
||||||
self.deviceType = DeviceType.EdgeDevice
|
self.deviceType = DeviceType.EdgeDevice
|
||||||
self.dataType = dataType
|
self.dataType = dataType
|
||||||
self.disconnected = disconnected
|
self.disconnected = disconnected
|
||||||
self.compromised = false
|
self.compromised = false
|
||||||
|
self.location = location
|
||||||
self.dutyCicle = dutyCicle
|
self.dutyCicle = dutyCicle
|
||||||
self.sensors = sensors
|
self.sensors = sensors
|
||||||
|
self.privateKey = privateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
public func addSensor(sensor: Sensor) {
|
public func addSensor(sensor: Sensor) {
|
||||||
self.sensors[numberOfSensors + 1] = sensor
|
self.sensors[numberOfSensors + 1] = sensor
|
||||||
}
|
}
|
||||||
|
|
||||||
public func removeSensor(id: Int) {
|
public func removeSensor(id: Int) {
|
||||||
self.sensors.removeValue(forKey: id)
|
self.sensors.removeValue(forKey: id)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func work(envrionment: PhysicalEnvironment) {
|
public func work(envrionment: PhysicalEnvironment) -> Message {
|
||||||
|
|
||||||
// UGLY: In case I have some optimization problems, fix here
|
// UGLY: Declaring here some variables manually, remove them if you want to offere flexibility
|
||||||
var values: [Float] = []
|
let numberOfSamples: Int = 10
|
||||||
|
|
||||||
for sensor in sensors {
|
let rowPointer =
|
||||||
values.append(
|
UnsafeMutablePointer<UnsafeMutablePointer<Float>?>.allocate(capacity: numberOfSamples)
|
||||||
sensor.value.read(envrionment).value
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Todo: START Remove this and Add Vincenzo's implementation
|
rowPointer.initialize(
|
||||||
let avg : Float = meanValue(values: values)
|
repeating: UnsafeMutablePointer<Float>
|
||||||
let std_dev : Float = standardDeviation(values: values)
|
.allocate(capacity: self.sensors.count),
|
||||||
|
count: numberOfSamples
|
||||||
// Todo: END Add Vincenzo's implementation
|
|
||||||
return Message(
|
|
||||||
msgType: MessageType.Data,
|
|
||||||
timestamp: ,
|
|
||||||
deviceID: String,
|
|
||||||
location: Location3D,
|
|
||||||
fields: [Field],
|
|
||||||
signature: [UInt8]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
for rowI in 0..<numberOfSamples {
|
||||||
|
for colI in 0..<self.sensors.count {
|
||||||
|
rowPointer[rowI]![colI] = self.sensors[colI]!.read(envrionment).value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let metrics: Metrics = getMetrics(
|
||||||
|
rowPointer, Int32(self.sensors.count), Int32(numberOfSamples))
|
||||||
|
|
||||||
|
// Todo: END Add Vincenzo's implementation
|
||||||
|
let msg: Message = Message(
|
||||||
|
msgType: MessageType.Data,
|
||||||
|
timestamp: Date(),
|
||||||
|
deviceID: self.deviceID,
|
||||||
|
location: self.location,
|
||||||
|
fields: [
|
||||||
|
Field(key: "data_type", value: "\(self.dataType)"),
|
||||||
|
Field(key: "mean_value", value: "\(metrics.mean)"),
|
||||||
|
Field(key: "std_value", value: "\(metrics.standardDeviation)"),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
msg.signMessage(key: self.privateKey)
|
||||||
|
|
||||||
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import RandomCpp
|
||||||
|
|
||||||
public class Sensor {
|
public class Sensor {
|
||||||
|
|
||||||
public let sensorID: Int
|
public let sensorID: Int
|
||||||
@ -20,7 +22,7 @@ public class Sensor {
|
|||||||
|
|
||||||
let datum = self._read(environment)
|
let datum = self._read(environment)
|
||||||
|
|
||||||
return self.faulty ? datum : datum + Float.random(in: 1E2...1E10)
|
return !self.faulty ? datum : datum + Float.random(in: 1E2...1E10)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +62,7 @@ public class RealSensor: Sensor {
|
|||||||
private var _stdNoise: Float
|
private var _stdNoise: Float
|
||||||
private let _quantizationBits: Int
|
private let _quantizationBits: Int
|
||||||
// TODO: add a generator of GaussianRNG
|
// TODO: add a generator of GaussianRNG
|
||||||
//private var gaussianNoise:
|
private var _gaussianNoise: GaussianRNG
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
sensorID: Int,
|
sensorID: Int,
|
||||||
@ -73,26 +75,30 @@ public class RealSensor: Sensor {
|
|||||||
self._meanNoise = meanNoise
|
self._meanNoise = meanNoise
|
||||||
self._stdNoise = stdNoise
|
self._stdNoise = stdNoise
|
||||||
self._quantizationBits = quantizationBits
|
self._quantizationBits = quantizationBits
|
||||||
|
self._gaussianNoise = GaussianRNG(self._meanNoise, self._stdNoise)
|
||||||
super.init(id: sensorID, sensorType: sensorType, faulty: faulty)
|
super.init(id: sensorID, sensorType: sensorType, faulty: faulty)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(
|
convenience public init(
|
||||||
sensorID: Int,
|
sensorID: Int,
|
||||||
sensorType: DataType,
|
sensorType: DataType,
|
||||||
meanNoise: Float,
|
meanNoise: Float,
|
||||||
stdNoise: Float,
|
stdNoise: Float,
|
||||||
quantizationBits: Int
|
quantizationBits: Int
|
||||||
) {
|
) {
|
||||||
self._meanNoise = meanNoise
|
self.init(
|
||||||
self._stdNoise = stdNoise
|
sensorID: sensorID,
|
||||||
self._quantizationBits = quantizationBits
|
sensorType: sensorType,
|
||||||
super.init(id: sensorID, sensorType: sensorType)
|
faulty: false,
|
||||||
|
meanNoise: meanNoise,
|
||||||
|
stdNoise: stdNoise,
|
||||||
|
quantizationBits: quantizationBits
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override public func read(_ environment: PhysicalEnvironment) -> PhysicalData {
|
override public func read(_ environment: PhysicalEnvironment) -> PhysicalData {
|
||||||
let value: PhysicalData = super.read(environment)
|
let value: PhysicalData = super.read(environment)
|
||||||
// TODO Add gaussian error here
|
return value + self._gaussianNoise.generate()
|
||||||
return value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -8,5 +8,9 @@ public class Field {
|
|||||||
self.key = key
|
self.key = key
|
||||||
self.value = value
|
self.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
return "\(self.key): \t\(self.value)"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -9,4 +9,8 @@ public class Location3D {
|
|||||||
self.y = y
|
self.y = y
|
||||||
self.z = z
|
self.z = z
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
return "X: \(self.x)\tY: \(self.y)\tZ: \(self.z)"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -9,9 +9,7 @@ public class Message {
|
|||||||
public let location: Location3D
|
public let location: Location3D
|
||||||
public let fields: [Field]
|
public let fields: [Field]
|
||||||
public var signature: String {
|
public var signature: String {
|
||||||
get{
|
return self._signature != nil ? self._signature! : "##INVALID"
|
||||||
return self._signature != nil ? self._signature! : "##INVALID"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private var _signature: String? = nil
|
private var _signature: String? = nil
|
||||||
|
|
||||||
@ -30,22 +28,41 @@ public class Message {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func toData() -> Data {
|
public func toDataCompatibleString() -> String {
|
||||||
var string: String = "" + "\(messageType)" + "\(timestamp)" + "\(deviceID)" + "\(location)"
|
var string: String = "\(self.messageType)"
|
||||||
|
string += "\(self.timestamp)"
|
||||||
|
string += "\(self.deviceID)"
|
||||||
|
string += "\(self.location.x)"
|
||||||
|
string += "\(self.location.y)"
|
||||||
|
string += "\(self.location.z)"
|
||||||
|
|
||||||
for field in self.fields {
|
for field in self.fields {
|
||||||
string += "\(field)"
|
string += "\(field.key)\(field.value)"
|
||||||
}
|
}
|
||||||
|
|
||||||
return Data(string.utf8)
|
return string
|
||||||
}
|
}
|
||||||
|
|
||||||
public func signMessage(key: P521.Signing.PrivateKey) {
|
public func signMessage(key: P521.Signing.PrivateKey) {
|
||||||
do {
|
do {
|
||||||
self._signature = try sign(object: self.toData(), key: key)
|
self._signature = try sign(string: self.toDataCompatibleString(), key: key)
|
||||||
} catch {
|
} catch {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public var description: String {
|
||||||
|
|
||||||
|
var string: String = "MessageType: \t\(self.messageType)\n"
|
||||||
|
string += "Timestamp: \t\(self.timestamp)\n"
|
||||||
|
string += "DeviceID: \t\(self.deviceID)\n"
|
||||||
|
string += "Location: \t\(self.location.description)\n"
|
||||||
|
|
||||||
|
for field in self.fields {
|
||||||
|
string += "\(field.description)\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
return string
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
55
Sources/IoT-Simulator-Core/Classes/Utils/WorkerTask.swift
Normal file
55
Sources/IoT-Simulator-Core/Classes/Utils/WorkerTask.swift
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/* import Foundation
|
||||||
|
|
||||||
|
public class WorkerTask {
|
||||||
|
|
||||||
|
public let env: PhysicalEnvironment
|
||||||
|
public let device: EdgeDeviceP
|
||||||
|
public let success: (_ msg: Message) throws -> Void
|
||||||
|
public let failure: () -> Void
|
||||||
|
private var task : Task<(), Never>?
|
||||||
|
|
||||||
|
public init(
|
||||||
|
env: PhysicalEnvironment,
|
||||||
|
dev: EdgeDeviceP,
|
||||||
|
success: @escaping (_ msg: Message) throws -> Void,
|
||||||
|
failure: @escaping () -> Void
|
||||||
|
) {
|
||||||
|
self.env = env
|
||||||
|
self.device = dev
|
||||||
|
self.success = success
|
||||||
|
self.failure = failure
|
||||||
|
self.task = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
public func work() {
|
||||||
|
|
||||||
|
task = Task{
|
||||||
|
|
||||||
|
while true {
|
||||||
|
|
||||||
|
let message = device.work(envrionment: env)
|
||||||
|
do {
|
||||||
|
try success(message)
|
||||||
|
} catch{
|
||||||
|
failure()
|
||||||
|
}
|
||||||
|
usleep(__useconds_t(device.dutyCicle))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public func cancel() {
|
||||||
|
if self.task == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.task!.cancel()
|
||||||
|
self.task = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
@ -1,4 +1,4 @@
|
|||||||
public enum DataType {
|
public enum DataType : Sendable{
|
||||||
case Temperature
|
case Temperature
|
||||||
case Humidity
|
case Humidity
|
||||||
case Scan
|
case Scan
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
public enum DeviceType {
|
public enum DeviceType : Sendable{
|
||||||
case AsyncEdgeDevice
|
case AsyncEdgeDevice
|
||||||
case EdgeDevice
|
case EdgeDevice
|
||||||
}
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
public enum CoreError : Error {
|
public enum CoreError : Error {
|
||||||
case NoPhysicalDataAvailable( dataType: String)
|
case NoPhysicalDataAvailable( dataType: String)
|
||||||
|
case NoEnvironment
|
||||||
}
|
}
|
||||||
@ -1,2 +1,73 @@
|
|||||||
// The Swift Programming Language
|
// The Swift Programming Language
|
||||||
// https://docs.swift.org/swift-book
|
// https://docs.swift.org/swift-book
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public actor IoTSimulatorCore {
|
||||||
|
|
||||||
|
private static var enviroments: [String: PhysicalEnvironment] = Dictionary()
|
||||||
|
private static var devices: [String: EdgeDeviceP] = Dictionary()
|
||||||
|
private static var env_dev: [String: Set<String>] = Dictionary()
|
||||||
|
private static var dev_tasks: [String: Task<(), Never>] = Dictionary()
|
||||||
|
|
||||||
|
public static func addEnv(environment: PhysicalEnvironment) {
|
||||||
|
IoTSimulatorCore.enviroments[environment.location] = environment
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func addDevice(location: String, device: EdgeDeviceP) throws {
|
||||||
|
if let environment = IoTSimulatorCore.enviroments[location] {
|
||||||
|
IoTSimulatorCore.devices[device.deviceID] = device
|
||||||
|
|
||||||
|
if IoTSimulatorCore.env_dev[location] == nil {
|
||||||
|
IoTSimulatorCore.env_dev[location] = Set()
|
||||||
|
}
|
||||||
|
|
||||||
|
IoTSimulatorCore.env_dev[location]!.insert(device.deviceID)
|
||||||
|
|
||||||
|
// schedule work
|
||||||
|
let task = IoTSimulatorCore.schedule(envID: environment.location, deviceID: device.deviceID) { msg in
|
||||||
|
print("\(msg.description)\n\n")
|
||||||
|
} failure: {
|
||||||
|
print("Something is wrong")
|
||||||
|
}
|
||||||
|
|
||||||
|
IoTSimulatorCore.dev_tasks[device.deviceID] = task
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw CoreError.NoEnvironment
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func getEnv(name: String) -> PhysicalEnvironment? {
|
||||||
|
return IoTSimulatorCore.enviroments[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func getDev(devID: String) -> EdgeDeviceP? {
|
||||||
|
return IoTSimulatorCore.devices[devID]
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func schedule(
|
||||||
|
envID: sending String,
|
||||||
|
deviceID: sending String,
|
||||||
|
success: sending @escaping (_ msg: Message) throws -> Void,
|
||||||
|
failure: sending @escaping () -> Void
|
||||||
|
) -> Task<(), Never> {
|
||||||
|
return Task {
|
||||||
|
|
||||||
|
while true {
|
||||||
|
let dev = IoTSimulatorCore.getDev(devID: deviceID)!
|
||||||
|
let env = IoTSimulatorCore.getEnv(name: envID)!
|
||||||
|
|
||||||
|
let message = dev.work(envrionment: env)
|
||||||
|
do {
|
||||||
|
try success(message)
|
||||||
|
} catch {
|
||||||
|
failure()
|
||||||
|
}
|
||||||
|
usleep(__useconds_t(dev.dutyCicle * 1000))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
|
import Crypto
|
||||||
|
|
||||||
public protocol EdgeDeviceP {
|
public protocol EdgeDeviceP {
|
||||||
|
|
||||||
var deviceID : String {get}
|
var deviceID : String {get}
|
||||||
var deviceType : DeviceType {get}
|
var deviceType : DeviceType {get}
|
||||||
var dataType : DataType {get}
|
var dataType : DataType {get}
|
||||||
|
var location: Location3D {get set}
|
||||||
var disconnected : Bool {get set}
|
var disconnected : Bool {get set}
|
||||||
var compromised : Bool {get set}
|
var compromised : Bool {get set}
|
||||||
var dutyCicle : UInt {get set}
|
var dutyCicle : UInt {get set}
|
||||||
var privateKey: [UInt8] {get}
|
var privateKey: P521.Signing.PrivateKey {get}
|
||||||
|
|
||||||
func work(envrionment: PhysicalEnvironment) -> Message
|
func work(envrionment: PhysicalEnvironment) -> Message
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,13 @@ public func sign(object: Data, key: P521.Signing.PrivateKey)throws -> String {
|
|||||||
return try key.signature<Data>(for: object).rawRepresentation.base64EncodedString()
|
return try key.signature<Data>(for: object).rawRepresentation.base64EncodedString()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
public func sign<T>(object: T, key: P521.Signing.PrivateKey) throws -> String {
|
||||||
|
|
||||||
|
var _object = object
|
||||||
|
let data: Data = Data(bytes: &_object, count: MemoryLayout<T>.stride)
|
||||||
|
|
||||||
|
} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
13
Tests/IoT-Simulator-CoreTests/DataAcquisition-Tests.swift
Normal file
13
Tests/IoT-Simulator-CoreTests/DataAcquisition-Tests.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import Testing
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import DataAcquisition
|
||||||
|
|
||||||
|
@testable import IoT_Simulator_Core
|
||||||
|
|
||||||
|
@Test func dataAcquisition() async throws {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
166
Tests/IoT-Simulator-CoreTests/Devices-Tests.swift
Normal file
166
Tests/IoT-Simulator-CoreTests/Devices-Tests.swift
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
import Testing
|
||||||
|
import RandomCpp
|
||||||
|
import Foundation
|
||||||
|
import Crypto
|
||||||
|
|
||||||
|
@testable import IoT_Simulator_Core
|
||||||
|
|
||||||
|
@Test func idealSensor() async throws {
|
||||||
|
|
||||||
|
let env = PhysicalEnvironment("Delta")
|
||||||
|
let truth = PhysicalData(.Temperature, 22)
|
||||||
|
|
||||||
|
env.setPhysicalData(DataType.Temperature, truth)
|
||||||
|
|
||||||
|
let sensor : Sensor = Sensor(id: 1, sensorType: .Temperature)
|
||||||
|
let data = sensor.read(env)
|
||||||
|
|
||||||
|
|
||||||
|
#expect(data.value == truth.value, "If values match, we are cool")
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func faultyIdealSensor() async throws {
|
||||||
|
|
||||||
|
let env = PhysicalEnvironment("Delta")
|
||||||
|
let truth = PhysicalData(.Temperature, 22)
|
||||||
|
|
||||||
|
env.setPhysicalData(DataType.Temperature, truth)
|
||||||
|
|
||||||
|
let sensor : Sensor = Sensor(id: 1, sensorType: .Temperature, faulty: true)
|
||||||
|
let data = sensor.read(env)
|
||||||
|
|
||||||
|
|
||||||
|
#expect(data.value != truth.value, "If these match, something is not working")
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func realSensor() async throws {
|
||||||
|
|
||||||
|
let env = PhysicalEnvironment("Delta")
|
||||||
|
let truth = PhysicalData(.Temperature, 22)
|
||||||
|
|
||||||
|
env.setPhysicalData(DataType.Temperature, truth)
|
||||||
|
|
||||||
|
let sensor : Sensor = RealSensor(sensorID: 1, sensorType: .Temperature, faulty: false, meanNoise: 0.5, stdNoise: 0.25, quantizationBits: 3)
|
||||||
|
let data = sensor.read(env)
|
||||||
|
|
||||||
|
|
||||||
|
#expect(data.value - truth.value < 10, "If these match, we are cool")
|
||||||
|
|
||||||
|
print(data.value)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func faultyRealSensor() async throws {
|
||||||
|
|
||||||
|
let env = PhysicalEnvironment("Delta")
|
||||||
|
let truth = PhysicalData(.Temperature, 22)
|
||||||
|
|
||||||
|
env.setPhysicalData(DataType.Temperature, truth)
|
||||||
|
|
||||||
|
let sensor : Sensor = RealSensor(sensorID: 1, sensorType: .Temperature, faulty: true, meanNoise: 0.5, stdNoise: 0.25, quantizationBits: 3)
|
||||||
|
let data = sensor.read(env)
|
||||||
|
|
||||||
|
|
||||||
|
#expect(data.value - truth.value > 10, "If these match, something is not working")
|
||||||
|
|
||||||
|
print(data.value)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func edgeDevice() async throws {
|
||||||
|
|
||||||
|
let env = PhysicalEnvironment("Delta")
|
||||||
|
let truth = PhysicalData(.Temperature, 22)
|
||||||
|
|
||||||
|
env.setPhysicalData(DataType.Temperature, truth)
|
||||||
|
|
||||||
|
let signKeyPath = "./Private/privateKey.pem"
|
||||||
|
|
||||||
|
let privateKey = try pem2key(filePath: signKeyPath)
|
||||||
|
|
||||||
|
let dev: EdgeDevice = EdgeDevice(
|
||||||
|
deviceID: "EDG-001",
|
||||||
|
dataType: .Temperature,
|
||||||
|
disconnected: false,
|
||||||
|
location: Location3D(20, 10, 0),
|
||||||
|
dutyCicle: 100098,
|
||||||
|
sensors: [
|
||||||
|
0: Sensor(id: 0, sensorType: DataType.Temperature),
|
||||||
|
1: Sensor(id: 0, sensorType: DataType.Temperature),
|
||||||
|
2: Sensor(id: 0, sensorType: DataType.Temperature, faulty: true)
|
||||||
|
],
|
||||||
|
privateKey: privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
let message = dev.work(envrionment: env)
|
||||||
|
message.signMessage(key: dev.privateKey)
|
||||||
|
|
||||||
|
|
||||||
|
#expect(message != nil, "If this is nil, I don't knwo what's going on")
|
||||||
|
#expect(message.signature != nil, "If signature is nil, something is wrong")
|
||||||
|
|
||||||
|
print(message.description)
|
||||||
|
print(message.signature)
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
try verifySignature(
|
||||||
|
signature:message.signature,
|
||||||
|
string: message.toDataCompatibleString(),
|
||||||
|
key: dev.privateKey.publicKey
|
||||||
|
),
|
||||||
|
"Let's see that signatures match"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test func edgeDeviceMean() async throws {
|
||||||
|
|
||||||
|
let env = PhysicalEnvironment("Delta")
|
||||||
|
let truth = PhysicalData(.Temperature, 22)
|
||||||
|
|
||||||
|
env.setPhysicalData(DataType.Temperature, truth)
|
||||||
|
|
||||||
|
let signKeyPath = "./Private/privateKey.pem"
|
||||||
|
|
||||||
|
let privateKey = try pem2key(filePath: signKeyPath)
|
||||||
|
|
||||||
|
let dev: EdgeDevice = EdgeDevice(
|
||||||
|
deviceID: "EDG-001",
|
||||||
|
dataType: .Temperature,
|
||||||
|
disconnected: false,
|
||||||
|
location: Location3D(20, 10, 0),
|
||||||
|
dutyCicle: 100098,
|
||||||
|
sensors: [
|
||||||
|
0: RealSensor(sensorID: 0, sensorType: .Temperature, faulty: false, meanNoise: 1, stdNoise: 3, quantizationBits: 3),
|
||||||
|
1: RealSensor(sensorID: 1, sensorType: .Temperature, faulty: false, meanNoise: 1, stdNoise: 3, quantizationBits: 3),
|
||||||
|
2: RealSensor(sensorID: 2, sensorType: .Temperature, faulty: false, meanNoise: 1, stdNoise: 3, quantizationBits: 3),
|
||||||
|
],
|
||||||
|
privateKey: privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
let message = dev.work(envrionment: env)
|
||||||
|
message.signMessage(key: dev.privateKey)
|
||||||
|
|
||||||
|
|
||||||
|
#expect(message != nil, "If this is nil, I don't knwo what's going on")
|
||||||
|
#expect(message.signature != nil, "If signature is nil, something is wrong")
|
||||||
|
|
||||||
|
print(message.description)
|
||||||
|
print(message.signature)
|
||||||
|
|
||||||
|
#expect(
|
||||||
|
try verifySignature(
|
||||||
|
signature:message.signature,
|
||||||
|
string: message.toDataCompatibleString(),
|
||||||
|
key: dev.privateKey.publicKey
|
||||||
|
),
|
||||||
|
"Let's see that signatures match"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
65
Tests/IoT-Simulator-CoreTests/IoTCore-Tests.swift
Normal file
65
Tests/IoT-Simulator-CoreTests/IoTCore-Tests.swift
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import DataAcquisition
|
||||||
|
import Foundation
|
||||||
|
import Testing
|
||||||
|
|
||||||
|
@testable import IoT_Simulator_Core
|
||||||
|
|
||||||
|
@Test func workLoop1() async throws {
|
||||||
|
|
||||||
|
let env = PhysicalEnvironment("Delta")
|
||||||
|
let truth = PhysicalData(.Temperature, 22)
|
||||||
|
|
||||||
|
env.setPhysicalData(DataType.Temperature, truth)
|
||||||
|
|
||||||
|
IoTSimulatorCore.addEnv(environment: env)
|
||||||
|
|
||||||
|
let signKeyPath = "./Private/privateKey.pem"
|
||||||
|
|
||||||
|
let privateKey = try pem2key(filePath: signKeyPath)
|
||||||
|
|
||||||
|
let dev: EdgeDevice = EdgeDevice(
|
||||||
|
deviceID: "EDG-001",
|
||||||
|
dataType: .Temperature,
|
||||||
|
disconnected: false,
|
||||||
|
location: Location3D(20, 10, 0),
|
||||||
|
dutyCicle: 3000,
|
||||||
|
sensors: [
|
||||||
|
0: RealSensor(
|
||||||
|
sensorID: 0, sensorType: .Temperature, faulty: false, meanNoise: 1, stdNoise: 3,
|
||||||
|
quantizationBits: 3),
|
||||||
|
1: RealSensor(
|
||||||
|
sensorID: 1, sensorType: .Temperature, faulty: false, meanNoise: 1, stdNoise: 3,
|
||||||
|
quantizationBits: 3),
|
||||||
|
2: RealSensor(
|
||||||
|
sensorID: 2, sensorType: .Temperature, faulty: false, meanNoise: 1, stdNoise: 3,
|
||||||
|
quantizationBits: 3),
|
||||||
|
],
|
||||||
|
privateKey: privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
let dev2: EdgeDevice = EdgeDevice(
|
||||||
|
deviceID: "EDG-002",
|
||||||
|
dataType: .Temperature,
|
||||||
|
disconnected: false,
|
||||||
|
location: Location3D(20, 10, 0),
|
||||||
|
dutyCicle: 1000,
|
||||||
|
sensors: [
|
||||||
|
0: RealSensor(
|
||||||
|
sensorID: 0, sensorType: .Temperature, faulty: false, meanNoise: 1, stdNoise: 3,
|
||||||
|
quantizationBits: 3),
|
||||||
|
1: RealSensor(
|
||||||
|
sensorID: 1, sensorType: .Temperature, faulty: false, meanNoise: 1, stdNoise: 3,
|
||||||
|
quantizationBits: 3),
|
||||||
|
2: RealSensor(
|
||||||
|
sensorID: 2, sensorType: .Temperature, faulty: false, meanNoise: 1, stdNoise: 3,
|
||||||
|
quantizationBits: 3),
|
||||||
|
],
|
||||||
|
privateKey: privateKey
|
||||||
|
)
|
||||||
|
|
||||||
|
try IoTSimulatorCore.addDevice(location: "Delta", device: dev)
|
||||||
|
try IoTSimulatorCore.addDevice(location: "Delta", device: dev2)
|
||||||
|
|
||||||
|
sleep(15)
|
||||||
|
|
||||||
|
}
|
||||||
@ -55,9 +55,9 @@ import Crypto
|
|||||||
let signature = try sign(string: obj, key: key)
|
let signature = try sign(string: obj, key: key)
|
||||||
let puKey = key.publicKey
|
let puKey = key.publicKey
|
||||||
|
|
||||||
let verify = try verify(signature: signature, string: obj, key: puKey)
|
let _verify = try verifySignature(signature: signature, string: obj, key: puKey)
|
||||||
print(verify)
|
print(_verify)
|
||||||
assert(verify)
|
assert(_verify)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user