IoT-Simulator/Sources/App/simulator-configuration.swift
Christian Risi 4ffee0ec63 0.6.6 Arroyo Toad
Fixed some bugs
2024-12-21 18:51:56 +00:00

145 lines
4.3 KiB
Swift

import Crypto
import Foundation
import FoundationNetworking
import IoT_Simulator_Core
import MessageUtils
public func configureSimulator() async throws {
guard
let configurationFilePath: String = ProcessInfo.processInfo.environment[
"CONFIGURATION_FILE"]
else {
throw ParsingError.ConfigFileNotExistent
}
let jsonData: Data = try Data(contentsOf: URL(filePath: configurationFilePath))
guard
let jsonObject: [String: Any] = try JSONSerialization.jsonObject(with: jsonData)
as? [String: Any]
else {
throw ParsingError.MalformedJSON(reason: "This is not a JSON file")
}
try await jsonConfigurationParser(jsonObject)
}
private func jsonConfigurationParser(_ json: [String: Any]) async throws {
guard
let version = json["version"] as? Int,
let environments = json["environments"] as? [[String: Any]]
else {
throw ParsingError.MalformedJSON(reason: "Missing either version or environemnt")
}
for environmentJSON in environments {
let env = try await json2env(environmentJSON)
await IoTSimulatorCore.addEnv(environment: env)
if let devices = environmentJSON["devices"] as? [[String: Any]] {
for deviceJSON in devices {
let devices = try await json2edge_dev(deviceJSON)
for dev in devices {
await try IoTSimulatorCore.addDevice(location: env.location, device: dev) { msg in
// UGLY: But fast
// TODO: add sending code here
let backendURL = ProcessInfo.processInfo.environment["BACKEND_URL"]!
var httpRequest = URLRequest(url: URL(string: backendURL)!)
httpRequest.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type")
httpRequest.httpMethod = "POST"
httpRequest.httpBody = msg
let _ = try await URLSession.shared.upload(for: httpRequest, from: msg)
} failure: {
print("Failed")
}
}
}
}
}
}
private func json2env(_ json: [String: Any]) async throws -> PhysicalEnvironment {
guard
let envName = json["name"] as? String
else {
throw ParsingError.MalformedJSON(reason: "Missing name of environment")
}
let environment = PhysicalEnvironment(envName)
if let physicalData = json["physicalData"] as? [[String: Any]] {
for physicalDatum in physicalData {
guard
let dataTypeString = physicalDatum["dataType"] as? String,
let value = physicalDatum["value"] as? Double,
let dataType = DataType(rawValue: dataTypeString)
else {
throw ParsingError.MalformedJSON(reason: "Physical Data is Misconfigured")
}
let datum = PhysicalData(dataType, Float(value))
await environment.setPhysicalData(datum.type, datum)
}
}
return environment
}
private func json2edge_dev(_ json: [String: Any]) async throws -> [EdgeDevice] {
var devices: [EdgeDevice] = []
guard
let _dataType = json["dataType"] as? String,
let dataType = DataType(rawValue: _dataType)
else {
throw ParsingError.MalformedJSON(reason: "Data Type missing in one device")
}
if let number = json["number"] as? UInt {
for _ in 0..<number {
let deviceID = try DeviceFactory.getUnusedID()
let privateKey = try await fetchPrivateP256Key(deviceID: UInt(deviceID))
// TODO: Get ID from DeviceFactory and push ID inside
devices.append(
try await DeviceFactory.createEdgeDevice(
deviceID: deviceID,
dataType: dataType,
privateKey: privateKey
)
)
}
// UGLY: Silent Bug, coul dhave both deviceID and number, but other properties would
// UGLY: be ignored
return devices
}
guard
let deviceID = json["deviceID"] as? UInt
else {
throw ParsingError.MalformedJSON(
reason: "Missing deviceID and number properties"
)
}
// TODO: check for other optionals
return devices
}