| 737 | } |
| 738 | |
| 739 | async fn get_metrics( |
| 740 | &self, |
| 741 | request: Request<api::GetDeviceMetricsRequest>, |
| 742 | ) -> Result<Response<api::GetDeviceMetricsResponse>, Status> { |
| 743 | let req = request.get_ref(); |
| 744 | let dev_eui = EUI64::from_str(&req.dev_eui).map_err(|e| e.status())?; |
| 745 | |
| 746 | self.validator |
| 747 | .validate( |
| 748 | request.extensions(), |
| 749 | validator::ValidateDeviceAccess::new(validator::Flag::Read, dev_eui), |
| 750 | ) |
| 751 | .await?; |
| 752 | |
| 753 | let start = SystemTime::try_from( |
| 754 | *req.start |
| 755 | .as_ref() |
| 756 | .ok_or_else(|| anyhow!("start is None")) |
| 757 | .map_err(|e| e.status())?, |
| 758 | ) |
| 759 | .map_err(|e| e.status())?; |
| 760 | |
| 761 | let end = SystemTime::try_from( |
| 762 | *req.end |
| 763 | .as_ref() |
| 764 | .ok_or_else(|| anyhow!("end is None")) |
| 765 | .map_err(|e| e.status())?, |
| 766 | ) |
| 767 | .map_err(|e| e.status())?; |
| 768 | |
| 769 | let start: DateTime<Local> = start.into(); |
| 770 | let end: DateTime<Local> = end.into(); |
| 771 | let aggregation = req.aggregation().from_proto(); |
| 772 | |
| 773 | let dev = device::get(&dev_eui).await.map_err(|e| e.status())?; |
| 774 | let dp = device_profile::get(&dev.device_profile_id) |
| 775 | .await |
| 776 | .map_err(|e| e.status())?; |
| 777 | |
| 778 | let mut out = api::GetDeviceMetricsResponse { |
| 779 | ..Default::default() |
| 780 | }; |
| 781 | |
| 782 | for (k, v) in dp.measurements.iter() { |
| 783 | match v.kind { |
| 784 | fields::MeasurementKind::UNKNOWN => { |
| 785 | continue; |
| 786 | } |
| 787 | fields::MeasurementKind::STRING => { |
| 788 | out.states.insert( |
| 789 | k.to_string(), |
| 790 | api::DeviceState { |
| 791 | name: v.name.to_string(), |
| 792 | value: metrics::get_state(&format!("device:{}:{}", dev.dev_eui, k)) |
| 793 | .await |
| 794 | .map_err(|e| e.status())?, |
| 795 | }, |
| 796 | ); |