how can i publish and subscribe an image (using mqtt in python) - mqtt

I use Baidu loT Core. I use two devices as clients, a database(TSDB) as server. The target function:One client send a image to database , then data bese transmits to another client. I get help from How can I publish a file using Mosquitto in python?
but it still doesn't work.
send image
import paho.mqtt.client as mqtt
import json
import cv2
HOST = '************'
PORT = 1883
client_id = '************'
username = '***********'
password = '******************'
topic = '******'
# obj = userdata
# mqttc = client
def on_connect(mqttc, obj, flags, rc):
print("rc: " + str(rc))
def on_message(mqttc, obj, msg):
print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload.decode('utf-8')))
def on_publish(mqttc, obj, mid):
print("mid: " + str(mid))
def on_subscribe(mqttc, obj, mid, granted_qos):
print("Subscribed: " + str(mid) + " " + str(granted_qos))
def on_log(mqttc, obj, level, string):
print(string)
def on_disconnect(mqttc, obj, rc):
print("unsuccess connect %s" % rc)
mqttc = mqtt.Client(client_id)
mqttc.username_pw_set(username, password) # thanks correction. I found I forget to connect broker.But the question is still
mqttc.on_message = on_message
mqttc.on_connect = on_connect
mqttc.on_publish = on_publish
mqttc.on_subscribe = on_subscribe
mqttc.on_disconnect = on_disconnect
# Uncomment to enable debug messages
mqttc.on_log = on_log
mqttc.connect(HOST, PORT, 60)
image = 'E:/_TempPhoto/0.jpg'
print(type(image))
def imageToStr(image):
with open(image, 'rb') as f:
image_byte = base64.b64encode(f.read())
print(type(image_byte))
image_str = image_byte.decode('ascii') # byte to str
print(type(image_str))
return image_str
image1 = imageToStr(image)
data = {
"engineeringdata": {
"date": 12,
"value": "59.3;98.5",
"image": image1
}
}
json_mod = json.dumps(data)
mqttc.publish(topic, json_mod, 0)
mqttc.loop_forever()
receive image
import paho.mqtt.client as mqtt
import cv2
import numpy as np
import json
HOST = '*********'
PORT = 1883
client_id = '************'
username = '*****************'
password = '******************'
topic = '***************'
def on_connect(client, userdata, flags, rc):
print("Connected with result code: " + str(rc))
def strToImage(str,filename):
image_str= str.encode('ascii')
image_byte = base64.b64decode(image_str)
image_json = open(filename, 'wb')
image_json.write(image_byte) #将图片存到当前文件的fileimage文件中
image_json.close()
def on_message(client, userdata, msg):
print(msg.topic + " " + str(msg.payload))
strToImage(str(msg.payload), 'E:/_TempPhoto/restore001.jpg')
client = mqtt.Client(client_id)
client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(HOST, PORT, 60)
client.subscribe(topic, 0)
client.on_message = on_message
client.loop_forever()
# while True:
# client.loop(15)
# time.sleep(2)
This is my send image 's message and log. I moit a part of printed data of image by '......'
Sending CONNECT (u1, p1, wr0, wq0, wf0, c1, k60) client_id=b'client_for_test'
<class 'str'>
<class 'bytes'>
<class 'str'>
Sending PUBLISH (d0, q0, r0, m1), 'b'$iot/client_for_test/user/fortest'', ... (102800 bytes)
mid: 1
Received CONNACK (0, 0)
rc: 0
Sending PINGREQ
Received PINGRESP
Sending PINGREQ
Received PINGRESP
this is receive image 's printed message:(seems right)
Connected with result code: 0
My error case is 5. And I didn't recvice a image. But it seemed that send successfully.
Maybe it's because the send image send once and end, but the receive image can't receive rightly.
I just need the most simple codes of two clients to send and receive the image through mqtt,please!
Give me a hand!
Thanks for help. The previous problems have been solved. But there has new trouble. I edit the new codes, I couldn't receive the image.
please, Correct my code.

you can encode the image to base64 before publishing it so the topic's content will be a string, example:
import base64
with open("t.png", "rb") as imageFile:
str = base64.b64encode(imageFile.read())
print str

Publisher.py
import paho.mqtt.publish as publish
f= open("myimage.jpg")
content = f.read()
mybyteArray = bytearray(content)
mqttc.publish(topic, mybyteArray , 1)
Receiver.py
def on_message(client, userdata, msg):
f = open('myReceivedImage.jpg','w')
f.write(msg.payload)
f.close()

Related

ChildProcess close with all studio code 1

I was trying to deploy ml model using node_js with help of ChildProcess package ,while running __predict(), it is taking too long and end with code_1 error.
Here I share all related code to decode the issue :
Model python code -->
import keras
import time
start = time.time()
encoder = keras.models.load_model('enc', compile = False)
decoder = keras.models.load_model('dec', compile = False)
import numpy as np
from flask import Flask, request, jsonify , render_template
import tensorflow as tf
import pickle
import string
import re
from keras_preprocessing.sequence import pad_sequences
def initialize_hidden_state():
return tf.zeros((1, 1024))
eng_tokenizer , hin_tokenizer = pickle.load( open('tokenizer.pkl','rb'))
def clean(text):
text = text.lower()
special_char = set(string.punctuation+'।') # Set of all special characters
# Remove all the special characters
text = ''.join(word for word in text if word not in special_char)
seq = eng_tokenizer.texts_to_sequences([text])
seq = pad_sequences(seq, maxlen=23, padding='post')
return seq
def __predict(data):
# Get the data from the POST request.
#data = request.get_json(force=True)
clean_input = clean(data)
# Make prediction using model loaded from disk as per the data.
hidden_enc = initialize_hidden_state()
enc_out, enc_hidden = encoder(clean_input, hidden_enc)
result = ''
dec_hidden = enc_hidden
dec_input = tf.expand_dims(hin_tokenizer.texts_to_sequences(['<Start>'])[0], 0)
#------------------------------------------------------------------
for t in range(25):
predictions, dec_hidden, attention_weights = decoder(dec_input, dec_hidden, enc_out)
predicted_id = tf.argmax(predictions[0]).numpy()
x = hin_tokenizer.sequences_to_texts([[predicted_id]])[0]
if x == 'end':
break
result += x + ' '
# the predicted ID is fed back into the model
dec_input = tf.expand_dims([predicted_id], 0)
CLEANR = re.compile(r"([A-Za-z])", re.DOTALL)
result = re.sub(CLEANR, '', result)
return result
# import json
# with open('data.json', 'r') as openfile:
# json_object = json.load(openfile).get('data')
data =__predict("file")
end= time.time()
# print(start-end)
data1 = data +"abcd"
print(data1)
# print("abcd")
# dictionary = {
# "data": data,
# }
# json_object = json.dumps(dictionary, indent=2)
# with open("result.json", "w") as outfile:
# outfile.write(json_object)
When I type print("abcd") or print(start-end), it is giving result ,ending with code_0. But when I type print("data") not giving any result and ending with code_1 .
Here is the childProcess code -->
app.get('/', (req, res) => {
let dataToSend
let largeDataSet = []
// spawn new child process to call the python script
const python = spawn('python', ['app.py'])
// console.log(python);
// collect data from script
python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...')
//dataToSend = data;
largeDataSet.push(data)
})
// in close event we are sure that stream is from child process is closed
python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`)
// send data to browser
// largeDataSet = []
console.log(largeDataSet.join(''));
res.send(largeDataSet.join(''))
})
})
Here is the error --->
child process close all stdio with code 1
Pls help , I tried to understand the problem but failed severely even in understanding it.
Thanks in advance !!!

pyUSB - delayed sending to the device?

I have an ESC printer.
I made a simple script to send data to the device, but after changing the content of the script - 1x the previous version of the subtitles is printed, and then, when called again, the current one.
As if the data from the USB was cached somewhere.
How can I make some FLUSH?
test.py
usb_= Connector(showUsbDevices=False)
usb_.send(b'I LOVE YOU')
connector:
class Connector:
def __init__(self, idVendor=0x0123, idProduct=0x1234, showUsbDevices=False):
self.idVendor = idVendor
self.idProduct = idProduct
if showUsbDevices:
pass
self.device = self.FindAndConnect()
if self.device is not None:
#if self.device.is_kernel_driver_active(0):
#self.device.detach_kernel_driver(0)
#self.device.detach_kernel_driver(1)
self.device.reset()
self.device.set_configuration()
self.cfg = self.device.get_active_configuration()
data_itfs = list(usb.util.find_descriptor(self.cfg, find_all=True,custom_match=lambda e: (e.bInterfaceClass == 0xA)))
intf = data_itfs[0]
self.device.set_interface_altsetting(intf)
itf_num = intf.bInterfaceNumber
print ("inf descriptor:===============", intf)
print("numer:===============",itf_num)
self.messageOut = usb.util.find_descriptor(intf, custom_match=lambda e: not (e.bEndpointAddress & 0x80))
self.messageIn = usb.util.find_descriptor(intf, custom_match=lambda e: (e.bEndpointAddress & 0x80))
#print(">>>>>>>>>>>>>>>>>>>Message Out",self.messageOut)
#print(">>>>>>>>>>>>>>>>>>>Message In",self.messageIn)
#print(repr(self.cfg))
def __del__(self):
if self.device is not None:
usb.util.dispose_resources(self.device)
def send(self, data):
#print ("endpoint_out",self.messageOut)
if self.device is not None:
print(data.decode("IBM852"))
self.messageOut.write(data)
#self.device.write(1,data,100)
#dane = self.messageIn.read(300)
#print("IN|->",dane)
def FindAndConnect(self):
device=usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct)
if device is None:
raise ValueError('Not found idVendor 0x%04x i idProduct 0x%04x' % (self.idVendor,self.idProduct))
print('Printer found idVendor 0x%04x i idProduct 0x%04x.... ' %(self.idVendor,self.idProduct))
return device
so when I run a test script that says
I LOVE YOU
I get
ILOVE YOU
when I change the inscription to
I HATE YOU and run the script
another copy is printed I LOVE YOU
and only the next start-up gives: I HATE YOU
What is it? Where's the bug?
I found it! Its:
self.device.reset() at finalizer:
def __del__(self):
if self.device is not None:
self.device.reset() ############### <<<< THIS IS THE KEY>>>> (added to all code)
usb.util.dispose_resources(self.device)

How to decrypt the encrypted string coming from python?

I get a encrypted base64 string from python. The format is AES 256 CBC. But when I try to decrypt using iOS Swift it return decrypted string as nil.
# coding=utf-8
import base64
from random import choice
from string import letters
try:
from Crypto import Random
from Crypto.Cipher import AES
except ImportError:
import crypto
import sys
sys.modules['Crypto'] = crypto
from crypto.Cipher import AES
from crypto import Random
class AESCipher(object):
def __init__(self, key):
self.bs = 32
self.key = key
def encrypt(self, raw):
_raw = raw
raw = self._pad(raw)
print raw, ';'
print _raw, ';'
iv = "".join([choice(letters[:26]) for i in xrange(16)])
print " iv :", iv
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))
def decrypt(self, enc):
enc = base64.b64decode(enc)
iv = enc[:AES.block_size]
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')
def _pad(self, s):
a = (self.bs - len(s) % self.bs)
b = chr(self.bs - len(s) % self.bs)
return s + a * b
#staticmethod
def _unpad(s):
return s[:-ord(s[len(s) - 1:])]
def encrypt(k, t):
o = AESCipher(k)
return o.encrypt(t)
def decrypt(k, t):
o = AESCipher(k)
return o.decrypt(t)
def main():
k = "qwertyuiopasdfghjklzxcvbnmqwerty"
s1 = "Hello World!"
d2 = encrypt(k, s1)
print " Password :", k
print "Encrypted :", d2
print " Plain :", decrypt(k, d2)
if __name__ == '__main__':
main()
iOS
Here I use AES256CBC Lib https://github.com/SwiftyBeaver/AES256CBC
let decrypted = AES256CBC.decryptString("Ymdqc3ZqdmZ1cXdsZG1sZenhgr4Xt0+ceARYRh1n40QkNDV/dyKbQjYLcbiXBBeO", password: "qwertyuiopasdfghjklzxcvbnmqwerty")
print("decrypted: \(String(describing: decrypted))") // here I get nil
when python run I get this Logs
iv : bgjsvjvfuqwldmle
Password : qwertyuiopasdfghjklzxcvbnmqwerty
Encrypted : Ymdqc3ZqdmZ1cXdsZG1sZenhgr4Xt0+ceARYRh1n40QkNDV/dyKbQjYLcbiXBBeO
Plain : Hello World!
I don't know why python and iOS not same in AES. Anyone solve this issue please put answer below. Thanks in advance.
I think you need to decode your base64 string first.
Maybe this will work (just googled it, I'm not a iOS dev, so I'm sorry to eventual errors)
let decodedData = NSData("Ymdqc3ZqdmZ1cXdsZG1sZenhgr4Xt0+ceARYRh1n40QkNDV/dyKbQjYLcbiXBBeO": base64String, options:NSDataBase64DecodingOptions.fromRaw(0)!)
let decodedString = NSString(data: decodedData, encoding: NSUTF8StringEncoding)
let decrypted = AES256CBC.decryptString(decodedString, password: "qwertyuiopasdfghjklzxcvbnmqwerty")
print("decrypted: \(String(describing: decrypted))")
It's also stated in the documentation

scapy dns sniff with additional records

i have python/scapy sniffer for DNS.
I am able to sniff DNS messages and get IP/UDP source and destination IP address and ports as well as DNS but I have problems parsing and getting additional answers and additional records if there is more then one.
from scapy i see DNS data i can get but do not know how to get additional records with ls(DNS),ls(DNSQR) and ls(DNSRR)
I would appreciate some help or solution to work this out.
My python/scapy script is below
#!/usr/bin/env python
from scapy.all import *
from datetime import datetime
import time
import datetime
import sys
############# MODIFY THIS PART IF NECESSARY ###############
interface = 'eth0'
filter_bpf = 'udp and port 53'
# ------ SELECT/FILTER MSGS
def select_DNS(pkt):
pkt_time = pkt.sprintf('%sent.time%')
# ------ SELECT/FILTER DNS MSGS
try:
if DNSQR in pkt and pkt.dport == 53:
# queries
print '[**] Detected DNS Message at: ' + pkt_time
p_id = pkt[DNS].id
cli_ip = pkt[IP].src
cli_port = pkt.sport
srv_ip = pkt[IP].dst
srv_port = pkt.dport
query = pkt[DNSQR].qname
q_class = pkt[DNSQR].qclass
qr_class = pkt[DNSQR].sprintf('%qclass%')
type = pkt[DNSQR].sprintf('%qtype%')
#
elif DNSRR in pkt and pkt.sport == 53:
# responses
pkt_time = pkt.sprintf('%sent.time%')
p_id = pkt[DNS].id
srv_ip = pkt[IP].src
srv_port = pkt.sport
cli_ip = pkt[IP].dst
cli_port = pkt.dport
response = pkt[DNSRR].rdata
r_class = pkt[DNSRR].rclass
rr_class = pkt[DNSRR].sprintf("%rclass%")
type = pkt[DNSRR].sprintf("%type%")
ttl = pkt[DNSRR].ttl
len = pkt[DNSRR].rdlen
#
print response
except:
pass
# ------ START SNIFFER
sniff(iface=interface, filter=filter_bpf, store=0, prn=select_DNS)

Getting {"errors":[{"message":"Bad Authentication data","code":215}]} using python-twitter API v1.0

I am using python-twitter API v1.0. It says that it works with v1.1 of the twitter API.
This is my code :
import json
import urllib2
import urllib
import csv
file1 = open("somez.csv", "wb")
fname="tw1.txt"
file=open(fname,"r")
ins = open( "tw1.txt", "r" )
array = []
for line in ins:
array.append( line )
s = 'https://api.twitter.com/1.1/statuses/show/' + line[:-1] + '.json'
print s
try:
data=urllib2.urlopen(s)
except:
print "Not Found"
continue
print data
json_format=json.load(data)
js=json_format
print line[:-1]
print js[('user')]['id']
print js[('user')]['created_at']
print js['retweet_count']
print js['text']
# js = js.decode('utf-8')
one = line[:-1].encode('utf-8')
thr = js['user']['id']
two = js['user']['created_at'].encode('utf-8')
four = js['retweet_count']
five = js['text'].encode('utf-8')
rw = [one,two,thr,four,five];
spamWriter = csv.writer(file1 , delimiter=',')
spamWriter.writerow(rw)
file1.close()
I am not able to retrieve any data. It is saying "Not Found". When I open one of the URLs, I get this error:
{"errors":[{"message":"Bad Authentication data","code":215}]}
Can anyone suggest what the problem might be?

Resources