Developers
Threads by month
- ----- 2025 -----
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 1 participants
- 2965 discussions
Is there a way of controlling the positioning of settings? Can I make the display like:
Setting A Setting B Setting C Setting D
vs the vertical default of
Setting A
Setting B
Setting C
Setting D?
actually what I want to do for the tyt h9800 band limit display (and potentially future setting) is something like
band limits
Band rx low rx high tx low tx high
30 mhz [ 26.000000] [ 33.000000] [ 26.000000] [ 33.000000]
50 mhz [ 47.000000] [ 54.000000] [ 47.000000] [ 54.000000]
…
Thanks.
James N1DDK.
3
5
Tested changes:
[Jim Unroe <rock.unroe(a)gmail.com>] [VV-898] Update Image Detections (Improved)
Improve method to fall back to original detection string for older data files
Better detect between Jetstream, Leixen (v1.02 and v1.03) images
related to #2119
[Marco Filippi <iz3gme.marco(a)gmail.com>] [FT1D] Remove more invalid chars from APRS message body
Some chars are printable but not accepted as valid chars setting string
To avoid exceptions remove them all from APRS message body
Fix implementation of #967
[nytowl] issue #967 - add a Yaesu FT1DR driver
- based on the Yaesu vx8 driver
- download and upload working
- memory channel and bank settings tested
- Need to figure out the digital modes for the radio
- most settings have been tested with the exception of the scan settings
- aprs message and beacons print out
Full log:
[...truncated 158 lines...]
test_delete_hole_with_all (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_delete_hole_with_all_full (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_delete_hole_with_hole (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_delete_hole_without_hole (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_insert_hole_with_space (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_insert_hole_without_space (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
----------------------------------------------------------------------
Ran 151 tests in 0.131s
OK
Registered Icom_IC-2820H = IC2820Radio
Registered TYT_TH-UVF8D = TYTUVF8DRadio
Registered AnyTone_5888UV = AnyTone5888UVRadio
Registered Intek_HR-2040 = IntekHR2040Radio
Registered Polmar_DB-50M = PolmarDB50MRadio
Registered Powerwerx_DB-750X = PowerwerxDB750XRadio
Registered Icom_IC-2200H = IC2200Radio
Registered Yaesu_FT-2800M = FT2800Radio
Registered Yaesu_VX-3 = VX3Radio
Registered Icom_IC-2100H = IC2100Radio
Registered Yaesu_FTM-350 = FTM350Radio
Registered Icom_IC-V82_U82 = ICx8xRadio
Registered Yaesu_VX-6 = VX6Radio
Registered Yaesu_VX-5 = VX5Radio
Registered Yaesu_FT-60 = FT60Radio
Registered Yaesu_VX-7 = VX7Radio
Registered Sainsonic_AP510 = AP510Radio
Registered Baofeng_UV-5R = BaofengUV5R
Registered Baofeng_F-11 = BaofengF11Radio
Registered Baofeng_UV-82 = BaofengUV82Radio
Registered Baofeng_UV-6 = BaofengUV6Radio
Registered Intek_KT-980HP = IntekKT980Radio
Registered Baofeng_BF-F8HP = BaofengBFF8HPRadio
Registered Yaesu_FT-1802M = FT1802Radio
Registered Kenwood_TK-7102 = KenwoodTK7102Radio
Registered Kenwood_TK-8102 = KenwoodTK8102Radio
Registered Kenwood_TK-7108 = KenwoodTK7108Radio
Registered Kenwood_TK-8108 = KenwoodTK8108Radio
Registered Icom_ID-31A = ID31Radio
Registered Icom_ID-51A = ID51Radio
Registered Icom_IC-2720H = IC2720Radio
Registered Icom_IC-T8A = ICT8ARadio
Registered Wouxun_KG-UVD1P = KGUVD1PRadio
Registered Wouxun_KG-UV6 = KGUV6DRadio
Registered Wouxun_KG-816 = KG816Radio
Registered Wouxun_KG-818 = KG818Radio
Registered TYT_TH-UVF1 = TYTTHUVF1Radio
Registered Yaesu_FT-90 = FT90Radio
Registered Generic_CSV = CSVRadio
Registered Commander_KG-UV = CommanderCSVRadio
Registered RT_Systems_CSV = RTCSVRadio
Registered Kenwood_ITM = ITMRadio
Registered TYT_TH-9800 = TYTTH9800File
Registered Alinco_DR03T = DR03Radio
Registered Alinco_DR06T = DR06Radio
Registered Alinco_DR135T = DR135Radio
Registered Alinco_DR235T = DR235Radio
Registered Alinco_DR435T = DR435Radio
Registered Alinco_DJ596 = DJ596Radio
Registered Jetstream_JT220M = JT220MRadio
Registered Alinco_DJ175 = DJ175Radio
Registered Kenwood_TH-D7 = THD7Radio
Registered Kenwood_TH-D7G = THD7GRadio
Registered Kenwood_TM-D700 = TMD700Radio
Registered Kenwood_TM-V7 = TMV7Radio
Registered Kenwood_TM-G707 = TMG707Radio
Registered Kenwood_TH-G71 = THG71Radio
Registered Kenwood_TH-F6 = THF6ARadio
Registered Kenwood_TH-F7 = THF7ERadio
Registered Kenwood_TM-D710 = TMD710Radio
Registered Kenwood_TH-D72_live_mode = THD72Radio
Registered Kenwood_TM-V71 = TMV71Radio
Registered Kenwood_TH-K2 = THK2Radio
Registered Kenwood_TM-271 = TM271Radio
Registered Kenwood_TM-281 = TM281Radio
Registered Kenwood_TM-471 = TM471Radio
Registered Yaesu_FT-1D_R = FT1Radio
Registered Wouxun_KG-UV8D = KGUV8DRadio
Registered Yaesu_VX-8_R = VX8Radio
Registered Yaesu_VX-8_DR = VX8DRadio
Registered Yaesu_VX-8_GE = VX8GERadio
Registered Icom_IC-T7H = ICT7HRadio
Registered Icom_IC-Q7A = ICQ7Radio
Registered Baofeng_UV-B5 = BaofengUVB5
Registered Generic_XML = XMLRadio
Registered Kenwood_HMK = HMKRadio
Registered Kenwood_TH-D72_clone_mode = THD72Radio
Registered Icom_IC-91_92AD = IC9xRadio
Registered Icom_IC-T70 = ICT70Radio
Registered Icom_IC-208H = IC208Radio
Registered Leixen_VV-898 = LeixenVV898Radio
Registered Jetstream_JT270M = JetstreamJT270MRadio
Registered Icom_ID-800H_v2 = ID800v2Radio
Registered Icom_7200 = Icom7200Radio
Registered Icom_7000 = Icom7000Radio
Registered Icom_746 = Icom746Radio
Registered ARRL_Travel_Plus = TpeRadio
Registered Vertex_Standard_VXA-700 = VXA700Radio
Registered Icom_IC-W32A = ICW32ARadio
Registered Baofeng_UV-3R = UV3RRadio
Registered Yaesu_VX-2 = VX2Radio
Registered Puxing_PX-777 = Puxing777Radio
Registered Puxing_PX-2R = Puxing2RRadio
Registered Baojie_BJ-UV55 = BaojieBJUV55Radio
Registered Baofeng_BF-888 = H777Radio
Registered Yaesu_FT-7800_7900 = FT7800Radio
Registered Yaesu_FT-8800 = FT8800Radio
Registered Yaesu_FT-8900 = FT8900Radio
Registered KYD_NC-630A = NC630aRadio
Registered Yaesu_FT-817 = FT817Radio
Registered Yaesu_FT-817ND = FT817NDRadio
Registered Yaesu_FT-817ND_US = FT817NDUSRadio
Registered Yaesu_FT-857_897 = FT857Radio
Registered Yaesu_FT-857_897_US = FT857USRadio
Registered Yaesu_VX-170 = VX170Radio
Registered Icom_ID-880H = ID880Radio
Registered Icom_ID-80H = ID80Radio
Registered TYT_TH-UV3R = TYTUV3RRadio
Alinco DJ175 Detect PASSED: All tests
Alinco DJ175 CopyAll PASSED: All tests
Alinco DJ175 Clone PASSED: All tests
Alinco DJ175 BruteForce PASSED: All tests
Alinco DJ175 Edges PASSED: All tests
Alinco DJ175 Banks SKIPPED: Banks not supported
Alinco DJ596 Detect PASSED: All tests
Alinco DJ596 CopyAll PASSED: All tests
Alinco DJ596 Clone PASSED: All tests
Alinco DJ596 BruteForce PASSED: All tests
Alinco DJ596 Edges PASSED: All tests
Alinco DJ596 Banks SKIPPED: Banks not supported
Alinco DR235T Detect PASSED: All tests
Alinco DR235T CopyAll PASSED: All tests
Alinco DR235T Clone PASSED: All tests
Alinco DR235T BruteForce PASSED: All tests
Alinco DR235T Edges PASSED: All tests
Alinco DR235T Banks SKIPPED: Banks not supported
Baofeng BF-888 Detect PASSED: All tests
Baofeng BF-888 CopyAll PASSED: All tests
Baofeng BF-888 Clone PASSED: All tests
Baofeng BF-888 BruteForce PASSED: All tests
Baofeng BF-888 Edges PASSED: All tests
Baofeng BF-888 Banks SKIPPED: Banks not supported
Baofeng F-11 Detect PASSED: All tests
Baofeng F-11 CopyAll PASSED: All tests
Baofeng F-11 Clone PASSED: All tests
Baofeng F-11 BruteForce PASSED: All tests
Baofeng F-11 Edges PASSED: All tests
Baofeng F-11 Banks SKIPPED: Banks not supported
Baofeng UV-3R Detect PASSED: All tests
Baofeng UV-3R CopyAll PASSED: All tests
Baofeng UV-3R Clone PASSED: All tests
Baofeng UV-3R BruteForce PASSED: All tests
Baofeng UV-3R Edges PASSED: All tests
Baofeng UV-3R Banks SKIPPED: Banks not supported
Baofeng UV-5R Detect PASSED: All tests
Baofeng UV-5R CopyAll PASSED: All tests
Baofeng UV-5R Clone PASSED: All tests
Baofeng UV-5R BruteForce PASSED: All tests
Baofeng UV-5R Edges PASSED: All tests
Baofeng UV-5R Banks SKIPPED: Banks not supported
Baofeng UV-B5 Detect PASSED: All tests
Baofeng UV-B5 CopyAll PASSED: All tests
Baofeng UV-B5 Clone PASSED: All tests
Baofeng UV-B5 BruteForce PASSED: All tests
Baofeng UV-B5 Edges PASSED: All tests
Baofeng UV-B5 Banks SKIPPED: Banks not supported
Icom IC-208H Detect PASSED: All tests
Icom IC-208H CopyAll PASSED: All tests
Icom IC-208H Clone PASSED: All tests
Icom IC-208H BruteForce PASSED: All tests
Icom IC-208H Edges PASSED: All tests
Icom IC-208H Banks PASSED: All tests
Icom IC-2100H Detect PASSED: All tests
Icom IC-2100H CopyAll PASSED: All tests
Icom IC-2100H Clone PASSED: All tests
Icom IC-2100H BruteForce PASSED: All tests
Icom IC-2100H Edges PASSED: All tests
Icom IC-2100H Banks SKIPPED: Banks not supported
Icom IC-2200H Detect PASSED: All tests
Icom IC-2200H CopyAll PASSED: All tests
Icom IC-2200H Clone PASSED: All tests
Icom IC-2200H BruteForce PASSED: All tests
Icom IC-2200H Edges PASSED: All tests
Icom IC-2200H Banks PASSED: All tests
Icom IC-2720H Detect PASSED: All tests
Icom IC-2720H CopyAll PASSED: All tests
Icom IC-2720H Clone PASSED: All tests
Icom IC-2720H BruteForce PASSED: All tests
Icom IC-2720H Edges PASSED: All tests
Icom IC-2720H Banks PASSED: All tests
Icom IC-2820H Detect PASSED: All tests
Icom IC-2820H CopyAll PASSED: All tests
Icom IC-2820H Clone PASSED: All tests
Icom IC-2820H BruteForce PASSED: All tests
Icom IC-2820H Edges PASSED: All tests
Icom IC-2820H Banks PASSED: All tests
Icom IC-Q7A Detect PASSED: All tests
Icom IC-Q7A CopyAll PASSED: All tests
Icom IC-Q7A Clone PASSED: All tests
Icom IC-Q7A BruteForce PASSED: All tests
Icom IC-Q7A Edges PASSED: All tests
Icom IC-Q7A Banks SKIPPED: Banks not supported
Icom IC-T70 Detect PASSED: All tests
Icom IC-T70 CopyAll PASSED: All tests
Icom IC-T70 Clone PASSED: All tests
Icom IC-T70 BruteForce PASSED: All tests
Icom IC-T70 Edges PASSED: All tests
Icom IC-T70 Banks PASSED: All tests
Icom IC-T7H Detect PASSED: All tests
Icom IC-T7H CopyAll PASSED: All tests
Icom IC-T7H Clone PASSED: All tests
Icom IC-T7H BruteForce PASSED: All tests
Icom IC-T7H Edges PASSED: All tests
Icom IC-T7H Banks SKIPPED: Banks not supported
Icom IC-T8A Detect PASSED: All tests
Icom IC-T8A CopyAll PASSED: All tests
Icom IC-T8A Clone PASSED: All tests
Icom IC-T8A BruteForce PASSED: All tests
Icom IC-T8A Edges PASSED: All tests
Icom IC-T8A Banks SKIPPED: Banks not supported
Icom IC-V82/U82 Detect PASSED: All tests
Icom IC-V82/U82 CopyAll PASSED: All tests
Icom IC-V82/U82 Clone PASSED: All tests
Icom IC-V82/U82 BruteForce PASSED: All tests
Icom IC-V82/U82 Edges PASSED: All tests
Icom IC-V82/U82 Banks PASSED: All tests
Icom IC-W32A VHF Detect PASSED: All tests
Icom IC-W32A VHF CopyAll PASSED: All tests
Icom IC-W32A VHF Clone PASSED: All tests
Icom IC-W32A VHF BruteForce PASSED: All tests
Icom IC-W32A VHF Edges PASSED: All tests
Icom IC-W32A VHF Banks SKIPPED: Banks not supported
Icom IC-W32A UHF Detect PASSED: All tests
Icom IC-W32A UHF CopyAll PASSED: All tests
Icom IC-W32A UHF Clone PASSED: All tests
Icom IC-W32A UHF BruteForce PASSED: All tests
Icom IC-W32A UHF Edges PASSED: All tests
Icom IC-W32A UHF Banks SKIPPED: Banks not supported
Icom ID-31A Detect PASSED: All tests
Icom ID-31A CopyAll PASSED: All tests
Icom ID-31A Clone PASSED: All tests
Icom ID-31A BruteForce PASSED: All tests
Icom ID-31A Edges PASSED: All tests
Icom ID-31A Banks PASSED: All tests
Icom ID-51A Detect PASSED: All tests
Icom ID-51A CopyAll PASSED: All tests
Icom ID-51A Clone PASSED: All tests
Icom ID-51A BruteForce PASSED: All tests
Icom ID-51A Edges PASSED: All tests
Icom ID-51A Banks PASSED: All tests
Icom ID-800H v2 Detect PASSED: All tests
Icom ID-800H v2 CopyAll PASSED: All tests
Icom ID-800H v2 Clone PASSED: All tests
Icom ID-800H v2 BruteForce PASSED: All tests
Icom ID-800H v2 Edges PASSED: All tests
Icom ID-800H v2 Banks PASSED: All tests
Icom ID-880H Detect PASSED: All tests
Icom ID-880H CopyAll PASSED: All tests
Icom ID-880H Clone PASSED: All tests
Icom ID-880H BruteForce PASSED: All tests
Icom ID-880H Edges PASSED: All tests
Icom ID-880H Banks PASSED: All tests
Jetstream JT220M Detect PASSED: All tests
Jetstream JT220M CopyAll PASSED: All tests
Jetstream JT220M Clone PASSED: All tests
Jetstream JT220M BruteForce PASSED: All tests
Jetstream JT220M Edges PASSED: All tests
Jetstream JT220M Banks SKIPPED: Banks not supported
Jetstream JT270M Detect PASSED: All tests
Jetstream JT270M CopyAll PASSED: All tests
Jetstream JT270M Clone PASSED: All tests
Jetstream JT270M BruteForce PASSED: All tests
Jetstream JT270M Edges PASSED: All tests
Jetstream JT270M Banks SKIPPED: Banks not supported
Kenwood TH-D72 (clone Detect PASSED: All tests
Kenwood TH-D72 (clone CopyAll PASSED: All tests
Kenwood TH-D72 (clone Clone PASSED: All tests
Kenwood TH-D72 (clone BruteForce PASSED: All tests
Kenwood TH-D72 (clone Edges PASSED: All tests
Kenwood TH-D72 (clone Banks SKIPPED: Banks not supported
Kenwood TK-8102 Detect PASSED: All tests
Kenwood TK-8102 CopyAll PASSED: All tests
Kenwood TK-8102 Clone PASSED: All tests
Kenwood TK-8102 BruteForce PASSED: All tests
Kenwood TK-8102 Edges PASSED: All tests
Kenwood TK-8102 Banks SKIPPED: Banks not supported
Leixen VV-898 Detect PASSED: All tests
Leixen VV-898 CopyAll PASSED: All tests
Leixen VV-898 Clone PASSED: All tests
Leixen VV-898 BruteForce PASSED: All tests
Leixen VV-898 Edges PASSED: All tests
Leixen VV-898 Banks SKIPPED: Banks not supported
Polmar DB-50M Detect PASSED: All tests
Polmar DB-50M CopyAll PASSED: All tests
Polmar DB-50M Clone PASSED: All tests
Polmar DB-50M BruteForce PASSED: All tests
Polmar DB-50M Edges PASSED: All tests
Polmar DB-50M Banks SKIPPED: Banks not supported
Puxing PX-2R Detect PASSED: All tests
Puxing PX-2R CopyAll PASSED: All tests
Puxing PX-2R Clone PASSED: All tests
Puxing PX-2R BruteForce PASSED: All tests
Puxing PX-2R Edges PASSED: All tests
Puxing PX-2R Banks SKIPPED: Banks not supported
Puxing PX-777 Detect PASSED: All tests
Puxing PX-777 CopyAll PASSED: All tests
Puxing PX-777 Clone PASSED: All tests
Puxing PX-777 BruteForce PASSED: All tests
Puxing PX-777 Edges PASSED: All tests
Puxing PX-777 Banks SKIPPED: Banks not supported
Sainsonic AP510 Detect PASSED: All tests
Sainsonic AP510 CopyAll PASSED: All tests
Sainsonic AP510 Clone PASSED: All tests
Sainsonic AP510 BruteForce PASSED: All tests
Sainsonic AP510 Edges PASSED: All tests
Sainsonic AP510 Banks SKIPPED: Banks not supported
TYT TH-UV3R Detect PASSED: All tests
TYT TH-UV3R CopyAll PASSED: All tests
TYT TH-UV3R Clone PASSED: All tests
TYT TH-UV3R BruteForce PASSED: All tests
TYT TH-UV3R Edges PASSED: All tests
TYT TH-UV3R Banks SKIPPED: Banks not supported
TYT TH-UVF1 Detect PASSED: All tests
TYT TH-UVF1 CopyAll PASSED: All tests
TYT TH-UVF1 Clone PASSED: All tests
TYT TH-UVF1 BruteForce PASSED: All tests
TYT TH-UVF1 Edges PASSED: All tests
TYT TH-UVF1 Banks SKIPPED: Banks not supported
Vertex VXA-700 Detect PASSED: All tests
Vertex VXA-700 CopyAll PASSED: All tests
Vertex VXA-700 Clone PASSED: All tests
Vertex VXA-700 BruteForce PASSED: All tests
Vertex VXA-700 Edges PASSED: All tests
Vertex VXA-700 Banks SKIPPED: Banks not supported
Wouxun KG-816 Detect PASSED: All tests
Wouxun KG-816 CopyAll PASSED: All tests
Wouxun KG-816 Clone PASSED: All tests
Wouxun KG-816 BruteForce PASSED: All tests
Wouxun KG-816 Edges PASSED: All tests
Wouxun KG-816 Banks SKIPPED: Banks not supported
Wouxun KG-818 Detect PASSED: All tests
Wouxun KG-818 CopyAll PASSED: All tests
Wouxun KG-818 Clone PASSED: All tests
Wouxun KG-818 BruteForce PASSED: All tests
Wouxun KG-818 Edges PASSED: All tests
Wouxun KG-818 Banks SKIPPED: Banks not supported
Wouxun KG-UV6 Detect PASSED: All tests
Wouxun KG-UV6 CopyAll PASSED: All tests
Wouxun KG-UV6 Clone PASSED: All tests
Wouxun KG-UV6 BruteForce PASSED: All tests
Wouxun KG-UV6 Edges PASSED: All tests
Wouxun KG-UV6 Banks SKIPPED: Banks not supported
Wouxun KG-UVD1P Detect PASSED: All tests
Wouxun KG-UVD1P CopyAll PASSED: All tests
Wouxun KG-UVD1P Clone PASSED: All tests
Wouxun KG-UVD1P BruteForce PASSED: All tests
Wouxun KG-UVD1P Edges PASSED: All tests
Wouxun KG-UVD1P Banks SKIPPED: Banks not supported
Yaesu FT-1802M Detect PASSED: All tests
Yaesu FT-1802M CopyAll PASSED: All tests
Yaesu FT-1802M Clone PASSED: All tests
Yaesu FT-1802M BruteForce PASSED: All tests
Yaesu FT-1802M Edges PASSED: All tests
Yaesu FT-1802M Banks SKIPPED: Banks not supported
Yaesu FT-2800M Detect PASSED: All tests
Yaesu FT-2800M CopyAll PASSED: All tests
Yaesu FT-2800M Clone PASSED: All tests
Yaesu FT-2800M BruteForce PASSED: All tests
Yaesu FT-2800M Edges PASSED: All tests
Yaesu FT-2800M Banks SKIPPED: Banks not supported
Yaesu FT-60 Detect PASSED: All tests
Yaesu FT-60 CopyAll PASSED: All tests
Yaesu FT-60 Clone PASSED: All tests
Yaesu FT-60 BruteForce PASSED: All tests
Yaesu FT-60 Edges PASSED: All tests
Yaesu FT-60 Banks SKIPPED: Banks not supported
Yaesu FT-7800/7900 Detect PASSED: All tests
Yaesu FT-7800/7900 CopyAll PASSED: All tests
Yaesu FT-7800/7900 Clone PASSED: All tests
Yaesu FT-7800/7900 BruteForce PASSED: All tests
Yaesu FT-7800/7900 Edges PASSED: All tests
Yaesu FT-7800/7900 Banks PASSED: All tests
Yaesu FT-817 Detect PASSED: All tests
Yaesu FT-817 CopyAll PASSED: All tests
Yaesu FT-817 Clone PASSED: All tests
Yaesu FT-817 BruteForce PASSED: All tests
Yaesu FT-817 Edges PASSED: All tests
Yaesu FT-817 Banks SKIPPED: Banks not supported
Yaesu FT-817ND Detect PASSED: All tests
Yaesu FT-817ND CopyAll PASSED: All tests
Yaesu FT-817ND Clone PASSED: All tests
Yaesu FT-817ND BruteForce PASSED: All tests
Yaesu FT-817ND Edges PASSED: All tests
Yaesu FT-817ND Banks SKIPPED: Banks not supported
Yaesu FT-817ND (US) Detect PASSED: All tests
Yaesu FT-817ND (US) CopyAll PASSED: All tests
Yaesu FT-817ND (US) Clone PASSED: All tests
Yaesu FT-817ND (US) BruteForce PASSED: All tests
Yaesu FT-817ND (US) Edges PASSED: All tests
Yaesu FT-817ND (US) Banks SKIPPED: Banks not supported
Yaesu FT-857/897 Detect PASSED: All tests
Yaesu FT-857/897 CopyAll PASSED: All tests
Yaesu FT-857/897 Clone PASSED: All tests
Yaesu FT-857/897 BruteForce PASSED: All tests
Yaesu FT-857/897 Edges PASSED: All tests
Yaesu FT-857/897 Banks SKIPPED: Banks not supported
Yaesu FT-857/897 (U Detect PASSED: All tests
Yaesu FT-857/897 (U CopyAll PASSED: All tests
Yaesu FT-857/897 (U Clone PASSED: All tests
Yaesu FT-857/897 (U BruteForce PASSED: All tests
Yaesu FT-857/897 (U Edges PASSED: All tests
Yaesu FT-857/897 (U Banks SKIPPED: Banks not supported
Yaesu FT-8800 Left Detect PASSED: All tests
Yaesu FT-8800 Left CopyAll PASSED: All tests
Yaesu FT-8800 Left Clone PASSED: All tests
Yaesu FT-8800 Left BruteForce PASSED: All tests
Yaesu FT-8800 Left Edges PASSED: All tests
Yaesu FT-8800 Left Banks PASSED: All tests
Yaesu FT-8800 Right Detect PASSED: All tests
Yaesu FT-8800 Right CopyAll PASSED: All tests
Yaesu FT-8800 Right Clone PASSED: All tests
Yaesu FT-8800 Right BruteForce PASSED: All tests
Yaesu FT-8800 Right Edges PASSED: All tests
Yaesu FT-8800 Right Banks PASSED: All tests
Yaesu FT-8900 Detect PASSED: All tests
Yaesu FT-8900 CopyAll PASSED: All tests
Yaesu FT-8900 Clone PASSED: All tests
Yaesu FT-8900 BruteForce PASSED: All tests
Yaesu FT-8900 Edges PASSED: All tests
Yaesu FT-8900 Banks SKIPPED: Banks not supported
Yaesu FTM-350 Left Detect PASSED: All tests
Yaesu FTM-350 Left CopyAll PASSED: All tests
Yaesu FTM-350 Left Clone PASSED: All tests
Yaesu FTM-350 Left BruteForce PASSED: All tests
Yaesu FTM-350 Left Edges PASSED: All tests
Yaesu FTM-350 Left Banks SKIPPED: Banks not supported
Yaesu FTM-350 Right Detect PASSED: All tests
Yaesu FTM-350 Right CopyAll PASSED: All tests
Yaesu FTM-350 Right Clone PASSED: All tests
Yaesu FTM-350 Right BruteForce PASSED: All tests
Yaesu FTM-350 Right Edges PASSED: All tests
Yaesu FTM-350 Right Banks SKIPPED: Banks not supported
Yaesu VX-2 Detect PASSED: All tests
Yaesu VX-2 CopyAll PASSED: All tests
Yaesu VX-2 Clone PASSED: All tests
Yaesu VX-2 BruteForce PASSED: All tests
Yaesu VX-2 Edges PASSED: All tests
Yaesu VX-2 Banks PASSED: All tests
Yaesu VX-3 Detect PASSED: All tests
Yaesu VX-3 CopyAll PASSED: All tests
Yaesu VX-3 Clone PASSED: All tests
Yaesu VX-3 BruteForce PASSED: All tests
Yaesu VX-3 Edges PASSED: All tests
Yaesu VX-3 Banks PASSED: All tests
Yaesu VX-5 Detect PASSED: All tests
Yaesu VX-5 CopyAll PASSED: All tests
Yaesu VX-5 Clone PASSED: All tests
Yaesu VX-5 BruteForce PASSED: All tests
Yaesu VX-5 Edges PASSED: All tests
Yaesu VX-5 Banks PASSED: All tests
Yaesu VX-6 Detect PASSED: All tests
Yaesu VX-6 CopyAll PASSED: All tests
Yaesu VX-6 Clone PASSED: All tests
Yaesu VX-6 BruteForce PASSED: All tests
Yaesu VX-6 Edges PASSED: All tests
Yaesu VX-6 Banks PASSED: All tests
Yaesu VX-7 Detect PASSED: All tests
Yaesu VX-7 CopyAll PASSED: All tests
Yaesu VX-7 Clone PASSED: All tests
Yaesu VX-7 BruteForce PASSED: All tests
Yaesu VX-7 Edges PASSED: All tests
Yaesu VX-7 Banks PASSED: All tests
Yaesu VX-8 R Detect PASSED: All tests
Yaesu VX-8 R CopyAll PASSED: All tests
Yaesu VX-8 R Clone PASSED: All tests
Yaesu VX-8 R BruteForce PASSED: All tests
Yaesu VX-8 R Edges PASSED: All tests
Yaesu VX-8 R Banks PASSED: All tests
----------------------------------------------------------------------
Results:
TOTAL : 360
FAILED : 0
SKIPPED: 41
PASSED : 319
CRASHED: 0
Registered Icom_IC-2820H = IC2820Radio
Registered TYT_TH-UVF8D = TYTUVF8DRadio
Registered AnyTone_5888UV = AnyTone5888UVRadio
Registered Intek_HR-2040 = IntekHR2040Radio
Registered Polmar_DB-50M = PolmarDB50MRadio
Registered Powerwerx_DB-750X = PowerwerxDB750XRadio
Registered Icom_IC-2200H = IC2200Radio
Registered Yaesu_FT-2800M = FT2800Radio
Registered Yaesu_VX-3 = VX3Radio
Registered Icom_IC-2100H = IC2100Radio
Registered Yaesu_FTM-350 = FTM350Radio
Registered Icom_IC-V82_U82 = ICx8xRadio
Registered Yaesu_VX-6 = VX6Radio
Registered Yaesu_VX-5 = VX5Radio
Registered Yaesu_FT-60 = FT60Radio
Registered Yaesu_VX-7 = VX7Radio
Registered Sainsonic_AP510 = AP510Radio
Registered Baofeng_UV-5R = BaofengUV5R
Registered Baofeng_F-11 = BaofengF11Radio
Registered Baofeng_UV-82 = BaofengUV82Radio
Registered Baofeng_UV-6 = BaofengUV6Radio
Registered Intek_KT-980HP = IntekKT980Radio
Registered Baofeng_BF-F8HP = BaofengBFF8HPRadio
Registered Yaesu_FT-1802M = FT1802Radio
Registered Kenwood_TK-7102 = KenwoodTK7102Radio
Registered Kenwood_TK-8102 = KenwoodTK8102Radio
Registered Kenwood_TK-7108 = KenwoodTK7108Radio
Registered Kenwood_TK-8108 = KenwoodTK8108Radio
Registered Icom_ID-31A = ID31Radio
Registered Icom_ID-51A = ID51Radio
Registered Icom_IC-2720H = IC2720Radio
Registered Icom_IC-T8A = ICT8ARadio
Registered Wouxun_KG-UVD1P = KGUVD1PRadio
Registered Wouxun_KG-UV6 = KGUV6DRadio
Registered Wouxun_KG-816 = KG816Radio
Registered Wouxun_KG-818 = KG818Radio
Registered TYT_TH-UVF1 = TYTTHUVF1Radio
Registered Yaesu_FT-90 = FT90Radio
Registered Generic_CSV = CSVRadio
Registered Commander_KG-UV = CommanderCSVRadio
Registered RT_Systems_CSV = RTCSVRadio
Registered Kenwood_ITM = ITMRadio
Registered TYT_TH-9800 = TYTTH9800File
Registered Alinco_DR03T = DR03Radio
Registered Alinco_DR06T = DR06Radio
Registered Alinco_DR135T = DR135Radio
Registered Alinco_DR235T = DR235Radio
Registered Alinco_DR435T = DR435Radio
Registered Alinco_DJ596 = DJ596Radio
Registered Jetstream_JT220M = JT220MRadio
Registered Alinco_DJ175 = DJ175Radio
Registered Kenwood_TH-D7 = THD7Radio
Registered Kenwood_TH-D7G = THD7GRadio
Registered Kenwood_TM-D700 = TMD700Radio
Registered Kenwood_TM-V7 = TMV7Radio
Registered Kenwood_TM-G707 = TMG707Radio
Registered Kenwood_TH-G71 = THG71Radio
Registered Kenwood_TH-F6 = THF6ARadio
Registered Kenwood_TH-F7 = THF7ERadio
Registered Kenwood_TM-D710 = TMD710Radio
Registered Kenwood_TH-D72_live_mode = THD72Radio
Registered Kenwood_TM-V71 = TMV71Radio
Registered Kenwood_TH-K2 = THK2Radio
Registered Kenwood_TM-271 = TM271Radio
Registered Kenwood_TM-281 = TM281Radio
Registered Kenwood_TM-471 = TM471Radio
Registered Yaesu_FT-1D_R = FT1Radio
Registered Wouxun_KG-UV8D = KGUV8DRadio
Registered Yaesu_VX-8_R = VX8Radio
Registered Yaesu_VX-8_DR = VX8DRadio
Registered Yaesu_VX-8_GE = VX8GERadio
Registered Icom_IC-T7H = ICT7HRadio
Registered Icom_IC-Q7A = ICQ7Radio
Registered Baofeng_UV-B5 = BaofengUVB5
Registered Generic_XML = XMLRadio
Registered Kenwood_HMK = HMKRadio
Registered Kenwood_TH-D72_clone_mode = THD72Radio
Registered Icom_IC-91_92AD = IC9xRadio
Registered Icom_IC-T70 = ICT70Radio
Registered Icom_IC-208H = IC208Radio
Registered Leixen_VV-898 = LeixenVV898Radio
Registered Jetstream_JT270M = JetstreamJT270MRadio
Registered Icom_ID-800H_v2 = ID800v2Radio
Registered Icom_7200 = Icom7200Radio
Registered Icom_7000 = Icom7000Radio
Registered Icom_746 = Icom746Radio
Registered ARRL_Travel_Plus = TpeRadio
Registered Vertex_Standard_VXA-700 = VXA700Radio
Registered Icom_IC-W32A = ICW32ARadio
Registered Baofeng_UV-3R = UV3RRadio
Registered Yaesu_VX-2 = VX2Radio
Registered Puxing_PX-777 = Puxing777Radio
Registered Puxing_PX-2R = Puxing2RRadio
Registered Baojie_BJ-UV55 = BaojieBJUV55Radio
Registered Baofeng_BF-888 = H777Radio
Registered Yaesu_FT-7800_7900 = FT7800Radio
Registered Yaesu_FT-8800 = FT8800Radio
Registered Yaesu_FT-8900 = FT8900Radio
Registered KYD_NC-630A = NC630aRadio
Registered Yaesu_FT-817 = FT817Radio
Registered Yaesu_FT-817ND = FT817NDRadio
Registered Yaesu_FT-817ND_US = FT817NDUSRadio
Registered Yaesu_FT-857_897 = FT857Radio
Registered Yaesu_FT-857_897_US = FT857USRadio
Registered Yaesu_VX-170 = VX170Radio
Registered Icom_ID-880H = ID880Radio
Registered Icom_ID-80H = ID80Radio
Registered TYT_TH-UV3R = TYTUV3RRadio
Patch 'tip' is OK
================================================
Tests OK
Email was triggered for: Success
Sending email for trigger: Success
1
0
30 Dec '14
# HG changeset patch
# User Jim Unroe <rock.unroe(a)gmail.com>
# Date 1419953224 18000
# Node ID bd0e17aaab95034535ffc65820849edec035ac10
# Parent 44cde2f5afd11fe7d3bd08afb4baaf1c9d4eaa5f
[VV-898] Update Image Detections (Improved)
Improve method to fall back to original detection string for older data files
Better detect between Jetstream, Leixen (v1.02 and v1.03) images
related to #2119
diff -r 44cde2f5afd1 -r bd0e17aaab95 chirp/leixen.py
--- a/chirp/leixen.py Thu Dec 25 07:25:01 2014 -0500
+++ b/chirp/leixen.py Tue Dec 30 10:27:04 2014 -0500
@@ -69,7 +69,7 @@
def _image_ident_from_data(data):
- return data[0x170:0x176]
+ return data[0x168:0x178]
def _image_ident_from_image(radio):
return _image_ident_from_data(radio.get_mmap())
@@ -148,7 +148,7 @@
_ranges = [(0x0d00, 0x2000)]
image_ident = _image_ident_from_image(radio)
- if image_ident == radio._file_ident:
+ if image_ident.startswith(radio._file_ident) and "LX-" in image_ident:
_ranges = radio._ranges
do_ident(radio)
@@ -183,11 +183,11 @@
MODEL = "VV-898"
BAUD_RATE = 9600
- _file_ident = "LX-\x89\x85\x63"
+ _file_ident = "Leixen"
_memsize = 0x2000
_ranges = [
(0x0000, 0x013f),
- (0x0148, 0x016f),
+ (0x0148, 0x0167),
(0x0184, 0x018f),
(0x0190, 0x01cf),
(0x0900, 0x090f),
@@ -360,11 +360,13 @@
@classmethod
def match_model(cls, filedata, filename):
- if filedata[0x170:0x176] == cls._file_ident:
+ if filedata[0x168:0x170].startswith(cls._file_ident) and \
+ filedata[0x170:0x178].startswith("LX-/x89/x85"):
return True
elif filedata[0x900:0x906] == cls.MODEL:
return True
- return False
+ else:
+ return False
@directory.register
@@ -373,4 +375,4 @@
VENDOR = "Jetstream"
MODEL = "JT270M"
- _file_ident = "LX-\x89\x85\x53"
+ _file_ident = "JET"
1
0
29 Dec '14
issue #967 - add aprs beacon and message parsing
The FT1DR stores the APRS messages and beacons in the clone.
This patch displays those messages in the settings tab.
diff -r c3dacbee3ecf -r 3e008f702ad9 chirp/ft1d.py
--- a/chirp/ft1d.py Sat Dec 27 23:16:48 2014 -0700
+++ b/chirp/ft1d.py Sun Dec 28 10:41:55 2014 -0700
@@ -16,6 +16,7 @@
import os
import re
+import string
from chirp import chirp_common, yaesu_clone, directory
from chirp import bitwise
@@ -317,19 +318,19 @@
#seekto 0x%04X;
struct {
- u8 dst_callsign[6];
- u8 dst_callsign_ssid;
- u8 src_callsign[6];
- u8 src_callsign_ssid;
- u8 path_and_body[%d];
+ char dst_callsign[9];
+ char path[30];
+ u16 flags;
+ u8 seperator;
+ char body[%d];
} aprs_beacon_pkt[%d];
#seekto 0x137c4;
struct {
- u8 unknown0;
- u8 dst_callsign[6];
+ u8 flag;
+ char dst_callsign[6];
u8 dst_callsign_ssid;
- u8 path_and_body[66];
+ char path_and_body[66];
u8 unknown[70];
} aprs_message_pkt[60];
@@ -515,7 +516,7 @@
_mem_params = (0xFECA, # APRS beacon metadata address.
60, # Number of beacons stored.
0x1064A, # APRS beacon content address.
- 162, # Length of beacon data stored.
+ 134, # Length of beacon data stored.
60) # Number of beacons stored.
_has_vibrate = False
_has_af_dual = True
@@ -944,6 +945,54 @@
return menu
+ def _get_aprs_msgs(self):
+ menu = RadioSettingGroup("aprs_msg", "APRS Messages")
+ aprs_msg = self._memobj.aprs_message_pkt
+
+ for index in range( 0, 60 ):
+ if aprs_msg[index].flag != 255 :
+ val = RadioSettingValueString(0, 9,
+ str(aprs_msg[index].dst_callsign).rstrip("\xFF") +
"-%d" % aprs_msg[index].dst_callsign_ssid )
+ rs = RadioSetting("aprs_msg.dst_callsign%d" % index,
"Dst Callsign %d" % index, val)
+ menu.append(rs)
+
+ val = RadioSettingValueString(0, 66,
+ str(aprs_msg[index].path_and_body).rstrip("\xFF"))
+ rs = RadioSetting("aprs_msg.path_and_body%d" % index,
"Body", val)
+ menu.append(rs)
+
+ return menu
+
+ def _get_aprs_beacons(self):
+ menu = RadioSettingGroup("aprs_beacons", "APRS Beacons")
+ aprs_beacon = self._memobj.aprs_beacon_pkt
+
+ for index in range( 0, 60 ):
+ # There is probably a more pythonesque way to do this
+ if int( aprs_beacon[index].dst_callsign[0] ) != 255 :
+ #print "DST callsign %s %d %s" % (
aprs_beacon[index].dst_callsign, aprs_beacon[index].dst_callsign[0],
list( str( aprs_beacon[index].dst_callsign )))
+ val = RadioSettingValueString(0, 9,
+ str(aprs_beacon[index].dst_callsign).rstrip("\xFF")
)
+ rs = RadioSetting("aprs_beacon.dst_callsign%d" % index,
"DST Callsign %d" % index, val)
+ menu.append(rs)
+
+ path = str( aprs_beacon[index].path ).replace( "\x00",
" " )
+ path = ''.join(c for c in path if c in
string.printable).strip()
+ path = str( path ).replace( "\xE0", "*" )
+ #print "path %s %s" % ( path, list(path) )
+ val = RadioSettingValueString(0, 32, path)
+ rs = RadioSetting("aprs_beacon.path%d" % index,
"Digipath", val)
+ menu.append(rs)
+
+ body = str( aprs_beacon[index].body ).rstrip("\xFF")
+ checksum = body[-2:]
+ body = ''.join(s for s in body[:-2] if s in
string.printable).replace( "\x0d", " " )
+ val = RadioSettingValueString(0, 134, body.strip())
+ rs = RadioSetting("aprs_beacon.body%d" % index, "Body",
val)
+ menu.append(rs)
+
+ return menu
+
def _get_aprs_rx_settings(self):
menu = RadioSettingGroup("aprs_rx", "APRS Receive")
aprs = self._memobj.aprs
@@ -1378,6 +1427,8 @@
self._get_aprs_rx_settings(),
self._get_aprs_tx_settings(),
self._get_aprs_smartbeacon(),
+ self._get_aprs_msgs(),
+ self._get_aprs_beacons(),
self._get_dtmf_settings(),
self._get_misc_settings(),
self._get_scan_settings())
5
9
This patch is to be applied over Angus's FT1D driver
In my area people use to put any kind of nasty char in APRS messages :(
73 de IZ3GME Marco
1
1
This patch combines all of the previous patches and adds some new APRS
fixes.
I was unable to get mecurial to talk to my smtps server so hopefully the
attachment works.
Angus
3
4
issue #967 - fix FT1DR settings
- fix the alignment for the aprs structs
- fix alignment for misc and scan settings
diff -r 7e83ceb5428d -r c3dacbee3ecf chirp/ft1d.py
--- a/chirp/ft1d.py Fri Dec 26 16:29:32 2014 -0700
+++ b/chirp/ft1d.py Sat Dec 27 23:16:48 2014 -0700
@@ -24,23 +24,46 @@
from chirp.settings import RadioSettingValueList,
RadioSettingValueBoolean
from textwrap import dedent
-OLD_FORMAT = """
+MEM_FORMAT = """
#seekto 0x049a;
struct {
u8 vfo_a;
u8 vfo_b;
} squelch;
-#seekto 0x04bf;
+#seekto 0x04c1;
struct {
u8 beep;
} beep_select;
+#seekto 0x04ce;
+struct {
+ u8 lcd_dimmer;
+ u8 dtmf_delay;
+ u8 unknown0[3];
+ u8 unknown1:4
+ lcd_contrast:4;
+ u8 lamp;
+ u8 unknown2[7];
+ u8 scan_restart;
+ u8 unknown3;
+ u8 scan_resume;
+ u8 unknown4[5];
+ u8 tot;
+ u8 unknown5[3];
+ u8 unknown6:2,
+ scan_lamp:1,
+ unknown7:2,
+ dtmf_speed:1,
+ unknown8:1,
+ dtmf_mode:1;
+ u8 busy_led:1,
+ unknown9:7;
+ u8 unknown10[2];
+ u8 vol_mode:1,
+ unknown11:7;
+} scan_settings;
-
-"""
-
-MEM_FORMAT = """
#seekto 0x064a;
struct {
u8 unknown0[4];
@@ -85,38 +108,11 @@
u8 checksum;
} vfo_info[6];
-#seekto 0x04ce;
-struct {
- u8 lcd_dimmer;
- u8 dtmf_delay;
- u8 unknown0[3];
- u8 unknown1:4
- lcd_contrast:4;
- u8 lamp;
- u8 unknown2[7];
- u8 scan_restart;
- u8 unknown3;
- u8 scan_resume;
- u8 unknown4[5];
- u8 tot;
- u8 unknown5[3];
- u8 unknown6:2,
- scan_lamp:1,
- unknown7:2,
- dtmf_speed:1,
- unknown8:1,
- dtmf_mode:1;
- u8 busy_led:1,
- unknown9:7;
- u8 unknown10[2];
- u8 vol_mode:1,
- unknown11:7;
-} scan_settings;
-
#seekto 0x047e;
struct {
- u16 flag;
- u16 unknown;
+ u8 unknown1;
+ u8 flag;
+ u16 unknown2;
struct {
u8 padded_yaesu[16];
} message;
@@ -175,8 +171,8 @@
#seekto 0xbeca;
struct {
+ u8 rx_baud;
u8 custom_symbol;
- u8 unknown2;
struct {
char callsign[6];
u8 ssid;
@@ -210,10 +206,8 @@
filter_weather:1,
filter_position:1,
filter_mic_e:1;
- u8 unknown12:2,
- timezone:6;
- u8 unknown13:4,
- beacon_interval:4;
+ u8 unknown12;
+ u8 unknown13;
u8 unknown14;
u8 unknown15:7,
latitude_sign:1;
@@ -229,19 +223,23 @@
selected_position:4;
u8 unknown18:5,
selected_beacon_status_txt:3;
- u8 unknown19:6,
+ u8 unknown19:4,
+ beacon_interval:4;
+ u8 unknowni21:4,
+ tx_delay:4;
+ u8 unknown21b:6,
gps_units_altitude_ft:1,
gps_units_position_sss:1;
u8 unknown20:6,
gps_units_speed:2;
- u8 unknown21[4];
+ u8 unknown21c[4];
struct {
struct {
char callsign[6];
u8 ssid;
} entry[8];
} digi_path_7;
- u8 unknown22[2];
+ u8 unknown22[18];
struct {
char padded_string[16];
} message_macro[7];
@@ -251,7 +249,10 @@
struct {
char padded_string[9];
} msg_group[8];
- u8 unknown25[4];
+ u8 unknown25;
+ u8 unknown25a:2,
+ timezone:6;
+ u8 unknown25b[2];
u8 active_smartbeaconing;
struct {
u8 low_speed_mph;
@@ -285,12 +286,18 @@
u8 unknown34:2,
vibrate_bln:6;
} aprs;
+
+#seekto 0xc26a;
+struct {
+ char padded_string[60];
+} aprs_beacon_status_txt[5];
+
#seekto 0x%04X;
struct {
bbcd date[3];
- u8 unknown1;
bbcd time[2];
u8 sequence;
+ u8 unknown1;
u8 unknown2;
u8 sender_callsign[7];
u8 data_type;
@@ -299,9 +306,13 @@
u8 unknown4:1,
callsign_is_ascii:1,
unknown5:6;
- u8 unknown6;
+ u8 unknown6[2];
u16 pkt_len;
+ u8 unknown7;
u16 in_use;
+ u16 unknown8;
+ u16 unknown9;
+ u16 unknown10;
} aprs_beacon_meta[%d];
#seekto 0x%04X;
@@ -313,10 +324,14 @@
u8 path_and_body[%d];
} aprs_beacon_pkt[%d];
-#seekto 0xf92a;
+#seekto 0x137c4;
struct {
- char padded_string[60];
-} aprs_beacon_status_txt[5];
+ u8 unknown0;
+ u8 dst_callsign[6];
+ u8 dst_callsign_ssid;
+ u8 path_and_body[66];
+ u8 unknown[70];
+} aprs_message_pkt[60];
#seekto 0x1FDC9;
u8 checksum;
@@ -500,7 +515,7 @@
_mem_params = (0xFECA, # APRS beacon metadata address.
60, # Number of beacons stored.
0x1064A, # APRS beacon content address.
- 144, # Length of beacon data stored.
+ 162, # Length of beacon data stored.
60) # Number of beacons stored.
_has_vibrate = False
_has_af_dual = True
@@ -561,7 +576,7 @@
["%.1fs" % (0.5 * x) for x in range(2,21)]
_LAMP_KEY = ["Key %d sec" % x for x in range(2,11)] +
["Continuous", "OFF"]
_LCD_CONTRAST = ["Level %d" % x for x in range(1,16)]
- _LCD_DIMMER = ["Level %d" % x for x in range(1,5)]
+ _LCD_DIMMER = ["Level %d" % x for x in range(1,7)]
_TOT_TIME = ["Off"] + ["%.1f min" % (0.5 * x) for x in range(1,
21)]
_OFF_ON = ("Off", "On")
_VOL_MODE = ("Normal", "Auto Back")
@@ -1006,7 +1021,7 @@
rs = RadioSetting("aprs.selected_msg_group", "Selected Message
Group",
val)
menu.append(rs)
-
+
val = RadioSettingValueBoolean(aprs.filter_mic_e)
rs = RadioSetting("aprs.filter_mic_e", "Receive Mic-E Beacons",
val)
menu.append(rs)
1
0
26 Dec '14
# HG changeset patch
# User nytowl
# Date 1419636572 25200
# Fri Dec 26 16:29:32 2014 -0700
# Node ID 7e83ceb5428d5e7ac3fff43424c022eea4f10939
# Parent 44cde2f5afd11fe7d3bd08afb4baaf1c9d4eaa5f
[ft1d] Add support for Yaesu FT1DR radio - issue #967
- This patch will upload and download channel and bank information to
the radio.
- This driver is based on the vx8 driver
- settings aren't working
- not all offsets have been checked, developer browser does show some
are correct
diff -r 44cde2f5afd1 -r 7e83ceb5428d chirp/ft1d.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/chirp/ft1d.py Fri Dec 26 16:29:32 2014 -0700
@@ -0,0 +1,1526 @@
+# Copyright 2010 Dan Smith <dsmith(a)danplanet.com>
+# Copyright 2014 Angus Ainslie <angus(a)akkea.ca>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import os
+import re
+
+from chirp import chirp_common, yaesu_clone, directory
+from chirp import bitwise
+from chirp.settings import RadioSettingGroup, RadioSetting
+from chirp.settings import RadioSettingValueInteger,
RadioSettingValueString
+from chirp.settings import RadioSettingValueList,
RadioSettingValueBoolean
+from textwrap import dedent
+
+OLD_FORMAT = """
+#seekto 0x049a;
+struct {
+ u8 vfo_a;
+ u8 vfo_b;
+} squelch;
+
+#seekto 0x04bf;
+struct {
+ u8 beep;
+} beep_select;
+
+
+
+"""
+
+MEM_FORMAT = """
+#seekto 0x064a;
+struct {
+ u8 unknown0[4];
+ u8 frequency_band;
+ u8 unknown1:6,
+ manual_or_mr:2;
+ u8 unknown2:7,
+ mr_banks:1;
+ u8 unknown3;
+ u16 mr_index;
+ u16 bank_index;
+ u16 bank_enable;
+ u8 unknown4[5];
+ u8 unknown5:6,
+ power:2;
+ u8 unknown6:4,
+ tune_step:4;
+ u8 unknown7:6,
+ duplex:2;
+ u8 unknown8:6,
+ tone_mode:2;
+ u8 unknown9:2,
+ tone:6;
+ u8 unknown10;
+ u8 unknown11:6,
+ mode:2;
+ bbcd freq0[4];
+ bbcd offset_freq[4];
+ u8 unknown12[2];
+ char label[16];
+ u8 unknown13[6];
+ bbcd band_lower[4];
+ bbcd band_upper[4];
+ bbcd rx_freq[4];
+ u8 unknown14[22];
+ bbcd freq1[4];
+ u8 unknown15[11];
+ u8 unknown16:3,
+ volume:5;
+ u8 unknown17[18];
+ u8 active_menu_item;
+ u8 checksum;
+} vfo_info[6];
+
+#seekto 0x04ce;
+struct {
+ u8 lcd_dimmer;
+ u8 dtmf_delay;
+ u8 unknown0[3];
+ u8 unknown1:4
+ lcd_contrast:4;
+ u8 lamp;
+ u8 unknown2[7];
+ u8 scan_restart;
+ u8 unknown3;
+ u8 scan_resume;
+ u8 unknown4[5];
+ u8 tot;
+ u8 unknown5[3];
+ u8 unknown6:2,
+ scan_lamp:1,
+ unknown7:2,
+ dtmf_speed:1,
+ unknown8:1,
+ dtmf_mode:1;
+ u8 busy_led:1,
+ unknown9:7;
+ u8 unknown10[2];
+ u8 vol_mode:1,
+ unknown11:7;
+} scan_settings;
+
+#seekto 0x047e;
+struct {
+ u16 flag;
+ u16 unknown;
+ struct {
+ u8 padded_yaesu[16];
+ } message;
+} opening_message;
+
+#seekto 0x0e4a;
+struct {
+ u8 memory[16];
+} dtmf[10];
+
+#seekto 0x154a;
+struct {
+ u16 channel[100];
+} bank_members[24];
+
+#seekto 0x54a;
+struct {
+ u16 in_use;
+} bank_used[24];
+
+#seekto 0x0EFE;
+struct {
+ u8 unknown[2];
+ u8 name[16];
+} bank_info[24];
+
+#seekto 0x2D4A;
+struct {
+ u8 unknown1;
+ u8 mode:2,
+ duplex:2,
+ tune_step:4;
+ bbcd freq[3];
+ u8 power:2,
+ unknown2:4,
+ tone_mode:2;
+ u8 charsetbits[2];
+ char label[16];
+ bbcd offset[3];
+ u8 unknown5:2,
+ tone:6;
+ u8 unknown6:1,
+ dcs:7;
+ u8 unknown7[3];
+} memory[900];
+
+#seekto 0x280A;
+struct {
+ u8 nosubvfo:1,
+ unknown:3,
+ pskip:1,
+ skip:1,
+ used:1,
+ valid:1;
+} flag[900];
+
+#seekto 0xbeca;
+struct {
+ u8 custom_symbol;
+ u8 unknown2;
+ struct {
+ char callsign[6];
+ u8 ssid;
+ } my_callsign;
+ u8 unknown3:4,
+ selected_position_comment:4;
+ u8 unknown4;
+ u8 set_time_manually:1,
+ tx_interval_beacon:1,
+ ring_beacon:1,
+ ring_msg:1,
+ aprs_mute:1,
+ unknown6:1,
+ tx_smartbeacon:1,
+ af_dual:1;
+ u8 unknown7:1,
+ aprs_units_wind_mph:1,
+ aprs_units_rain_inch:1,
+ aprs_units_temperature_f:1
+ aprs_units_altitude_ft:1,
+ unknown8:1,
+ aprs_units_distance_m:1,
+ aprs_units_position_mmss:1;
+ u8 unknown9:6,
+ aprs_units_speed:2;
+ u8 unknown11:1,
+ filter_other:1,
+ filter_status:1,
+ filter_item:1,
+ filter_object:1,
+ filter_weather:1,
+ filter_position:1,
+ filter_mic_e:1;
+ u8 unknown12:2,
+ timezone:6;
+ u8 unknown13:4,
+ beacon_interval:4;
+ u8 unknown14;
+ u8 unknown15:7,
+ latitude_sign:1;
+ u8 latitude_degree;
+ u8 latitude_minute;
+ u8 latitude_second;
+ u8 unknown16:7,
+ longitude_sign:1;
+ u8 longitude_degree;
+ u8 longitude_minute;
+ u8 longitude_second;
+ u8 unknown17:4,
+ selected_position:4;
+ u8 unknown18:5,
+ selected_beacon_status_txt:3;
+ u8 unknown19:6,
+ gps_units_altitude_ft:1,
+ gps_units_position_sss:1;
+ u8 unknown20:6,
+ gps_units_speed:2;
+ u8 unknown21[4];
+ struct {
+ struct {
+ char callsign[6];
+ u8 ssid;
+ } entry[8];
+ } digi_path_7;
+ u8 unknown22[2];
+ struct {
+ char padded_string[16];
+ } message_macro[7];
+ u8 unknown23:5,
+ selected_msg_group:3;
+ u8 unknown24;
+ struct {
+ char padded_string[9];
+ } msg_group[8];
+ u8 unknown25[4];
+ u8 active_smartbeaconing;
+ struct {
+ u8 low_speed_mph;
+ u8 high_speed_mph;
+ u8 slow_rate_min;
+ u8 fast_rate_sec;
+ u8 turn_angle;
+ u8 turn_slop;
+ u8 turn_time_sec;
+ } smartbeaconing_profile[3];
+ u8 unknown26:2,
+ flash_msg:6;
+ u8 unknown27:2,
+ flash_grp:6;
+ u8 unknown28:2,
+ flash_bln:6;
+ u8 selected_digi_path;
+ struct {
+ struct {
+ char callsign[6];
+ u8 ssid;
+ } entry[2];
+ } digi_path_3_6[4];
+ u8 unknown30:6,
+ selected_my_symbol:2;
+ u8 unknown31[3];
+ u8 unknown32:2,
+ vibrate_msg:6;
+ u8 unknown33:2,
+ vibrate_grp:6;
+ u8 unknown34:2,
+ vibrate_bln:6;
+} aprs;
+#seekto 0x%04X;
+struct {
+ bbcd date[3];
+ u8 unknown1;
+ bbcd time[2];
+ u8 sequence;
+ u8 unknown2;
+ u8 sender_callsign[7];
+ u8 data_type;
+ u8 yeasu_data_type;
+ u8 unknown3;
+ u8 unknown4:1,
+ callsign_is_ascii:1,
+ unknown5:6;
+ u8 unknown6;
+ u16 pkt_len;
+ u16 in_use;
+} aprs_beacon_meta[%d];
+
+#seekto 0x%04X;
+struct {
+ u8 dst_callsign[6];
+ u8 dst_callsign_ssid;
+ u8 src_callsign[6];
+ u8 src_callsign_ssid;
+ u8 path_and_body[%d];
+} aprs_beacon_pkt[%d];
+
+#seekto 0xf92a;
+struct {
+ char padded_string[60];
+} aprs_beacon_status_txt[5];
+
+#seekto 0x1FDC9;
+u8 checksum;
+"""
+
+TMODES = ["", "Tone", "TSQL", "DTCS"]
+DUPLEX = ["", "-", "+", "split"]
+MODES = ["FM", "AM", "WFM"]
+STEPS = list(chirp_common.TUNING_STEPS)
+STEPS.remove(30.0)
+STEPS.append(100.0)
+STEPS.insert(2, 0.0) # There is a skipped tuning step at index 2 (?)
+SKIPS = ["", "S", "P"]
+FT1_DTMF_CHARS = list("0123456789ABCD*#-")
+
+CHARSET = ["%i" % int(x) for x in range(0, 10)] + \
+ [chr(x) for x in range(ord("A"), ord("Z")+1)] + \
+ [" ",] + \
+ [chr(x) for x in range(ord("a"), ord("z")+1)] + \
+ list(".,:;*#_-/&()@!?^ ") + list("\x00" * 100)
+
+POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00),
+ chirp_common.PowerLevel("L3", watts=2.50),
+ chirp_common.PowerLevel("L2", watts=1.00),
+ chirp_common.PowerLevel("L1", watts=0.05)]
+
+class FT1Bank(chirp_common.NamedBank):
+ """A FT1 bank"""
+
+ def get_name(self):
+ _bank = self._model._radio._memobj.bank_info[self.index]
+ _bank_used = self._model._radio._memobj.bank_used[self.index]
+
+ name = ""
+ for i in _bank.name:
+ if i == 0xFF:
+ break
+ name += CHARSET[i & 0x7F]
+ return name.rstrip()
+
+ def set_name(self, name):
+ _bank = self._model._radio._memobj.bank_info[self.index]
+ _bank.name = [CHARSET.index(x) for x in name.ljust(16)[:16]]
+
+class FT1BankModel(chirp_common.BankModel):
+ """A FT1 bank model"""
+ def __init__(self, radio, name='Banks'):
+ super(FT1BankModel, self).__init__(radio, name)
+
+ _banks = self._radio._memobj.bank_info
+ self._bank_mappings = []
+ for index, _bank in enumerate(_banks):
+ bank = FT1Bank(self, "%i" % index, "BANK-%i" % index)
+ bank.index = index
+ self._bank_mappings.append(bank)
+
+ def get_num_mappings(self):
+ return len(self._bank_mappings)
+
+ def get_mappings(self):
+ return self._bank_mappings
+
+ def _channel_numbers_in_bank(self, bank):
+ _bank_used = self._radio._memobj.bank_used[bank.index]
+ if _bank_used.in_use == 0xFFFF:
+ return set()
+
+ _members = self._radio._memobj.bank_members[bank.index]
+ return set([int(ch) + 1 for ch in _members.channel if ch !=
0xFFFF])
+
+ def update_vfo(self):
+ chosen_bank = [None, None]
+ chosen_mr = [None, None]
+
+ flags = self._radio._memobj.flag
+
+ # Find a suitable bank and MR for VFO A and B.
+ for bank in self.get_mappings():
+ for channel in self._channel_numbers_in_bank(bank):
+ chosen_bank[0] = bank.index
+ chosen_mr[0] = channel
+ if not flags[channel].nosubvfo:
+ chosen_bank[1] = bank.index
+ chosen_mr[1] = channel
+ break
+ if chosen_bank[1]:
+ break
+
+ for vfo_index in (0, 1):
+ # 3 VFO info structs are stored as 3 pairs of (master,
backup)
+ vfo = self._radio._memobj.vfo_info[vfo_index * 2]
+ vfo_bak = self._radio._memobj.vfo_info[(vfo_index * 2) + 1]
+
+ if vfo.checksum != vfo_bak.checksum:
+ print "Warning: VFO settings are inconsistent with
backup"
+ else:
+ if ((chosen_bank[vfo_index] is None) and
+ (vfo.bank_index != 0xFFFF)):
+ print "Disabling banks for VFO %d" % vfo_index
+ vfo.bank_index = 0xFFFF
+ vfo.mr_index = 0xFFFF
+ vfo.bank_enable = 0xFFFF
+ elif ((chosen_bank[vfo_index] is not None) and
+ (vfo.bank_index == 0xFFFF)):
+ print "Enabling banks for VFO %d" % vfo_index
+ vfo.bank_index = chosen_bank[vfo_index]
+ vfo.mr_index = chosen_mr[vfo_index]
+ vfo.bank_enable = 0x0000
+ vfo_bak.bank_index = vfo.bank_index
+ vfo_bak.mr_index = vfo.mr_index
+ vfo_bak.bank_enable = vfo.bank_enable
+
+ def _update_bank_with_channel_numbers(self, bank,
channels_in_bank):
+ _members = self._radio._memobj.bank_members[bank.index]
+ if len(channels_in_bank) > len(_members.channel):
+ raise Exception("Too many entries in bank %d" % bank.index)
+
+ empty = 0
+ for index, channel_number in
enumerate(sorted(channels_in_bank)):
+ _members.channel[index] = channel_number - 1
+ empty = index + 1
+ for index in range(empty, len(_members.channel)):
+ _members.channel[index] = 0xFFFF
+
+ def add_memory_to_mapping(self, memory, bank):
+ channels_in_bank = self._channel_numbers_in_bank(bank)
+ channels_in_bank.add(memory.number)
+ self._update_bank_with_channel_numbers(bank, channels_in_bank)
+
+ _bank_used = self._radio._memobj.bank_used[bank.index]
+ _bank_used.in_use = 0x06
+
+ self.update_vfo()
+
+ def remove_memory_from_mapping(self, memory, bank):
+ channels_in_bank = self._channel_numbers_in_bank(bank)
+ try:
+ channels_in_bank.remove(memory.number)
+ except KeyError:
+ raise Exception("Memory %i is not in bank %s. Cannot
remove" % \
+ (memory.number, bank))
+ self._update_bank_with_channel_numbers(bank, channels_in_bank)
+
+ if not channels_in_bank:
+ _bank_used = self._radio._memobj.bank_used[bank.index]
+ _bank_used.in_use = 0xFFFF
+
+ self.update_vfo()
+
+ def get_mapping_memories(self, bank):
+ memories = []
+ for channel in self._channel_numbers_in_bank(bank):
+ memories.append(self._radio.get_memory(channel))
+
+ return memories
+
+ def get_memory_mappings(self, memory):
+ banks = []
+ for bank in self.get_mappings():
+ if memory.number in self._channel_numbers_in_bank(bank):
+ banks.append(bank)
+
+ return banks
+
+def _wipe_memory(mem):
+ mem.set_raw("\x00" * (mem.size() / 8))
+ mem.unknown1 = 0x05
+
+(a)directory.register
+class FT1Radio(yaesu_clone.YaesuCloneModeRadio):
+ """Yaesu FT1DR"""
+ BAUD_RATE = 38400
+ VENDOR = "Yaesu"
+ MODEL = "FT-1"
+ VARIANT = "DR"
+
+ _model = "AH44M"
+ _memsize = 130507
+ _block_lengths = [ 10, 130497 ]
+ _block_size = 32
+ _mem_params = (0xFECA, # APRS beacon metadata address.
+ 60, # Number of beacons stored.
+ 0x1064A, # APRS beacon content address.
+ 144, # Length of beacon data stored.
+ 60) # Number of beacons stored.
+ _has_vibrate = False
+ _has_af_dual = True
+
+ _SG_RE = re.compile(r"(?P<sign>[-+NESW]?)(?P<d>[\d]+)[\s\.,]*"
+ "(?P<m>[\d]*)[\s\']*(?P<s>[\d]*)")
+
+ _RX_BAUD = ("off", "1200 baud", "9600 baud")
+ _TX_DELAY = ("100ms", "150ms", "200ms", "250ms", "300ms",
+ "400ms", "500ms", "750ms", "1000ms")
+ _WIND_UNITS = ("m/s", "mph")
+ _RAIN_UNITS = ("mm", "inch")
+ _TEMP_UNITS = ("C", "F")
+ _ALT_UNITS = ("m", "ft")
+ _DIST_UNITS = ("km", "mile")
+ _POS_UNITS = ("dd.mmmm'", "dd mm'ss\"")
+ _SPEED_UNITS = ("km/h", "knot", "mph")
+ _TIME_SOURCE = ("manual", "GPS")
+ _TZ = ("-13:00", "-13:30", "-12:00", "-12:30", "-11:00", "-11:30",
+ "-10:00", "-10:30", "-09:00", "-09:30", "-08:00", "-08:30",
+ "-07:00", "-07:30", "-06:00", "-06:30", "-05:00", "-05:30",
+ "-04:00", "-04:30", "-03:00", "-03:30", "-02:00", "-02:30",
+ "-01:00", "-01:30", "-00:00", "-00:30", "+01:00", "+01:30",
+ "+02:00", "+02:30", "+03:00", "+03:30", "+04:00", "+04:30",
+ "+05:00", "+05:30", "+06:00", "+06:30", "+07:00", "+07:30",
+ "+08:00", "+08:30", "+09:00", "+09:30", "+10:00", "+10:30",
+ "+11:00", "+11:30")
+ _BEACON_TYPE = ("Off", "Interval", "SmartBeaconing")
+ _SMARTBEACON_PROFILE = ("Off", "Type 1", "Type 2", "Type 3")
+ _BEACON_INT = ("30s", "1m", "2m", "3m", "5m", "10m", "15m",
+ "20m", "30m", "60m")
+ _DIGI_PATHS = ("OFF", "WIDE1-1", "WIDE1-1, WIDE2-1", "Digi Path 4",
+ "Digi Path 5", "Digi Path 6", "Digi Path 7", "Digi
Path 8")
+ _MSG_GROUP_NAMES = ("Message Group 1", "Message Group 2",
+ "Message Group 3", "Message Group 4",
+ "Message Group 5", "Message Group 6",
+ "Message Group 7", "Message Group 8")
+ _POSITIONS = ("GPS", "Manual Latitude/Longitude",
+ "Manual Latitude/Longitude", "P1", "P2", "P3", "P4",
+ "P5", "P6", "P7", "P8", "P9")
+ _FLASH = ("OFF", "2 seconds", "4 seconds", "6 seconds", "8
seconds",
+ "10 seconds", "20 seconds", "30 seconds", "60 seconds",
+ "CONTINUOUS", "every 2 seconds", "every 3 seconds",
+ "every 4 seconds", "every 5 seconds", "every 6 seconds",
+ "every 7 seconds", "every 8 seconds", "every 9 seconds",
+ "every 10 seconds", "every 20 seconds", "every 30
seconds",
+ "every 40 seconds", "every 50 seconds", "every minute",
+ "every 2 minutes", "every 3 minutes", "every 4 minutes",
+ "every 5 minutes", "every 6 minutes", "every 7 minutes",
+ "every 8 minutes", "every 9 minutes", "every 10 minutes")
+ _BEEP_SELECT = ("Off", "Key+Scan", "Key")
+ _SQUELCH = ["%d" % x for x in range (0,16)]
+ _VOLUME = ["%d" % x for x in range (0,33)]
+ _OPENING_MESSAGE = ("Off", "DC", "Message", "Normal")
+ _SCAN_RESUME = ["%.1fs" % (0.5 * x) for x in range(4,21)] + \
+ ["Busy", "Hold"]
+ _SCAN_RESTART = ["%.1fs" % (0.1 * x) for x in range(1,10)] + \
+ ["%.1fs" % (0.5 * x) for x in range(2,21)]
+ _LAMP_KEY = ["Key %d sec" % x for x in range(2,11)] +
["Continuous", "OFF"]
+ _LCD_CONTRAST = ["Level %d" % x for x in range(1,16)]
+ _LCD_DIMMER = ["Level %d" % x for x in range(1,5)]
+ _TOT_TIME = ["Off"] + ["%.1f min" % (0.5 * x) for x in range(1,
21)]
+ _OFF_ON = ("Off", "On")
+ _VOL_MODE = ("Normal", "Auto Back")
+ _DTMF_MODE = ("Manual", "Auto")
+ _DTMF_SPEED = ("50ms", "100ms")
+ _DTMF_DELAY = ("50ms", "250ms", "450ms", "750ms", "1000ms")
+ _MY_SYMBOL = ("/[ Person", "/b Bike", "/> Car", "User selected")
+
+ @classmethod
+ def get_prompts(cls):
+ rp = chirp_common.RadioPrompts()
+ rp.pre_download = _(dedent("""\
+ 1. Turn radio off.
+ 2. Connect cable to DATA jack.
+ 3. Press and hold in the [FW] key while turning the radio
on
+ ("CLONE" will appear on the display).
+ 4. <b>After clicking OK</b>, press the [BAND] key to send
image."""))
+ rp.pre_upload = _(dedent("""\
+ 1. Turn radio off.
+ 2. Connect cable to DATA jack.
+ 3. Press and hold in the [FW] key while turning the radio
on
+ ("CLONE" will appear on the display).
+ 4. Press the [MODE] key ("-WAIT-" will appear on the
LCD)."""))
+ return rp
+
+ def process_mmap(self):
+ self._memobj = bitwise.parse(MEM_FORMAT % self._mem_params,
self._mmap)
+
+ def get_features(self):
+ rf = chirp_common.RadioFeatures()
+ rf.has_dtcs_polarity = False
+ rf.valid_modes = list(MODES)
+ rf.valid_tmodes = list(TMODES)
+ rf.valid_duplexes = list(DUPLEX)
+ rf.valid_tuning_steps = list(STEPS)
+ rf.valid_bands = [(500000, 999900000)]
+ rf.valid_skips = SKIPS
+ rf.valid_power_levels = POWER_LEVELS
+ rf.valid_characters = "".join(CHARSET)
+ rf.valid_name_length = 16
+ rf.memory_bounds = (1, 900)
+ rf.can_odd_split = True
+ rf.has_ctone = False
+ rf.has_bank_names = True
+ rf.has_settings = True
+ return rf
+
+ def get_raw_memory(self, number):
+ return repr(self._memobj.memory[number])
+
+ def _checksums(self):
+ return [ yaesu_clone.YaesuChecksum(0x064A, 0x06C8),
+ yaesu_clone.YaesuChecksum(0x06CA, 0x0748),
+ yaesu_clone.YaesuChecksum(0x074A, 0x07C8),
+ yaesu_clone.YaesuChecksum(0x07CA, 0x0848),
+ yaesu_clone.YaesuChecksum(0x0000, 0x1FDC9) ]
+
+ @staticmethod
+ def _add_ff_pad(val, length):
+ return val.ljust(length, "\xFF")[:length]
+
+ @classmethod
+ def _strip_ff_pads(cls, messages):
+ result = []
+ for msg_text in messages:
+ result.append(str(msg_text).rstrip("\xFF"))
+ return result
+
+ def get_memory(self, number):
+ flag = self._memobj.flag[number-1]
+ _mem = self._memobj.memory[number-1]
+
+ mem = chirp_common.Memory()
+ mem.number = number
+ if not flag.used:
+ mem.empty = True
+ if not flag.valid:
+ mem.empty = True
+ return mem
+ mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000)
+ mem.offset = int(_mem.offset) * 1000
+ mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone]
+ mem.tmode = TMODES[_mem.tone_mode]
+ mem.duplex = DUPLEX[_mem.duplex]
+ if mem.duplex == "split":
+ mem.offset = chirp_common.fix_rounded_step(mem.offset)
+ mem.mode = MODES[_mem.mode]
+ mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs]
+ mem.tuning_step = STEPS[_mem.tune_step]
+ mem.power = POWER_LEVELS[3 - _mem.power]
+ mem.skip = flag.pskip and "P" or flag.skip and "S" or ""
+
+ charset = ''.join(CHARSET).ljust(256, '.')
+ mem.name = str(_mem.label).rstrip("\xFF").translate(charset)
+
+ return mem
+
+ def _debank(self, mem):
+ bm = self.get_bank_model()
+ for bank in bm.get_memory_mappings(mem):
+ bm.remove_memory_from_mapping(mem, bank)
+
+ def set_memory(self, mem):
+ _mem = self._memobj.memory[mem.number-1]
+ flag = self._memobj.flag[mem.number-1]
+
+ self._debank(mem)
+
+ if not mem.empty and not flag.valid:
+ _wipe_memory(_mem)
+
+ if mem.empty and flag.valid and not flag.used:
+ flag.valid = False
+ return
+ flag.used = not mem.empty
+ flag.valid = flag.used
+
+ if mem.empty:
+ return
+
+ if mem.freq < 30000000 or \
+ (mem.freq > 88000000 and mem.freq < 108000000) or \
+ mem.freq > 580000000:
+ flag.nosubvfo = True # Masked from VFO B
+ else:
+ flag.nosubvfo = False # Available in both VFOs
+
+ _mem.freq = int(mem.freq / 1000)
+ _mem.offset = int(mem.offset / 1000)
+ _mem.tone = chirp_common.TONES.index(mem.rtone)
+ _mem.tone_mode = TMODES.index(mem.tmode)
+ _mem.duplex = DUPLEX.index(mem.duplex)
+ _mem.mode = MODES.index(mem.mode)
+ _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs)
+ _mem.tune_step = STEPS.index(mem.tuning_step)
+ if mem.power:
+ _mem.power = 3 - POWER_LEVELS.index(mem.power)
+ else:
+ _mem.power = 0
+
+ label = "".join([chr(CHARSET.index(x)) for x in
mem.name.rstrip()])
+ _mem.label = self._add_ff_pad(label, 16)
+ # We only speak english here in chirpville
+ _mem.charsetbits[0] = 0x00
+ _mem.charsetbits[1] = 0x00
+
+ flag.skip = mem.skip == "S"
+ flag.pskip = mem.skip == "P"
+
+ def get_bank_model(self):
+ return FT1BankModel(self)
+
+ @classmethod
+ def _digi_path_to_str(cls, path):
+ path_cmp = []
+ for entry in path.entry:
+ callsign = str(entry.callsign).rstrip("\xFF")
+ if not callsign:
+ break
+ path_cmp.append("%s-%d" % (callsign, entry.ssid))
+ return ",".join(path_cmp)
+
+ @staticmethod
+ def _latlong_sanity(sign, l_d, l_m, l_s, is_lat):
+ if sign not in (0, 1):
+ sign = 0
+ if is_lat:
+ d_max = 90
+ else:
+ d_max = 180
+ if l_d < 0 or l_d > d_max:
+ l_d = 0
+ l_m = 0
+ l_s = 0
+ if l_m < 0 or l_m > 60:
+ l_m = 0
+ l_s = 0
+ if l_s < 0 or l_s > 60:
+ l_s = 0
+ return sign, l_d, l_m, l_s
+
+ @classmethod
+ def _latlong_to_str(cls, sign, l_d, l_m, l_s, is_lat,
to_sexigesimal=True):
+ sign, l_d, l_m, l_s = cls._latlong_sanity(sign, l_d, l_m, l_s,
is_lat)
+ mult = sign and -1 or 1
+ if to_sexigesimal:
+ return "%d,%d'%d\"" % (mult * l_d, l_m, l_s)
+ return "%0.5f" % (mult * l_d + (l_m / 60.0) + (l_s / (60.0 *
60.0)))
+
+ @classmethod
+ def _str_to_latlong(cls, lat_long, is_lat):
+ sign = 0
+ result = [0, 0, 0]
+
+ lat_long = lat_long.strip()
+
+ if not lat_long:
+ return 1, 0, 0, 0
+
+ try:
+ # DD.MMMMM is the simple case, try that first.
+ val = float(lat_long)
+ if val < 0:
+ sign = 1
+ val = abs(val)
+ result[0] = int(val)
+ result[1] = int(val * 60) % 60
+ result[2] = int(val * 3600) % 60
+ except ValueError:
+ # Try DD MM'SS" if DD.MMMMM failed.
+ match = cls._SG_RE.match(lat_long.strip())
+ if match:
+ if match.group("sign") and (match.group("sign") in
"SE-"):
+ sign = 1
+ else:
+ sign = 0
+ if match.group("d"):
+ result[0] = int(match.group("d"))
+ if match.group("m"):
+ result[1] = int(match.group("m"))
+ if match.group("s"):
+ result[2] = int(match.group("s"))
+ elif len(lat_long) > 4:
+ raise Exception("Lat/Long should be DD MM'SS\" or
DD.MMMMM")
+
+ return cls._latlong_sanity(sign, result[0], result[1],
result[2],
+ is_lat)
+
+ def _get_aprs_general_settings(self):
+ menu = RadioSettingGroup("aprs_general", "APRS General")
+ aprs = self._memobj.aprs
+
+ val = RadioSettingValueString(0, 6,
+ str(aprs.my_callsign.callsign).rstrip("\xFF"))
+ rs = RadioSetting("aprs.my_callsign.callsign", "My Callsign",
val)
+ rs.set_apply_callback(self.apply_callsign, aprs.my_callsign)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ chirp_common.APRS_SSID,
+ chirp_common.APRS_SSID[aprs.my_callsign.ssid])
+ rs = RadioSetting("aprs.my_callsign.ssid", "My SSID", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._MY_SYMBOL,
+
self._MY_SYMBOL[aprs.selected_my_symbol])
+ rs = RadioSetting("aprs.selected_my_symbol", "My Symbol", val)
+ menu.append(rs)
+
+ symbols = list(chirp_common.APRS_SYMBOLS)
+ selected = aprs.custom_symbol
+ if aprs.custom_symbol >= len(chirp_common.APRS_SYMBOLS):
+ symbols.append("%d" % aprs.custom_symbol)
+ selected = len(symbols) - 1
+ val = RadioSettingValueList(symbols, symbols[selected])
+ rs = RadioSetting("aprs.custom_symbol_text", "User Selected
Symbol",
+ val)
+ rs.set_apply_callback(self.apply_custom_symbol, aprs)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ chirp_common.APRS_POSITION_COMMENT,
+
chirp_common.APRS_POSITION_COMMENT[aprs.selected_position_comment])
+ rs = RadioSetting("aprs.selected_position_comment", "Position
Comment",
+ val)
+ menu.append(rs)
+
+ latitude = self._latlong_to_str(aprs.latitude_sign,
+ aprs.latitude_degree,
+ aprs.latitude_minute,
+ aprs.latitude_second,
+ True,
aprs.aprs_units_position_mmss)
+ longitude = self._latlong_to_str(aprs.longitude_sign,
+ aprs.longitude_degree,
+ aprs.longitude_minute,
+ aprs.longitude_second,
+ False,
aprs.aprs_units_position_mmss)
+
+ # TODO: Rebuild this when aprs_units_position_mmss changes.
+ # TODO: Rebuild this when latitude/longitude change.
+ # TODO: Add saved positions p1 - p10 to memory map.
+ position_str = list(self._POSITIONS)
+ #position_str[1] = "%s %s" % (latitude, longitude)
+ #position_str[2] = "%s %s" % (latitude, longitude)
+ val = RadioSettingValueList(position_str,
+
position_str[aprs.selected_position])
+ rs = RadioSetting("aprs.selected_position", "My Position", val)
+ menu.append(rs)
+
+ val = RadioSettingValueString(0, 10, latitude)
+ rs = RadioSetting("latitude", "Manual Latitude", val)
+ rs.set_apply_callback(self.apply_lat_long, aprs)
+ menu.append(rs)
+
+ val = RadioSettingValueString(0, 11, longitude)
+ rs = RadioSetting("longitude", "Manual Longitude", val)
+ rs.set_apply_callback(self.apply_lat_long, aprs)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._TIME_SOURCE,
+ self._TIME_SOURCE[aprs.set_time_manually])
+ rs = RadioSetting("aprs.set_time_manually", "Time Source", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._TZ, self._TZ[aprs.timezone])
+ rs = RadioSetting("aprs.timezone", "Timezone", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._SPEED_UNITS,
+
self._SPEED_UNITS[aprs.aprs_units_speed])
+ rs = RadioSetting("aprs.aprs_units_speed", "APRS Speed Units",
val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._SPEED_UNITS,
+
self._SPEED_UNITS[aprs.gps_units_speed])
+ rs = RadioSetting("aprs.gps_units_speed", "GPS Speed Units",
val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._ALT_UNITS,
+ self._ALT_UNITS[aprs.aprs_units_altitude_ft])
+ rs = RadioSetting("aprs.aprs_units_altitude_ft", "APRS Altitude
Units",
+ val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._ALT_UNITS,
+ self._ALT_UNITS[aprs.gps_units_altitude_ft])
+ rs = RadioSetting("aprs.gps_units_altitude_ft", "GPS Altitude
Units",
+ val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._POS_UNITS,
+ self._POS_UNITS[aprs.aprs_units_position_mmss])
+ rs = RadioSetting("aprs.aprs_units_position_mmss",
+ "APRS Position Format", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._POS_UNITS,
+ self._POS_UNITS[aprs.gps_units_position_sss])
+ rs = RadioSetting("aprs.gps_units_position_sss",
+ "GPS Position Format", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._DIST_UNITS,
+ self._DIST_UNITS[aprs.aprs_units_distance_m])
+ rs = RadioSetting("aprs.aprs_units_distance_m", "APRS Distance
Units",
+ val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._WIND_UNITS,
+
self._WIND_UNITS[aprs.aprs_units_wind_mph])
+ rs = RadioSetting("aprs.aprs_units_wind_mph", "APRS Wind Speed
Units",
+ val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._RAIN_UNITS,
+ self._RAIN_UNITS[aprs.aprs_units_rain_inch])
+ rs = RadioSetting("aprs.aprs_units_rain_inch", "APRS Rain
Units", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._TEMP_UNITS,
+ self._TEMP_UNITS[aprs.aprs_units_temperature_f])
+ rs = RadioSetting("aprs.aprs_units_temperature_f",
+ "APRS Temperature Units", val)
+ menu.append(rs)
+
+ return menu
+
+ def _get_aprs_rx_settings(self):
+ menu = RadioSettingGroup("aprs_rx", "APRS Receive")
+ aprs = self._memobj.aprs
+
+ val = RadioSettingValueList(self._RX_BAUD,
self._RX_BAUD[aprs.rx_baud])
+ rs = RadioSetting("aprs.rx_baud", "Modem RX", val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.aprs_mute)
+ rs = RadioSetting("aprs.aprs_mute", "APRS Mute", val)
+ menu.append(rs)
+
+ if self._has_af_dual:
+ val = RadioSettingValueBoolean(aprs.af_dual)
+ rs = RadioSetting("aprs.af_dual", "AF Dual", val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.ring_msg)
+ rs = RadioSetting("aprs.ring_msg", "Ring on Message RX", val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.ring_beacon)
+ rs = RadioSetting("aprs.ring_beacon", "Ring on Beacon RX", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._FLASH,
+ self._FLASH[aprs.flash_msg])
+ rs = RadioSetting("aprs.flash_msg", "Flash on personal
message", val)
+ menu.append(rs)
+
+ if self._has_vibrate:
+ val = RadioSettingValueList(self._FLASH,
+ self._FLASH[aprs.vibrate_msg])
+ rs = RadioSetting("aprs.vibrate_msg",
+ "Vibrate on personal message", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._FLASH[:10],
+ self._FLASH[aprs.flash_bln])
+ rs = RadioSetting("aprs.flash_bln", "Flash on bulletin
message", val)
+ menu.append(rs)
+
+ if self._has_vibrate:
+ val = RadioSettingValueList(self._FLASH[:10],
+ self._FLASH[aprs.vibrate_bln])
+ rs = RadioSetting("aprs.vibrate_bln",
+ "Vibrate on bulletin message", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._FLASH[:10],
+ self._FLASH[aprs.flash_grp])
+ rs = RadioSetting("aprs.flash_grp", "Flash on group message",
val)
+ menu.append(rs)
+
+ if self._has_vibrate:
+ val = RadioSettingValueList(self._FLASH[:10],
+ self._FLASH[aprs.vibrate_grp])
+ rs = RadioSetting("aprs.vibrate_grp",
+ "Vibrate on group message", val)
+ menu.append(rs)
+
+ filter_val = [m.padded_string for m in aprs.msg_group]
+ filter_val = self._strip_ff_pads(filter_val)
+ for index, filter_text in enumerate(filter_val):
+ val = RadioSettingValueString(0, 9, filter_text)
+ rs = RadioSetting("aprs.msg_group_%d" % index,
+ "Message Group %d" % (index + 1), val)
+ menu.append(rs)
+ rs.set_apply_callback(self.apply_ff_padded_string,
+ aprs.msg_group[index])
+ # TODO: Use filter_val as the list entries and update it on
edit.
+ val = RadioSettingValueList(
+ self._MSG_GROUP_NAMES,
+ self._MSG_GROUP_NAMES[aprs.selected_msg_group])
+ rs = RadioSetting("aprs.selected_msg_group", "Selected Message
Group",
+ val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.filter_mic_e)
+ rs = RadioSetting("aprs.filter_mic_e", "Receive Mic-E Beacons",
val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.filter_position)
+ rs = RadioSetting("aprs.filter_position", "Receive Position
Beacons",
+ val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.filter_weather)
+ rs = RadioSetting("aprs.filter_weather", "Receive Weather
Beacons",
+ val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.filter_object)
+ rs = RadioSetting("aprs.filter_object", "Receive Object
Beacons", val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.filter_item)
+ rs = RadioSetting("aprs.filter_item", "Receive Item Beacons",
val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.filter_status)
+ rs = RadioSetting("aprs.filter_status", "Receive Status
Beacons", val)
+ menu.append(rs)
+
+ val = RadioSettingValueBoolean(aprs.filter_other)
+ rs = RadioSetting("aprs.filter_other", "Receive Other Beacons",
val)
+ menu.append(rs)
+
+ return menu
+
+ def _get_aprs_tx_settings(self):
+ menu = RadioSettingGroup("aprs_tx", "APRS Transmit")
+ aprs = self._memobj.aprs
+
+ beacon_type = (aprs.tx_smartbeacon << 1) |
aprs.tx_interval_beacon;
+ val = RadioSettingValueList(self._BEACON_TYPE,
+ self._BEACON_TYPE[beacon_type])
+ rs = RadioSetting("aprs.transmit", "TX Beacons", val)
+ rs.set_apply_callback(self.apply_beacon_type, aprs)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._TX_DELAY,
+ self._TX_DELAY[aprs.tx_delay])
+ rs = RadioSetting("aprs.tx_delay", "TX Delay", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(self._BEACON_INT,
+
self._BEACON_INT[aprs.beacon_interval])
+ rs = RadioSetting("aprs.beacon_interval", "Beacon Interval",
val)
+ menu.append(rs)
+
+ desc = []
+ status = [m.padded_string for m in
self._memobj.aprs_beacon_status_txt]
+ status = self._strip_ff_pads(status)
+ for index, msg_text in enumerate(status):
+ val = RadioSettingValueString(0, 60, msg_text)
+ desc.append("Beacon Status Text %d" % (index + 1))
+ rs = RadioSetting("aprs_beacon_status_txt_%d" % index,
desc[-1],
+ val)
+ rs.set_apply_callback(self.apply_ff_padded_string,
+
self._memobj.aprs_beacon_status_txt[index])
+ menu.append(rs)
+ val = RadioSettingValueList(desc,
+
desc[aprs.selected_beacon_status_txt])
+ rs = RadioSetting("aprs.selected_beacon_status_txt",
+ "Beacon Status Text", val)
+ menu.append(rs)
+
+ message_macro = [m.padded_string for m in aprs.message_macro]
+ message_macro = self._strip_ff_pads(message_macro)
+ for index, msg_text in enumerate(message_macro):
+ val = RadioSettingValueString(0, 16, msg_text)
+ rs = RadioSetting("aprs.message_macro_%d" % index,
+ "Message Macro %d" % (index + 1), val)
+ rs.set_apply_callback(self.apply_ff_padded_string,
+ aprs.message_macro[index])
+ menu.append(rs)
+
+ path_str = list(self._DIGI_PATHS)
+ path_str[3] = self._digi_path_to_str(aprs.digi_path_3_6[0])
+ val = RadioSettingValueString(0, 22, path_str[3])
+ rs = RadioSetting("aprs.digi_path_3", "Digi Path 4 (2
entries)", val)
+ rs.set_apply_callback(self.apply_digi_path,
aprs.digi_path_3_6[0])
+ menu.append(rs)
+
+ path_str[4] = self._digi_path_to_str(aprs.digi_path_3_6[1])
+ val = RadioSettingValueString(0, 22, path_str[4])
+ rs = RadioSetting("aprs.digi_path_4", "Digi Path 5 (2
entries)", val)
+ rs.set_apply_callback(self.apply_digi_path,
aprs.digi_path_3_6[1])
+ menu.append(rs)
+
+ path_str[5] = self._digi_path_to_str(aprs.digi_path_3_6[2])
+ val = RadioSettingValueString(0, 22, path_str[5])
+ rs = RadioSetting("aprs.digi_path_5", "Digi Path 6 (2
entries)", val)
+ rs.set_apply_callback(self.apply_digi_path,
aprs.digi_path_3_6[2])
+ menu.append(rs)
+
+ path_str[6] = self._digi_path_to_str(aprs.digi_path_3_6[3])
+ val = RadioSettingValueString(0, 22, path_str[6])
+ rs = RadioSetting("aprs.digi_path_6", "Digi Path 7 (2
entries)", val)
+ rs.set_apply_callback(self.apply_digi_path,
aprs.digi_path_3_6[3])
+ menu.append(rs)
+
+ path_str[7] = self._digi_path_to_str(aprs.digi_path_7)
+ val = RadioSettingValueString(0, 88, path_str[7])
+ rs = RadioSetting("aprs.digi_path_7", "Digi Path 8 (8
entries)", val)
+ rs.set_apply_callback(self.apply_digi_path, aprs.digi_path_7)
+ menu.append(rs)
+
+ # Show friendly messages for empty slots rather than blanks.
+ # TODO: Rebuild this when digi_path_[34567] change.
+ #path_str[3] = path_str[3] or self._DIGI_PATHS[3]
+ #path_str[4] = path_str[4] or self._DIGI_PATHS[4]
+ #path_str[5] = path_str[5] or self._DIGI_PATHS[5]
+ #path_str[6] = path_str[6] or self._DIGI_PATHS[6]
+ #path_str[7] = path_str[7] or self._DIGI_PATHS[7]
+ path_str[3] = self._DIGI_PATHS[3]
+ path_str[4] = self._DIGI_PATHS[4]
+ path_str[5] = self._DIGI_PATHS[5]
+ path_str[6] = self._DIGI_PATHS[6]
+ path_str[7] = self._DIGI_PATHS[7]
+ val = RadioSettingValueList(path_str,
+ path_str[aprs.selected_digi_path])
+ rs = RadioSetting("aprs.selected_digi_path", "Selected Digi
Path", val)
+ menu.append(rs)
+
+ return menu
+
+ def _get_aprs_smartbeacon(self):
+ menu = RadioSettingGroup("aprs_smartbeacon", "APRS
SmartBeacon")
+ aprs = self._memobj.aprs
+
+ val = RadioSettingValueList(
+ self._SMARTBEACON_PROFILE,
+ self._SMARTBEACON_PROFILE[aprs.active_smartbeaconing])
+ rs = RadioSetting("aprs.active_smartbeaconing", "SmartBeacon
profile",
+ val)
+ menu.append(rs)
+
+ for profile in range(3):
+ pfx = "type%d" % (profile + 1)
+ path = "aprs.smartbeaconing_profile[%d]" % profile
+ prof = aprs.smartbeaconing_profile[profile]
+
+ low_val = RadioSettingValueInteger(2, 30,
prof.low_speed_mph)
+ high_val = RadioSettingValueInteger(3, 70,
prof.high_speed_mph)
+ low_val.get_max = lambda: min(30, int(high_val.get_value())
- 1)
+
+ rs = RadioSetting("%s.low_speed_mph" % path,
+ "%s Low Speed (mph)" % pfx, low_val)
+ menu.append(rs)
+
+ rs = RadioSetting("%s.high_speed_mph" % path,
+ "%s High Speed (mph)" % pfx, high_val)
+ menu.append(rs)
+
+ val = RadioSettingValueInteger(1, 100, prof.slow_rate_min)
+ rs = RadioSetting("%s.slow_rate_min" % path,
+ "%s Slow rate (minutes)" % pfx, val)
+ menu.append(rs)
+
+ val = RadioSettingValueInteger(10, 180, prof.fast_rate_sec)
+ rs = RadioSetting("%s.fast_rate_sec" % path,
+ "%s Fast rate (seconds)" % pfx, val)
+ menu.append(rs)
+
+ val = RadioSettingValueInteger(5, 90, prof.turn_angle)
+ rs = RadioSetting("%s.turn_angle" % path,
+ "%s Turn angle (degrees)" % pfx, val)
+ menu.append(rs)
+
+ val = RadioSettingValueInteger(1, 255, prof.turn_slop)
+ rs = RadioSetting("%s.turn_slop" % path,
+ "%s Turn slop" % pfx, val)
+ menu.append(rs)
+
+ val = RadioSettingValueInteger(5, 180, prof.turn_time_sec)
+ rs = RadioSetting("%s.turn_time_sec" % path,
+ "%s Turn time (seconds)" % pfx, val)
+ menu.append(rs)
+
+ return menu
+
+ def _get_dtmf_settings(self):
+ menu = RadioSettingGroup("dtmf_settings", "DTMF")
+ dtmf = self._memobj.scan_settings
+
+ val = RadioSettingValueList(
+ self._DTMF_MODE,
+ self._DTMF_MODE[dtmf.dtmf_mode])
+ rs = RadioSetting("scan_settings.dtmf_mode", "DTMF Mode", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._DTMF_SPEED,
+ self._DTMF_SPEED[dtmf.dtmf_speed])
+ rs = RadioSetting("scan_settings.dtmf_speed", "DTMF AutoDial
Speed", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._DTMF_DELAY,
+ self._DTMF_DELAY[dtmf.dtmf_delay])
+ rs = RadioSetting("scan_settings.dtmf_delay", "DTMF AutoDial
Delay", val)
+ menu.append(rs)
+
+ for i in range(10):
+ name = "dtmf_%02d" % i
+ dtmfsetting = self._memobj.dtmf[i]
+ dtmfstr = ""
+ for c in dtmfsetting.memory:
+ if c == 0xFF:
+ break
+ if c < len(FT1_DTMF_CHARS):
+ dtmfstr += FT1_DTMF_CHARS[c]
+ dtmfentry = RadioSettingValueString(0, 16, dtmfstr)
+ dtmfentry.set_charset(FT1_DTMF_CHARS + list("abcd "))
+ rs = RadioSetting(name, name.upper(), dtmfentry)
+ rs.set_apply_callback(self.apply_dtmf, i)
+ menu.append(rs)
+
+ return menu
+
+ def _get_misc_settings(self):
+ menu = RadioSettingGroup("misc_settings", "Misc")
+ scan_settings = self._memobj.scan_settings
+
+ val = RadioSettingValueList(
+ self._LCD_DIMMER,
+ self._LCD_DIMMER[scan_settings.lcd_dimmer])
+ rs = RadioSetting("scan_settings.lcd_dimmer", "LCD Dimmer",
val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._LCD_CONTRAST,
+ self._LCD_CONTRAST[scan_settings.lcd_contrast - 1])
+ rs = RadioSetting("scan_settings.lcd_contrast", "LCD Contrast",
+ val)
+ rs.set_apply_callback(self.apply_lcd_contrast, scan_settings)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._LAMP_KEY,
+ self._LAMP_KEY[scan_settings.lamp])
+ rs = RadioSetting("scan_settings.lamp", "Lamp", val)
+ menu.append(rs)
+
+ beep_select = self._memobj.beep_select
+
+ val = RadioSettingValueList(
+ self._BEEP_SELECT,
+ self._BEEP_SELECT[beep_select.beep])
+ rs = RadioSetting("beep_select.beep", "Beep Select", val)
+ menu.append(rs)
+
+ opening_message = self._memobj.opening_message
+
+ val = RadioSettingValueList(
+ self._OPENING_MESSAGE,
+ self._OPENING_MESSAGE[opening_message.flag])
+ rs = RadioSetting("opening_message.flag", "Opening Msg Mode",
+ val)
+ menu.append(rs)
+
+ msg = ""
+ for i in opening_message.message.padded_yaesu:
+ if i == 0xFF:
+ break
+ msg += CHARSET[i & 0x7F]
+ val = RadioSettingValueString(0, 16, msg)
+ rs = RadioSetting("opening_message.message.padded_yaesu",
+ "Opening Message", val)
+ rs.set_apply_callback(self.apply_ff_padded_yaesu,
+ opening_message.message)
+ menu.append(rs)
+
+ return menu
+
+ def _get_scan_settings(self):
+ menu = RadioSettingGroup("scan_settings", "Scan")
+ scan_settings = self._memobj.scan_settings
+
+ val = RadioSettingValueList(
+ self._VOL_MODE,
+ self._VOL_MODE[scan_settings.vol_mode])
+ rs = RadioSetting("scan_settings.vol_mode", "Volume Mode", val)
+ menu.append(rs)
+
+ vfoa = self._memobj.vfo_info[0]
+ val = RadioSettingValueList(
+ self._VOLUME,
+ self._VOLUME[vfoa.volume])
+ rs = RadioSetting("vfo_info[0].volume", "VFO A Volume", val)
+ rs.set_apply_callback(self.apply_volume, 0)
+ menu.append(rs)
+
+ vfob = self._memobj.vfo_info[1]
+ val = RadioSettingValueList(
+ self._VOLUME,
+ self._VOLUME[vfob.volume])
+ rs = RadioSetting("vfo_info[1].volume", "VFO B Volume", val)
+ rs.set_apply_callback(self.apply_volume, 1)
+ menu.append(rs)
+
+ squelch = self._memobj.squelch
+ val = RadioSettingValueList(
+ self._SQUELCH,
+ self._SQUELCH[squelch.vfo_a])
+ rs = RadioSetting("squelch.vfo_a", "VFO A Squelch", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._SQUELCH,
+ self._SQUELCH[squelch.vfo_b])
+ rs = RadioSetting("squelch.vfo_b", "VFO B Squelch", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._SCAN_RESTART,
+ self._SCAN_RESTART[scan_settings.scan_restart])
+ rs = RadioSetting("scan_settings.scan_restart", "Scan Restart",
val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._SCAN_RESUME,
+ self._SCAN_RESUME[scan_settings.scan_resume])
+ rs = RadioSetting("scan_settings.scan_resume", "Scan Resume",
val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._OFF_ON,
+ self._OFF_ON[scan_settings.busy_led])
+ rs = RadioSetting("scan_settings.busy_led", "Busy LED", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._OFF_ON,
+ self._OFF_ON[scan_settings.scan_lamp])
+ rs = RadioSetting("scan_settings.scan_lamp", "Scan Lamp", val)
+ menu.append(rs)
+
+ val = RadioSettingValueList(
+ self._TOT_TIME,
+ self._TOT_TIME[scan_settings.tot])
+ rs = RadioSetting("scan_settings.tot", "Transmit Timeout
(TOT)", val)
+ menu.append(rs)
+
+ return menu
+
+ def _get_settings(self):
+ top = RadioSettingGroup("all", "All Settings",
+ self._get_aprs_general_settings(),
+ self._get_aprs_rx_settings(),
+ self._get_aprs_tx_settings(),
+ self._get_aprs_smartbeacon(),
+ self._get_dtmf_settings(),
+ self._get_misc_settings(),
+ self._get_scan_settings())
+ return top
+
+ def get_settings(self):
+ try:
+ return self._get_settings()
+ except:
+ import traceback
+ print "Failed to parse settings:"
+ traceback.print_exc()
+ return None
+
+ @staticmethod
+ def apply_custom_symbol(setting, obj):
+ # Ensure new value falls within known bounds, otherwise leave
it as
+ # it's a custom value from the radio that's outside our list.
+ if setting.value.get_value() in chirp_common.APRS_SYMBOLS:
+ setattr(obj, "custom_symbol",
+
chirp_common.APRS_SYMBOLS.index(setting.value.get_value()))
+
+ @classmethod
+ def _apply_callsign(cls, callsign, obj, default_ssid=None):
+ ssid = default_ssid
+ dash_index = callsign.find("-")
+ if dash_index >= 0:
+ ssid = callsign[dash_index + 1:]
+ callsign = callsign[:dash_index]
+ try:
+ ssid = int(ssid) % 16
+ except ValueError:
+ ssid = default_ssid
+ setattr(obj, "callsign", cls._add_ff_pad(callsign, 6))
+ if ssid is not None:
+ setattr(obj, "ssid", ssid)
+
+ def apply_beacon_type(cls, setting, obj):
+ beacon_type = str(setting.value.get_value())
+ beacon_index = cls._BEACON_TYPE.index(beacon_type)
+ tx_smartbeacon = beacon_index >> 1
+ tx_interval_beacon = beacon_index & 1
+ if tx_interval_beacon:
+ setattr(obj, "tx_interval_beacon", 1)
+ setattr(obj, "tx_smartbeacon", 0)
+ elif tx_smartbeacon:
+ setattr(obj, "tx_interval_beacon", 0)
+ setattr(obj, "tx_smartbeacon", 1)
+ else:
+ setattr(obj, "tx_interval_beacon", 0)
+ setattr(obj, "tx_smartbeacon", 0)
+
+ @classmethod
+ def apply_callsign(cls, setting, obj, default_ssid=None):
+ # Uppercase, strip SSID then FF pad to max string length.
+ callsign = setting.value.get_value().upper()
+ cls._apply_callsign(callsign, obj, default_ssid)
+
+ def apply_digi_path(self, setting, obj):
+ # Parse and map to aprs.digi_path_4_7[0-3] or aprs.digi_path_8
+ # and FF terminate.
+ path = str(setting.value.get_value())
+ callsigns = [c.strip() for c in path.split(",")]
+ for index in range(len(obj.entry)):
+ try:
+ self._apply_callsign(callsigns[index],
obj.entry[index], 0)
+ except IndexError:
+ self._apply_callsign("", obj.entry[index], 0)
+ if len(callsigns) > len(obj.entry):
+ raise Exception("This path only supports %d entries" %
(index + 1))
+
+ @classmethod
+ def apply_ff_padded_string(cls, setting, obj):
+ # FF pad.
+ val = setting.value.get_value()
+ max_len = getattr(obj, "padded_string").size() / 8
+ val = str(val).rstrip()
+ setattr(obj, "padded_string", cls._add_ff_pad(val, max_len))
+
+ @classmethod
+ def apply_lat_long(cls, setting, obj):
+ name = setting.get_name()
+ is_latitude = name.endswith("latitude")
+ lat_long = setting.value.get_value().strip()
+ sign, l_d, l_m, l_s = cls._str_to_latlong(lat_long,
is_latitude)
+ if os.getenv("CHIRP_DEBUG"):
+ print "%s: %d %d %d %d" % (name, sign, l_d, l_m, l_s)
+ setattr(obj, "%s_sign" % name, sign)
+ setattr(obj, "%s_degree" % name, l_d)
+ setattr(obj, "%s_minute" % name, l_m)
+ setattr(obj, "%s_second" % name, l_s)
+
+ def set_settings(self, settings):
+ _mem = self._memobj
+ for element in settings:
+ if not isinstance(element, RadioSetting):
+ self.set_settings(element)
+ continue
+ if not element.changed():
+ continue
+ try:
+ if element.has_apply_callback():
+ print "Using apply callback"
+ try:
+ element.run_apply_callback()
+ except NotImplementedError as e:
+ print e
+ continue
+
+ # Find the object containing setting.
+ obj = _mem
+ bits = element.get_name().split(".")
+ setting = bits[-1]
+ for name in bits[:-1]:
+ if name.endswith("]"):
+ name, index = name.split("[")
+ index = int(index[:-1])
+ obj = getattr(obj, name)[index]
+ else:
+ obj = getattr(obj, name)
+
+ try:
+ old_val = getattr(obj, setting)
+ if os.getenv("CHIRP_DEBUG"):
+ print "Setting %s(%r) <= %s" % (
+ element.get_name(), old_val, element.value)
+ setattr(obj, setting, element.value)
+ except AttributeError as e:
+ print "Setting %s is not in the memory map: %s" % (
+ element.get_name(), e)
+ except Exception, e:
+ print element.get_name()
+ raise
+
+ def apply_ff_padded_yaesu(cls, setting, obj):
+ # FF pad yaesus custom string format.
+ rawval = setting.value.get_value()
+ max_len = getattr(obj, "padded_yaesu").size() / 8
+ rawval = str(rawval).rstrip()
+ val = [CHARSET.index(x) for x in rawval]
+ for x in range(len(val), max_len):
+ val.append(0xFF)
+ obj.padded_yaesu = val
+
+ def apply_volume(cls, setting, vfo):
+ val = setting.value.get_value()
+ cls._memobj.vfo_info[(vfo*2)].volume = val
+ cls._memobj.vfo_info[(vfo*2)+1].volume = val
+
+ def apply_lcd_contrast(cls, setting, obj):
+ rawval = setting.value.get_value()
+ val = cls._LCD_CONTRAST.index(rawval) + 1
+ obj.lcd_contrast = val
+
+ def apply_dtmf(cls, setting, i):
+ rawval = setting.value.get_value().upper().rstrip()
+ val = [FT1_DTMF_CHARS.index(x) for x in rawval]
+ for x in range(len(val), 16):
+ val.append(0xFF)
+ cls._memobj.dtmf[i].memory = val
+
1
0
I am changing the leixen.py to better detect the saved data file. It
works perfectly detecting a Leixen VV-898 data file or a Jetstream
JT270M data file but I am getting a failure when executing the
"run_tests" utility.
Leixen VV-898 Detect ←[1;41m FAILED:←[0m Failed to detect
The Jetstream JT270M Detect test passes.
Any ideas what it could be?
Jim KC9HI
3
18
Tested changes:
[Jim Unroe <rock.unroe(a)gmail.com>] [VV-898] Update Image Detections
Add method to fall back to original detection string for older data files
Add method to skip uploading settings area block for older data files
related to #2119
Full log:
[...truncated 156 lines...]
test_radio_setting_value_string (tests.unit.test_settings.TestSettingValues) ... ok
test_validate_callback (tests.unit.test_settings.TestSettingValues) ... ok
test_delete_hole_with_all (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_delete_hole_with_all_full (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_delete_hole_with_hole (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_delete_hole_without_hole (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_insert_hole_with_space (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
test_insert_hole_without_space (tests.unit.test_shiftdialog.ShiftDialogTest) ... ok
----------------------------------------------------------------------
Ran 151 tests in 0.107s
OK
Registered Icom_IC-2820H = IC2820Radio
Registered TYT_TH-UVF8D = TYTUVF8DRadio
Registered AnyTone_5888UV = AnyTone5888UVRadio
Registered Intek_HR-2040 = IntekHR2040Radio
Registered Polmar_DB-50M = PolmarDB50MRadio
Registered Powerwerx_DB-750X = PowerwerxDB750XRadio
Registered Icom_IC-2200H = IC2200Radio
Registered Yaesu_FT-2800M = FT2800Radio
Registered Yaesu_VX-3 = VX3Radio
Registered Icom_IC-2100H = IC2100Radio
Registered Yaesu_FTM-350 = FTM350Radio
Registered Icom_IC-V82_U82 = ICx8xRadio
Registered Yaesu_VX-6 = VX6Radio
Registered Yaesu_VX-5 = VX5Radio
Registered Yaesu_FT-60 = FT60Radio
Registered Yaesu_VX-7 = VX7Radio
Registered Sainsonic_AP510 = AP510Radio
Registered Baofeng_UV-5R = BaofengUV5R
Registered Baofeng_F-11 = BaofengF11Radio
Registered Baofeng_UV-82 = BaofengUV82Radio
Registered Baofeng_UV-6 = BaofengUV6Radio
Registered Intek_KT-980HP = IntekKT980Radio
Registered Baofeng_BF-F8HP = BaofengBFF8HPRadio
Registered Yaesu_FT-1802M = FT1802Radio
Registered Kenwood_TK-7102 = KenwoodTK7102Radio
Registered Kenwood_TK-8102 = KenwoodTK8102Radio
Registered Kenwood_TK-7108 = KenwoodTK7108Radio
Registered Kenwood_TK-8108 = KenwoodTK8108Radio
Registered Icom_ID-31A = ID31Radio
Registered Icom_ID-51A = ID51Radio
Registered Icom_IC-2720H = IC2720Radio
Registered Icom_IC-T8A = ICT8ARadio
Registered Wouxun_KG-UVD1P = KGUVD1PRadio
Registered Wouxun_KG-UV6 = KGUV6DRadio
Registered Wouxun_KG-816 = KG816Radio
Registered Wouxun_KG-818 = KG818Radio
Registered TYT_TH-UVF1 = TYTTHUVF1Radio
Registered Yaesu_FT-90 = FT90Radio
Registered Generic_CSV = CSVRadio
Registered Commander_KG-UV = CommanderCSVRadio
Registered RT_Systems_CSV = RTCSVRadio
Registered Kenwood_ITM = ITMRadio
Registered TYT_TH-9800 = TYTTH9800File
Registered Alinco_DR03T = DR03Radio
Registered Alinco_DR06T = DR06Radio
Registered Alinco_DR135T = DR135Radio
Registered Alinco_DR235T = DR235Radio
Registered Alinco_DR435T = DR435Radio
Registered Alinco_DJ596 = DJ596Radio
Registered Jetstream_JT220M = JT220MRadio
Registered Alinco_DJ175 = DJ175Radio
Registered Kenwood_TH-D7 = THD7Radio
Registered Kenwood_TH-D7G = THD7GRadio
Registered Kenwood_TM-D700 = TMD700Radio
Registered Kenwood_TM-V7 = TMV7Radio
Registered Kenwood_TM-G707 = TMG707Radio
Registered Kenwood_TH-G71 = THG71Radio
Registered Kenwood_TH-F6 = THF6ARadio
Registered Kenwood_TH-F7 = THF7ERadio
Registered Kenwood_TM-D710 = TMD710Radio
Registered Kenwood_TH-D72_live_mode = THD72Radio
Registered Kenwood_TM-V71 = TMV71Radio
Registered Kenwood_TH-K2 = THK2Radio
Registered Kenwood_TM-271 = TM271Radio
Registered Kenwood_TM-281 = TM281Radio
Registered Kenwood_TM-471 = TM471Radio
Registered Wouxun_KG-UV8D = KGUV8DRadio
Registered Yaesu_VX-8_R = VX8Radio
Registered Yaesu_VX-8_DR = VX8DRadio
Registered Yaesu_VX-8_GE = VX8GERadio
Registered Icom_IC-T7H = ICT7HRadio
Registered Icom_IC-Q7A = ICQ7Radio
Registered Baofeng_UV-B5 = BaofengUVB5
Registered Generic_XML = XMLRadio
Registered Kenwood_HMK = HMKRadio
Registered Kenwood_TH-D72_clone_mode = THD72Radio
Registered Icom_IC-91_92AD = IC9xRadio
Registered Icom_IC-T70 = ICT70Radio
Registered Icom_IC-208H = IC208Radio
Registered Leixen_VV-898 = LeixenVV898Radio
Registered Jetstream_JT270M = JetstreamJT270MRadio
Registered Icom_ID-800H_v2 = ID800v2Radio
Registered Icom_7200 = Icom7200Radio
Registered Icom_7000 = Icom7000Radio
Registered Icom_746 = Icom746Radio
Registered ARRL_Travel_Plus = TpeRadio
Registered Vertex_Standard_VXA-700 = VXA700Radio
Registered Icom_IC-W32A = ICW32ARadio
Registered Baofeng_UV-3R = UV3RRadio
Registered Yaesu_VX-2 = VX2Radio
Registered Puxing_PX-777 = Puxing777Radio
Registered Puxing_PX-2R = Puxing2RRadio
Registered Baojie_BJ-UV55 = BaojieBJUV55Radio
Registered Baofeng_BF-888 = H777Radio
Registered Yaesu_FT-7800_7900 = FT7800Radio
Registered Yaesu_FT-8800 = FT8800Radio
Registered Yaesu_FT-8900 = FT8900Radio
Registered KYD_NC-630A = NC630aRadio
Registered Yaesu_FT-817 = FT817Radio
Registered Yaesu_FT-817ND = FT817NDRadio
Registered Yaesu_FT-817ND_US = FT817NDUSRadio
Registered Yaesu_FT-857_897 = FT857Radio
Registered Yaesu_FT-857_897_US = FT857USRadio
Registered Yaesu_VX-170 = VX170Radio
Registered Icom_ID-880H = ID880Radio
Registered Icom_ID-80H = ID80Radio
Registered TYT_TH-UV3R = TYTUV3RRadio
Alinco DJ175 Detect PASSED: All tests
Alinco DJ175 CopyAll PASSED: All tests
Alinco DJ175 Clone PASSED: All tests
Alinco DJ175 BruteForce PASSED: All tests
Alinco DJ175 Edges PASSED: All tests
Alinco DJ175 Banks SKIPPED: Banks not supported
Alinco DJ596 Detect PASSED: All tests
Alinco DJ596 CopyAll PASSED: All tests
Alinco DJ596 Clone PASSED: All tests
Alinco DJ596 BruteForce PASSED: All tests
Alinco DJ596 Edges PASSED: All tests
Alinco DJ596 Banks SKIPPED: Banks not supported
Alinco DR235T Detect PASSED: All tests
Alinco DR235T CopyAll PASSED: All tests
Alinco DR235T Clone PASSED: All tests
Alinco DR235T BruteForce PASSED: All tests
Alinco DR235T Edges PASSED: All tests
Alinco DR235T Banks SKIPPED: Banks not supported
Baofeng BF-888 Detect PASSED: All tests
Baofeng BF-888 CopyAll PASSED: All tests
Baofeng BF-888 Clone PASSED: All tests
Baofeng BF-888 BruteForce PASSED: All tests
Baofeng BF-888 Edges PASSED: All tests
Baofeng BF-888 Banks SKIPPED: Banks not supported
Baofeng F-11 Detect PASSED: All tests
Baofeng F-11 CopyAll PASSED: All tests
Baofeng F-11 Clone PASSED: All tests
Baofeng F-11 BruteForce PASSED: All tests
Baofeng F-11 Edges PASSED: All tests
Baofeng F-11 Banks SKIPPED: Banks not supported
Baofeng UV-3R Detect PASSED: All tests
Baofeng UV-3R CopyAll PASSED: All tests
Baofeng UV-3R Clone PASSED: All tests
Baofeng UV-3R BruteForce PASSED: All tests
Baofeng UV-3R Edges PASSED: All tests
Baofeng UV-3R Banks SKIPPED: Banks not supported
Baofeng UV-5R Detect PASSED: All tests
Baofeng UV-5R CopyAll PASSED: All tests
Baofeng UV-5R Clone PASSED: All tests
Baofeng UV-5R BruteForce PASSED: All tests
Baofeng UV-5R Edges PASSED: All tests
Baofeng UV-5R Banks SKIPPED: Banks not supported
Baofeng UV-B5 Detect PASSED: All tests
Baofeng UV-B5 CopyAll PASSED: All tests
Baofeng UV-B5 Clone PASSED: All tests
Baofeng UV-B5 BruteForce PASSED: All tests
Baofeng UV-B5 Edges PASSED: All tests
Baofeng UV-B5 Banks SKIPPED: Banks not supported
Icom IC-208H Detect PASSED: All tests
Icom IC-208H CopyAll PASSED: All tests
Icom IC-208H Clone PASSED: All tests
Icom IC-208H BruteForce PASSED: All tests
Icom IC-208H Edges PASSED: All tests
Icom IC-208H Banks PASSED: All tests
Icom IC-2100H Detect PASSED: All tests
Icom IC-2100H CopyAll PASSED: All tests
Icom IC-2100H Clone PASSED: All tests
Icom IC-2100H BruteForce PASSED: All tests
Icom IC-2100H Edges PASSED: All tests
Icom IC-2100H Banks SKIPPED: Banks not supported
Icom IC-2200H Detect PASSED: All tests
Icom IC-2200H CopyAll PASSED: All tests
Icom IC-2200H Clone PASSED: All tests
Icom IC-2200H BruteForce PASSED: All tests
Icom IC-2200H Edges PASSED: All tests
Icom IC-2200H Banks PASSED: All tests
Icom IC-2720H Detect PASSED: All tests
Icom IC-2720H CopyAll PASSED: All tests
Icom IC-2720H Clone PASSED: All tests
Icom IC-2720H BruteForce PASSED: All tests
Icom IC-2720H Edges PASSED: All tests
Icom IC-2720H Banks PASSED: All tests
Icom IC-2820H Detect PASSED: All tests
Icom IC-2820H CopyAll PASSED: All tests
Icom IC-2820H Clone PASSED: All tests
Icom IC-2820H BruteForce PASSED: All tests
Icom IC-2820H Edges PASSED: All tests
Icom IC-2820H Banks PASSED: All tests
Icom IC-Q7A Detect PASSED: All tests
Icom IC-Q7A CopyAll PASSED: All tests
Icom IC-Q7A Clone PASSED: All tests
Icom IC-Q7A BruteForce PASSED: All tests
Icom IC-Q7A Edges PASSED: All tests
Icom IC-Q7A Banks SKIPPED: Banks not supported
Icom IC-T70 Detect PASSED: All tests
Icom IC-T70 CopyAll PASSED: All tests
Icom IC-T70 Clone PASSED: All tests
Icom IC-T70 BruteForce PASSED: All tests
Icom IC-T70 Edges PASSED: All tests
Icom IC-T70 Banks PASSED: All tests
Icom IC-T7H Detect PASSED: All tests
Icom IC-T7H CopyAll PASSED: All tests
Icom IC-T7H Clone PASSED: All tests
Icom IC-T7H BruteForce PASSED: All tests
Icom IC-T7H Edges PASSED: All tests
Icom IC-T7H Banks SKIPPED: Banks not supported
Icom IC-T8A Detect PASSED: All tests
Icom IC-T8A CopyAll PASSED: All tests
Icom IC-T8A Clone PASSED: All tests
Icom IC-T8A BruteForce PASSED: All tests
Icom IC-T8A Edges PASSED: All tests
Icom IC-T8A Banks SKIPPED: Banks not supported
Icom IC-V82/U82 Detect PASSED: All tests
Icom IC-V82/U82 CopyAll PASSED: All tests
Icom IC-V82/U82 Clone PASSED: All tests
Icom IC-V82/U82 BruteForce PASSED: All tests
Icom IC-V82/U82 Edges PASSED: All tests
Icom IC-V82/U82 Banks PASSED: All tests
Icom IC-W32A VHF Detect PASSED: All tests
Icom IC-W32A VHF CopyAll PASSED: All tests
Icom IC-W32A VHF Clone PASSED: All tests
Icom IC-W32A VHF BruteForce PASSED: All tests
Icom IC-W32A VHF Edges PASSED: All tests
Icom IC-W32A VHF Banks SKIPPED: Banks not supported
Icom IC-W32A UHF Detect PASSED: All tests
Icom IC-W32A UHF CopyAll PASSED: All tests
Icom IC-W32A UHF Clone PASSED: All tests
Icom IC-W32A UHF BruteForce PASSED: All tests
Icom IC-W32A UHF Edges PASSED: All tests
Icom IC-W32A UHF Banks SKIPPED: Banks not supported
Icom ID-31A Detect PASSED: All tests
Icom ID-31A CopyAll PASSED: All tests
Icom ID-31A Clone PASSED: All tests
Icom ID-31A BruteForce PASSED: All tests
Icom ID-31A Edges PASSED: All tests
Icom ID-31A Banks PASSED: All tests
Icom ID-51A Detect PASSED: All tests
Icom ID-51A CopyAll PASSED: All tests
Icom ID-51A Clone PASSED: All tests
Icom ID-51A BruteForce PASSED: All tests
Icom ID-51A Edges PASSED: All tests
Icom ID-51A Banks PASSED: All tests
Icom ID-800H v2 Detect PASSED: All tests
Icom ID-800H v2 CopyAll PASSED: All tests
Icom ID-800H v2 Clone PASSED: All tests
Icom ID-800H v2 BruteForce PASSED: All tests
Icom ID-800H v2 Edges PASSED: All tests
Icom ID-800H v2 Banks PASSED: All tests
Icom ID-880H Detect PASSED: All tests
Icom ID-880H CopyAll PASSED: All tests
Icom ID-880H Clone PASSED: All tests
Icom ID-880H BruteForce PASSED: All tests
Icom ID-880H Edges PASSED: All tests
Icom ID-880H Banks PASSED: All tests
Jetstream JT220M Detect PASSED: All tests
Jetstream JT220M CopyAll PASSED: All tests
Jetstream JT220M Clone PASSED: All tests
Jetstream JT220M BruteForce PASSED: All tests
Jetstream JT220M Edges PASSED: All tests
Jetstream JT220M Banks SKIPPED: Banks not supported
Jetstream JT270M Detect PASSED: All tests
Jetstream JT270M CopyAll PASSED: All tests
Jetstream JT270M Clone PASSED: All tests
Jetstream JT270M BruteForce PASSED: All tests
Jetstream JT270M Edges PASSED: All tests
Jetstream JT270M Banks SKIPPED: Banks not supported
Kenwood TH-D72 (clone Detect PASSED: All tests
Kenwood TH-D72 (clone CopyAll PASSED: All tests
Kenwood TH-D72 (clone Clone PASSED: All tests
Kenwood TH-D72 (clone BruteForce PASSED: All tests
Kenwood TH-D72 (clone Edges PASSED: All tests
Kenwood TH-D72 (clone Banks SKIPPED: Banks not supported
Kenwood TK-8102 Detect PASSED: All tests
Kenwood TK-8102 CopyAll PASSED: All tests
Kenwood TK-8102 Clone PASSED: All tests
Kenwood TK-8102 BruteForce PASSED: All tests
Kenwood TK-8102 Edges PASSED: All tests
Kenwood TK-8102 Banks SKIPPED: Banks not supported
Leixen VV-898 Detect PASSED: All tests
Leixen VV-898 CopyAll PASSED: All tests
Leixen VV-898 Clone PASSED: All tests
Leixen VV-898 BruteForce PASSED: All tests
Leixen VV-898 Edges PASSED: All tests
Leixen VV-898 Banks SKIPPED: Banks not supported
Polmar DB-50M Detect PASSED: All tests
Polmar DB-50M CopyAll PASSED: All tests
Polmar DB-50M Clone PASSED: All tests
Polmar DB-50M BruteForce PASSED: All tests
Polmar DB-50M Edges PASSED: All tests
Polmar DB-50M Banks SKIPPED: Banks not supported
Puxing PX-2R Detect PASSED: All tests
Puxing PX-2R CopyAll PASSED: All tests
Puxing PX-2R Clone PASSED: All tests
Puxing PX-2R BruteForce PASSED: All tests
Puxing PX-2R Edges PASSED: All tests
Puxing PX-2R Banks SKIPPED: Banks not supported
Puxing PX-777 Detect PASSED: All tests
Puxing PX-777 CopyAll PASSED: All tests
Puxing PX-777 Clone PASSED: All tests
Puxing PX-777 BruteForce PASSED: All tests
Puxing PX-777 Edges PASSED: All tests
Puxing PX-777 Banks SKIPPED: Banks not supported
Sainsonic AP510 Detect PASSED: All tests
Sainsonic AP510 CopyAll PASSED: All tests
Sainsonic AP510 Clone PASSED: All tests
Sainsonic AP510 BruteForce PASSED: All tests
Sainsonic AP510 Edges PASSED: All tests
Sainsonic AP510 Banks SKIPPED: Banks not supported
TYT TH-UV3R Detect PASSED: All tests
TYT TH-UV3R CopyAll PASSED: All tests
TYT TH-UV3R Clone PASSED: All tests
TYT TH-UV3R BruteForce PASSED: All tests
TYT TH-UV3R Edges PASSED: All tests
TYT TH-UV3R Banks SKIPPED: Banks not supported
TYT TH-UVF1 Detect PASSED: All tests
TYT TH-UVF1 CopyAll PASSED: All tests
TYT TH-UVF1 Clone PASSED: All tests
TYT TH-UVF1 BruteForce PASSED: All tests
TYT TH-UVF1 Edges PASSED: All tests
TYT TH-UVF1 Banks SKIPPED: Banks not supported
Vertex VXA-700 Detect PASSED: All tests
Vertex VXA-700 CopyAll PASSED: All tests
Vertex VXA-700 Clone PASSED: All tests
Vertex VXA-700 BruteForce PASSED: All tests
Vertex VXA-700 Edges PASSED: All tests
Vertex VXA-700 Banks SKIPPED: Banks not supported
Wouxun KG-816 Detect PASSED: All tests
Wouxun KG-816 CopyAll PASSED: All tests
Wouxun KG-816 Clone PASSED: All tests
Wouxun KG-816 BruteForce PASSED: All tests
Wouxun KG-816 Edges PASSED: All tests
Wouxun KG-816 Banks SKIPPED: Banks not supported
Wouxun KG-818 Detect PASSED: All tests
Wouxun KG-818 CopyAll PASSED: All tests
Wouxun KG-818 Clone PASSED: All tests
Wouxun KG-818 BruteForce PASSED: All tests
Wouxun KG-818 Edges PASSED: All tests
Wouxun KG-818 Banks SKIPPED: Banks not supported
Wouxun KG-UV6 Detect PASSED: All tests
Wouxun KG-UV6 CopyAll PASSED: All tests
Wouxun KG-UV6 Clone PASSED: All tests
Wouxun KG-UV6 BruteForce PASSED: All tests
Wouxun KG-UV6 Edges PASSED: All tests
Wouxun KG-UV6 Banks SKIPPED: Banks not supported
Wouxun KG-UVD1P Detect PASSED: All tests
Wouxun KG-UVD1P CopyAll PASSED: All tests
Wouxun KG-UVD1P Clone PASSED: All tests
Wouxun KG-UVD1P BruteForce PASSED: All tests
Wouxun KG-UVD1P Edges PASSED: All tests
Wouxun KG-UVD1P Banks SKIPPED: Banks not supported
Yaesu FT-1802M Detect PASSED: All tests
Yaesu FT-1802M CopyAll PASSED: All tests
Yaesu FT-1802M Clone PASSED: All tests
Yaesu FT-1802M BruteForce PASSED: All tests
Yaesu FT-1802M Edges PASSED: All tests
Yaesu FT-1802M Banks SKIPPED: Banks not supported
Yaesu FT-2800M Detect PASSED: All tests
Yaesu FT-2800M CopyAll PASSED: All tests
Yaesu FT-2800M Clone PASSED: All tests
Yaesu FT-2800M BruteForce PASSED: All tests
Yaesu FT-2800M Edges PASSED: All tests
Yaesu FT-2800M Banks SKIPPED: Banks not supported
Yaesu FT-60 Detect PASSED: All tests
Yaesu FT-60 CopyAll PASSED: All tests
Yaesu FT-60 Clone PASSED: All tests
Yaesu FT-60 BruteForce PASSED: All tests
Yaesu FT-60 Edges PASSED: All tests
Yaesu FT-60 Banks SKIPPED: Banks not supported
Yaesu FT-7800/7900 Detect PASSED: All tests
Yaesu FT-7800/7900 CopyAll PASSED: All tests
Yaesu FT-7800/7900 Clone PASSED: All tests
Yaesu FT-7800/7900 BruteForce PASSED: All tests
Yaesu FT-7800/7900 Edges PASSED: All tests
Yaesu FT-7800/7900 Banks PASSED: All tests
Yaesu FT-817 Detect PASSED: All tests
Yaesu FT-817 CopyAll PASSED: All tests
Yaesu FT-817 Clone PASSED: All tests
Yaesu FT-817 BruteForce PASSED: All tests
Yaesu FT-817 Edges PASSED: All tests
Yaesu FT-817 Banks SKIPPED: Banks not supported
Yaesu FT-817ND Detect PASSED: All tests
Yaesu FT-817ND CopyAll PASSED: All tests
Yaesu FT-817ND Clone PASSED: All tests
Yaesu FT-817ND BruteForce PASSED: All tests
Yaesu FT-817ND Edges PASSED: All tests
Yaesu FT-817ND Banks SKIPPED: Banks not supported
Yaesu FT-817ND (US) Detect PASSED: All tests
Yaesu FT-817ND (US) CopyAll PASSED: All tests
Yaesu FT-817ND (US) Clone PASSED: All tests
Yaesu FT-817ND (US) BruteForce PASSED: All tests
Yaesu FT-817ND (US) Edges PASSED: All tests
Yaesu FT-817ND (US) Banks SKIPPED: Banks not supported
Yaesu FT-857/897 Detect PASSED: All tests
Yaesu FT-857/897 CopyAll PASSED: All tests
Yaesu FT-857/897 Clone PASSED: All tests
Yaesu FT-857/897 BruteForce PASSED: All tests
Yaesu FT-857/897 Edges PASSED: All tests
Yaesu FT-857/897 Banks SKIPPED: Banks not supported
Yaesu FT-857/897 (U Detect PASSED: All tests
Yaesu FT-857/897 (U CopyAll PASSED: All tests
Yaesu FT-857/897 (U Clone PASSED: All tests
Yaesu FT-857/897 (U BruteForce PASSED: All tests
Yaesu FT-857/897 (U Edges PASSED: All tests
Yaesu FT-857/897 (U Banks SKIPPED: Banks not supported
Yaesu FT-8800 Left Detect PASSED: All tests
Yaesu FT-8800 Left CopyAll PASSED: All tests
Yaesu FT-8800 Left Clone PASSED: All tests
Yaesu FT-8800 Left BruteForce PASSED: All tests
Yaesu FT-8800 Left Edges PASSED: All tests
Yaesu FT-8800 Left Banks PASSED: All tests
Yaesu FT-8800 Right Detect PASSED: All tests
Yaesu FT-8800 Right CopyAll PASSED: All tests
Yaesu FT-8800 Right Clone PASSED: All tests
Yaesu FT-8800 Right BruteForce PASSED: All tests
Yaesu FT-8800 Right Edges PASSED: All tests
Yaesu FT-8800 Right Banks PASSED: All tests
Yaesu FT-8900 Detect PASSED: All tests
Yaesu FT-8900 CopyAll PASSED: All tests
Yaesu FT-8900 Clone PASSED: All tests
Yaesu FT-8900 BruteForce PASSED: All tests
Yaesu FT-8900 Edges PASSED: All tests
Yaesu FT-8900 Banks SKIPPED: Banks not supported
Yaesu FTM-350 Left Detect PASSED: All tests
Yaesu FTM-350 Left CopyAll PASSED: All tests
Yaesu FTM-350 Left Clone PASSED: All tests
Yaesu FTM-350 Left BruteForce PASSED: All tests
Yaesu FTM-350 Left Edges PASSED: All tests
Yaesu FTM-350 Left Banks SKIPPED: Banks not supported
Yaesu FTM-350 Right Detect PASSED: All tests
Yaesu FTM-350 Right CopyAll PASSED: All tests
Yaesu FTM-350 Right Clone PASSED: All tests
Yaesu FTM-350 Right BruteForce PASSED: All tests
Yaesu FTM-350 Right Edges PASSED: All tests
Yaesu FTM-350 Right Banks SKIPPED: Banks not supported
Yaesu VX-2 Detect PASSED: All tests
Yaesu VX-2 CopyAll PASSED: All tests
Yaesu VX-2 Clone PASSED: All tests
Yaesu VX-2 BruteForce PASSED: All tests
Yaesu VX-2 Edges PASSED: All tests
Yaesu VX-2 Banks PASSED: All tests
Yaesu VX-3 Detect PASSED: All tests
Yaesu VX-3 CopyAll PASSED: All tests
Yaesu VX-3 Clone PASSED: All tests
Yaesu VX-3 BruteForce PASSED: All tests
Yaesu VX-3 Edges PASSED: All tests
Yaesu VX-3 Banks PASSED: All tests
Yaesu VX-5 Detect PASSED: All tests
Yaesu VX-5 CopyAll PASSED: All tests
Yaesu VX-5 Clone PASSED: All tests
Yaesu VX-5 BruteForce PASSED: All tests
Yaesu VX-5 Edges PASSED: All tests
Yaesu VX-5 Banks PASSED: All tests
Yaesu VX-6 Detect PASSED: All tests
Yaesu VX-6 CopyAll PASSED: All tests
Yaesu VX-6 Clone PASSED: All tests
Yaesu VX-6 BruteForce PASSED: All tests
Yaesu VX-6 Edges PASSED: All tests
Yaesu VX-6 Banks PASSED: All tests
Yaesu VX-7 Detect PASSED: All tests
Yaesu VX-7 CopyAll PASSED: All tests
Yaesu VX-7 Clone PASSED: All tests
Yaesu VX-7 BruteForce PASSED: All tests
Yaesu VX-7 Edges PASSED: All tests
Yaesu VX-7 Banks PASSED: All tests
Yaesu VX-8 R Detect PASSED: All tests
Yaesu VX-8 R CopyAll PASSED: All tests
Yaesu VX-8 R Clone PASSED: All tests
Yaesu VX-8 R BruteForce PASSED: All tests
Yaesu VX-8 R Edges PASSED: All tests
Yaesu VX-8 R Banks PASSED: All tests
----------------------------------------------------------------------
Results:
TOTAL : 360
FAILED : 0
SKIPPED: 41
PASSED : 319
CRASHED: 0
Registered Icom_IC-2820H = IC2820Radio
Registered TYT_TH-UVF8D = TYTUVF8DRadio
Registered AnyTone_5888UV = AnyTone5888UVRadio
Registered Intek_HR-2040 = IntekHR2040Radio
Registered Polmar_DB-50M = PolmarDB50MRadio
Registered Powerwerx_DB-750X = PowerwerxDB750XRadio
Registered Icom_IC-2200H = IC2200Radio
Registered Yaesu_FT-2800M = FT2800Radio
Registered Yaesu_VX-3 = VX3Radio
Registered Icom_IC-2100H = IC2100Radio
Registered Yaesu_FTM-350 = FTM350Radio
Registered Icom_IC-V82_U82 = ICx8xRadio
Registered Yaesu_VX-6 = VX6Radio
Registered Yaesu_VX-5 = VX5Radio
Registered Yaesu_FT-60 = FT60Radio
Registered Yaesu_VX-7 = VX7Radio
Registered Sainsonic_AP510 = AP510Radio
Registered Baofeng_UV-5R = BaofengUV5R
Registered Baofeng_F-11 = BaofengF11Radio
Registered Baofeng_UV-82 = BaofengUV82Radio
Registered Baofeng_UV-6 = BaofengUV6Radio
Registered Intek_KT-980HP = IntekKT980Radio
Registered Baofeng_BF-F8HP = BaofengBFF8HPRadio
Registered Yaesu_FT-1802M = FT1802Radio
Registered Kenwood_TK-7102 = KenwoodTK7102Radio
Registered Kenwood_TK-8102 = KenwoodTK8102Radio
Registered Kenwood_TK-7108 = KenwoodTK7108Radio
Registered Kenwood_TK-8108 = KenwoodTK8108Radio
Registered Icom_ID-31A = ID31Radio
Registered Icom_ID-51A = ID51Radio
Registered Icom_IC-2720H = IC2720Radio
Registered Icom_IC-T8A = ICT8ARadio
Registered Wouxun_KG-UVD1P = KGUVD1PRadio
Registered Wouxun_KG-UV6 = KGUV6DRadio
Registered Wouxun_KG-816 = KG816Radio
Registered Wouxun_KG-818 = KG818Radio
Registered TYT_TH-UVF1 = TYTTHUVF1Radio
Registered Yaesu_FT-90 = FT90Radio
Registered Generic_CSV = CSVRadio
Registered Commander_KG-UV = CommanderCSVRadio
Registered RT_Systems_CSV = RTCSVRadio
Registered Kenwood_ITM = ITMRadio
Registered TYT_TH-9800 = TYTTH9800File
Registered Alinco_DR03T = DR03Radio
Registered Alinco_DR06T = DR06Radio
Registered Alinco_DR135T = DR135Radio
Registered Alinco_DR235T = DR235Radio
Registered Alinco_DR435T = DR435Radio
Registered Alinco_DJ596 = DJ596Radio
Registered Jetstream_JT220M = JT220MRadio
Registered Alinco_DJ175 = DJ175Radio
Registered Kenwood_TH-D7 = THD7Radio
Registered Kenwood_TH-D7G = THD7GRadio
Registered Kenwood_TM-D700 = TMD700Radio
Registered Kenwood_TM-V7 = TMV7Radio
Registered Kenwood_TM-G707 = TMG707Radio
Registered Kenwood_TH-G71 = THG71Radio
Registered Kenwood_TH-F6 = THF6ARadio
Registered Kenwood_TH-F7 = THF7ERadio
Registered Kenwood_TM-D710 = TMD710Radio
Registered Kenwood_TH-D72_live_mode = THD72Radio
Registered Kenwood_TM-V71 = TMV71Radio
Registered Kenwood_TH-K2 = THK2Radio
Registered Kenwood_TM-271 = TM271Radio
Registered Kenwood_TM-281 = TM281Radio
Registered Kenwood_TM-471 = TM471Radio
Registered Wouxun_KG-UV8D = KGUV8DRadio
Registered Yaesu_VX-8_R = VX8Radio
Registered Yaesu_VX-8_DR = VX8DRadio
Registered Yaesu_VX-8_GE = VX8GERadio
Registered Icom_IC-T7H = ICT7HRadio
Registered Icom_IC-Q7A = ICQ7Radio
Registered Baofeng_UV-B5 = BaofengUVB5
Registered Generic_XML = XMLRadio
Registered Kenwood_HMK = HMKRadio
Registered Kenwood_TH-D72_clone_mode = THD72Radio
Registered Icom_IC-91_92AD = IC9xRadio
Registered Icom_IC-T70 = ICT70Radio
Registered Icom_IC-208H = IC208Radio
Registered Leixen_VV-898 = LeixenVV898Radio
Registered Jetstream_JT270M = JetstreamJT270MRadio
Registered Icom_ID-800H_v2 = ID800v2Radio
Registered Icom_7200 = Icom7200Radio
Registered Icom_7000 = Icom7000Radio
Registered Icom_746 = Icom746Radio
Registered ARRL_Travel_Plus = TpeRadio
Registered Vertex_Standard_VXA-700 = VXA700Radio
Registered Icom_IC-W32A = ICW32ARadio
Registered Baofeng_UV-3R = UV3RRadio
Registered Yaesu_VX-2 = VX2Radio
Registered Puxing_PX-777 = Puxing777Radio
Registered Puxing_PX-2R = Puxing2RRadio
Registered Baojie_BJ-UV55 = BaojieBJUV55Radio
Registered Baofeng_BF-888 = H777Radio
Registered Yaesu_FT-7800_7900 = FT7800Radio
Registered Yaesu_FT-8800 = FT8800Radio
Registered Yaesu_FT-8900 = FT8900Radio
Registered KYD_NC-630A = NC630aRadio
Registered Yaesu_FT-817 = FT817Radio
Registered Yaesu_FT-817ND = FT817NDRadio
Registered Yaesu_FT-817ND_US = FT817NDUSRadio
Registered Yaesu_FT-857_897 = FT857Radio
Registered Yaesu_FT-857_897_US = FT857USRadio
Registered Yaesu_VX-170 = VX170Radio
Registered Icom_ID-880H = ID880Radio
Registered Icom_ID-80H = ID80Radio
Registered TYT_TH-UV3R = TYTUV3RRadio
Patch 'tip' is OK
================================================
Tests OK
Email was triggered for: Success
Sending email for trigger: Success
1
0