(feature: &Feature)
| 686 | // ─── GlobalProfile Getter/Setter (0x26) ────────────────────────────────────── |
| 687 | |
| 688 | fn global_profile_get(feature: &Feature) -> f32 { |
| 689 | let bitmask = match feature.id { |
| 690 | FeatureId::SbxMaster => 0x01u8, |
| 691 | FeatureId::ScoutMode => 0x02u8, |
| 692 | _ => panic!("global_profile_get called on {:?}", feature.id), |
| 693 | }; |
| 694 | |
| 695 | debug!( |
| 696 | "Querying global profile: {} (bit 0x{:02x})", |
| 697 | feature.id, bitmask |
| 698 | ); |
| 699 | |
| 700 | let mut payload = [0u8; 65]; |
| 701 | payload[1] = 0x5a; |
| 702 | payload[2] = 0x26; |
| 703 | payload[3] = 0x03; |
| 704 | payload[4] = 0x08; |
| 705 | payload[5] = 0xff; |
| 706 | payload[6] = 0xff; |
| 707 | |
| 708 | DEVICE_CONNECTION |
| 709 | .get() |
| 710 | .expect("Device connection must be initialized") |
| 711 | .lock() |
| 712 | .unwrap() |
| 713 | .write(&payload) |
| 714 | .expect("Failed to send query to device"); |
| 715 | |
| 716 | for attempt in 0..MAX_READ_ATTEMPTS { |
| 717 | let Some(response) = read_packet() else { |
| 718 | error!( |
| 719 | "No response on attempt {}/{} for {}", |
| 720 | attempt + 1, |
| 721 | MAX_READ_ATTEMPTS, |
| 722 | feature.id |
| 723 | ); |
| 724 | continue; |
| 725 | }; |
| 726 | |
| 727 | // expected: 5a 26 0b 08 ff ff [bitmask] ... |
| 728 | if response[0] == 0x5a && response[1] == 0x26 { |
| 729 | let device_bitmask = response[6]; |
| 730 | let is_on = (device_bitmask & bitmask) != 0; |
| 731 | let value = if is_on { 1.0 } else { 0.0 }; |
| 732 | debug!( |
| 733 | "Read {} = {} (device bitmask: 0x{:02x})", |
| 734 | feature.id, value, device_bitmask |
| 735 | ); |
| 736 | *feature.value.lock().unwrap() = value; |
| 737 | return value; |
| 738 | } |
| 739 | |
| 740 | debug!( |
| 741 | "Discarded stale packet on attempt {}: {:02x?}", |
| 742 | attempt + 1, |
| 743 | &response[..12] |
| 744 | ); |
| 745 | } |
nothing calls this directly
no test coverage detected