Django Channels with MQTT - python

Am trying to create websocket using django channels and integrate mqtt with channels and mqtt publish message should be received by the function inside consumer.py should be sent to websocket client.
I have consumer channel like below
consumer.py
from channels.consumer import AsyncConsumer
from paho.mqtt import client as Mqtt
class Testing(AsyncConsumer):
async def websocket_connect(self, event):
obj = Mqtt.Client()
obj.connect("localhost", 1883, 60)
obj.on_message = self.updater
obj.subscribe("Testing")
obj.loop_start()
async def updater(self, arg1, arg2, message):
print(message)
await self.send({
"type": "websocket.send",
"text": message})
async def websocket_receive(self, text_data):
pass
In the above mqtt connection has happened but if I publish a message to the topic its not working. updater function inside consumer.py is not being called. How to achieve this ?

After coming here looking for help on this topic myself I created chanmqttproxy
Essentially it's a fully async Channels 3 proxy to MQTT that allows publishing and subscribing. The documentation show how to extend the standard Channels tutorial so chat messages are seen on MQTT topics - and can be sent from MQTT topics to all websocket browser clients.
I looked at MQTTAsgi (and credited it for inspiration) but felt that using a pure async solution with full Channels integration was more appropriate.

Related

I canĀ“t publish MQTT messages after a few days

I'm using "mqttasgi" as library with Django justo to listen and posting many messages. However, for some reason after a few days it is no longer possible to continue posting messages. It should be noted that I am using the amazon login with "mqttasgi" and a level 1 of QO(because AWS doesn't allow a level 2 of QO).
This is my procfile
mqttasgi -H $MQTT_URL -p $MQTT_PORT -v 2 -C $TLS_CERT -K $TLS_KEY -S $TLS_CA iot_stracontech.asgi:application```
and this is my consumer.py
from mqttasgi.consumers import MqttConsumer
from mqtt_handler.tasks import processmqttmessage
import json
class MyMqttConsumer(MqttConsumer):
async def connect(self):
await self.subscribe('tpx/things/+/uplink', 0)
await self.channel_layer.group_add("stracontech", self.channel_name)
async def receive(self, mqtt_message):
print('Received a message at topic:', mqtt_message['topic'])
print('With payload', mqtt_message['payload'])
print('And QOS:', mqtt_message['qos'])
dictresult = json.loads(mqtt_message['payload'])
jsonresult = json.dumps(dictresult)
processmqttmessage.delay(jsonresult, mqtt_message['topic'])
pass
async def publish_results(self, event):
data = event['result']
await self.publish("stracontech/procesed/" + event['result']['device_id'] + "/result",
json.dumps(data).encode('utf-8'), qos=1, retain=False)
async def disconnect(self):
await self.unsubscribe('tpx/things/+/uplink')
I want to know if exist a way to know why does it stop publishing messages, anyway to do a debug or see the logs?
Pd: #Santiago Ivulich maybe you can give me a hand with that.

How can I send messages to my private telegram channel with Telethon?

I want to send a message to a private telegram channel using python with Telethon.
What I tried:
from telethon import TelegramClient
from telethon.tl.types import Channel
client = TelegramClient('fx', api id, "API hash")
client.start()
def sendMSG(channel, msg):
entity = client.get_entity(channel)
client.send_message(entity = entity,message=msg)
sendMSG("Channel Name", "Hello")
But this code gives me this error:
RuntimeWarning: coroutine 'UserMethods.get_entity' was never awaited
sendMSG("Channel", "Hello")
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Telethon is an asynchronous library. This means you need to await almost everything.
import asyncio
async def sendMSG(channel, msg):
entity = client.get_entity(channel)
await client.send_message(entity = entity,message=msg)
asyncio.run(sendMSG("Channel Name", "Hello"))

How to do object detection on a video stream coming from a websocket url

I am getting a stream from a source which I made so that it can be accessed at a particular websocket URL (Not sure if this ideal and would appreciate any other architectures as well). I need to now do object detection on this video stream, and thought of the architecture that I will connect to the websocket URL through a client websocket library like websocket in a server which is made through flask or fastapi, and then again stream the object detected video to multiple clients through another websocket URL.
The problem is I am unable to receive any images even after connecting to the websocket URL and am not sure how to handle asyncio in a server scenario as in where to put the line run_until_complete.
Any suggestions or help would be greatly appreciated
Server code
import uvicorn
from fastapi import FastAPI, WebSocket
# import websockets
# import asyncio
# init app
app = FastAPI()
async def clientwebsocketconnection():
uri = "wss://<websocket URL here>"
async with websockets.connect(uri) as websocket:
print("reached here")
data = await websocket.recv()
print(f"< {data}")
# Routes
#app.get('/')
async def index():
return {"text": "Its working"}
#app.websocket('/websocketconnection') # FIXME: change this to a websocket endpoint
async def websocketconnection():
return {"text": "Its working"}
if __name__ == '__main__':
uvicorn.run(app, host="127.0.0.1", port=8000)
# asyncio.get_event_loop().run_until_complete(clientwebsocketconnection())
I assume you want to send a text via websocket. TO do this you need the following code:
#app.websocket('/websocketconnection')
async def websocketconnection(websocket: WebSocket) -> None:
await websocket.accept()
await websocket.send_text("It's working!")
await websocket.close()
You may find more examples in the official FastAPI docs.

Listener in python - telegram

Hi I am working telegram api telethon. Here I wanted to continuously listen the group messages in python code.
I am able to read the messages from group but every time i need to run the code. is there any way to implement it that my code should listen the message synchronically.
below is the code snippets which gives me the messages in group. need to add listener code in it.
client = TelegramClient('session_read', api_id, api_hash)
client.start()
dialog_count = 50
dialogs = client.get_dialogs(dialog_count)
for i, entity in enumerate(dialogs):
if entity.name == 'GroupName':
print('{}'.format(entity.message.message))
Telethon has event handlers as documented here. For a basic new message handler, the first example should do:
from telethon import TelegramClient, events
client = TelegramClient('session_read', api_id, api_hash)
#client.on(events.NewMessage)
async def my_event_handler(event):
print('{}'.format(event))
client.start()
client.run_until_disconnected()
If you want to check that it's in a specific group, you can use the chats parameter on events.NewMessage:
#client.on(events.NewMessage(chats=("GroupName", "Group2")))
async def my_event_handler(event):
print(event)
There are a lot of other filtering options too, so I recommend checking out the documentation linked earlier.

python websockets consumer and producer examples needed

http://websockets.readthedocs.io/en/stable/intro.html#consumer contains the following example:
async def consumer_handler(websocket, path):
while True:
message = await websocket.recv()
await consumer(message)
and http://websockets.readthedocs.io/en/stable/intro.html#producer
async def producer_handler(websocket, path):
while True:
message = await producer()
await websocket.send(message)
But there is no example for consumer() and producer() implementation or any explanation. Can somebody provide any simple example for that?
In the first example, consumer_handler listens for the messages from a websocket connection. It then passes the messages to a consumer. In its simplest form, a consumer can look like this:
async def consumer(message):
# do something with the message
In the second example, producer_handler receives a message from a producer and sends it to the websocket connection. A producer can look like this:
async def producer():
message = "Hello, World!"
await asyncio.sleep(5) # sleep for 5 seconds before returning message
return message

Categories

Resources