Skip to content

Instantly share code, notes, and snippets.

@jschoch
Created March 8, 2026 19:47
Show Gist options
  • Select an option

  • Save jschoch/c50f8a082f6ccb75894850bfa649ec26 to your computer and use it in GitHub Desktop.

Select an option

Save jschoch/c50f8a082f6ccb75894850bfa649ec26 to your computer and use it in GitHub Desktop.
Swing #1 OCR → {'captured_at': '2026-03-08T18:43:10.708682+00:00', 'metrics': {'angle_of_attack_deg': -5.67, 'carry_yd': 64.1, 'efficiency': 1.07, 'hla_deg': 16.0, 'launch_deg': 9.3, 'path_deg': 2.38, 'speed_mph': 82.7, 'spin_axis_deg': None, 'spin_rpm': 6475}, 'source': 'gc2', 'swing_id': 'pair-000001'}
GSPro connected to 192.168.1.220:49152
GSPro shot #1 → {'Code': 200}
Swing #2 OCR → {'captured_at': '2026-03-08T18:43:18.253538+00:00', 'metrics': {'angle_of_attack_deg': -5.67, 'carry_yd': 64.1, 'efficiency': 1.07, 'hla_deg': 16.0, 'launch_deg': 9.3, 'path_deg': 2.38, 'speed_mph': 82.7, 'spin_axis_deg': None, 'spin_rpm': 6475}, 'source': 'gc2', 'swing_id': 'pair-000002'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #3 OCR → {'captured_at': '2026-03-08T18:43:56.594099+00:00', 'metrics': {'angle_of_attack_deg': -5.67, 'carry_yd': None, 'efficiency': 1.07, 'hla_deg': -9.0, 'launch_deg': 20.3, 'path_deg': 2.38, 'speed_mph': 82.5, 'spin_axis_deg': 5.67, 'spin_rpm': None}, 'source': 'gc2', 'swing_id': 'pair-000003'}
GSPro: skipping send — missing required fields: ['carry_yd']
Swing #4 OCR → {'captured_at': '2026-03-08T18:44:02.059274+00:00', 'metrics': {'angle_of_attack_deg': -5.31, 'carry_yd': 101.0, 'efficiency': 1.27, 'hla_deg': -0.9, 'launch_deg': 20.3, 'path_deg': 3.86, 'speed_mph': 82.5, 'spin_axis_deg': -10.0, 'spin_rpm': 6874}, 'source': 'gc2', 'swing_id': 'pair-000004'}
GSPro shot #2 → {'Code': 200}
Swing #5 OCR → {'captured_at': '2026-03-08T18:44:10.774741+00:00', 'metrics': {'angle_of_attack_deg': -5.31, 'carry_yd': 101.0, 'efficiency': 1.27, 'hla_deg': -0.9, 'launch_deg': 20.3, 'path_deg': 3.86, 'speed_mph': 82.5, 'spin_axis_deg': -10.0, 'spin_rpm': 6874}, 'source': 'gc2', 'swing_id': 'pair-000005'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #6 OCR → {'captured_at': '2026-03-08T18:44:18.295620+00:00', 'metrics': {'angle_of_attack_deg': -5.31, 'carry_yd': 101.0, 'efficiency': 1.27, 'hla_deg': -0.9, 'launch_deg': 20.3, 'path_deg': 3.86, 'speed_mph': 82.5, 'spin_axis_deg': -10.0, 'spin_rpm': 6874}, 'source': 'gc2', 'swing_id': 'pair-000006'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #7 OCR → {'captured_at': '2026-03-08T18:44:38.103686+00:00', 'metrics': {'angle_of_attack_deg': -5.31, 'carry_yd': 101.0, 'efficiency': 1.27, 'hla_deg': -0.9, 'launch_deg': 20.3, 'path_deg': 3.86, 'speed_mph': 82.5, 'spin_axis_deg': -10.0, 'spin_rpm': 6874}, 'source': 'gc2', 'swing_id': 'pair-000007'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #8 OCR → {'captured_at': '2026-03-08T18:44:43.501693+00:00', 'metrics': {'angle_of_attack_deg': -5.31, 'carry_yd': 101.0, 'efficiency': 1.27, 'hla_deg': -0.9, 'launch_deg': 20.3, 'path_deg': 3.86, 'speed_mph': 82.5, 'spin_axis_deg': -10.0, 'spin_rpm': 6874}, 'source': 'gc2', 'swing_id': 'pair-000008'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #9 OCR → {'captured_at': '2026-03-08T18:45:42.428773+00:00', 'metrics': {'angle_of_attack_deg': -5.31, 'carry_yd': 95.3, 'efficiency': 1.27, 'hla_deg': -2.4, 'launch_deg': None, 'path_deg': 3.86, 'speed_mph': 78.4, 'spin_axis_deg': -1.0, 'spin_rpm': 6099}, 'source': 'gc2', 'swing_id': 'pair-000009'}
GSPro shot #3 → {'Code': 200}
Swing #10 OCR → {'captured_at': '2026-03-08T18:46:01.055815+00:00', 'metrics': {'angle_of_attack_deg': -4.94, 'carry_yd': 95.3, 'efficiency': 1.09, 'hla_deg': -2.4, 'launch_deg': None, 'path_deg': -1.76, 'speed_mph': 78.4, 'spin_axis_deg': -1.0, 'spin_rpm': 6099}, 'source': 'gc2', 'swing_id': 'pair-000010'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #11 OCR → {'captured_at': '2026-03-08T18:46:24.783265+00:00', 'metrics': {'angle_of_attack_deg': -6.52, 'carry_yd': 111.0, 'efficiency': 1.24, 'hla_deg': -1.7, 'launch_deg': 20.4, 'path_deg': 0.78, 'speed_mph': 88.0, 'spin_axis_deg': -2.0, 'spin_rpm': 7449}, 'source': 'gc2', 'swing_id': 'pair-000011'}
GSPro shot #4 → {'Code': 200}
Swing #12 OCR → {'captured_at': '2026-03-08T18:46:29.021620+00:00', 'metrics': {'angle_of_attack_deg': -6.52, 'carry_yd': 111.0, 'efficiency': 1.24, 'hla_deg': -1.7, 'launch_deg': 20.4, 'path_deg': 0.78, 'speed_mph': 88.0, 'spin_axis_deg': -2.0, 'spin_rpm': 7449}, 'source': 'gc2', 'swing_id': 'pair-000012'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #13 OCR → {'captured_at': '2026-03-08T18:48:55.500374+00:00', 'metrics': {'angle_of_attack_deg': -6.33, 'carry_yd': 116.0, 'efficiency': 1.21, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': -0.13, 'speed_mph': 90.7, 'spin_axis_deg': 3.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000013'}
GSPro send error (attempt 1): Expecting value: line 1 column 1 (char 0)
GSPro send error (attempt 2): timed out
Swing #14 OCR → {'captured_at': '2026-03-08T18:49:13.628219+00:00', 'metrics': {'angle_of_attack_deg': -6.33, 'carry_yd': 116.0, 'efficiency': 1.21, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': -0.13, 'speed_mph': 90.7, 'spin_axis_deg': 3.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000014'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #15 OCR → {'captured_at': '2026-03-08T18:50:48.092763+00:00', 'metrics': {'angle_of_attack_deg': -6.33, 'carry_yd': 116.0, 'efficiency': 1.21, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': -0.13, 'speed_mph': 90.7, 'spin_axis_deg': 3.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000015'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #16 OCR → {'captured_at': '2026-03-08T18:50:53.689292+00:00', 'metrics': {'angle_of_attack_deg': -6.33, 'carry_yd': 116.0, 'efficiency': 1.21, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': -0.13, 'speed_mph': 90.7, 'spin_axis_deg': 3.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000016'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #17 OCR → {'captured_at': '2026-03-08T18:51:13.243503+00:00', 'metrics': {'angle_of_attack_deg': -6.33, 'carry_yd': 116.0, 'efficiency': 1.21, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': -0.13, 'speed_mph': 90.7, 'spin_axis_deg': 3.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000017'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #18 OCR → {'captured_at': '2026-03-08T18:51:28.517630+00:00', 'metrics': {'angle_of_attack_deg': -6.33, 'carry_yd': 116.0, 'efficiency': 1.21, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': -0.13, 'speed_mph': 90.7, 'spin_axis_deg': 3.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000018'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #19 OCR → {'captured_at': '2026-03-08T18:51:49.168865+00:00', 'metrics': {'angle_of_attack_deg': -6.33, 'carry_yd': 116.0, 'efficiency': 1.21, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': -0.13, 'speed_mph': 90.7, 'spin_axis_deg': 30.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000019'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #20 OCR → {'captured_at': '2026-03-08T18:51:52.353555+00:00', 'metrics': {'angle_of_attack_deg': -6.33, 'carry_yd': 116.0, 'efficiency': 1.21, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': -0.13, 'speed_mph': 90.7, 'spin_axis_deg': 30.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000020'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #21 OCR → {'captured_at': '2026-03-08T18:53:23.052019+00:00', 'metrics': {'angle_of_attack_deg': None, 'carry_yd': 116.0, 'efficiency': None, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': None, 'speed_mph': 90.7, 'spin_axis_deg': 3.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000021'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #22 OCR → {'captured_at': '2026-03-08T18:53:29.755234+00:00', 'metrics': {'angle_of_attack_deg': -6.33, 'carry_yd': 116.0, 'efficiency': 1.21, 'hla_deg': 0.1, 'launch_deg': 22.5, 'path_deg': -0.13, 'speed_mph': 90.7, 'spin_axis_deg': 3.0, 'spin_rpm': 8275}, 'source': 'gc2', 'swing_id': 'pair-000022'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #23 OCR → {'captured_at': '2026-03-08T18:58:12.796607+00:00', 'metrics': {'angle_of_attack_deg': -3.5, 'carry_yd': 74.1, 'efficiency': 1.27, 'hla_deg': -3.4, 'launch_deg': 22.6, 'path_deg': 1.29, 'speed_mph': 67.8, 'spin_axis_deg': -13.0, 'spin_rpm': 4200}, 'source': 'gc2', 'swing_id': 'pair-000023'}
GSPro connected to 192.168.1.220:49152
GSPro shot #5 → {'Code': 200}
Swing #24 OCR → {'captured_at': '2026-03-08T18:58:27.844170+00:00', 'metrics': {'angle_of_attack_deg': -3.5, 'carry_yd': 74.1, 'efficiency': 1.27, 'hla_deg': -3.4, 'launch_deg': 22.6, 'path_deg': 1.29, 'speed_mph': 67.8, 'spin_axis_deg': -13.0, 'spin_rpm': 4200}, 'source': 'gc2', 'swing_id': 'pair-000024'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #25 OCR → {'captured_at': '2026-03-08T18:58:38.632146+00:00', 'metrics': {'angle_of_attack_deg': -7.22, 'carry_yd': 96.0, 'efficiency': 1.1, 'hla_deg': 0.2, 'launch_deg': 20.4, 'path_deg': -0.68, 'speed_mph': 80.6, 'spin_axis_deg': 14.0, 'spin_rpm': 7700}, 'source': 'gc2', 'swing_id': 'pair-000025'}
GSPro shot #6 → {'Code': 200}
Swing #26 OCR → {'captured_at': '2026-03-08T18:59:21.411384+00:00', 'metrics': {'angle_of_attack_deg': -5.92, 'carry_yd': 105.0, 'efficiency': 1.21, 'hla_deg': 1.4, 'launch_deg': 22.8, 'path_deg': 0.78, 'speed_mph': 84.0, 'spin_axis_deg': 2.0, 'spin_rpm': 6924}, 'source': 'gc2', 'swing_id': 'pair-000026'}
GSPro shot #7 → {'Code': 200}
Swing #27 OCR → {'captured_at': '2026-03-08T19:00:03.806917+00:00', 'metrics': {'angle_of_attack_deg': -5.07, 'carry_yd': 113.0, 'efficiency': 1.24, 'hla_deg': -1.0, 'launch_deg': 0.9, 'path_deg': 1.81, 'speed_mph': 88.5, 'spin_axis_deg': -4.0, 'spin_rpm': 7474}, 'source': 'gc2', 'swing_id': 'pair-000027'}
GSPro shot #8 → {'Code': 200}
Swing #28 OCR → {'captured_at': '2026-03-08T19:00:27.411912+00:00', 'metrics': {'angle_of_attack_deg': -5.07, 'carry_yd': 107.0, 'efficiency': 1.24, 'hla_deg': 2.9, 'launch_deg': 24.2, 'path_deg': 1.81, 'speed_mph': 86.2, 'spin_axis_deg': 9.0, 'spin_rpm': 8575}, 'source': 'gc2', 'swing_id': 'pair-000028'}
GSPro shot #9 → {'Code': 200}
Swing #29 OCR → {'captured_at': '2026-03-08T19:00:36.278071+00:00', 'metrics': {'angle_of_attack_deg': -6.38, 'carry_yd': 107.0, 'efficiency': 1.18, 'hla_deg': 2.9, 'launch_deg': 24.2, 'path_deg': -0.21, 'speed_mph': 86.2, 'spin_axis_deg': 9.0, 'spin_rpm': 8575}, 'source': 'gc2', 'swing_id': 'pair-000029'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #30 OCR → {'captured_at': '2026-03-08T19:01:33.675888+00:00', 'metrics': {'angle_of_attack_deg': -5.54, 'carry_yd': None, 'efficiency': 1.22, 'hla_deg': -1.3, 'launch_deg': 22.9, 'path_deg': -0.62, 'speed_mph': 92.1, 'spin_axis_deg': None, 'spin_rpm': None}, 'source': 'gc2', 'swing_id': 'pair-000030'}
GSPro: skipping send — missing required fields: ['carry_yd']
Swing #31 OCR → {'captured_at': '2026-03-08T19:01:37.200284+00:00', 'metrics': {'angle_of_attack_deg': -5.54, 'carry_yd': 119.0, 'efficiency': 1.22, 'hla_deg': -1.3, 'launch_deg': 22.9, 'path_deg': -0.62, 'speed_mph': 92.1, 'spin_axis_deg': 2.0, 'spin_rpm': 7724}, 'source': 'gc2', 'swing_id': 'pair-000031'}
GSPro shot #10 → {'Code': 200}
Swing #32 OCR → {'captured_at': '2026-03-08T19:02:31.063650+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000032'}
GSPro shot #11 → {'Code': 200}
Swing #33 OCR → {'captured_at': '2026-03-08T19:02:47.291639+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000033'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #34 OCR → {'captured_at': '2026-03-08T19:02:53.787014+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000034'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #35 OCR → {'captured_at': '2026-03-08T19:03:21.409139+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000035'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #36 OCR → {'error': 'pair must contain one club view and one ball view'}
Swing #37 OCR → {'captured_at': '2026-03-08T19:06:18.532667+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000036'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #38 OCR → {'captured_at': '2026-03-08T19:07:24.004236+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000037'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #39 OCR → {'error': 'pair must contain one club view and one ball view'}
Swing #40 OCR → {'captured_at': '2026-03-08T19:07:45.937658+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000038'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #41 OCR → {'captured_at': '2026-03-08T19:07:59.435341+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000039'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #42 OCR → {'captured_at': '2026-03-08T19:08:12.405420+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000040'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #43 OCR → {'captured_at': '2026-03-08T19:08:28.817072+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000041'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #44 OCR → {'captured_at': '2026-03-08T19:08:31.995724+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000042'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #45 OCR → {'captured_at': '2026-03-08T19:08:37.344083+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000043'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #46 OCR → {'captured_at': '2026-03-08T19:09:49.652663+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000044'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #47 OCR → {'captured_at': '2026-03-08T19:09:59.559148+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000045'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #48 OCR → {'captured_at': '2026-03-08T19:10:10.409790+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -6.0, 'launch_deg': 22.902, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000046'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #49 OCR → {'captured_at': '2026-03-08T19:10:16.957577+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -8.0, 'launch_deg': None, 'path_deg': -0.59, 'speed_mph': None, 'spin_axis_deg': None, 'spin_rpm': None}, 'source': 'gc2', 'swing_id': 'pair-000047'}
GSPro: skipping send — missing required fields: ['speed_mph']
Swing #50 OCR → {'captured_at': '2026-03-08T19:10:27.747699+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000048'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #51 OCR → {'captured_at': '2026-03-08T19:12:30.979233+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000049'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #52 OCR → {'captured_at': '2026-03-08T19:12:38.615425+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': None, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000050'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #53 OCR → {'captured_at': '2026-03-08T19:12:44.220676+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000051'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #54 OCR → {'captured_at': '2026-03-08T19:12:56.256176+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000052'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #55 OCR → {'captured_at': '2026-03-08T19:13:03.880992+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000053'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #56 OCR → {'captured_at': '2026-03-08T19:13:50.658235+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000054'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #57 OCR → {'error': 'pair must contain one club view and one ball view'}
Swing #58 OCR → {'captured_at': '2026-03-08T19:15:01.824310+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000055'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #59 OCR → {'captured_at': '2026-03-08T19:15:31.686336+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000056'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #60 OCR → {'captured_at': '2026-03-08T19:16:17.587063+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000057'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #61 OCR → {'error': 'pair must contain one club view and one ball view'}
Swing #62 OCR → {'captured_at': '2026-03-08T19:19:18.824209+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000058'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #63 OCR → {'captured_at': '2026-03-08T19:19:39.650988+00:00', 'metrics': {'angle_of_attack_deg': -7.74, 'carry_yd': 126.0, 'efficiency': 1.23, 'hla_deg': -2.6, 'launch_deg': 22.9, 'path_deg': -0.59, 'speed_mph': 93.9, 'spin_axis_deg': 2.0, 'spin_rpm': 5375}, 'source': 'gc2', 'swing_id': 'pair-000059'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #1 OCR → {'error': 'pair must contain one club view and one ball view'}
Swing #2 OCR → {'captured_at': '2026-03-08T19:25:17.258303+00:00', 'metrics': {'angle_of_attack_deg': -3.9, 'carry_yd': 116.0, 'efficiency': 1.23, 'hla_deg': -6.0, 'launch_deg': 20.8, 'path_deg': -0.74, 'speed_mph': 90.8, 'spin_axis_deg': -11.0, 'spin_rpm': 7750}, 'source': 'gc2', 'swing_id': 'pair-000060'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 1,
"APIversion": "1",
"BallData": {
"Speed": 90.8,
"SpinAxis": -11.0,
"TotalSpin": 7750.0,
"BackSpin": 7607.6,
"SideSpin": -1478.8,
"HLA": -6.0,
"VLA": 20.8,
"CarryDistance": 116.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -3.9,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -0.74,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro connected to 192.168.1.220:49152
GSPro shot #1 → {'Code': 200}
Swing #3 OCR → {'captured_at': '2026-03-08T19:25:20.624604+00:00', 'metrics': {'angle_of_attack_deg': -3.9, 'carry_yd': 35.8, 'efficiency': 1.23, 'hla_deg': 3.6, 'launch_deg': 4.9, 'path_deg': -0.74, 'speed_mph': 79.5, 'spin_axis_deg': None, 'spin_rpm': 4524}, 'source': 'gc2', 'swing_id': 'pair-000061'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 2,
"APIversion": "1",
"BallData": {
"Speed": 79.5,
"SpinAxis": 0.0,
"TotalSpin": 4524.0,
"BackSpin": 0.0,
"SideSpin": 0.0,
"HLA": 3.6,
"VLA": 4.9,
"CarryDistance": 35.8
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -3.9,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -0.74,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #2 → {'Code': 200}
Swing #4 OCR → {'captured_at': '2026-03-08T19:25:39.003914+00:00', 'metrics': {'angle_of_attack_deg': -1.27, 'carry_yd': 99.3, 'efficiency': 1.19, 'hla_deg': -8.0, 'launch_deg': 21.8, 'path_deg': -3.44, 'speed_mph': 81.3, 'spin_axis_deg': None, 'spin_rpm': 5049}, 'source': 'gc2', 'swing_id': 'pair-000062'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 3,
"APIversion": "1",
"BallData": {
"Speed": 81.3,
"SpinAxis": 0.0,
"TotalSpin": 5049.0,
"BackSpin": 0.0,
"SideSpin": 0.0,
"HLA": -8.0,
"VLA": 21.8,
"CarryDistance": 99.3
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -1.27,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -3.44,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #3 → {'Code': 200}
Swing #5 OCR → {'error': 'could not extract OCR metrics from both images'}
Swing #6 OCR → {'captured_at': '2026-03-08T19:26:11.283058+00:00', 'metrics': {'angle_of_attack_deg': -6.17, 'carry_yd': 113.0, 'efficiency': 1.21, 'hla_deg': -5.7, 'launch_deg': 18.8, 'path_deg': -2.11, 'speed_mph': 89.5, 'spin_axis_deg': -5.0, 'spin_rpm': 7774}, 'source': 'gc2', 'swing_id': 'pair-000063'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 4,
"APIversion": "1",
"BallData": {
"Speed": 89.5,
"SpinAxis": -5.0,
"TotalSpin": 7774.0,
"BackSpin": 7744.4,
"SideSpin": -677.5,
"HLA": -5.7,
"VLA": 18.8,
"CarryDistance": 113.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -6.17,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -2.11,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #4 → {'Code': 200}
Swing #7 OCR → {'captured_at': '2026-03-08T19:27:07.478793+00:00', 'metrics': {'angle_of_attack_deg': -5.76, 'carry_yd': 115.0, 'efficiency': 1.25, 'hla_deg': -3.2, 'launch_deg': 21.8, 'path_deg': -2.35, 'speed_mph': 89.9, 'spin_axis_deg': None, 'spin_rpm': 7824}, 'source': 'gc2', 'swing_id': 'pair-000064'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 5,
"APIversion": "1",
"BallData": {
"Speed": 89.9,
"SpinAxis": 0.0,
"TotalSpin": 7824.0,
"BackSpin": 0.0,
"SideSpin": 0.0,
"HLA": -3.2,
"VLA": 21.8,
"CarryDistance": 115.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -5.76,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -2.35,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #5 → {'Code': 200}
Swing #8 OCR → {'captured_at': '2026-03-08T19:27:23.835214+00:00', 'metrics': {'angle_of_attack_deg': -5.76, 'carry_yd': 116.0, 'efficiency': 1.25, 'hla_deg': -7.1, 'launch_deg': 20.5, 'path_deg': -2.35, 'speed_mph': 90.7, 'spin_axis_deg': -11.0, 'spin_rpm': 7475}, 'source': 'gc2', 'swing_id': 'pair-000065'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 6,
"APIversion": "1",
"BallData": {
"Speed": 90.7,
"SpinAxis": -11.0,
"TotalSpin": 7475.0,
"BackSpin": 7337.7,
"SideSpin": -1426.3,
"HLA": -7.1,
"VLA": 20.5,
"CarryDistance": 116.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -5.76,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -2.35,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #6 → {'Code': 200}
Swing #9 OCR → {'captured_at': '2026-03-08T19:28:08.242463+00:00', 'metrics': {'angle_of_attack_deg': -7.12, 'carry_yd': 119.0, 'efficiency': 1.24, 'hla_deg': -6.1, 'launch_deg': 19.66, 'path_deg': -3.71, 'speed_mph': 92.6, 'spin_axis_deg': -2.0, 'spin_rpm': 8099}, 'source': 'gc2', 'swing_id': 'pair-000066'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 7,
"APIversion": "1",
"BallData": {
"Speed": 92.6,
"SpinAxis": -2.0,
"TotalSpin": 8099.0,
"BackSpin": 8094.1,
"SideSpin": -282.7,
"HLA": -6.1,
"VLA": 19.66,
"CarryDistance": 119.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -7.12,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -3.71,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #7 → {'Code': 200}
Swing #10 OCR → {'captured_at': '2026-03-08T19:28:43.876592+00:00', 'metrics': {'angle_of_attack_deg': -3.49, 'carry_yd': 114.0, 'efficiency': 1.2, 'hla_deg': None, 'launch_deg': 24.4, 'path_deg': -11.37, 'speed_mph': 89.8, 'spin_axis_deg': 5.0, 'spin_rpm': 8474}, 'source': 'gc2', 'swing_id': 'pair-000067'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 8,
"APIversion": "1",
"BallData": {
"Speed": 89.8,
"SpinAxis": 5.0,
"TotalSpin": 8474.0,
"BackSpin": 8441.8,
"SideSpin": 738.6,
"HLA": 0.0,
"VLA": 24.4,
"CarryDistance": 114.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -3.49,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -11.37,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #8 → {'Code': 200}
Swing #11 OCR → {'captured_at': '2026-03-08T19:28:53.598588+00:00', 'metrics': {'angle_of_attack_deg': -3.49, 'carry_yd': 114.0, 'efficiency': 1.2, 'hla_deg': None, 'launch_deg': 24.4, 'path_deg': -11.37, 'speed_mph': 89.8, 'spin_axis_deg': 5.0, 'spin_rpm': 8474}, 'source': 'gc2', 'swing_id': 'pair-000068'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #12 OCR → {'captured_at': '2026-03-08T19:29:06.873651+00:00', 'metrics': {'angle_of_attack_deg': -2.97, 'carry_yd': 114.0, 'efficiency': 1.23, 'hla_deg': None, 'launch_deg': 24.4, 'path_deg': -7.33, 'speed_mph': 89.8, 'spin_axis_deg': 5.0, 'spin_rpm': 8474}, 'source': 'gc2', 'swing_id': 'pair-000069'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #13 OCR → {'captured_at': '2026-03-08T19:29:26.302085+00:00', 'metrics': {'angle_of_attack_deg': -2.97, 'carry_yd': 121.0, 'efficiency': 1.23, 'hla_deg': -8.6, 'launch_deg': 25.1, 'path_deg': -7.33, 'speed_mph': 90.9, 'spin_axis_deg': -3.0, 'spin_rpm': 5524}, 'source': 'gc2', 'swing_id': 'pair-000070'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 9,
"APIversion": "1",
"BallData": {
"Speed": 90.9,
"SpinAxis": -3.0,
"TotalSpin": 5524.0,
"BackSpin": 5516.4,
"SideSpin": -289.1,
"HLA": -8.6,
"VLA": 25.1,
"CarryDistance": 121.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -2.97,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -7.33,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #9 → {'Code': 200}
Swing #14 OCR → {'captured_at': '2026-03-08T19:29:50.982772+00:00', 'metrics': {'angle_of_attack_deg': None, 'carry_yd': 154.0, 'efficiency': None, 'hla_deg': None, 'launch_deg': None, 'path_deg': None, 'speed_mph': 108.0, 'spin_axis_deg': -9.0, 'spin_rpm': 4450}, 'source': 'gc2', 'swing_id': 'pair-000071'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 10,
"APIversion": "1",
"BallData": {
"Speed": 108.0,
"SpinAxis": -9.0,
"TotalSpin": 4450.0,
"BackSpin": 4395.2,
"SideSpin": -696.1,
"HLA": 0.0,
"VLA": 0.0,
"CarryDistance": 154.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": 0.0,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": 0.0,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": false,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #10 → {'Code': 200}
Swing #15 OCR → {'captured_at': '2026-03-08T19:31:41.285584+00:00', 'metrics': {'angle_of_attack_deg': None, 'carry_yd': 155.0, 'efficiency': None, 'hla_deg': -9.0, 'launch_deg': 17.18, 'path_deg': None, 'speed_mph': 109.0, 'spin_axis_deg': -14.0, 'spin_rpm': 4199}, 'source': 'gc2', 'swing_id': 'pair-000072'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 11,
"APIversion": "1",
"BallData": {
"Speed": 109.0,
"SpinAxis": -14.0,
"TotalSpin": 4199.0,
"BackSpin": 4074.3,
"SideSpin": -1015.8,
"HLA": -9.0,
"VLA": 17.18,
"CarryDistance": 155.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": 0.0,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": 0.0,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": false,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #11 → {'Code': 200}
Swing #16 OCR → {'captured_at': '2026-03-08T19:31:59.003085+00:00', 'metrics': {'angle_of_attack_deg': None, 'carry_yd': 155.0, 'efficiency': None, 'hla_deg': -8.9, 'launch_deg': 17.1, 'path_deg': None, 'speed_mph': 109.0, 'spin_axis_deg': -14.0, 'spin_rpm': 4199}, 'source': 'gc2', 'swing_id': 'pair-000073'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #17 OCR → {'captured_at': '2026-03-08T19:32:04.362640+00:00', 'metrics': {'angle_of_attack_deg': -3.91, 'carry_yd': 155.0, 'efficiency': 1.32, 'hla_deg': -9.6, 'launch_deg': 10.4, 'path_deg': -4.61, 'speed_mph': 107.0, 'spin_axis_deg': None, 'spin_rpm': 4199}, 'source': 'gc2', 'swing_id': 'pair-000074'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 12,
"APIversion": "1",
"BallData": {
"Speed": 107.0,
"SpinAxis": 0.0,
"TotalSpin": 4199.0,
"BackSpin": 0.0,
"SideSpin": 0.0,
"HLA": -9.6,
"VLA": 10.4,
"CarryDistance": 155.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -3.91,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -4.61,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #12 → {'Code': 200}
Swing #18 OCR → {'captured_at': '2026-03-08T19:34:15.252774+00:00', 'metrics': {'angle_of_attack_deg': -3.55, 'carry_yd': 151.0, 'efficiency': 1.39, 'hla_deg': -7.9, 'launch_deg': 15.4, 'path_deg': -3.36, 'speed_mph': 108.0, 'spin_axis_deg': -12.0, 'spin_rpm': 4774}, 'source': 'gc2', 'swing_id': 'pair-000075'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 13,
"APIversion": "1",
"BallData": {
"Speed": 108.0,
"SpinAxis": -12.0,
"TotalSpin": 4774.0,
"BackSpin": 4669.7,
"SideSpin": -992.6,
"HLA": -7.9,
"VLA": 15.4,
"CarryDistance": 151.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -3.55,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -3.36,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #13 → {'Code': 200}
Swing #19 OCR → {'captured_at': '2026-03-08T19:34:35.859395+00:00', 'metrics': {'angle_of_attack_deg': -2.1, 'carry_yd': 148.0, 'efficiency': 1.36, 'hla_deg': -7.4, 'launch_deg': None, 'path_deg': -5.04, 'speed_mph': 104.0, 'spin_axis_deg': None, 'spin_rpm': 4124}, 'source': 'gc2', 'swing_id': 'pair-000076'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 14,
"APIversion": "1",
"BallData": {
"Speed": 104.0,
"SpinAxis": 0.0,
"TotalSpin": 4124.0,
"BackSpin": 0.0,
"SideSpin": 0.0,
"HLA": -7.4,
"VLA": 0.0,
"CarryDistance": 148.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -2.1,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -5.04,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #14 → {'Code': 200}
Swing #20 OCR → {'captured_at': '2026-03-08T19:34:46.813730+00:00', 'metrics': {'angle_of_attack_deg': -2.1, 'carry_yd': 148.0, 'efficiency': 1.36, 'hla_deg': -7.4, 'launch_deg': None, 'path_deg': -5.04, 'speed_mph': 104.0, 'spin_axis_deg': None, 'spin_rpm': 4124}, 'source': 'gc2', 'swing_id': 'pair-000077'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #21 OCR → {'captured_at': '2026-03-08T19:35:19.455334+00:00', 'metrics': {'angle_of_attack_deg': -2.1, 'carry_yd': 148.0, 'efficiency': 1.36, 'hla_deg': -7.4, 'launch_deg': 18.0, 'path_deg': -5.04, 'speed_mph': 104.0, 'spin_axis_deg': -11.0, 'spin_rpm': 4124}, 'source': 'gc2', 'swing_id': 'pair-000078'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #22 OCR → {'captured_at': '2026-03-08T19:35:27.212338+00:00', 'metrics': {'angle_of_attack_deg': -2.1, 'carry_yd': None, 'efficiency': 1.36, 'hla_deg': -7.48, 'launch_deg': None, 'path_deg': -5.04, 'speed_mph': None, 'spin_axis_deg': None, 'spin_rpm': None}, 'source': 'gc2', 'swing_id': 'pair-000079'}
GSPro: skipping send — missing required fields: ['speed_mph', 'carry_yd']
Swing #23 OCR → {'captured_at': '2026-03-08T19:35:31.543039+00:00', 'metrics': {'angle_of_attack_deg': -2.1, 'carry_yd': 148.0, 'efficiency': 1.36, 'hla_deg': -7.4, 'launch_deg': 18.0, 'path_deg': -5.04, 'speed_mph': 104.0, 'spin_axis_deg': -11.0, 'spin_rpm': 4124}, 'source': 'gc2', 'swing_id': 'pair-000080'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #24 OCR → {'captured_at': '2026-03-08T19:35:54.487692+00:00', 'metrics': {'angle_of_attack_deg': None, 'carry_yd': 148.0, 'efficiency': 1.37, 'hla_deg': -7.4, 'launch_deg': None, 'path_deg': None, 'speed_mph': 104.0, 'spin_axis_deg': -11.0, 'spin_rpm': 4124}, 'source': 'gc2', 'swing_id': 'pair-000081'}
GSPro: skipping duplicate shot (same speed+carry as previous)
Swing #25 OCR → {'captured_at': '2026-03-08T19:36:20.844630+00:00', 'metrics': {'angle_of_attack_deg': 2.5, 'carry_yd': 160.0, 'efficiency': 1.46, 'hla_deg': -8.7, 'launch_deg': 15.0, 'path_deg': -4.2, 'speed_mph': 114.0, 'spin_axis_deg': 30.0, 'spin_rpm': 2650}, 'source': 'gc2', 'swing_id': 'pair-000082'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 15,
"APIversion": "1",
"BallData": {
"Speed": 114.0,
"SpinAxis": 30.0,
"TotalSpin": 2650.0,
"BackSpin": 2295.0,
"SideSpin": 1325.0,
"HLA": -8.7,
"VLA": 15.0,
"CarryDistance": 160.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": 2.5,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -4.2,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #15 → {'Code': 200}
Swing #26 OCR → {'captured_at': '2026-03-08T19:36:44.012150+00:00', 'metrics': {'angle_of_attack_deg': 2.5, 'carry_yd': 165.0, 'efficiency': 1.46, 'hla_deg': -8.7, 'launch_deg': None, 'path_deg': -4.2, 'speed_mph': 114.0, 'spin_axis_deg': -26.0, 'spin_rpm': 2875}, 'source': 'gc2', 'swing_id': 'pair-000083'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 16,
"APIversion": "1",
"BallData": {
"Speed": 114.0,
"SpinAxis": -26.0,
"TotalSpin": 2875.0,
"BackSpin": 2584.0,
"SideSpin": -1260.3,
"HLA": -8.7,
"VLA": 0.0,
"CarryDistance": 165.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": 2.5,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -4.2,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #16 → {'Code': 200}
Swing #27 OCR → {'captured_at': '2026-03-08T19:36:51.807728+00:00', 'metrics': {'angle_of_attack_deg': 0.02, 'carry_yd': 123.0, 'efficiency': 1.23, 'hla_deg': -6.9, 'launch_deg': 13.5, 'path_deg': -3.7, 'speed_mph': 98.7, 'spin_axis_deg': -29.0, 'spin_rpm': 2850}, 'source': 'gc2', 'swing_id': 'pair-000084'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 17,
"APIversion": "1",
"BallData": {
"Speed": 98.7,
"SpinAxis": -29.0,
"TotalSpin": 2850.0,
"BackSpin": 2492.7,
"SideSpin": -1381.7,
"HLA": -6.9,
"VLA": 13.5,
"CarryDistance": 123.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": 0.02,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -3.7,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #17 → {'Code': 200}
Swing #28 OCR → {'captured_at': '2026-03-08T19:38:09.664505+00:00', 'metrics': {'angle_of_attack_deg': -0.63, 'carry_yd': 154.0, 'efficiency': 1.37, 'hla_deg': -5.9, 'launch_deg': 14.1, 'path_deg': -4.12, 'speed_mph': 108.0, 'spin_axis_deg': -13.0, 'spin_rpm': 2625}, 'source': 'gc2', 'swing_id': 'pair-000085'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 18,
"APIversion": "1",
"BallData": {
"Speed": 108.0,
"SpinAxis": -13.0,
"TotalSpin": 2625.0,
"BackSpin": 2557.7,
"SideSpin": -590.5,
"HLA": -5.9,
"VLA": 14.1,
"CarryDistance": 154.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -0.63,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -4.12,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #18 → {'Code': 200}
Swing #29 OCR → {'captured_at': '2026-03-08T19:38:41.377545+00:00', 'metrics': {'angle_of_attack_deg': -0.63, 'carry_yd': 154.0, 'efficiency': 1.37, 'hla_deg': -0.3, 'launch_deg': 15.4, 'path_deg': -4.12, 'speed_mph': 115.0, 'spin_axis_deg': -13.0, 'spin_rpm': 2625}, 'source': 'gc2', 'swing_id': 'pair-000086'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 19,
"APIversion": "1",
"BallData": {
"Speed": 115.0,
"SpinAxis": -13.0,
"TotalSpin": 2625.0,
"BackSpin": 2557.7,
"SideSpin": -590.5,
"HLA": -0.3,
"VLA": 15.4,
"CarryDistance": 154.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -0.63,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -4.12,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
GSPro shot #19 → {'Code': 200}
Swing #30 OCR → {'error': 'timed out'}
Swing #31 OCR → {'error': 'timed out'}
Swing #32 OCR → {'error': 'timed out'}
Swing #33 OCR → {'error': 'timed out'}
Swing #34 OCR → {'error': 'timed out'}
Swing #35 OCR → {'error': 'timed out'}
Swing #36 OCR → {'error': 'timed out'}
Swing #37 OCR → {'error': 'timed out'}
Swing #38 OCR → {'error': 'timed out'}
Swing #39 OCR → {'error': 'timed out'}
Swing #40 OCR → {'error': 'timed out'}
Swing #41 OCR → {'error': 'timed out'}
Swing #42 OCR → {'error': '[Errno 104] Connection reset by peer'}
Swing #43 OCR → {'error': '[Errno 111] Connection refused'}
Swing #44 OCR → {'captured_at': '2026-03-08T19:45:44.177775+00:00', 'metrics': {'angle_of_attack_deg': -6.48, 'carry_yd': 118.0, 'efficiency': 1.19, 'hla_deg': -9.5, 'launch_deg': 22.2, 'path_deg': -6.31, 'speed_mph': 90.8, 'spin_axis_deg': -7.0, 'spin_rpm': 6774}, 'source': 'gc2', 'swing_id': 'pair-000001'}
GSPro TX: {
"DeviceID": "GSPro LM 1.1",
"Units": "Yards",
"ShotNumber": 20,
"APIversion": "1",
"BallData": {
"Speed": 90.8,
"SpinAxis": -7.0,
"TotalSpin": 6774.0,
"BackSpin": 6723.5,
"SideSpin": -825.5,
"HLA": -9.5,
"VLA": 22.2,
"CarryDistance": 118.0
},
"ClubData": {
"Speed": 0.0,
"AngleOfAttack": -6.48,
"FaceToTarget": 0.0,
"Lie": 0.0,
"Loft": 0.0,
"Path": -6.31,
"SpeedAtImpact": 0.0,
"VerticalFaceImpact": 0.0,
"HorizontalFaceImpact": 0.0,
"ClosureRate": 0.0
},
"ShotDataOptions": {
"ContainsBallData": true,
"ContainsClubData": true,
"LaunchMonitorIsReady": true,
"LaunchMonitorBallDetected": true,
"IsHeartBeat": false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment