variable referenced before assignment: Python - python
I'm trying to get data from raspberry pi 3 to Azure
The script reads data from Raspberry Pi3, which is connect via bluetooth to sensors and takes several values.
Unfortunately i am getting an error, when I run it
"local variable 'temperature' referenced before assignment"
def iothub_client_sample_run():
msgs=[]
for address, name in list(devices.items()):
try:
client = iothub_client_init()
if client.protocol == IoTHubTransportProvider.MQTT & (name == "Flower care"):
msg_txt_formatted = MSG_TXT % (
temperature,
sunlight,
moisture,
fertility)
message = IoTHubMessage(msg_txt_formatted)
# optional: assign ids
message.temperature_id = "%d" % temperature
client.send_event_async(message, send_confirmation_callback, devices.items())
print ( "IoTHubClient.send_event_async accepted message {} for transmission to IoT Hub.".format(devices.items()) )
return msgs
while 1:
msgs=iothub_client_sample_run()
for msg in msgs:
print msg['topic']
print msg['payload']
(result, mid)=mqttc.publish(msg['topic'],msg['payload'])
print ( "Send status: %s" % status )
time.sleep(10)
mqttc.disconnect()
except IoTHubError as iothub_error:
print ( "Unexpected error %s from IoTHub" % iothub_error )
return
except KeyboardInterrupt:
print ( "IoTHubClient sample stopped" )
print_last_message_time(client)
The error message here is pretty clear.
Remember that Python reads and executes code one line at a time so if you have a variable stated after the function that uses it then it is going to throw an error. Juggle your code around to put your variables before they are called and you shouldn't have any problems with this error again.
Related
Python socket server new line issue
so I am making a socket server in python but every time a message is sent it does a new line like this Rank: Admin Rank Password: **Censored** Nickname: SomeoneElse [Admin ] Testusername : hello but what I want it to Receive is [Admin] Testusername: hello but every time the code is asking for the nickname rank and message with %s it does a new line here is the code being used def rank(conn, prefix="Rank: "): conn.send(prefix) return conn.recv(512) def nickname(conn, prefix="Nickname: "): conn.send(prefix) return conn.recv(512) rank = rank(conn) nickname = nickname(conn) message = conn.recv(512) if message: reply = "[%s] %s: %s" % (rank, nickname, message) broadcast(reply, conn) else: remove(conn) def broadcast(message, connection): for cons in bc: if cons != connection: try: cons.sendall(message) except: cons.close() remove(cons) def remove(connection): if connection in bc: bc.remove(connection) that is the code to the message system why is it doing a new line every time %s is used? btw I removed the other code cause its irrelevant to my question I changed nickname to "nickname" so and it showed this [Admin ] nickname: hi
Error on socket.recv (Python)
I got a small python program that communicates with an EV3 robot (lego's robot) via BT. The program sends the EV3 a number 1/2 or 3, the robot makes a predefined movement and send back 'A' to indicate that the movement is done and that it is ready for next command. The system works great but once in a while the python app crushes with this error message: 'An established connection was aborted by the software in your host machine.' this comes from socket.recv that is called inside btListener() thread. The relevant python parts: import bluetooth from gmail import * import re from gtts import gTTS from time import sleep import pygame import serial import thread import os import ftplib from StringIO import StringIO from blynkapi import Blynk def a(): #Send 'a' to 'Status' mailbox print "Send a to robot" for i in commandA: client_sock.send(chr(i)) sleep(1) def b(): # Send 'b' to 'Status' mailbox def c(): # Send 'c' to 'Status' mailbox def clear(): # Send clear array to 'Status' mailbox for i in clearArray: client_sock.send(chr(i)) def btListener(): # Listen for end of run reply from the EV3 global ev3Flag, listenFlag while True: if listenFlag and (not ev3Flag): try: data = client_sock.recv(1024) #Check if EV3 is ready for new command if data[-2] == 'A': ev3Flag = True print "Received 'Ready' from EV3 " sleep(1) except Exception as e: print(e) print "Failed to read data from socket" def queueHandler(): # Read next command from QueueArray, call sendFunc and clear the queue global ev3Flag, listenFlag, queueArray while True: if len(queueArray) > 0 and ev3Flag: sendFunc(queueArray[0]) queueArray.pop(0) def sendFunc(cmd): #Send the next command on QueueArray to the EV3 global ev3Flag, listenFlag if cmd == 1: try: ev3Flag = False listenFlag = False a() listenFlag = True sleep(3) clear() # clear the EV3 btsocket with a default message except Exception as e: print "Error on sendFunc cmd = 1" print(e) elif cmd == 2: try: except Exception as e: elif cmd == 3: try: except Exception as e: if __name__ == "__main__": # Blynk setup blynk = Blynk(auth_token) switch1 = Blynk(auth_token, pin = "V0") switch2 = Blynk(auth_token, pin = "V1") switch3 = Blynk(auth_token, pin = "V2") print "Blynk connected" queueArray = [] # Queue array to hold incoming commands listenFlag = True # Listen to message from EV3 ev3Flag = True # EV3 ready for new command flag # BT CONNECTION WITH EV3 # print "Searching for BT connections: " nearby_devices = bluetooth.discover_devices() for bdaddr in nearby_devices: print bdaddr + " - " + bluetooth.lookup_name(bdaddr) if target_name == bluetooth.lookup_name(bdaddr): target_address = bdaddr break 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 if target_address is not None: print "found target bluetooth device with address ", target_address else: print "could not find target bluetooth device nearby" # END BT CONNECTION WITH EV3 # try: thread.start_new_thread(queueHandler, ()) except Exception as e: print(e) try: thread.start_new_thread(btListener, ()) except Exception as e: print(e) while True: res1 = switch1.get_val() res2 = switch2.get_val() res3 = switch3.get_val() if (int)(res1[0]) == 1: print "Add 1 to queue" queueArray.append(1) if (int)(res2[0]) == 1: print "Add 2 to queue" queueArray.append(2) if (int)(res3[0]) == 1: print "Add 3 to queue" queueArray.append(3) Edit 1: I tested it a bit more and it seems that the crush happens when the program tries to recv data and send data the same time. (via the clear() or a()/b()/c() functions), could that be the situation? I'm new to sockets so the first solution that comes in mind is create a flag to limit the action of the socket, is there a better/smarter way to keep that from happening? Edit 2: I moved the 'listenFlag = True' line inside sendFunc() to after my call to clear() and it seems to solve the problem which was probably due to the python program trying to receive and sand at the same time.
I moved the 'listenFlag = True' line inside sendFunc() to after my call to clear() and it seems to solve the problem which was probably due to the python program trying to receive and sand at the same time.
TypeError: 'int' object has no attribute '__getitem__' - Error recieved in IRC weather bot in Python
Okay, so I've got a bit of Python IRC Bot code, and I recently added a weather command to it, but it doesn't seem to work... heres the code # Import some necessary libraries. import socket import time import httplib def commands(nick,channel,message): if message.find('!test')!=-1: ircsock.send('PRIVMSG %s :%s: test complete\r\n' % (channel,nick)) elif message.find('!help')!=-1: ircsock.send('PRIVMSG %s :%s: My other command is test.\r\n' % (channel,nick)) elif message.find('!sex')!=-1: ircsock.send('PRIVMSG %s :%s: But why?\r\n' % (channel,nick)) elif message.find('!quit')!=-1: ircsock.send('QUIT :For the bones of the weak shall support me\r\n') die('Quit command given') elif message.find('!op')!=-1: ircsock.send('MODE %s +o :%s\n' % (channel,nick)) elif message.find('!deop')!=-1: ircsock.send('MODE %s -o :%s\n' % (channel,nick)) elif message.find('!weather')!=-1: tmp = message.find(':!weather') city = tmp[1].strip() reqest_str = '/laika_zinas/?city=' + city c = httplib.HTTPConnection("www.1188.lv") c.request("GET", reqest_str) ra = c.getresponse() datas = ra.read() temp, wind = tpars(datas) ircsock.send('PRIVMSG %s :%s: [+] Temp: '+ temp +' C | Wind: '+ wind +' m/s' % (channel,nick)) c.close() # Some basic variables used to configure the bot server = "n0cht.bawx.net" # Server channel = "#python" # Channel botnick = "PyleDrivr" # Your bots nick def ping(ircmsg): # This is our first function! It will respond to server Pings. ircsock.send("PONG "+ ircmsg +"\n") print("Ping replied\n\r") def sendmsg(chan , msg): # This is the send message function, it simply sends messages to the channel. ircsock.send("PRIVMSG "+ chan +" :"+ msg +"\n") def joinchan(chan): # This function is used to join channels. ircsock.send("JOIN "+ chan +"\n") ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircsock.connect((server, 6667)) # Here we connect to the server using the port 6667 ircsock.send("USER "+ botnick +" "+ botnick +" "+ botnick +" :PyleDrivr\n") # user authentication ircsock.send("NICK "+ botnick +"\n") # here we actually assign the nick to the bot joinchan(channel) # Join the channel using the functions we previously defined while 1: # Be careful with these! it might send you to an infinite loop ircmsg = ircsock.recv(2048) # receive data from the server ircmsg = ircmsg.strip('\n\r') # removing any unnecessary linebreaks. print(ircmsg) # Here we print what's coming from the server if ircmsg.find(' PRIVMSG ')!=-1: nick=ircmsg.split('!')[0][1:] channel=ircmsg.split(' PRIVMSG ')[-1].split(' :')[0] commands(nick,channel,ircmsg) if ircmsg.find("PING :") != -1: # if the server pings us then we've got to respond! ping(ircmsg) Now, when I run the bot, it works just fine, but then this happens when I issue the command: <wh0r3[mint]> !weather 99654 * PyleDrivr has quit (Client exited) And here's what the term shows: :wh0r3[mint]!~wh0r3#n0cht-D1D272D.gci.net PRIVMSG #lobby :!weather 99654 Traceback (most recent call last): File "pyledrivr.py", line 65, in <module> commands(nick,channel,ircmsg) File "pyledrivr.py", line 22, in commands city = tmp[1].strip() TypeError: 'int' object has no attribute '__getitem__' I have no idea what this means or how to fix it. and ideas?
This line: tmp = message.find(':!weather') assigns an integer to tmp: the position at which the string ':!weather' was found in message (see find). It may not even be found at all, since you check in the line above that '!weather' is in message, not ':!weather'. Then you try and access tmp[1]. But tmp is just a number; it doesn't have a [1]. If you want to get the substring of message that follows '!weather', you could do this: city = message[message.find('!weather')+8:].strip() (8 being the length of '!weather') Or you might find it easier to use split: city = message.split('!weather')[1].strip()
How do I recover from a serialException using pySerial
I have an application that reads and transmits data to a device connected via USB. I'm using pySerial to facilitate this communication. Everything works fine until the USB cable is unplugged from the PC and an exception is thrown. Once the cable is plugged back in, I can't seem to recover and reconnect to my device. The only way for me to recover is to close down the application and unplug and plug the cable in again. Any help in understanding what's going on would be much appreciated. This is basic test code that I'm useing to help me understand the process. # Class used to communicate with USB Dongle import serial import time import sys class LPort: def __init__(self, port=0): "initialize the LPort class" self.error = "" self.traffic = "" self.dest = None if port == None: self.simulation = True else: self.simulation = False self.port = port # serial port we should use self.reset() self.time = time.time() def reInit(self): self.close() def reset(self): "flush port, reset the LPort, initialize LPort" if self.simulation: r = "LPort simulator" else: self.port.flushInput() self.port.flushOutput() self.fail = False self.command("/H1") self.dest = None r = "reset" self.error = "" self.traffic = "" return r def status(self): "return accumulated status info, reset collection" s = self.error self.error = "" return s def data(self): "return accumulated traffic data, reset collection" s = self.traffic self.traffic = "" return s def set_dest(self, addr): "set the destination address (if necessary)" if addr != self.dest: self.dest = addr self.command("/O") r = self.command("/D%02X" % addr) if r != "*": self.dest = None self.error += r else: r = True return r def checksum(self, bytes): "calculate the CRC-8 checksum for the given packet" crc_table = [ # this table is taken from the CP rectifier code 0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,0x38,0x3F, 0x36,0x31,0x24,0x23,0x2A,0x2D,0x70,0x77,0x7E,0x79, 0x6C,0x6B,0x62,0x65,0x48,0x4F,0x46,0x41,0x54,0x53, 0x5A,0x5D,0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5, 0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,0x90,0x97, 0x9E,0x99,0x8C,0x8B,0x82,0x85,0xA8,0xAF,0xA6,0xA1, 0xB4,0xB3,0xBA,0xBD,0xC7,0xC0,0xC9,0xCE,0xDB,0xDC, 0xD5,0xD2,0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA, 0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2,0x8F,0x88, 0x81,0x86,0x93,0x94,0x9D,0x9A,0x27,0x20,0x29,0x2E, 0x3B,0x3C,0x35,0x32,0x1F,0x18,0x11,0x16,0x03,0x04, 0x0D,0x0A,0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42, 0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A,0x89,0x8E, 0x87,0x80,0x95,0x92,0x9B,0x9C,0xB1,0xB6,0xBF,0xB8, 0xAD,0xAA,0xA3,0xA4,0xF9,0xFE,0xF7,0xF0,0xE5,0xE2, 0xEB,0xEC,0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4, 0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,0x51,0x56, 0x5F,0x58,0x4D,0x4A,0x43,0x44,0x19,0x1E,0x17,0x10, 0x05,0x02,0x0B,0x0C,0x21,0x26,0x2F,0x28,0x3D,0x3A, 0x33,0x34,0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B, 0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63,0x3E,0x39, 0x30,0x37,0x22,0x25,0x2C,0x2B,0x06,0x01,0x08,0x0F, 0x1A,0x1D,0x14,0x13,0xAE,0xA9,0xA0,0xA7,0xB2,0xB5, 0xBC,0xBB,0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83, 0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,0xE6,0xE1, 0xE8,0xEF,0xFA,0xFD,0xF4,0xF3] for i in range(len(bytes)): b = int(bytes[i]) if i == 0: chksum = crc_table[b] else: chksum = crc_table[chksum ^ b] return chksum def command(self, cmd): "transmit distinct commands to unit, and accept response" if self.simulation: r = "*" else: try: self.port.write(cmd + chr(13)) except serial.serialutil.SerialTimeoutException: r = "/TO" return r except: print "Unexpected error:", sys.exc_info()[0] r = "/Unknown" return r r = "" eol = False while True: c = self.port.read(1) if not c: r = "/FAIL " + r + " " + cmd self.error = r break else: r += c ordc = ord(c) if ordc == 13 or ordc == 42: break return r def checkRawDataForErrors(self, raw, errors = []): errorCodes = {'/SNA':'Slave Not Acknowledging', '/I81':'Busy, Command Ignored', '/I88':'Connection Not Open', '/I89':'Invalid Command Argument', '/I8A':'Transmit Not Active', '/I8F':'Invalid Command', '/I90':'Buffer Overflow', '/DAT':'Data Error', '/BADPEC':'Bad PEC Value', '/NO_MRC':'No Master Read Complete Signal', '/FAIL':'General Failure', '/LEN':'Data Length Error'} for ekey, eval in errorCodes.items(): if ekey in raw: errors.append(eval) return errors # self-testing module if __name__ == "__main__": com = serial.Serial(port=4, baudrate=115200, timeout=1, xonxoff=0) if com: port = LPort(com) print port time.sleep(5) port = LPort(com) print "/V =", port.command("/V") print "/V", port.data(), port.status() print "/O =", port.command("/O") print "/O", port.data(), port.status() print "/A =", port.command("/A") print "/A", port.data(), port.status() print "/L =", port.command("/L") print "/L", port.data(), port.status() com.close() else: print "cannot open com port" UPDATE: The following is the code around the creatfile() in serialwin32.py which returns the following message: serial.serialutil.SerialException: could not open port COM5: [Error 2] The system cannot find the file specified. self.hComPort = win32.CreateFile(port, win32.GENERIC_READ | win32.GENERIC_WRITE, 0, # exclusive access None, # no security win32.OPEN_EXISTING, win32.FILE_ATTRIBUTE_NORMAL | win32.FILE_FLAG_OVERLAPPED, 0) if self.hComPort == win32.INVALID_HANDLE_VALUE: self.hComPort = None # 'cause __del__ is called anyway raise SerialException("could not open port %s: %s" % (self.portstr, ctypes.WinError()))
Assuming your device is well-behaved, all you must do is this: close your serial port (serial.Serial instance) find the COMX name of your port again open the serial port The 2nd part is problematic because Windows tries to be clever. In your case the following happens: USB device is connected and is assigned name COM2 Your program opens the device USB disconnects USB reconnects quickly before your program noticed that device died Windows sees that COM2 is busy and assigns a different name to this USB device (optional) your program closes the device your program tries to open COM2 again, but there's no hardware at that name The are way to get around Windows being clever -- you can specifically assign fixed COMX name to this device in Device Manager, COM ports, your port, advanced options. Another option is to detect device dying very fast and closing the file handle. If you are lucky then by the time device reconnects original COM2 is free again. Yet another option is to use a USB-serial converter from another manufacturer that uses another driver. Somehow COMX letter assignment is driver-specific. Better drivers may give you a stable name.
I've come across this problem as well. Sometimes my program has locked up when the device is plugged in again. NB. I have fixed the COMx name of the port as mentioned by #qarma I've rearranged my program so that as soon as an exception is thrown from the read() or write() methods of Serial I stop calling those methods. I then have a function which periodically retries opening the port to try to detect when the device has been plugged in again. This function creates a new instance of Serial with the same parameters as the original and tries to open it: def try_to_open_new_port(self): ret = False test = serial.Serial(baudrate=9600, timeout=0, writeTimeout=0) test.port = self.current_port_name try: test.open() if test.isOpen(): test.close() ret = True except serial.serialutil.SerialException: pass return ret A return of True indicates that the port is present once again.
How to do scheduled sending of email with django-mailer
I'm making a django app that needs to be able to make emails and then send these out at a given time. I was thinking i could use django-mailer to put things in que and then send it of. But even though theire sample case list, lists that this is a feature, I cant seem to find out how. What I need is to be able to set a 'when_to_send' field in the message model of django-mailer, and when the cron job fires the send_mail function this needs to filter out the ones that has a 'when_to_send' date that is greater than the current time... def send_all(): """ Send all eligible messages in the queue. """ lock = FileLock("send_mail") logging.debug("acquiring lock...") try: lock.acquire(LOCK_WAIT_TIMEOUT) except AlreadyLocked: logging.debug("lock already in place. quitting.") return except LockTimeout: logging.debug("waiting for the lock timed out. quitting.") return logging.debug("acquired.") start_time = time.time() dont_send = 0 deferred = 0 sent = 0 try: for message in prioritize(): if DontSendEntry.objects.has_address(message.to_address): logging.info("skipping email to %s as on don't send list " % message.to_address) MessageLog.objects.log(message, 2) # ### avoid using literal result code message.delete() dont_send += 1 else: try: logging.info("sending message '%s' to %s" % (message.subject.encode("utf-8"), message.to_address.encode("utf-8"))) core_send_mail(message.subject, message.message_body, message.from_address, [message.to_address]) MessageLog.objects.log(message, 1) # ### avoid using literal result code message.delete() sent += 1 except (socket_error, smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPAuthenticationError), err: message.defer() logging.info("message deferred due to failure: %s" % err) MessageLog.objects.log(message, 3, log_message=str(err)) # ### avoid using literal result code deferred += 1 finally: logging.debug("releasing lock...") lock.release() logging.debug("released.") logging.info("") logging.info("%s sent; %s deferred; %s don't send" % (sent, deferred, dont_send)) logging.info("done in %.2f seconds" % (time.time() - start_time)) Anyone see how to customize this function to don't send email's where the message.when_to_send field is greater than the current time?
You need to implement the cron job for django-mailer: * * * * * (cd $PINAX; /usr/local/bin/python2.5 manage.py send_mail >> $PINAX/cron_mail.log 2>&1) And then in engine.py line 96: # Get rid of "while True:" while not Message.objects.all(): # Get rid of logging.debug("sleeping for %s seconds before checking queue again" % EMPTY_QUEUE_SLEEP) # Get rid of sleep send_all()
You can just add another clause to the conditionals under your message processing loop (you will also need to import datetime at the top of your file): for message in prioritize(): if DontSendEntry.objects.has_address(message.to_address): logging.info("skipping email to %s as on don't send list " % message.to_address) MessageLog.objects.log(message, 2) # ### avoid using literal result code message.delete() dont_send += 1 elif message.when_to_send > datetime.datetime.now(): continue else: try: ... the rest of your code ...