Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagohm committed Aug 28, 2024
2 parents fe3870d + b9d51ed commit 62015dd
Show file tree
Hide file tree
Showing 83 changed files with 1,549 additions and 257 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import nebulosa.api.calibration.CalibrationFrameRepository
import nebulosa.api.connection.ConnectionService
import nebulosa.indi.device.Device
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.dustcap.DustCap
import nebulosa.indi.device.filterwheel.FilterWheel
import nebulosa.indi.device.focuser.Focuser
import nebulosa.indi.device.gps.GPS
import nebulosa.indi.device.guider.GuideOutput
import nebulosa.indi.device.lightbox.LightBox
import nebulosa.indi.device.mount.Mount
import nebulosa.indi.device.rotator.Rotator
import nebulosa.indi.device.thermometer.Thermometer
Expand Down Expand Up @@ -41,6 +43,8 @@ class DeviceOrEntityParamMethodArgumentResolver(
Rotator::class.java to { connectionService.rotator(it) },
GPS::class.java to { connectionService.gps(it) },
GuideOutput::class.java to { connectionService.guideOutput(it) },
LightBox::class.java to { connectionService.lightBox(it) },
DustCap::class.java to { connectionService.dustCap(it) },
Thermometer::class.java to { connectionService.thermometer(it) },
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package nebulosa.api.cameras

import nebulosa.api.beans.converters.device.DeviceDeserializer
import nebulosa.api.devices.DeviceDeserializer
import nebulosa.api.connection.ConnectionService
import nebulosa.indi.device.camera.Camera
import org.springframework.beans.factory.annotation.Autowired
Expand Down
139 changes: 66 additions & 73 deletions api/src/main/kotlin/nebulosa/api/cameras/CameraSerializer.kt
Original file line number Diff line number Diff line change
@@ -1,91 +1,84 @@
package nebulosa.api.cameras

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.ser.std.StdSerializer
import nebulosa.api.devices.DeviceSerializer
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.camera.GuideHead
import org.springframework.stereotype.Component
import java.nio.file.Path

@Component
class CameraSerializer(private val capturesPath: Path) : StdSerializer<Camera>(Camera::class.java) {
class CameraSerializer(private val capturesPath: Path) : DeviceSerializer<Camera>(Camera::class.java) {

override fun serialize(value: Camera, gen: JsonGenerator, provider: SerializerProvider) {
gen.writeStartObject()
gen.writeStringField("type", value.type.name)
gen.writeStringField("sender", value.sender.id)
gen.writeStringField("driverName", value.driverName)
gen.writeStringField("driverVersion", value.driverVersion)
gen.writeStringField("id", value.id)
gen.writeStringField("name", value.name)
gen.writeBooleanField("connected", value.connected)
gen.writeBooleanField("exposuring", value.exposuring)
gen.writeBooleanField("hasCoolerControl", value.hasCoolerControl)
gen.writeNumberField("coolerPower", value.coolerPower)
gen.writeBooleanField("cooler", value.cooler)
gen.writeBooleanField("hasDewHeater", value.hasDewHeater)
gen.writeBooleanField("dewHeater", value.dewHeater)
gen.writeObjectField("frameFormats", value.frameFormats)
gen.writeBooleanField("canAbort", value.canAbort)
gen.writeNumberField("cfaOffsetX", value.cfaOffsetX)
gen.writeNumberField("cfaOffsetY", value.cfaOffsetY)
gen.writeStringField("cfaType", value.cfaType.name)
gen.writeNumberField("exposureMin", value.exposureMin.toNanos() / 1000L)
gen.writeNumberField("exposureMax", value.exposureMax.toNanos() / 1000L)
gen.writeStringField("exposureState", value.exposureState.name)
gen.writeNumberField("exposureTime", value.exposureTime.toNanos() / 1000L)
gen.writeBooleanField("hasCooler", value.hasCooler)
gen.writeBooleanField("canSetTemperature", value.canSetTemperature)
gen.writeBooleanField("canSubFrame", value.canSubFrame)
gen.writeNumberField("x", value.x)
gen.writeNumberField("minX", value.minX)
gen.writeNumberField("maxX", value.maxX)
gen.writeNumberField("y", value.y)
gen.writeNumberField("minY", value.minY)
gen.writeNumberField("maxY", value.maxY)
gen.writeNumberField("width", value.width)
gen.writeNumberField("minWidth", value.minWidth)
gen.writeNumberField("maxWidth", value.maxWidth)
gen.writeNumberField("height", value.height)
gen.writeNumberField("minHeight", value.minHeight)
gen.writeNumberField("maxHeight", value.maxHeight)
gen.writeBooleanField("canBin", value.canBin)
gen.writeNumberField("maxBinX", value.maxBinX)
gen.writeNumberField("maxBinY", value.maxBinY)
gen.writeNumberField("binX", value.binX)
gen.writeNumberField("binY", value.binY)
gen.writeNumberField("gain", value.gain)
gen.writeNumberField("gainMin", value.gainMin)
gen.writeNumberField("gainMax", value.gainMax)
gen.writeNumberField("offset", value.offset)
gen.writeNumberField("offsetMin", value.offsetMin)
gen.writeNumberField("offsetMax", value.offsetMax)
gen.writeBooleanField("hasGuideHead", value.guideHead != null)
gen.writeNumberField("pixelSizeX", value.pixelSizeX)
gen.writeNumberField("pixelSizeY", value.pixelSizeY)
gen.writeBooleanField("canPulseGuide", value.canPulseGuide)
gen.writeBooleanField("pulseGuiding", value.pulseGuiding)
gen.writeBooleanField("hasThermometer", value.hasThermometer)
gen.writeNumberField("temperature", value.temperature)
gen.writeObjectField("capturesPath", Path.of("$capturesPath", value.name))
override fun JsonGenerator.serialize(value: Camera) {
writeBooleanField("exposuring", value.exposuring)
writeBooleanField("hasCoolerControl", value.hasCoolerControl)
writeNumberField("coolerPower", value.coolerPower)
writeBooleanField("cooler", value.cooler)
writeBooleanField("hasDewHeater", value.hasDewHeater)
writeBooleanField("dewHeater", value.dewHeater)
writeObjectField("frameFormats", value.frameFormats)
writeBooleanField("canAbort", value.canAbort)
writeNumberField("cfaOffsetX", value.cfaOffsetX)
writeNumberField("cfaOffsetY", value.cfaOffsetY)
writeStringField("cfaType", value.cfaType.name)
writeNumberField("exposureMin", value.exposureMin.toNanos() / 1000L)
writeNumberField("exposureMax", value.exposureMax.toNanos() / 1000L)
writeStringField("exposureState", value.exposureState.name)
writeNumberField("exposureTime", value.exposureTime.toNanos() / 1000L)
writeBooleanField("hasCooler", value.hasCooler)
writeBooleanField("canSetTemperature", value.canSetTemperature)
writeBooleanField("canSubFrame", value.canSubFrame)
writeNumberField("x", value.x)
writeNumberField("minX", value.minX)
writeNumberField("maxX", value.maxX)
writeNumberField("y", value.y)
writeNumberField("minY", value.minY)
writeNumberField("maxY", value.maxY)
writeNumberField("width", value.width)
writeNumberField("minWidth", value.minWidth)
writeNumberField("maxWidth", value.maxWidth)
writeNumberField("height", value.height)
writeNumberField("minHeight", value.minHeight)
writeNumberField("maxHeight", value.maxHeight)
writeBooleanField("canBin", value.canBin)
writeNumberField("maxBinX", value.maxBinX)
writeNumberField("maxBinY", value.maxBinY)
writeNumberField("binX", value.binX)
writeNumberField("binY", value.binY)
writeNumberField("gain", value.gain)
writeNumberField("gainMin", value.gainMin)
writeNumberField("gainMax", value.gainMax)
writeNumberField("offset", value.offset)
writeNumberField("offsetMin", value.offsetMin)
writeNumberField("offsetMax", value.offsetMax)
writeBooleanField("hasGuideHead", value.guideHead != null)
writeNumberField("pixelSizeX", value.pixelSizeX)
writeNumberField("pixelSizeY", value.pixelSizeY)
writeBooleanField("canPulseGuide", value.canPulseGuide)
writeBooleanField("pulseGuiding", value.pulseGuiding)
writeBooleanField("hasThermometer", value.hasThermometer)
writeNumberField("temperature", value.temperature)
writeObjectField("capturesPath", Path.of("$capturesPath", value.name))

if (value is GuideHead) {
gen.writeMainOrGuideHead(value.main, "main")
writeMainOrGuideHead(value.main, "main")
} else if (value.guideHead != null) {
gen.writeMainOrGuideHead(value.guideHead!!, "guideHead")
writeMainOrGuideHead(value.guideHead!!, "guideHead")
}

gen.writeEndObject()
}

private fun JsonGenerator.writeMainOrGuideHead(camera: Camera, fieldName: String) {
writeObjectFieldStart(fieldName)
writeStringField("type", camera.type.name)
writeStringField("id", camera.id)
writeStringField("name", camera.name)
writeStringField("sender", camera.sender.id)
writeBooleanField("connected", camera.connected)
writeEndObject()
companion object {

@JvmStatic
private fun JsonGenerator.writeMainOrGuideHead(camera: Camera, fieldName: String) {
writeObjectFieldStart(fieldName)
writeStringField("type", camera.type.name)
writeStringField("id", camera.id)
writeStringField("name", camera.name)
writeStringField("sender", camera.sender.id)
writeBooleanField("connected", camera.connected)
writeEndObject()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package nebulosa.api.connection

import nebulosa.api.cameras.CameraEventHub
import nebulosa.api.dustcap.DustCapEventHub
import nebulosa.api.focusers.FocuserEventHub
import nebulosa.api.guiding.GuideOutputEventHub
import nebulosa.api.lightboxes.LightBoxEventHub
import nebulosa.api.mounts.MountEventHub
import nebulosa.api.rotators.RotatorEventHub
import nebulosa.api.wheels.WheelEventHub
import nebulosa.indi.device.DeviceConnectionEvent
import nebulosa.indi.device.DeviceEvent
import nebulosa.indi.device.DeviceEventHandler
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.dustcap.DustCap
import nebulosa.indi.device.filterwheel.FilterWheel
import nebulosa.indi.device.focuser.Focuser
import nebulosa.indi.device.guider.GuideOutput
import nebulosa.indi.device.lightbox.LightBox
import nebulosa.indi.device.mount.Mount
import nebulosa.indi.device.rotator.Rotator
import org.springframework.stereotype.Component
Expand All @@ -25,6 +29,8 @@ class ConnectionEventHub(
private val wheelEventHub: WheelEventHub,
private val guideOutputEventHub: GuideOutputEventHub,
private val rotatorEventHub: RotatorEventHub,
private val lightBoxEventHub: LightBoxEventHub,
private val dustCapEventHub: DustCapEventHub,
) : DeviceEventHandler.EventReceived {

override fun onEventReceived(event: DeviceEvent<*>) {
Expand All @@ -37,6 +43,8 @@ class ConnectionEventHub(
if (device is FilterWheel) wheelEventHub.onConnectionChanged(device)
if (device is Rotator) rotatorEventHub.onConnectionChanged(device)
if (device is GuideOutput) guideOutputEventHub.onConnectionChanged(device)
if (device is LightBox) lightBoxEventHub.onConnectionChanged(device)
if (device is DustCap) dustCapEventHub.onConnectionChanged(device)
}
}
}
36 changes: 36 additions & 0 deletions api/src/main/kotlin/nebulosa/api/connection/ConnectionService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import nebulosa.indi.device.Device
import nebulosa.indi.device.DeviceEventHandler
import nebulosa.indi.device.INDIDeviceProvider
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.dustcap.DustCap
import nebulosa.indi.device.filterwheel.FilterWheel
import nebulosa.indi.device.focuser.Focuser
import nebulosa.indi.device.gps.GPS
import nebulosa.indi.device.guider.GuideOutput
import nebulosa.indi.device.lightbox.LightBox
import nebulosa.indi.device.mount.Mount
import nebulosa.indi.device.rotator.Rotator
import nebulosa.indi.device.thermometer.Thermometer
Expand Down Expand Up @@ -134,6 +136,14 @@ class ConnectionService(
return providers[id]?.guideOutputs() ?: emptyList()
}

fun lightBoxes(id: String): Collection<LightBox> {
return providers[id]?.lightBoxes() ?: emptyList()
}

fun dustCaps(id: String): Collection<DustCap> {
return providers[id]?.dustCaps() ?: emptyList()
}

fun thermometers(id: String): Collection<Thermometer> {
return providers[id]?.thermometers() ?: emptyList()
}
Expand Down Expand Up @@ -166,6 +176,14 @@ class ConnectionService(
return providers.values.flatMap { it.guideOutputs() }
}

fun lightBoxes(): List<LightBox> {
return providers.values.flatMap { it.lightBoxes() }
}

fun dustCaps(): List<DustCap> {
return providers.values.flatMap { it.dustCaps() }
}

fun thermometers(): List<Thermometer> {
return providers.values.flatMap { it.thermometers() }
}
Expand Down Expand Up @@ -198,6 +216,14 @@ class ConnectionService(
return providers[id]?.guideOutput(name)
}

fun lightBox(id: String, name: String): LightBox? {
return providers[id]?.lightBox(name)
}

fun dustCap(id: String, name: String): DustCap? {
return providers[id]?.dustCap(name)
}

fun thermometer(id: String, name: String): Thermometer? {
return providers[id]?.thermometer(name)
}
Expand Down Expand Up @@ -230,6 +256,14 @@ class ConnectionService(
return providers.firstNotNullOfOrNull { it.value.guideOutput(name) }
}

fun lightBox(name: String): LightBox? {
return providers.firstNotNullOfOrNull { it.value.lightBox(name) }
}

fun dustCap(name: String): DustCap? {
return providers.firstNotNullOfOrNull { it.value.dustCap(name) }
}

fun thermometer(name: String): Thermometer? {
return providers.firstNotNullOfOrNull { it.value.thermometer(name) }
}
Expand All @@ -241,6 +275,8 @@ class ConnectionService(
?: wheel(name)
?: rotator(name)
?: guideOutput(name)
?: lightBox(name)
?: dustCap(name)
?: gps(name)
?: thermometer(name)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package nebulosa.api.beans.converters.device
package nebulosa.api.devices

import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.DeserializationContext
Expand Down
24 changes: 24 additions & 0 deletions api/src/main/kotlin/nebulosa/api/devices/DeviceSerializer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package nebulosa.api.devices

import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.ser.std.StdSerializer
import nebulosa.indi.device.Device

abstract class DeviceSerializer<T : Device>(type: Class<T>) : StdSerializer<T>(type) {

protected abstract fun JsonGenerator.serialize(value: T)

final override fun serialize(value: T, gen: JsonGenerator, provider: SerializerProvider) {
gen.writeStartObject()
gen.writeStringField("type", value.type.name)
gen.writeStringField("sender", value.sender.id)
gen.writeStringField("driverName", value.driverName)
gen.writeStringField("driverVersion", value.driverVersion)
gen.writeStringField("id", value.id)
gen.writeStringField("name", value.name)
gen.writeBooleanField("connected", value.connected)
gen.serialize(value)
gen.writeEndObject()
}
}
51 changes: 51 additions & 0 deletions api/src/main/kotlin/nebulosa/api/dustcap/DustCapController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package nebulosa.api.dustcap

import nebulosa.api.connection.ConnectionService
import nebulosa.indi.device.dustcap.DustCap
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("dust-caps")
class DustCapController(
private val connectionService: ConnectionService,
private val dustCapService: DustCapService,
) {

@GetMapping
fun dustCaps(): List<DustCap> {
return connectionService.dustCaps().sorted()
}

@GetMapping("{dustCap}")
fun dustCap(dustCap: DustCap): DustCap {
return dustCap
}

@PutMapping("{dustCap}/connect")
fun connect(dustCap: DustCap) {
dustCapService.connect(dustCap)
}

@PutMapping("{dustCap}/disconnect")
fun disconnect(dustCap: DustCap) {
dustCapService.disconnect(dustCap)
}

@PutMapping("{dustCap}/park")
fun park(dustCap: DustCap) {
dustCapService.park(dustCap)
}

@PutMapping("{dustCap}/unpark")
fun unpark(dustCap: DustCap) {
dustCapService.unpark(dustCap)
}

@PutMapping("{dustCap}/listen")
fun listen(dustCap: DustCap) {
dustCapService.listen(dustCap)
}
}
Loading

0 comments on commit 62015dd

Please sign in to comment.