feat: cif work
Some checks failed
Verify Latest Dependencies / Verify Latest Dependencies (push) Has been cancelled
build and test / wxbox - latest (push) Has been cancelled

This commit is contained in:
core 2025-05-19 23:01:29 -04:00
parent 182252e209
commit d7c84d60e8
Signed by: core
GPG key ID: FDBF740DADDCEECF
8 changed files with 119 additions and 299 deletions

1
Cargo.lock generated
View file

@ -3630,6 +3630,7 @@ version = "0.1.0"
dependencies = [
"capnp",
"capnpc",
"nexrad-decode",
"wxbox-ar2",
]

View file

@ -5,11 +5,13 @@ edition = "2024"
[dependencies]
capnp = "0.20"
wxbox-ar2 = { path = "../ar2", optional = true }
nexrad-decode = { path = "../nexrad-decode", optional = true }
[features]
default = []
ar2 = ["dep:wxbox-ar2"]
ar2 = ["dep:wxbox-ar2", "dep:nexrad-decode"]
[build-dependencies]
capnpc = "0.20"

View file

@ -19,10 +19,7 @@ struct Radial {
elevationNumber @5 :UInt8;
elevationDegrees @6 :Float32;
requestedProduct :union {
unavailable @7 :Void;
available @8 :MomentaryProduct;
}
requestedProduct @7 :MomentaryProduct;
}
enum RadialStatus {

View file

@ -1,5 +1,7 @@
use wxbox_ar2::Scan;
pub fn serialize_scan_to_cif_message(scan: &Scan, elevation_number: u8) -> Vec<u8> {
use std::io::Cursor;
use nexrad_decode::messages::digital_radar_data::RadialStatus;
use wxbox_ar2::{MomentData, Radial, Scan};
pub fn serialize_scan_to_cif_message(scan: &Scan, elevation_number: u8, requested_product: &str) -> Vec<u8> {
let mut message = capnp::message::Builder::new_default();
let cif_message = message.init_root::<crate::schema_capnp::message::Builder>();
let mut digital_radar_data = cif_message.init_digital_radar_data();
@ -10,10 +12,72 @@ pub fn serialize_scan_to_cif_message(scan: &Scan, elevation_number: u8) -> Vec<u
// find the elevation the user requested
let maybe_elevation = scan.sweeps.iter().find(|u| u.elevation_number == elevation_number);
if let Some(elevation) = maybe_elevation {
// parse out the radials
let mut radials_we_can_use: Vec<(&Radial, &MomentData)> = vec![];
for radial in &elevation.radials {
match requested_product {
"REF" if radial.reflectivity.is_some() => {
radials_we_can_use.push((&radial, &radial.reflectivity.as_ref().unwrap()));
},
"VEL" if radial.velocity.is_some() => {
radials_we_can_use.push((&radial, &radial.velocity.as_ref().unwrap()));
},
"SW" if radial.spectrum_width.is_some() => {
radials_we_can_use.push((&radial, &radial.spectrum_width.as_ref().unwrap()));
},
"ZDR" if radial.differential_reflectivity.is_some() => {
radials_we_can_use.push((&radial, &radial.differential_reflectivity.as_ref().unwrap()));
},
"PHI" if radial.differential_phase.is_some() => {
radials_we_can_use.push((&radial, &radial.differential_phase.as_ref().unwrap()));
},
"RHO" if radial.correlation_coefficient.is_some() => {
radials_we_can_use.push((&radial, &radial.correlation_coefficient.as_ref().unwrap()));
},
"CFP" if radial.specific_differential_phase.is_some() => {
radials_we_can_use.push((&radial, &radial.specific_differential_phase.as_ref().unwrap()));
},
_ => {}
}
}
let mut radials = digital_radar_data.reborrow().init_radials(radials_we_can_use.len() as u32);
for (number, (radial, data)) in radials_we_can_use.iter().enumerate() {
let mut this_radial_msg = radials.reborrow().get(number as u32);
this_radial_msg.set_collection_timestamp(radial.collection_timestamp);
this_radial_msg.set_azimuth_number(radial.azimuth_number);
this_radial_msg.set_azimuth_angle_degrees(radial.azimuth_angle_degrees);
this_radial_msg.set_azimuth_spacing_degrees(radial.azimuth_spacing_degrees);
this_radial_msg.set_elevation_number(radial.elevation_number);
this_radial_msg.set_elevation_degrees(radial.elevation_number_degrees);
this_radial_msg.set_radial_status(match radial.radial_status {
RadialStatus::ElevationStart => crate::digitalRadarData_capnp::RadialStatus::ElevationStart,
RadialStatus::IntermediateRadialData => crate::digitalRadarData_capnp::RadialStatus::IntermediateRadialData,
RadialStatus::ElevationEnd => crate::digitalRadarData_capnp::RadialStatus::ElevationEnd,
RadialStatus::VolumeScanStart => crate::digitalRadarData_capnp::RadialStatus::VolumeScanStart,
RadialStatus::VolumeScanEnd => crate::digitalRadarData_capnp::RadialStatus::VolumeScanEnd,
RadialStatus::ElevationStartVCPFinal => crate::digitalRadarData_capnp::RadialStatus::ElevationStartVCPFinal,
});
let mut msg_requested_product = this_radial_msg.reborrow().init_requested_product();
let mut product_metadata = msg_requested_product.reborrow().init_product_metadata();
product_metadata.set_product_name(requested_product);
let mut momentary_product_data = msg_requested_product.reborrow().init_data();
momentary_product_data.set_scale(data.scale);
momentary_product_data.set_offset(data.offset);
momentary_product_data.set_start_range(data.start_range);
momentary_product_data.set_sample_interval(data.sample_interval);
momentary_product_data.set_values(&*data.values).unwrap();
}
} else {
digital_radar_data.reborrow().init_radials(0); // no elevation is signalled by an empty radials field
}
todo!()
let mut output = Cursor::new(Vec::new());
capnp::serialize_packed::write_message(&mut output, &message).unwrap();
output.into_inner()
}

View file

@ -364,8 +364,12 @@ pub mod radial {
self.reader.get_data_field::<f32>(6)
}
#[inline]
pub fn get_requested_product(self) -> crate::digitalRadarData_capnp::radial::requested_product::Reader<'a> {
self.reader.into()
pub fn get_requested_product(self) -> ::capnp::Result<crate::digitalRadarData_capnp::momentary_product::Reader<'a>> {
::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None)
}
#[inline]
pub fn has_requested_product(&self) -> bool {
!self.reader.get_pointer_field(0).is_null()
}
}
@ -478,14 +482,20 @@ pub mod radial {
self.builder.set_data_field::<f32>(6, value);
}
#[inline]
pub fn get_requested_product(self) -> crate::digitalRadarData_capnp::radial::requested_product::Builder<'a> {
self.builder.into()
pub fn get_requested_product(self) -> ::capnp::Result<crate::digitalRadarData_capnp::momentary_product::Builder<'a>> {
::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None)
}
#[inline]
pub fn init_requested_product(mut self, ) -> crate::digitalRadarData_capnp::radial::requested_product::Builder<'a> {
self.builder.set_data_field::<u16>(11, 0);
self.builder.reborrow().get_pointer_field(0).clear();
self.builder.into()
pub fn set_requested_product(&mut self, value: crate::digitalRadarData_capnp::momentary_product::Reader<'_>) -> ::capnp::Result<()> {
::capnp::traits::SetterInput::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false)
}
#[inline]
pub fn init_requested_product(self, ) -> crate::digitalRadarData_capnp::momentary_product::Builder<'a> {
::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), 0)
}
#[inline]
pub fn has_requested_product(&self) -> bool {
!self.builder.is_pointer_field_null(0)
}
}
@ -496,19 +506,19 @@ pub mod radial {
}
}
impl Pipeline {
pub fn get_requested_product(&self) -> crate::digitalRadarData_capnp::radial::requested_product::Pipeline {
::capnp::capability::FromTypelessPipeline::new(self._typeless.noop())
pub fn get_requested_product(&self) -> crate::digitalRadarData_capnp::momentary_product::Pipeline {
::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(0))
}
}
mod _private {
pub static ENCODED_NODE: [::capnp::Word; 145] = [
pub static ENCODED_NODE: [::capnp::Word; 152] = [
::capnp::word(0, 0, 0, 0, 6, 0, 6, 0),
::capnp::word(52, 61, 253, 131, 10, 228, 32, 210),
::capnp::word(23, 0, 0, 0, 1, 0, 4, 0),
::capnp::word(138, 240, 108, 5, 28, 207, 29, 249),
::capnp::word(1, 0, 7, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(145, 0, 0, 0, 1, 2, 0, 0),
::capnp::word(145, 0, 0, 0, 194, 1, 0, 0),
::capnp::word(21, 0, 0, 0, 242, 0, 0, 0),
::capnp::word(33, 0, 0, 0, 7, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
@ -571,12 +581,12 @@ pub mod radial {
::capnp::word(16, 1, 0, 0, 3, 0, 1, 0),
::capnp::word(28, 1, 0, 0, 2, 0, 1, 0),
::capnp::word(7, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(1, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(53, 153, 198, 6, 37, 147, 62, 245),
::capnp::word(0, 0, 1, 0, 7, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(25, 1, 0, 0, 138, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(28, 1, 0, 0, 3, 0, 1, 0),
::capnp::word(40, 1, 0, 0, 2, 0, 1, 0),
::capnp::word(99, 111, 108, 108, 101, 99, 116, 105),
::capnp::word(111, 110, 84, 105, 109, 101, 115, 116),
::capnp::word(97, 109, 112, 0, 0, 0, 0, 0),
@ -647,6 +657,13 @@ pub mod radial {
::capnp::word(114, 101, 113, 117, 101, 115, 116, 101),
::capnp::word(100, 80, 114, 111, 100, 117, 99, 116),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(16, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(145, 161, 46, 18, 18, 53, 76, 181),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(16, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
];
pub fn get_field_types(index: u16) -> ::capnp::introspect::Type {
match index {
@ -657,7 +674,7 @@ pub mod radial {
4 => <crate::digitalRadarData_capnp::RadialStatus as ::capnp::introspect::Introspect>::introspect(),
5 => <u8 as ::capnp::introspect::Introspect>::introspect(),
6 => <f32 as ::capnp::introspect::Introspect>::introspect(),
7 => <crate::digitalRadarData_capnp::radial::requested_product::Owned as ::capnp::introspect::Introspect>::introspect(),
7 => <crate::digitalRadarData_capnp::momentary_product::Owned as ::capnp::introspect::Introspect>::introspect(),
_ => panic!("invalid field index {}", index),
}
}
@ -675,273 +692,6 @@ pub mod radial {
pub static MEMBERS_BY_NAME : &[u16] = &[2,1,3,0,6,5,4,7];
pub const TYPE_ID: u64 = 0xd220_e40a_83fd_3d34;
}
pub mod requested_product {
pub use self::Which::{Unavailable,Available};
#[derive(Copy, Clone)]
pub struct Owned(());
impl ::capnp::introspect::Introspect for Owned { fn introspect() -> ::capnp::introspect::Type { ::capnp::introspect::TypeVariant::Struct(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types, annotation_types: _private::get_annotation_types }).into() } }
impl ::capnp::traits::Owned for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; }
impl ::capnp::traits::OwnedStruct for Owned { type Reader<'a> = Reader<'a>; type Builder<'a> = Builder<'a>; }
impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; }
pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> }
impl <> ::core::marker::Copy for Reader<'_,> {}
impl <> ::core::clone::Clone for Reader<'_,> {
fn clone(&self) -> Self { *self }
}
impl <> ::capnp::traits::HasTypeId for Reader<'_,> {
const TYPE_ID: u64 = _private::TYPE_ID;
}
impl <'a,> ::core::convert::From<::capnp::private::layout::StructReader<'a>> for Reader<'a,> {
fn from(reader: ::capnp::private::layout::StructReader<'a>) -> Self {
Self { reader, }
}
}
impl <'a,> ::core::convert::From<Reader<'a,>> for ::capnp::dynamic_value::Reader<'a> {
fn from(reader: Reader<'a,>) -> Self {
Self::Struct(::capnp::dynamic_struct::Reader::new(reader.reader, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>})))
}
}
impl <> ::core::fmt::Debug for Reader<'_,> {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::result::Result<(), ::core::fmt::Error> {
core::fmt::Debug::fmt(&::core::convert::Into::<::capnp::dynamic_value::Reader<'_>>::into(*self), f)
}
}
impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> {
fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result<Self> {
::core::result::Result::Ok(reader.get_struct(default)?.into())
}
}
impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> {
fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> {
self.reader
}
}
impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> {
fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) {
self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table))
}
}
impl <'a,> Reader<'a,> {
pub fn reborrow(&self) -> Reader<'_,> {
Self { .. *self }
}
pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
self.reader.total_size()
}
#[inline]
pub fn has_available(&self) -> bool {
if self.reader.get_data_field::<u16>(11) != 1 { return false; }
!self.reader.get_pointer_field(0).is_null()
}
#[inline]
pub fn which(self) -> ::core::result::Result<WhichReader<'a,>, ::capnp::NotInSchema> {
match self.reader.get_data_field::<u16>(11) {
0 => {
::core::result::Result::Ok(Unavailable(
()
))
}
1 => {
::core::result::Result::Ok(Available(
::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None)
))
}
x => ::core::result::Result::Err(::capnp::NotInSchema(x))
}
}
}
pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> }
impl <> ::capnp::traits::HasStructSize for Builder<'_,> {
const STRUCT_SIZE: ::capnp::private::layout::StructSize = ::capnp::private::layout::StructSize { data: 4, pointers: 1 };
}
impl <> ::capnp::traits::HasTypeId for Builder<'_,> {
const TYPE_ID: u64 = _private::TYPE_ID;
}
impl <'a,> ::core::convert::From<::capnp::private::layout::StructBuilder<'a>> for Builder<'a,> {
fn from(builder: ::capnp::private::layout::StructBuilder<'a>) -> Self {
Self { builder, }
}
}
impl <'a,> ::core::convert::From<Builder<'a,>> for ::capnp::dynamic_value::Builder<'a> {
fn from(builder: Builder<'a,>) -> Self {
Self::Struct(::capnp::dynamic_struct::Builder::new(builder.builder, ::capnp::schema::StructSchema::new(::capnp::introspect::RawBrandedStructSchema { generic: &_private::RAW_SCHEMA, field_types: _private::get_field_types::<>, annotation_types: _private::get_annotation_types::<>})))
}
}
impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> {
fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) {
self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table))
}
}
impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> {
fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Self {
builder.init_struct(<Self as ::capnp::traits::HasStructSize>::STRUCT_SIZE).into()
}
fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [::capnp::Word]>) -> ::capnp::Result<Self> {
::core::result::Result::Ok(builder.get_struct(<Self as ::capnp::traits::HasStructSize>::STRUCT_SIZE, default)?.into())
}
}
impl <> ::capnp::traits::SetterInput<Owned<>> for Reader<'_,> {
fn set_pointer_builder(mut pointer: ::capnp::private::layout::PointerBuilder<'_>, value: Self, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) }
}
impl <'a,> Builder<'a,> {
pub fn into_reader(self) -> Reader<'a,> {
self.builder.into_reader().into()
}
pub fn reborrow(&mut self) -> Builder<'_,> {
Builder { builder: self.builder.reborrow() }
}
pub fn reborrow_as_reader(&self) -> Reader<'_,> {
self.builder.as_reader().into()
}
pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> {
self.builder.as_reader().total_size()
}
#[inline]
pub fn set_unavailable(&mut self, _value: ()) {
self.builder.set_data_field::<u16>(11, 0);
}
#[inline]
pub fn set_available(&mut self, value: crate::digitalRadarData_capnp::momentary_product::Reader<'_>) -> ::capnp::Result<()> {
self.builder.set_data_field::<u16>(11, 1);
::capnp::traits::SetterInput::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false)
}
#[inline]
pub fn init_available(self, ) -> crate::digitalRadarData_capnp::momentary_product::Builder<'a> {
self.builder.set_data_field::<u16>(11, 1);
::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(0), 0)
}
#[inline]
pub fn has_available(&self) -> bool {
if self.builder.get_data_field::<u16>(11) != 1 { return false; }
!self.builder.is_pointer_field_null(0)
}
#[inline]
pub fn which(self) -> ::core::result::Result<WhichBuilder<'a,>, ::capnp::NotInSchema> {
match self.builder.get_data_field::<u16>(11) {
0 => {
::core::result::Result::Ok(Unavailable(
()
))
}
1 => {
::core::result::Result::Ok(Available(
::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None)
))
}
x => ::core::result::Result::Err(::capnp::NotInSchema(x))
}
}
}
pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline }
impl ::capnp::capability::FromTypelessPipeline for Pipeline {
fn new(typeless: ::capnp::any_pointer::Pipeline) -> Self {
Self { _typeless: typeless, }
}
}
impl Pipeline {
}
mod _private {
pub static ENCODED_NODE: [::capnp::Word; 52] = [
::capnp::word(0, 0, 0, 0, 6, 0, 6, 0),
::capnp::word(53, 153, 198, 6, 37, 147, 62, 245),
::capnp::word(30, 0, 0, 0, 1, 0, 4, 0),
::capnp::word(52, 61, 253, 131, 10, 228, 32, 210),
::capnp::word(1, 0, 7, 0, 1, 0, 2, 0),
::capnp::word(11, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(21, 0, 0, 0, 122, 1, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(33, 0, 0, 0, 119, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(100, 105, 103, 105, 116, 97, 108, 82),
::capnp::word(97, 100, 97, 114, 68, 97, 116, 97),
::capnp::word(46, 99, 97, 112, 110, 112, 58, 82),
::capnp::word(97, 100, 105, 97, 108, 46, 114, 101),
::capnp::word(113, 117, 101, 115, 116, 101, 100, 80),
::capnp::word(114, 111, 100, 117, 99, 116, 0, 0),
::capnp::word(8, 0, 0, 0, 3, 0, 4, 0),
::capnp::word(0, 0, 255, 255, 0, 0, 0, 0),
::capnp::word(0, 0, 1, 0, 7, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(41, 0, 0, 0, 98, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(40, 0, 0, 0, 3, 0, 1, 0),
::capnp::word(52, 0, 0, 0, 2, 0, 1, 0),
::capnp::word(1, 0, 254, 255, 0, 0, 0, 0),
::capnp::word(0, 0, 1, 0, 8, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(49, 0, 0, 0, 82, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(48, 0, 0, 0, 3, 0, 1, 0),
::capnp::word(60, 0, 0, 0, 2, 0, 1, 0),
::capnp::word(117, 110, 97, 118, 97, 105, 108, 97),
::capnp::word(98, 108, 101, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(97, 118, 97, 105, 108, 97, 98, 108),
::capnp::word(101, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(16, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(145, 161, 46, 18, 18, 53, 76, 181),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(16, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
];
pub fn get_field_types(index: u16) -> ::capnp::introspect::Type {
match index {
0 => <() as ::capnp::introspect::Introspect>::introspect(),
1 => <crate::digitalRadarData_capnp::momentary_product::Owned as ::capnp::introspect::Introspect>::introspect(),
_ => panic!("invalid field index {}", index),
}
}
pub fn get_annotation_types(child_index: Option<u16>, index: u32) -> ::capnp::introspect::Type {
panic!("invalid annotation indices ({:?}, {}) ", child_index, index)
}
pub static RAW_SCHEMA: ::capnp::introspect::RawStructSchema = ::capnp::introspect::RawStructSchema {
encoded_node: &ENCODED_NODE,
nonunion_members: NONUNION_MEMBERS,
members_by_discriminant: MEMBERS_BY_DISCRIMINANT,
members_by_name: MEMBERS_BY_NAME,
};
pub static NONUNION_MEMBERS : &[u16] = &[];
pub static MEMBERS_BY_DISCRIMINANT : &[u16] = &[0,1];
pub static MEMBERS_BY_NAME : &[u16] = &[1,0];
pub const TYPE_ID: u64 = 0xf53e_9325_06c6_9935;
}
pub enum Which<A0> {
Unavailable(()),
Available(A0),
}
pub type WhichReader<'a,> = Which<::capnp::Result<crate::digitalRadarData_capnp::momentary_product::Reader<'a>>>;
pub type WhichBuilder<'a,> = Which<::capnp::Result<crate::digitalRadarData_capnp::momentary_product::Builder<'a>>>;
}
}
#[repr(u16)]
@ -990,7 +740,7 @@ pub static ENCODED_NODE: [::capnp::Word; 52] = [
::capnp::word(138, 240, 108, 5, 28, 207, 29, 249),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(3, 2, 0, 0, 224, 2, 0, 0),
::capnp::word(196, 1, 0, 0, 161, 2, 0, 0),
::capnp::word(21, 0, 0, 0, 34, 1, 0, 0),
::capnp::word(37, 0, 0, 0, 7, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
@ -1229,7 +979,7 @@ pub mod momentary_product {
::capnp::word(138, 240, 108, 5, 28, 207, 29, 249),
::capnp::word(2, 0, 7, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(226, 2, 0, 0, 78, 3, 0, 0),
::capnp::word(163, 2, 0, 0, 15, 3, 0, 0),
::capnp::word(21, 0, 0, 0, 66, 1, 0, 0),
::capnp::word(37, 0, 0, 0, 7, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
@ -1455,7 +1205,7 @@ pub mod momentary_product_meta {
::capnp::word(138, 240, 108, 5, 28, 207, 29, 249),
::capnp::word(1, 0, 7, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(80, 3, 0, 0, 137, 3, 0, 0),
::capnp::word(17, 3, 0, 0, 74, 3, 0, 0),
::capnp::word(21, 0, 0, 0, 98, 1, 0, 0),
::capnp::word(41, 0, 0, 0, 7, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
@ -1714,7 +1464,7 @@ pub mod momentary_product_data {
::capnp::word(138, 240, 108, 5, 28, 207, 29, 249),
::capnp::word(1, 0, 7, 0, 0, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),
::capnp::word(138, 3, 0, 0, 48, 4, 0, 0),
::capnp::word(75, 3, 0, 0, 241, 3, 0, 0),
::capnp::word(21, 0, 0, 0, 98, 1, 0, 0),
::capnp::word(41, 0, 0, 0, 7, 0, 0, 0),
::capnp::word(0, 0, 0, 0, 0, 0, 0, 0),

View file

@ -5,5 +5,5 @@ pub mod digitalRadarData_capnp;
#[allow(non_snake_case)]
pub mod tilerStatusReport_capnp;
#[cfg(feature = ar2)]
#[cfg(feature = "ar2")]
pub mod ar2;

View file

@ -46,4 +46,4 @@ wxbox-common = { path = "../common" }
chrono = "0.4"
quick-xml = { version = "0.37", features = ["serialize"] }
wxbox-interchange = { path = "../interchange" }
wxbox-interchange = { path = "../interchange", features = ["ar2"] }

View file

@ -24,6 +24,7 @@ use std::sync::Arc;
use tracing::{debug, info_span};
use wxbox_ar2::sites::wsr88d::{SITES, Wsr88dSite};
use wxbox_ar2::{MomentValue, Radial, Scan, Sweep, parse};
use wxbox_interchange::ar2::serialize_scan_to_cif_message;
use wxbox_pal::ColorPalette;
pub type NexradDataCache = Cache<DataId, Arc<wxbox_ar2::Scan>>;
@ -126,7 +127,12 @@ pub async fn nexrad_data_handler(
state.nexrad_data_cache.get(&data_id).await.unwrap()
};
todo!()
Ok((
[(header::CONTENT_TYPE, "application/wxbox-common-interchange-format")],
serialize_scan_to_cif_message(&data, sweep, &product),
))
}
async fn load_nexrad_data(