กระจายสัญญาณ GPS บนเครือข่ายภายใน
(evertpot.com)- หลังจาก Mozilla ยุติบริการ GPS location service การระบุตำแหน่งบน Linux ที่อิงกับ GeoClue ก็มีความแม่นยำน้อยลง โดย
where-am-iระบุตำแหน่งใกล้ Toronto ด้วย GeoIP ที่มีความแม่นยำ 25km - ผู้เขียนอาศัยข้อเท็จจริงที่ว่าโฮมเซิร์ฟเวอร์แบบติดตั้งประจำที่ไม่ได้เคลื่อนที่ จึงตั้งค่าให้ส่งออก พิกัด GPS ที่ต้องการภายในเครือข่ายบ้านแบบโลคัล
- GeoClue เปิดใช้
network-nmeaไว้เป็นค่าเริ่มต้นใน/etc/geoclue/geoclue.confและจะค้นหา บริการ mDNS_nmea-0183._tcpเพื่อรับข้อมูล GPS - nmea-static-gps-server จะส่งข้อความ GPS แบบ NMEA 0183 ผ่าน TCP ทุกหนึ่งวินาที และลงทะเบียนบริการ
_nmea-0183._tcpด้วย Avahi - หลังรีสตาร์ต GeoClue ไคลเอนต์ก็รับพิกัดจากเซิร์ฟเวอร์ได้ทันที โดยผลลัพธ์แสดงคำอธิบาย
GPS GGA+RMCและความแม่นยำ 0 meters ส่วน Gnome Maps ก็แสดงตำแหน่งที่ถูกต้องได้ทันที
การตั้งค่า GeoClue และ NMEA
- หลังจาก Mozilla ยุติ GPS location service ความแม่นยำของตำแหน่งบน Linux ก็ลดลง และ GeoClue ซึ่ง Firefox และ Gnome Maps ใช้บนหลายระบบ Linux ก็อาศัย GeoIP จึงระบุตำแหน่งใกล้ Toronto ด้วยความแม่นยำ 25km เมื่อทดสอบด้วย
where-am-i - เดโม
where-am-iสามารถติดตั้งได้จากแพ็กเกจของแต่ละดิสโทร# Fedora sudo dnf install geoclue2-demos # Debian family sudo apt install geoclue-2-demo - ผู้เขียนอาศัยข้อเท็จจริงที่ว่าโฮมเซิร์ฟเวอร์แบบติดตั้งประจำที่ไม่ได้เคลื่อนที่ จึงตั้งค่าให้ส่งออก พิกัด GPS ที่ต้องการจากภายในเครือข่ายบ้านแบบโลคัล
- โปรโตคอลที่ใช้คือ NMEA 0183 ซึ่งเป็นชุดข้อกำหนดสำหรับอุปกรณ์อิเล็กทรอนิกส์ทางเรือ โดยสามารถส่งข้อความผ่านพอร์ตอนุกรมหรือ TCP socket ได้
- ตัวอย่างข้อความ GPS ประกอบด้วยบรรทัด
GPRMCและGPGGA$GPRMC,204049.000,A,5308.3999,N,00601.9266,E,0.000,0.000,030526,,*02 $GPGGA,204049.000,5308.3999,N,00601.9266,E,1,08,1.0,119.0,M,0.0,M,,*6F - GeoClue เปิดใช้ network-nmea ไว้เป็นค่าเริ่มต้นใน
/etc/geoclue/geoclue.conf# Network NMEA source configuration options [network-nmea] # Fetch location from NMEA sources on local network? enable=true - GeoClue จะค้นหา บริการ mDNS ชื่อ
_nmea-0183._tcpและเมื่อพบเรคอร์ดก็จะเชื่อมต่อไปยังที่อยู่นั้นเพื่อรับข้อมูล GPS
การทำเซิร์ฟเวอร์และการตรวจสอบการทำงาน
- nmea-static-gps-server เป็นเซิร์ฟเวอร์ TCP ที่ส่งข้อมูล GPS ทุกหนึ่งวินาที และลงทะเบียนบริการ
_nmea-0183._tcpผ่าน Avahi - Avahi คือ implementation มาตรฐานของ mDNS บน Linux ส่วนบน Mac จะมี Bonjour ทำหน้าที่เดียวกัน และ mDNS ยังใช้กับที่อยู่
.localในเครือข่ายภายในหรือการค้นหาอุปกรณ์อย่างเครื่องพิมพ์และทีวีด้วย - ในรีโพซิทอรีมีไฟล์ตั้งค่าบริการ Avahi ดังนี้
<?xml version="1.0" standalone='no'?> <!DOCTYPE service-group SYSTEM "avahi-service.dtd"> <service-group> <name replace-wildcards="yes">NMEA GPS (%h)</name> <service> <type>_nmea-0183._tcp</type> <port>10110</port> </service> </service-group> - หลังคัดลอกไฟล์นี้ไปไว้ที่
/etc/avahi/services/nmea-statis-gpc.serviceก็สามารถตรวจสอบการค้นพบบริการจากเครื่องอื่นด้วยavahi-browse$ avahi-browse _nmea-0183._tcp -r -t + wlp192s0 IPv6 NMEA GPS (node05) _nmea-0183._tcp local + wlp192s0 IPv4 NMEA GPS (node05) _nmea-0183._tcp local = wlp192s0 IPv6 NMEA GPS (node05) _nmea-0183._tcp local hostname = [node05.local] address = [fe80::a8c2:15de:9af:19b] port = [10110] txt = [] = wlp192s0 IPv4 NMEA GPS (node05) _nmea-0183._tcp local hostname = [node05.local] address = [192.168.2.205] port = [10110] txt = [] - เมื่อบริการทำงานอยู่บน
node05.localก็สามารถทดสอบตัวเซิร์ฟเวอร์ TCP ได้ง่าย ๆ ด้วยtelnet node05.local 10110 - เมื่อรีสตาร์ต GeoClue บนฝั่งไคลเอนต์ ก็รับพิกัดของเซิร์ฟเวอร์ได้ทันที
$ sudo systemctl restart geoclue $ /usr/libexec/geoclue-2.0/demos/where-am-i - ผลลัพธ์จะแสดงพิกัดที่แม่นยำของเซิร์ฟเวอร์พร้อมคำอธิบาย
GPS GGA+RMCและความแม่นยำเป็น 0 metersClient object: /org/freedesktop/GeoClue2/Client/3 New location: Latitude: 43.645758° Longitude: -79.410510° Accuracy: 0 meters Altitude: 119.000000 meters Speed: 0.000000 meters/second Description: GPS GGA+RMC Timestamp: Sun 03 May 2026 04:58:58 PM (1777841938 seconds since the Epoch) - Gnome Maps แสดงตำแหน่งที่ถูกต้องได้ทันที ส่วน Firefox ต้องรีสตาร์ตก่อน
- บน Mac ใน Apple Maps ก็ดูเหมือนจะทำงานเมื่อปิด Location Services แต่บนแผนที่ไม่ได้แสดงจุดที่แม่นยำ แค่ระบุพื้นที่โดยรวมได้ถูกต้อง
- วิธีนี้ช่วยให้เครื่อง Linux ภายในบ้านระบุตำแหน่งที่ถูกต้องได้ทันทีโดยไม่ต้องรอการค้นหา GPS ที่ช้าและไม่แม่นยำ และยังใช้สปูฟตำแหน่งผิด ๆ ให้กับแขกหรือเพื่อนร่วมงานที่ใช้ Linux ได้ด้วย
- https://github.com/evert/nmea-static-gps-server
1 ความคิดเห็น
ความคิดเห็นจาก Lobste.rs
ไม่เคยรู้มาก่อนเลยว่ามีมาตรฐาน บริการ mDNS สำหรับประกาศ GNSS บน LAN ซึ่งมันแก้ปัญหาที่ผม/ฉันครุ่นคิดเป็นพัก ๆ มาราว 6 เดือนได้ตรงจุดทันที
การสปูฟตำแหน่ง GPS เป็นไอเดียที่ดี แต่ถ้าจะทำจริงก็ดูเหมือนจะมีงานพอสมควร
ถ้าในตั้งค่า Android หรือในส่วนขยาย Firefox มีตัวเลือกง่าย ๆ อย่าง “ใช้ตำแหน่งจริง / ใช้ตำแหน่งที่กำหนดเอง” ก็น่าจะดี
แต่ก็สงสัยเหมือนกันว่าเวลามันขัดกับปัจจัยอื่นอย่าง IP หรือ locale แล้ว ตำแหน่ง GPS จะถูกให้น้ำหนักมากแค่ไหน
เพิ่มเติมคือผม/ฉันตกใจอยู่แวบหนึ่งตอนเห็นรูป Jeff Geerling ตรงท้ายหน้า ก่อนจะมารู้ทีหลังว่าเขาไม่ได้เป็นผู้เขียน แค่กดไลก์ไว้เท่านั้น
ถ้าเป็นไปได้ ปกติผม/ฉันจะเลี่ยงงานของเขา
ผม/ฉันเคยใช้ตัวรับสัญญาณ GNSS ของ Trimble จำไม่ได้แล้วว่าเป็น USB OTG หรือ BLE แต่แอปของ Trimble สามารถทำหน้าที่เป็นแหล่ง Mock Locations เพื่อให้แอป Android ใด ๆ ก็ได้ รับพิกัดความแม่นยำสูงจากไม้สตาฟสำรวจ แทนที่จะใช้พิกัดความแม่นยำค่อนข้างต่ำของตัวโทรศัพท์เอง ประมาณ 2 ซม.
น่าสนใจดี แต่ก็น่าจะทำเองได้ แล้วก็เขียนสคริปต์ให้ Android ส่งข้อมูลนี้ออกมาเมื่ออยู่ในเครือข่ายบ้าน
แต่ก็ยังไม่แน่ใจเต็มที่ว่าจำเป็นต้องใช้จริงไหม :p
เพิ่งรู้ว่า NMEA 0183 เป็นชุดสเปกสำหรับอุปกรณ์อิเล็กทรอนิกส์ทางทะเล
ไม่เคยสงสัยมากพอจะไปค้นว่า NMEA ย่อมาจากอะไร แต่ก็รู้จักชื่อนี้จาก ModemManager และโมเด็ม Qualcomm