Skip to content

Commit

Permalink
Merge pull request #6 from fa21-collaborative-drone-interactions/feat…
Browse files Browse the repository at this point in the history
…ure/sensors-endpoint

Modify interface for ApodiniDeploy
  • Loading branch information
Lerbert authored Sep 25, 2021
2 parents 9ff66f1 + 86132d8 commit ed43eec
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 55 deletions.
9 changes: 9 additions & 0 deletions WebService/Sources/Demo/ConductivitySensor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Apodini
import Foundation


struct ConductivitySensor: SensorHandler {
static let dirPath = "data"
static let sensorType: SensorType = .CONDUCTIVITY
static let converter = getMeasurementConverterInstance(sensorType: .CONDUCTIVITY)
}
25 changes: 25 additions & 0 deletions WebService/Sources/Demo/JSONUtil.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Foundation

let mountDir = URL(fileURLWithPath: "/buoy")

func readJSONFromFile<T>(_ type: T.Type, filePath: String) -> T? where T: Decodable {
readJSONFromFile(type, fileURL: mountDir.appendingPathComponent(filePath))
}

func readJSONFromFile<T>(_ type: T.Type, fileURL: URL) -> T? where T: Decodable {
guard let data = try? Data(contentsOf: fileURL) else {
return nil
}
return try? JSONDecoder().decode(T.self, from: data)
}

func readJSONDirectory<T>(_ type: T.Type, dirPath: String) -> [T] where T: Decodable {
guard let files = try? FileManager.default.contentsOfDirectory(at: mountDir.appendingPathComponent(dirPath),
includingPropertiesForKeys: nil)
else {
return []
}
return files.compactMap {fileURL in
readJSONFromFile(T.self, fileURL: fileURL)
}
}
40 changes: 40 additions & 0 deletions WebService/Sources/Demo/MeasurementConverter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Apodini


protocol MeasurementConverter {
func convert(rawValue: Double) -> Double
}

func getMeasurementConverterInstance(sensorType: SensorType) -> MeasurementConverter {
switch sensorType {
case TemperatureSensor.sensorType:
return PolynomialMeasurementConverter(configFilePath: "sensorconfig/TemperatureSensor.json")
case ConductivitySensor.sensorType:
return PolynomialMeasurementConverter(configFilePath: "sensorconfig/ConductivitySensor.json")
case PhSensor.sensorType:
return PolynomialMeasurementConverter(configFilePath: "sensorconfig/PhSensor.json")
default:
return NoopConverter()
}
}

struct NoopConverter: MeasurementConverter {
func convert(rawValue: Double) -> Double {
rawValue
}
}

struct PolynomialMeasurementConverter: MeasurementConverter {
var polynomialCoefficients: [Double]


init(configFilePath: String) {
self.polynomialCoefficients = readJSONFromFile([Double].self, filePath: configFilePath) ?? []
}

func convert(rawValue: Double) -> Double {
polynomialCoefficients.reduce(0) {result, coeff in
result * rawValue + coeff
}
}
}
19 changes: 4 additions & 15 deletions WebService/Sources/Demo/PhSensor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,8 @@ import Apodini
import Foundation


struct PhSensor: Handler {
@Parameter var offset: Int = 0


func handle() -> [String] {
let path = FileManager.default.currentDirectoryPath.appendingPathComponent("ph_values.txt")
do {
let data = try String(contentsOfFile: path, encoding: .utf8)
let lines = data.components(separatedBy: .newlines)
return Array(lines[offset...])
} catch {
print("Error reading file")
return []
}
}
struct PhSensor: SensorHandler {
static let dirPath = "data"
static let sensorType: SensorType = .POTENTIAHYDROGENII
static let converter = getMeasurementConverterInstance(sensorType: .POTENTIAHYDROGENII)
}
14 changes: 3 additions & 11 deletions WebService/Sources/Demo/Sensor.swift
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import Apodini
import Foundation


struct Sensor: Handler {
func handle() -> String {
"""
List of sensors:
pH
"""
}

var content: some Component {
Group("ph") {
PhSensor()
}
func handle() -> [Int] {
readJSONFromFile([Int].self, filePath: "available_sensors.json") ?? []
}
}
53 changes: 28 additions & 25 deletions WebService/Sources/Demo/SensorData.swift
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
import Apodini
import Foundation

struct MeasurementItem: Content, Decodable {
var sensorID: Int
var sensorType: Int
var measurement: Double
}

struct SensorDump: Content, Decodable {
var buoyId: Int
var date: String
var location: Location
var measurements: [MeasurementItem]
}

struct Location: Content, Decodable {
var latitude: Double
var longitude: Double
}

struct SensorData: Handler {
static let dirPath = "data"

func handle() -> [SensorDump] {
let dirPath = "/buoy/data"
guard let files = try? FileManager.default.contentsOfDirectory(atPath: dirPath) else {
return []
}
return files.compactMap {fileName in
guard let data = try? Data(contentsOf: URL(fileURLWithPath: dirPath + "/" + fileName)) else {
return nil
readJSONDirectory(SensorDump.self, dirPath: Self.dirPath)
.map {
SensorDump(
buoyId: $0.buoyId,
date: $0.date,
location: $0.location,
measurements: $0.measurements.map { item in
MeasurementItem(
sensorID: item.sensorID,
sensorType: item.sensorType,
measurement: getMeasurementConverterInstance(sensorType: item.sensorType).convert(rawValue: item.measurement))
}
)
}
return try? JSONDecoder().decode(SensorDump.self, from: data)
}

var content: some Component {
Group(TemperatureSensor.sensorType.description) {
TemperatureSensor()
}

Group(ConductivitySensor.sensorType.description) {
ConductivitySensor()
}

Group(PhSensor.sensorType.description) {
PhSensor()
}
}
}
53 changes: 53 additions & 0 deletions WebService/Sources/Demo/SensorDump.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Apodini

struct SensorDump: Content, Decodable {
var buoyId: Int
var date: String
var location: Location
var measurements: [MeasurementItem]

func filteredBySensorType(_ sensorType: SensorType) -> SensorDump {
SensorDump(
buoyId: self.buoyId,
date: self.date,
location: self.location,
measurements: self.measurements.filter { $0.sensorType == sensorType }
)
}

func convertMeasurements(_ converter: MeasurementConverter) -> SensorDump {
SensorDump(
buoyId: self.buoyId,
date: self.date,
location: self.location,
measurements: self.measurements.map { item in
MeasurementItem(sensorID: item.sensorID, sensorType: item.sensorType, measurement: converter.convert(rawValue: item.measurement))
}
)
}
}

struct Location: Content, Decodable {
var latitude: Double
var longitude: Double
}

struct MeasurementItem: Content, Decodable {
var sensorID: Int
var sensorType: SensorType
var measurement: Double
}

enum SensorType: Int, Content, Decodable, CustomStringConvertible {
case TEMPERATURE
case CONDUCTIVITY
case POTENTIAHYDROGENII

var description: String {
switch self {
case .TEMPERATURE: return "temperature"
case .CONDUCTIVITY: return "conductivity"
case .POTENTIAHYDROGENII: return "ph"
}
}
}
18 changes: 18 additions & 0 deletions WebService/Sources/Demo/SensorHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Apodini


protocol SensorHandler: Handler {
static var dirPath: String { get }
static var sensorType: SensorType { get }
static var converter: MeasurementConverter { get }

func handle() -> [SensorDump]
}

extension SensorHandler {
func handle() -> [SensorDump] {
readJSONDirectory(SensorDump.self, dirPath: Self.dirPath)
.map { $0.filteredBySensorType(Self.sensorType).convertMeasurements(Self.converter) }
.filter { !$0.measurements.isEmpty }
}
}
9 changes: 9 additions & 0 deletions WebService/Sources/Demo/TemperatureSensor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Apodini
import Foundation


struct TemperatureSensor: SensorHandler {
static let dirPath = "data"
static let sensorType: SensorType = .TEMPERATURE
static let converter = getMeasurementConverterInstance(sensorType: .TEMPERATURE)
}
4 changes: 0 additions & 4 deletions WebService/ph_values.txt

This file was deleted.

0 comments on commit ed43eec

Please sign in to comment.