Python2.7 + Bluez 5.61 + dbus - InterfacesRemoved never called - python

I'm trying to get a raspberry scanning for Bluetooth devices using Bluez 5.61.
I need this raspberry to be able to detect when a Bluetooth device (here, another Raspberry also using Bluez) cannot be detected anymore.
I was thinking using InterfacesRemoved signal from dbus but I guess I don't understand properly how it works as it's never called.
My questions:
I'm not sure I understand properly what interfacesAdded and interfacesRemoved are used for as they are rarely called when expected (propertiesChanged works fine)
Is it possible to get a signal for each advertisement message received even if the content has not changed since the last one? That would allow me to set up a timer to trigger the "non detectable anymore" event.
Here is the code I use to register my signals:
self.bus.add_signal_receiver(
self._interfaces_added,
dbus_interface=common.OBJECT_MANAGER,
signal_name="InterfacesAdded")
self.bus.add_signal_receiver(
self._interfaces_removed,
dbus_interface=common.OBJECT_MANAGER,
signal_name="InterfacesRemoved")
self.bus.add_signal_receiver(
self._properties_changed,
dbus_interface=common.DBUS_PROP_IFACE,
signal_name="PropertiesChanged",
arg0=common.DEVICE_INTERFACE,
path_keyword="path")

Related

Why can't I access my ESP3288 USB after detaching REPL from UART0?

What I put into my otherwise mostly empty main function was basically:
import uos
uos.dupterm(None, 1)
I uploaded this code to my microcontroller and it stopped being able to connect to my computer. My aim was trying to connect to a Bluetooth module (ZS-040). Now I can't even connect to the microcontroller.
I was intending to make a serial connection to the Bluetooth module while keeping the UART0 bus separate for USB and REPL connection. Now, I am stranded, having done quite the opposite. How do I fix this?
If you have enabled the webrepl, try using it to connect & upload a new, blank 'main.py'.
https://docs.micropython.org/en/latest/esp8266/tutorial/repl.html?highlight=webrepl
(this works on my ESP8266 after running dupterm(None, 1)). Failing that, re-flash the firmware to erase 'main.py' and re write the script to either issue dupterm manually at the start or to issue 'dupterm(UART(0, 115200), 1)' after some later event to re-attach the repl.

Listening to i2c input changes with python

Let's say I have a raspberry pi here and I want to write a Python script that turns on the light as soon as a i2c signal reaches the pi and some pin gets high. I do not want to use polling for this task, as it could slow down the process
(I know just a bit but I'ts just bad practice and puts load on the CPU and so on, so I don't want to permacycle asking for the input state)
Is there any kind of server or callback function I could use to realize this with a python script? Which library could I use to reach such a behaviour?
First Ideas are enviromental variables/the i2c Interface in the Linux system that I could listen to constantly somehow and catch it to make it do what I want it to.
As I see it no need to use python but I don't see whole picture so I don't know if this will help You,
just regarding this part of question:
Is there any kind of server or callback function...
rpio.poll(pin, callback());
Watch pin for changes and execute the callback callback() on events.
callback() takes a single argument, the pin which triggered the callback.
The optional direction argument can be used to watch for specific
events:
rpio.POLL_LOW: poll for falling edge transitions to low.
rpio.POLL_HIGH: poll for rising edge transitions to high.
rpio.POLL_BOTH: poll for both transitions (the default).
Complete documentation - this is the npm module documentation
My example of configuring node.js server

Raspberry pi - AdaFruit DHT in wsgi script (non-root)

Using the ADAFRUIT_DHT python library from https://github.com/adafruit/Adafruit_Python_DHT and a DHT22 temp/humidity sensor (https://www.adafruit.com/products/393) I'm able to easily read temperature and humidity values.
The problem is, that I need to run my script as root, in order to interact with the GPIO pins. This is simply not possible, when running my script through a website, via wsgi, as apache will not let me (for good reason) set the WSGIDaemonProcess's user to root.
I've got pigpiod running which allows me to interact with the GPIO through it, as a non-root user, however, the ADAFRUIT_DHT doesn't go through the daemon, and interacts directly with the GPIO. I'm not 100% sure the pigpio daemon would be fast enough for the bit-banging, required to decode the response from the DHT22 unit, but, perhaps.
So, is there a way for me to coerce the ADAFRUIT_DHT library to not require being run as root, or, are there alternatives to the library available that might accomplish what I'm looking for?
Create a small server that runs as root and listens on a local Unix or TCP socket. When another process connects, your server reads the data from sensor and returns it.
Now your WSGI process only needs permissions to connect to the listening socket, which can be easily managed either via permissions on a Unix socket, or simply throwing access control to the wind and opening a TCP socket bound to the localhost address (so that only processes on the local machine can connect).
There are several advantages to doing this...for example, you can now have multiple programs consuming the temperature data at the same time, and not need to worry about device contention (because only the temperature server is actually reading the data). You can even implement short-term caching to provide faster responses.
Also, note that there is a raspberry pi specific stackexchange.
pigpio can certainly read the DHT11/22 etc. sensors.
There are two examples using the daemon (which means root privileges are not required).
DHT11/21/22/33/44 Sensor written in C which auto detects the model.
DHT22 written in Python which only handles the DHT22 (the github has a DHT11 example).
Both examples are likely to give reliable results (read error rates of better than 1 in 10 thousand rather than worse than 1 in 10).

Interrupts using i2c and Python

Some background:
I have an i2c device (MCP23017), which has 6 switches connected to its GPIO ports. The MCP23017 is connected to a Raspberry Pi via i2c.
I'm able to read the state of each of the switches as required.
My issue is in regards to interrupts. I'm using the WiringPi2 library for Python, which allows me to interface with the MCP23017 under Python. From the research I've done, the WiringPiISR library allows for i2c interrupt protocols to be run, although it only seems to work (properly) under C.
My question is this: is there a simple solution for implementing i2c interrupts under Python?
I'm considering dropping Python for C for this particular project, but the GUI interface has already been written (in Python), so I'd like to keep that as a last option.
Any guidance/input/comments would be greatly appreciated!
Thanks!
As far as I understand, WiringPiISR library only allows you to configure a Pin to be an interrupt and define its type (ie, edge based or level based). Since you're talking about I2c interrupt, there is no way you can have I2C interrupt as in this case, Your Rpi works as a master device and other connected device(s) as slave(s). Since in I2C, communication is always initiated by the master, slaves can not interrupt you. (at least not via I2C channel)
Hope it helps.
There are devices that have an interrupt line in addition to I2C lines. For example I have a rotary encoder I2C interface board from duppa.net which has 5 pins - SDA, SCL, +, - and interrupt.
The python library that comes with it configures the Raspberry Pi GPIO 4 line as an input edge triggered interrupt and sets up callbacks. On a change (the rotary encoder is rotated for instance) the interrupt line wiggles, the interrupt handler reads the status register over I2C and calls the appropriate callback.
So this is completely conventional interrupt usage in the context of I2C doing to usual task of freeing the master from having to poll the bus.

What are the functions / AT commands to reconnect a disconnected GSM modem?

I have a GSM modem that disconnect after a while, maybe because of low signal. I am just wondering is there an AT command that can detect the disconnection and re-establish a reconnection.
Is there a way in code (preferably python) I can detect the disconnection and re-establish a reconnection?
Gath
Depending on what type of connection, circuit switched (CS) or packet switched (PS), the monitoring will be a little bit different. To detect a disconnect you can enable UR (unsolicited result) code AT+CPSB=1 to monitor PDP context activity (aka packet switched connections). For circuit switched calls you can monitor with the +CIEV: UR code enabled with AT+CMER=3,0,0,2.
To re-establish the connection you have to set up the connection again. For CS you will either have to know the phone number dialed, or you can use the special form of ATD, ATDL [1] which will dial the last dialed number. You can use ATDL for PS as well if the call was started with ATD (i.e. "ATD*99*....") which is quite common, but I do not think there is any way if started with AT+CGDATA for instance.
However, none of the above related to ATD matters, because it is not what you want. For CS you might set up a call from your python script, but then so what? After receiving CONNECT all the data traffic would be coming on the serial connection that your python script are using. And for PS the connection will not even finish successfully unless the phone receives PPP traffic from the PC as part of connection establishment. Do you intend your python script to supply that?
What you really want is to trigger your PC to try to connect again, whether this is standard operating system dial up networking or some special application launching it. So monitor the modem with a python script and then take appropriate action on the PC side to re-establish the connection.
[1]
Side note to ATDL: notice that if you want to repeat the last voice call you should still terminate with a semicolon, i.e. ATDL;, otherwise you would start a data call.
Here is how I do it with Telit devices:
I use AT+CGREG=1 to subscribe to unsolicited messages. Extract from documentation:
+CGREG - GPRS Network Registration Status
AT+CGREG=[<n>]
Set command controls the presentation of an unsolicited result code
+CGREG: (see format below).
Parameter:
<n> - result code presentation mode
0 - disable network registration unsolicited result code
1 - enable network registration unsolicited result code; if there is a change in the terminal GPRS network registration status, it is issued the unsolicited result code:
+CGREG: <stat>
And I wait on the modem's serial line for +CGREG messages. When something comes I check to see if stat is 1 (connected to the home network) or 5 (connected in roaming).
NOTE: A different response +CGREG comes when issuing the AT+CGREG? which is not hard to isolate.
You can try to check the signal strength on a regular basis with AT+CSQ. If the signal goes under a given threshold consider that you are disconnected and force a new connection.
You can try the very nice pyserial http://pyserial.sourceforge.net/ Python library to send the AT commands to the modem.
I hope it helps

Categories

Resources