Running functions on bluetooth pair request - python

I've recently been learning electric circuitry using arduino and am looking to implement some changes to my Raspberry Pi application.
I used this outdated tutorial a few years ago to create my pi bluetooth receiver which is working well at the moment (https://www.instructables.com/id/Turn-your-Raspberry-Pi-into-a-Portable-Bluetooth-A/) but one downfall of this out-dated tutorial is that bluetooth connections have to be accepted via the screen (which is off because bluetooth speakers do not have screens).
My plan: use a button to accept bluetooth connections and use a flashing green LED to indicate a connection request.
How can I create a script that 'listens' for bluetooth pairing requests and run python code accordingly when its listening? With this, how can I connect to the bluetooth to accept a pair request?
I'm not too familiar with Raspberry Pi script placement, but am familiar with Python and know how I can connect to GPIO.
Thanks :)

What you are searching for is called a Bluetooth Agent. You need to use an official linux bluetooth protocol stack BlueZ. There is documentation describing the Agent API link. It uses DBus for communication. You need to invoke the following steps:
Create a bluetooth agent written in python and publish it at certain DBus object path. Your agent must implement org.bluez.Agent1 interface as described in Agent API doc.
Then you need to register this agent by calling RegisterAgent method from Agent API. Here you will provide the DBus path where your agent is located and also you will provide the capability in your case "DisplayYesNo" (LED as a display for pairing request, and button with some timeout for implementing Yes/No).
Also register your agent as a default agent by calling RequestDefaultAgent
Now if you try to pair with your device the appropriate function in your agent will be called (I think for your use case it will be RequestAuthorization) If you want to accept the pairing you will just return from this function, if you want to reject the pairing you must throw a DBus error inside this function.
As a starting point for you I would suggest you to look at this simple python Agent: https://github.com/pauloborges/bluez/blob/master/test/simple-agent
It implements all the functionality you need so just update it according to your needs.
Have fun :)

Have you tried using this Python library ? It lists Raspberry Pi support
Additionally, here's some info on listening for incoming Bluetooth connections:
Bluetooth programming in Python follows the socket programming model.
This is a concept that should be familiar to almost all network
programmers, and makes the transition from Internet programming to
Bluetooth programming much simpler. Example 3-2 and Example 3-3 show
how to establish a connection using an RFCOMM socket, transfer some
data, and disconnect.
import bluetooth
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
port = 1
server_sock.bind(("",port))
server_sock.listen(1)
client_sock,address = server_sock.accept()
print "Accepted connection from ",address
data = client_sock.recv(1024)
print "received [%s]" % data
client_sock.close()
server_sock.close()
An RFCOMM BluetoothSocket used to accept incoming connections must be
attached to operating system resources with the bind method. bind
takes in a tuple specifying the address of the local Bluetooth adapter
to use and a port number to listen on. Usually, there is only one
local Bluetooth adapter or it doesn't matter which one to use, so the
empty string indicates that any local Bluetooth adapter is acceptable.
Once a socket is bound, a call to listen puts the socket into
listening mode and it is then ready to accept incoming connections.
...
Source

Related

Connecting Client/Server program outside of LAN with Python

I am trying to create a chess game between two different computers that are not in the same LAN. I am having trouble connecting the two via a TCP connection (UDP would probably be sufficient as well if the packets are arriving, but ideally TCP).
I am new to a lot of networking and am unaware of many different tools that may be useful and I am also in university and therefore don't have control over the router to update firewall rules. What can I do to work around the router firewall to connect the two devices.
I am primarily using the Python socket library at the moment to implement the connection.
Any information about how I can send messages between the two computers outside of a LAN would be very useful. Thank you for your help!
I have ensured that the client side is using the public IP of the server and the server is using "" for its socket host. I also checked that the connection was working when utilizing a LAN without issue. I included a batch file that enables the specific port used for the game at the beginning of runtime and disables it at the end of the program. If I am not mistaken, that only impacts the computer's firewall rules not the router's. I have looked into receive the packets through port 80 and redirecting it to my specific program, but was unsuccesful in finding a solution of that type.
If the server is behind a router/firewall you'll have to use some sort of hole punching method to create the connection. STUN is one of the most common, though I've never actually used it in a Python program so I don't know what Python implementations are out there.

Socket over internet Python Embedded

I have an embedded system on which I can connect to internet. This embedded system must send sensor data to PC client.
I put a socket client using python on my PC. I put a socket server ( using C++ language on the embedded system because you can only use C++ ).
I can succesfully connect from my PC to the embedded system using the sockets and send and recieve whatever I want.
Now, the problem is I use local IP to connect to the system and both of them must be connected to the same Wifi router.
In the real application, I won't know where the embedded system is in the world. I need to get to it through internet, because it will be connectet to internet through 4g.
My question is, how can I connect to it through internet, if the embedded system is connected to internet using 4G?
Thank you
Realistically in typical situations, neither a PC nor an embedded device hanging off a 4g modem will likely have (or should be allowed) to have externally routable addresses.
What this practically means is that you need to bounce your traffic through a mutually visible relay in the cloud.
One very common way of doing that for IoT devices (which is basically to say, connected embedded devices) is to use MQTT. You'll find support in one form or another for most computing platforms with any sort of IP networking capability.
Of course there are many other schemes, too - you can do something with a RESTful API, or websockets (perhaps as an alternate mode of an MQTT broker), or various proprietary IoT solutions offered by the big cloud platforms.
It's also going to be really key that you wrap the traffic in SSL, so you'll need support for that in your embedded device, too. And you'll have to think about which CA certs you package, and what you do about time given its formal requirement as an input to SSL validation.
I think your problem is more easily solved if you reverse the roles of your embedded system and PC. If you are communicating to a device using IP protocols across cellular networks, it is much easier to have the device connect to a server on the PC rather than the other way around. Some networks/cellular modems do not allow server sockets and in any case, the IP address is usually dynamically allocated and therefore difficult to know. By having the device connect to a server, it "knows" the domain name (or IP address) and port to which it should make the connection. You just have to make sure that there is indeed a server program running at that host bound to some agreed upon port number. You can wake up the device to form the connection based on a number of criteria, e.g. time or amount of collected data, etc.

How to read modbus slaves (RTU) connected to a Siemens PAC4200 gateway (TCP) with python?

Please note I need to read the meters remote via the network via modbus gateway.
Siemens documentation states gateway can be reached via port 17002 (module 1)
I tried a TCP-client to the server on port 502 which works fine with pymodbus.
Slaves addresses are at 10-24.
a piece of sample code would be great.
If you have already connected to the PAC4200's server the gateways to the RS485 bus should be very much the same.
Just change the port, Modbus unit ID and target the registers you want to read.
A bare minimum should look like this:
from pymodbus.client.sync import ModbusTcpClient
host = 'device_IP' # The same you used already for port 502
port = 17002 # for MOD1 slot, use 17003 for MOD2
client = ModbusTcpClient(host, port)
client.connect()
start_reg=0x1 # write starting target register here
number_of_regs=10 # write number of registers to read here
slave_unit=10 # write slave ID of target device here
rr = client.read_holding_registers(start_reg,number_of_regs,unit=slave_unit)
print rr.registers # print registers, change to print(rr.registers) for Python 3.x
I'm not able to infer what devices you are connecting to the RS485 bus. If the sample code above is not working you should double-check the device's Modbus map and the connections to the PAC (see section 6.6 Connecting the PAC RS485 expansion module on the manual).
Thank you very much!
I learned from Siemens support team the PAC4200 isn't multi user capable.
As the desigo server is already occupying the connection, my requests stay unanswered.
A workaround was to enable the desigo web services. This way I'm able to read the power consumption of the slaves now.
Another alternative would be to install a 3rd party gateway which can handle multiple sessions and downgrade the PAC4200 to a client.

Modbus sniffing using python

I have 2 devices communicating with each other using Modbus and I would like to sniff this communication line using Python for logging purposes. I have connected my computer to the communication bus via a Modbus dongle, but I don't know how I can actually read the data.
I have used Pymodbus before, but I don't think that would work in this case since it only allows for master or slave devices (as far as I know)
Are there any other libraries that I can use for my purpose? Would it be possible for me to implement something like a read only socket on the COM port that doesn't interfere with existing communication on the bus?
Thank you!
You can try a MODBUS simulator like this one: It has an option to see the activity on the bus.
If you want to use another python MODBUS I recommend using modbus_tk. It has an example on how to create an MODBUS simulator. But to be able sniff the packets sent to other devices you will need to do some modifications to disable the automatic response.
If the only thing you want to do is to see the activity on the bus I recommend the first option.
I hope this helps you.
[Edit]:To be more specific you will need to download the following software : Modbus Poll - MODBUS slave simulator(which works on Windows) and plug your MODBUS dongle in the port you intend to use. After you do all the settings for the serial communications go to the Display tab and click on Communication. You will be able to see the traffic on the line.

python sockets and a serial to IP device

Using a Lantronix UDS-1100 serial to IP converter. The goal is to write a small proof of concept piece in Python to capture serial data output by this device over IP.
I've done a couple test projects using sockets in python, but they were all done between python processes (python > python): listen() on one end, and connect(), sendall() etc on the other.
I think I can use sockets for this project, but before I invest a bunch of time into it, wanted to make sure it is a viable solution.
Can python sockets be used to capture IP traffic when the traffic is originating from a non-python source? I have full control over the IP and port that the device sends the serial data to, but there will be no python connect() initiated by the client. I can pre-pend then serial data with some connect() string if needed.
If sockets won't work, please recommend another solution...guessing it will be REST or similar.
Of course. TCP/IP is supposed to be cross-platform and cross-language, so in theory you should be able to communicate with every kind of device as long as you manage to process and send the expected protocol.

Categories