Getting position data from UBX protocol - python

I am working on a project which is use ublox .ubx protocol to getting position information. I'm using serial communication to connect my GPS module and getting position information to python sketch. I used Serial and pyubx2 libraries my sketch as follows,
from serial import Serial
from pyubx2 import UBXReader
stream = Serial('COM8', 38400)
while True:
ubr = UBXReader(stream)
(raw_data, parsed_data) = ubr.read()
print(parsed_data)
Then I have received information from GPS module as follows. It is continuously sending many of information in every second like as follows,
<UBX(NAV-SOL, iTOW=00:11:43, fTOW=-215069, week=0, gpsFix=0, gpsfixOK=0, diffSoln=0, wknSet=0, towSet=0, ecefX=637813700, ecefY=0, ecefZ=0, pAcc=649523840, ecefVX=0, ecefVY=0, ecefVZ=0, sAcc=2000, pDOP=99.99, reserved1=2, numSV=0, reserved2=215800)>
<UBX(NAV-PVT, iTOW=00:11:43, year=2015, month=10, day=18, hour=0, min=12, second=1, validDate=0, validTime=0, fullyResolved=0, validMag=0, tAcc=4294967295, nano=-215068, fixType=0, gnssFixOk=0, difSoln=0, psmState=0, headVehValid=0, carrSoln=0, confirmedAvai=0, confirmedDate=0, confirmedTime=0, numSV=0, lon=0.0, lat=0.0, height=0, hMSL=-17000, hAcc=4294967295, vAcc=3750027776, velN=0, velE=0, velD=0, gSpeed=0, headMot=0.0, sAcc=20000, headAcc=180.0, pDOP=99.99, invalidLlh=0, lastCorrectionAge=0, reserved0=2312952, headVeh=0.0, magDec=0.0, magAcc=0.0)>
I want to assign those position information (latitude, longitude, altitude etc.) into variables and hope to do some analysis part in further. So how can I derive positional information individually from this type of sentences.

Try something like this (press CTRL-C to terminate) ...
from serial import Serial
from pyubx2 import UBXReader
try:
stream = Serial('COM8', 38400)
while True:
ubr = UBXReader(stream)
(raw_data, parsed_data) = ubr.read()
# print(parsed_data)
if parsed_data.identity == "NAV-PVT":
lat, lon, alt = parsed_data.lat, parsed_data.lon, parsed_data.hMSL
print(f"lat = {lat}, lon = {lon}, alt = {alt/1000} m")
except KeyboardInterrupt:
print("Terminated by user")
For further assistance, refer to https://github.com/semuconsulting/pyubx2 (there are several example Python scripts in the /examples folder).

Related

Live Location Tracking using Python

I am using an app called cedalo connect to get my phone's GPS data using an online mqtt server. I constantly get latitude and longitude information using this app.
I want to show it on a map using python. I wrote such a code but it kept giving me errors like (AttributeError: module 'folium' has no attribute 'MarkerCluster')
I honestly don't know what else to use.
Could you please tell me what I can do about it?
what I tried:
import json
import paho.mqtt.client as mqtt
import folium
import time
from folium.plugins import MarkerCluster
# Variable to hold the current latitude and longitude
latitude = 50.780036278929614
longitude = 6.10363592985153
# Callback function when a message is received
def on_message(client, userdata, message):
global latitude, longitude
# Convert the message payload from bytes to string
data = message.payload.decode()
# parse the json string
data = json.loads(data)
# Extract the latitude and longitude
if 'GPS' in data:
gps_data = data["GPS"]
latitude = gps_data["Latitude"]
longitude = gps_data["Longitude"]
# Create MQTT client
client = mqtt.Client()
# Attach callback function to the message event
client.on_message = on_message
# Connect to the MQTT broker
client.connect("broker.mqttdashboard.com", 1883)
# Subscribe to the desired topic
client.subscribe("gpsdata")
# Start the MQTT loop
client.loop_start()
# Initialize the map
# Initialize the map
m = folium.Map(location=[latitude, longitude], zoom_start=15)
mc = folium.MarkerCluster()
m.add_child(mc)
marker = None
while True:
# Check if the latitude and longitude have been updated
if latitude and longitude:
# Remove the previous marker
if marker:
mc.remove_child(marker)
# Update the marker on the map to the current location
marker = folium.Marker(location=[latitude, longitude])
mc.add_child(marker)
# Save the map
m.save("current_location.html")
# Wait for one second
time.sleep(1)
The result is an attribute error.
The MarkerCluster class is located in folium.plugins. So, instead of
mc = folium.MarkerCluster()
try
mc = MarkerCluster()
or
mc = folium.plugins.MarkerCluster()

How to create a python dictionary containing an ARP table?

I have created a python script to detect an ARP attack. I have already initiated a ARP spoof attack and stored the wireshark capture in a pcap file. Once the code is executed, the code is designed to alert of any possible attack based on the MAC value change.
But how do I create a dictionary in the first place to store the MAC--IP mappings, and then detect when there is a change of values to indicate an alert?
Can anyone guide me please?
from scapy.all import *
mac_table = {}
def main():
pkts = rdpcap('/root/Desktop/arp_capture.pcap')
for packet in pkts:
if packet.haslayer(ARP):
if packet[ARP].op == 2:
try:
original_mac = req_mac(packet[ARP].psrc)
new_mac = packet[ARP].hwsrc
if original_mac != new_mac:
print(f"[**] ATTACK ALERT !!!!!! CHECK ARP TABLES !!![**]")
except IndexError:
pass
def req_mac(ip):
arp_req = ARP(pdst=ip)
bcst_req = Ether(dst='ff:ff:ff:ff:ff:ff')
p = bcst_req/arp_req
result = srp(p, timeout=3, verbose=False)[0]
return result[0][1].hwsrc
if __name__ == "__main__":
main()

Ardupilot - Dronekit Setting the Current Location of the Vehicle

Hello everybody, hope you are all doing well.
I am doing in a project in which I receive GPS data (Longitude, and Latitude) from an Android device via an SQL server. What I am trying to do is to send this Longitude - Latitude data to my SITL vehicle in Ardupilot. I thought about using Dronekit Python API as such:
from dronekit import connect, VehicleMode
import time
import mysql.connector
import time
#--- Start the Software In The Loop (SITL)
import dronekit_sitl
#
sitl = dronekit_sitl.start_default() #(sitl.start)
#connection_string = sitl.connection_string()
mydb = mysql.connector.connect(
host="******",
user="******",
password="*****",
database="koordinat"
)
mycursor = mydb.cursor()
#--- Now that we have started the SITL and we have the connection string (basically the ip and udp port)...
print("Araca bağlanılıyor")
vehicle = connect('tcp:127.0.0.1:5762', wait_ready=False, baud = 115200)
vehicle.wait_ready(True, raise_exception=False)
#-- Read information from the autopilot:
#- Version and attributes
vehicle.wait_ready('autopilot_version')
print('Autopilot version: %s'%vehicle.version)
#- Does the firmware support the companion pc to set the attitude?
print('Supports set attitude from companion: %s'%vehicle.capabilities.set_attitude_target_local_ned)
vehicle.mode = VehicleMode("GUIDED")
vehicle.armed = True
while(True):
mycursor.execute("SELECT * FROM koordinat WHERE 1")
location = str(mycursor.fetchall())
location = location.split(",")
location[0] = location[0].replace("[", "")
location[0] = location[0].replace("(", "")
location[0] = location[0].replace("'", "")
location[1] = location[1].replace("[", "")
location[1] = location[1].replace(")", "")
location[1] = location[1].replace("'", "")
location[1] = location[1].replace(")", "")
# Converting the longitude and latitude to float, before assigning to the vehicle GPS data:
location[0] = float(location[0])
location[1] = float(location[1])
# Setting the location of the vehicle:
vehicle.location.global_frame.lat = location[0]
vehicle.location.global_frame.lon = location[1]
print('Konum:', str(vehicle.location.global_frame.lat)+str(","), str(vehicle.location.global_frame.lon)+str(","), str(vehicle.location.global_frame.alt))
#- When did we receive the last heartbeat
print('Son bilgi gelişi: %s'%vehicle.last_heartbeat)
time.sleep(1)
However, when I check from the SITL and Mission Planner (also from the print statement from my code) the location does not change; the simulator simply ignores those commands sent by the Dronekit. Is there a working method to accomplish what I am trying to do? I tried to change the sim_vehicle.py script which I use to start the simulation. But I was only able to change the starting/home location of the vehicle. I was not able to change the current location of the vehicle on SITL and Mission Planner.
This is incorrect. You're modifying the attribute of the vehicle object that's connected to the SITL, not sending any commands to the actual autopilot.
vehicle.location.global_frame.lat = location[0]
vehicle.location.global_frame.lon = location[1]
What you want to do is set the mode to GUIDED and use the simple_goto function in dronekit to make the drone move to lat/lon/alt coordinates.
Otherwise, you can also send this MAVLink command SET_POSITION_TARGET_GLOBAL_INT to guide it.

How to automate control of Wemo light switch based on iPhone GPS

I'm writing a program to toggle the lights at my house based on my iPhone's GPS coordinates. Below is what I have so far. However, I feel like there must be a better way to do this. Is there a way to get GPS data without pinging my phone every five minutes?
So far I've tried the following with no joy:
Using Shortcuts and Scriptable I tried to write some JavaScript that would trigger when I got close to home. However, I could not figure out how to use await require('wemo-client') using scriptablify. I kept getting an error, "ReferenceError: Can't find variable: require".
IFTTT does not have a variable timed trigger so the lights won't turn off after 15 minutes. Also, I plan on adding a motion sensor trigger that is unsupported.
Pythonista is $10. Yes, I am that cheap.
Apple HomeKit does not support the model I'm using, Wemo Smart Light Switch F7C030.
The code below works, but I hate that I have to ping my phone every five minutes. I'd rather save battery life by firing this code once or twice a day, as needed.
Any suggestions would be greatly appreciated.
Code:
import sys
import time
import datetime
import os
from pyicloud import PyiCloudService
import pywemo
APPLE_ID = os.getenv('APPLE_ID') # Apple ID username
APPLE_ID_PASSWORD = os.getenv('APPLE_ID_PASSWORD') # Apple ID password
API = PyiCloudService(APPLE_ID, APPLE_ID_PASSWORD)
IPHONE = API.devices[1]
LOCATION = IPHONE.location()
FIVE = 300 # 5 * 60 seconds
FIFTEEN = 900 # 15 * 60 seconds
ONEMILE = 0.01449275362318840579710144927536 # one mile is 1/69 degrees lat or long
HOMELAT = # my home's latitude
HOMELONG = # my home's longitude
WEMOS = pywemo.discover_devices()
LEN_WEMOS = range(len(WEMOS))
# Two factor authentication to retrieve iPhone data
if API.requires_2fa:
import click
print("Two-step authentication required. Your trusted devices are:")
DEVICES = API.devices
for i, device in enumerate(DEVICES):
print(" %s: %s" % (i, device.get('deviceName', "SMS to %s" % device.get('phoneNumber'))))
DEF_DEVICE = click.prompt('Which device would you like to use?', default=0)
DEVICE = DEVICES[DEF_DEVICE]
if not API.send_verification_code(DEVICE):
print("Failed to send verification code")
sys.exit(1)
CODE = click.prompt('Please enter validation code')
if not API.validate_verification_code(DEVICE, CODE):
print("Failed to verify verification code")
sys.exit(1)
# Turn off the lights when I leave
def leavehome():
timenow = datetime.datetime.now()
print("Left home on {}".format(timenow.strftime("%B %d, %Y at %H:%M:%S")))
for wemo in LEN_WEMOS:
WEMOS[wemo].off()
# Turn on the lights for 15 minutes when I get home
def arrivehome():
timenow = datetime.datetime.now()
print("Arrived home on {}".format(timenow.strftime("%B %d, %Y at %H:%M:%S")))
# Loop through all Wemo devices
for wemo in LEN_WEMOS:
WEMOS[wemo].on()
time.sleep(FIFTEEN)
for wemo in LEN_WEMOS:
WEMOS[wemo].off()
# Automatically turn off the lights after 15 minutes - save electricity
def timeoff():
time.sleep(FIFTEEN)
for wemo in LEN_WEMOS:
WEMOS[wemo].off()
# Ping my phone for GPS data
def pingphone(prev):
mylat = LOCATION["latitude"]
mylong = LOCATION["longitude"]
logic(prev, mylat, mylong)
time.sleep(FIVE)
# Perform logic to determine if I'm home, out, arriving, or leaving
def logic(prev, lat, long):
inrange = (HOMELAT+ONEMILE >= lat >= HOMELAT-ONEMILE and HOMELONG+ONEMILE >= long >= HOMELONG-ONEMILE)
current = bool(inrange)
previous = prev
if current and not previous:
arrivehome()
elif previous and not current:
leavehome()
else:
timeoff()
pingphone(current)
# Run the script
pingphone(False)

How to receive multiple ATCommand response packets from the local xbee for the "FN" (finding neighbour) AT command using python digi-xbee library

This is the code which works well for all AT commands except "FN":
from digi.xbee.devices import XBeeDevice
#Initialise a serial port for the local xbee
local_xbee = XBeeDevice("/dev/tty.usbserial-AH02D9Q4", 9600).
#Opens serial port for sending commands
local_xbee.open()
#Sets new timeout for sync command operation
local.set_sync_ops_timeout(10).
#Send "FN" AT command to local xbee to receive neighbour list
neighbour_xbee_list = local.get_parameter("FN")
print(neighbour_xbee_list)
local_xbee.close()
Note:
The above code returns only one neighbour whereas I have more than one nodes in the network.
I believe the point of the question is not how to use the FN command, but how to discover neighbors.
For this, you can use the start_discovery_process function described here.
http://xbplib.readthedocs.io/en/latest/user_doc/discovering_the_xbee_network.html#discovernetwork
import serial
from digi.xbee.packets.common import ATCommPacket
from digi.xbee.devices import XBeeDevice
from digi.xbee.reader import PacketListener
from digi.xbee.serial import XBeeSerialPort
from digi.xbee.util import utils
import time
local_xbee = XBeeDevice("/dev/tty.usbserial-AH02D9Q4", 9600)
local_xbee.open()
print("This is : ", local_xbee.get_node_id())
print(local_xbee._packet_listener.is_running())
parameter = "FN"
frame_id = 33
my_packet = ATCommPacket(frame_id, parameter)
#print(my_packet)
#print(my_packet.frame_id)
#print(my_packet.command)
final_send = my_packet.output()
local_xbee._serial_port.write(final_send)
print("Finding Neighbours")
while True:
print(".")
Queue = local_xbee._packet_listener.get_queue()
received_packet = Queue.get_by_id(frame_id)
if received_packet != None:
#if received_packet.status == ATCommandStatus.OK:
final = received_packet._get_api_packet_spec_data().__str__()
print(final)
time.sleep(0.5)
local_xbee.close()

Categories