Following a tutorial I was able to get and parse the Twitter stream for my own account and send this information through the serial connection to interact with my Arduino project. However I need to get messages sent directly to me and not my public feed. Below is the code to get the public feed then my attempt at trying to get my direct messages.
How can I achieve this?
##Import Libraries
import twitter
import serial
import time
##authenticate yourself with twitter
api = twitter.Api(consumer_key='*************', consumer_secret='**************', access_token_key='************', access_token_secret='*************')
##set to your serial port
ser = serial.Serial('/dev/tty.usbmodem1a21', 19200)
## check serial port
def checkokay():
ser.flushInput()
time.sleep(3)
line=ser.readline()
time.sleep(3)
if line == ' ':
line=ser.readline()
print 'here'
## Welcome message
print 'Starting Wooden Wave!'
def driptwit():
status = []
x = 0
status = api.GetUserTimeline('wooden_wave') ##grab latest statuses
checkIt = [s.text for s in status] ##put status in an array
drip = checkIt[0].split() ##split first tweet into words
## check for match and write to serial if match
if drip[0] == '#high':
print 'Tweet Recieved, raise block high.'
ser.write('1')
elif drip[0] == '#low': ##break if done
ser.write('0')
print 'Tweet Recieved, raise block low.'
elif drip[0] == '#light': ##break if done
ser.write('2')
print 'Tweet Recieved, turn on LED.'
else:
ser.write('0')
print 'Awaiting Tweet'
while 1:
driptwit() ## call driptwit function
time.sleep(15) ## sleep for 15 seconds to avoid rate limiting
Attempt at gaining direct messages:
##Import Libraries
import twitter
import serial
import time
##authenticate yourself with twitter
api = twitter.Api(consumer_key='***********', consumer_secret='***********', access_token_key='***********', access_token_secret='***********')
##set to your serial port
ser = serial.Serial('/dev/tty.usbmodem1a21', 19200)
## check serial port
def checkokay():
ser.flushInput()
time.sleep(3)
line=ser.readline()
time.sleep(3)
if line == ' ':
line=ser.readline()
print 'here'
## Welcome message
print 'Starting Wooden Wave!'
def driptwit():
status = []
x = 0
status = api.GetDirectMessages() ##grab latest statuses
checkIt = [s.text for s in status] ##put status in an array
drip = checkIt[0].split() ##split first tweet into words
## check for match and write to serial if match
if drip[0] == '#high':
print 'Tweet Recieved, raise block high.'
ser.write('1')
elif drip[0] == '#low': ##break if done
ser.write('0')
print 'Tweet Recieved, raise block low.'
elif drip[0] == '#light': ##break if done
ser.write('2')
print 'Tweet Recieved, turn on LED.'
else:
ser.write('0')
print 'Awaiting Tweet'
while 1:
driptwit() ## call driptwit function
time.sleep(15) ## sleep for 15 seconds to avoid rate limiting
//// UPDATE //
def driptwit():
status = []
x = 0
status = api.GetMentions() ##grab latest statuses
print [s.text for s in status]
checkIt = [s.text for s in status] ##put status in an array
drip = checkIt[0].split() ##split first tweet into words
## check for match and write to serial if match
if drip[0] == '#high':
print 'Tweet Recieved, raise block high.'
ser.write('1')
elif drip[0] == '#low': ##break if done
ser.write('0')
print 'Tweet Recieved, raise block low.'
elif drip[0] == '#light': ##break if done
ser.write('2')
print 'Tweet Recieved, turn on LED.'
else:
ser.write('0')
print 'Awaiting Tweet'
while 1:
driptwit() ## call driptwit function
time.sleep(15) ## sleep for 15 seconds to avoid rate limiting
From your comment, it sounds like api.GetDirectMessages() returned an empty list. Print len(status) directly after the API call to verify that. Are you sure there are new direct messages available to read? Have you tried setting a specific date with api.GetDirectMessages() using the since parameter?
Instead of checking for hash tags in the first token only, check the entire string. In other words test if '#high' in drip instead of if drip[0] == '#high'.
Related
I’ve been stuck on a work project. The problem is to accept connections from various clients, store them on the server in some kind of queue or list, and then after some condition is fulfilled, send response to the queued clients in FIFO order.
#!/usr/bin/python3
import socket
import time
all_connections = []
all_address = []
all_msg= []
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((socket.gethostname(), 4424))
server_socket.listen(20)
wait_list, interface_list, device_list = ([] for i in range(3))
print ("getting order from client...") #Wait for next request from client
while True:
clientsocket, address = server_socket.accept()
all_connections.append(clientsocket)
all_address.append(address)
print(f"Connection from {address} has been established.")
message_from_client = all_connections[0].recv(1024)
print(message_from_client)###
decode_msg= message_from_client.decode("utf-8")
all_msg.append(decode_msg)
if "success" in all_msg[0] and len(wait_list) != 0:
print("Received request: %s" % decode_msg)
new_decode_msg=all_msg[0].replace("success", "")
if new_decode_msg not in wait_list:
print("stored in wait list")
wait_list.append(new_decode_msg)
socket.send(b'stored')
else:
print("already stored")
socket.send(b'already stored')
wait_parts= wait_list[0].split(" ")
if wait_parts[0] not in interface_list:
print("Server is ready")
response= wait_list[0] + " connect"
all_connections[0].sendto(response.encode('utf-8'), all_address[0]) #Send reply back to client
interface_list.append(wait_parts[0])
device_list.append(wait_parts[0] + wait_parts[1])
try:
wait_list.pop(0)
all_msg.pop(0)
all_address.pop(0)
all_connections.pop(0)
print(all_msg)
print(all_address)
except:
pass
finally:
time.sleep(2)
else:
print("waiting for disconnection")
all_connections[0].send(b'not disconnected')
time.sleep(2)
elif "failure" in decode_msg:
new_decode_msg=decode_msg.replace("failure", "")
parts=new_decode_msg.split(" ")
if parts[0] in interface_list and (parts[0] + parts[1]) in device_list:
print("Received request: %s" % decode_msg)
print("disconnected successfully")
all_connections[0].send(b'disconnect') #Send reply back to client
interface_list.remove(parts[0])
device_list.remove(parts[0] + parts[1])
time.sleep(2)
else:
all_connections[0].send(b'not disconnected')
time.sleep(2)
else:
wait_list.append(decode_msg.replace("success", ""))
all_connections[0].send(b'not yet connected')
So the client file is also an infinite while loop.
the client file:
while True:
if args.connect:
server_socket.send(bytes(" success ".join([args.interface, args.device]), 'utf-8'))
recived_response=server_socket.recv(1048)
d_rec= recived_response.decode("utf-8")
msg_array=d_rec.split(" ")
if 'connect' in msg_array:
connect(relayboards.get(devices[args.device][args.interface].get("board")) ,int(PORT))
digital_command(args.device, args.interface, "connect")
print("ready to connect...%s" % d_rec)
print("~~CONNECTED~~")
#server_socket.close()
break
else:
continue
#print("oops")
elif args.disconnect:
connect(relayboards.get(devices[args.device][args.interface].get("board")) ,int(PORT))
server_socket.send(bytes(" failure ".join([args.interface, args.device]), 'utf-8'))
if server_socket.recv(30)== b'disconnect':
digital_command(args.device, args.interface, "disconnect")
print("~~DISCONNECTED~~")
#server_socket.close()
break
else:
print("the device was not connected at the first place")
#server_socket.close()
break
Any ideas on this??
Thanks
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.
This script is supposed to continuously read different rfid tags once, print out the tag number and send it to the remote xbee. However, it keeps reading tags in a continuous loop. I want it to read a tag once display the result and send it to the remote xbee, then wait for a different tag and repeat the process.
def main():
ann = as3992_api.AntennaDevice()
print "Firmware info: %s\nHardware info: %s" % ann.get_system_info()
print "Activating antenna"
ann.set_antenna_state(True)
print " Reading Tags:"
while True:
try:
for epc, rssi in ann.iter_epc_rssi():
#time.sleep(1)
print "---------------------------------------"
print "Scanning Tag..."
time.sleep(1)
print "Tag code epc:" +epc.encode("HEX"),rssi
#send tag info to remote xbee
xbee.tx_long_addr(frame='0x1', dest_addr=XBEE1_ADDR_LONG, data=epc.encode("HEX"))
print "---------------------------------------"
time.sleep(1)
print "Sending tag information to XBee 1 ..."
except KeyboardInterrupt:
ann.set_antenna_state(False)
break
if __name__ == "__main__":
main()
def main():
ann = as3992_api.AntennaDevice()
print "Firmware info: %s\nHardware info: %s" % ann.get_system_info()
print "Activating antenna"
ann.set_antenna_state(True)
print " Reading Tags:"
ok=[]
while True:
try:
for epc, rssi in ann.iter_epc_rssi():
if epc+rssi not in ok:
#time.sleep(1)
print "---------------------------------------"
print "Scanning Tag..."
time.sleep(1)
print "Tag code epc:" +epc.encode("HEX"),rssi
#send tag info to remote xbee
xbee.tx_long_addr(frame='0x1', dest_addr=XBEE1_ADDR_LONG, data=epc.encode("HEX"))
print "---------------------------------------"
time.sleep(1)
print "Sending tag information to XBee 1 ..."
ok.append( epc+rssi )
except KeyboardInterrupt:
ann.set_antenna_state(False)
break
I'm trying to get my Arduino to ring a bell every time the #annoyingbellbot receives the #ringit message. I adapted a lot of this code this instructable but I changed some of it to work with the bell. By the way, I took the twitter API info out so I don't think that is the problem and assume all the spacing is correct. So my problem is that when I tweet at the #annoyingbellbot, nothing happens. It just stays in the loop forever. Any help would be greatly appreciated. Thanks!
##Import Libraries
import twitter
import serial
import time
##authenticate yourself with twitter
api = twitter.Api(consumer_key='', consumer_secret='', access_token_key='', access_token_secret='')
##set to your serial port
#ser = serial.Serial(port='COM3')
ser = serial.Serial()
ser.baudrate = 9600
ser.port = 3
## check serial port
def checkokay():
ser.flushInput()
time.sleep(3)
line=ser.readline()
time.sleep(3)
if line == ' ':
line=ser.readline()
print 'here'
## Welcome message
print 'Welcome To Bell Bot!'
def driptwit():
status = []
x = 0
drip = []
status = api.GetUserTimeline('annoyingbellbot') ##grab latest statuses
checkIt = [s.text for s in status] ##put status in an array
if len(status) != 0:
drip = checkIt[0].split() ##split first tweet into words
## check for match and write to serial if match
if drip[0] == '#ringit':
print 'Tweet Recieved, Ringing Bell'
ser.write('1')
else:
ser.write('0')
print 'Awaiting Tweet'
print "Loop"
while 1:
driptwit() ## call driptwit function
time.sleep(15) ## sleep for 15 seconds to avoid rate limiting
I am trying to figure out how to get my client to send and receive data 'simultaneously' and am using threads. My problem is that, depending on the way I set it up, the way here it waits for data from the server in the recieveFromServer function which is in its own thread and cannot stop it when nothing will be sent. The other way it just waits for user input, and will send to the server and then I'd call the function recieveFromServer after the client sends a message to the server which doesn't allow for fluent communication, but cannot get it to alternate automatically. How do I release the thread when the client has nothing to be sent, or there is no more to be received from the server.
It would get to long if I tried to explain everything I have tried. :)
Thanks.
The client:
from socket import *
from threading import *
import thread
import time
from struct import pack,unpack
from networklingo import *
#from exception import *
HOST = '192.168.0.105'
PORT = 21567
BUFFSIZE = 1024
ADDR = (HOST,PORT)
lock = thread.allocate_lock()
class TronClient:
def __init__(self,control=None):
self.tcpSock = socket(AF_INET,SOCK_STREAM)
#self.tcpSock.settimeout(.2)
self.recvBuff = []
def connect(self):
self.tcpSock.connect(ADDR)
self.clientUID = self.tcpSock.recv(BUFFSIZE)
print 'My clientUID is ', self.clientUID
t = Thread(target = self.receiveFromSrv())
t.setDaemon(1)
t.start()
print 'going to main loop'
self.mainLoop()
#t = Thread(target = self.mainLoop())
#t.setName('mainLoop')
#t.setDaemon(1)
#t.start()
def receiveFromSrv(self):
RECIEVING = 1
while RECIEVING:
#print 'Attempting to retrieve more data'
#lock.acquire()
#print 'Lock Aquired in recieveFromSrv'
#try:
data = self.tcpSock.recv(BUFFSIZE)
#except socket.timeout,e:
#print 'Error recieving data, ',e
#continue
#print data
if not data: continue
header = data[:6]
msgType,msgLength,clientID = unpack("hhh",header)
print msgType
print msgLength
print clientID,'\n'
msg = data[6:]
while len(msg) < msgLength:
data = self.tcpSock.recv(BUFFSIZE)
dataLen = len(data)
if dataLen <= msgLength:
msg += data
else:
remLen = msgLength-len(data) #we just need to retrieve first bit of data to complete msg
msg += data[:remLen]
self.recvBuff.append(data[remLen:])
print msg
#else:
#lock.release()
# print 'lock release in receiveFromSrv'
#time.sleep(2)
#RECIEVING = 0
def disconnect(self,data=''):
self.send(DISCONNECT_REQUEST,data)
#self.tcpSock.close()
def send(self,msgType,msg):
header = pack("hhh",msgType,len(msg),self.clientUID)
msg = header+msg
self.tcpSock.send(msg)
def mainLoop(self):
while 1:
try:
#lock.acquire()
#print 'lock aquired in mainLoop'
data = raw_input('> ')
except EOFError: # enter key hit without any data (blank line) so ignore and continue
continue
#if not data or data == '': # no valid data so just continue
# continue
if data=='exit': # client wants to disconnect, so send request to server
self.disconnect()
break
else:
self.send(TRON_CHAT,data)
#lock.release()
#print 'lock released in main loop'
#self.recieveFromSrv()
#data = self.tcpSock.recv(BUFFSIZE)
#t = Thread(target = self.receiveFromSrv())
#t.setDaemon(1)
#t.start()
if __name__ == "__main__":
cli = TronClient()
cli.connect()
#t = Thread(target = cli.connect())
#t.setName('connect')
#t.setDaemon(1)
#t.start()
The server (uses a lock when incrementing or decrementing number of clients):
from socket import *
from threading import *
import thread
from controller import *
from networklingo import *
from struct import pack,unpack
HOST = ''
PORT = 21567
BUFSIZE = 1024
ADDR = (HOST,PORT)
nclntlock = thread.allocate_lock()
class TronServer:
def __init__(self,maxConnect=4,control=None):
self.servSock = socket(AF_INET,SOCK_STREAM)
# ensure that you can restart server quickly when it terminates
self.servSock.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
self.servSock.bind(ADDR)
self.servSock.listen(maxConnect)
# keep track of number of connected clients
self.clientsConnected = 0
# give each client a unique identfier for this run of server
self.clientUID = 0
# list of all clients to cycle through for sending
self.allClients = {}
# keep track of threads
self.cliThreads = {}
#reference back to controller
self.controller = control
self.recvBuff = []
def removeClient(self,clientID,addr):
if clientID in self.allClients.keys():
self.allClients[clientID].close()
print "Disconnected from", addr
nclntlock.acquire()
self.clientsConnected -= 1
nclntlock.release()
del self.allClients[clientID]
else:
print 'ClientID is not valid'
def recieve(self,clientsock,addr):
RECIEVING = 1
# loop serving the new client
while RECIEVING: # while PLAYING???
try:
data = clientsock.recv(BUFSIZE)
except:
RECIEVING = 0
continue
# if not data: break #no data was recieved
if data != '':
print 'Recieved msg from client: ',data
header = data[:6]
msgType,msgLength,clientID = unpack("hhh",header)
print msgType
print msgLength
print clientID,'\n'
if msgType == DISCONNECT_REQUEST: #handle disconnect request
self.removeClient(clientID,addr)
else: #pass message type and message off to controller
msg = data[6:]
while len(msg) < msgLength:
data = self.tcpSock.recv(BUFSIZE)
dataLen = len(data)
if dataLen <= msgLength:
msg += data
else:
remLen = msgLength-len(data) #we just need to retrieve first bit of data to complete msg
msg += data[:remLen]
self.recvBuff.append(data[remLen:])
print msg
# echo back the same data you just recieved
#clientsock.sendall(data)
self.send(TRON_CHAT,msg,-1) #send to client 0
for k in self.allClients.keys():
if self.allClients[k] == clientsock:
self.removeClient(k,addr)
print 'deleted after hard exit from clientID ', k
#self.cliThreads[k].join()
#del self.cliThreads[k]
# then tell controller to delete player with k
break
def send(self,msgType,msg,clientID=-1):
header = pack("hhh",msgType,len(msg),clientID)
msg = header+msg
if clientID in self.allClients:
self.allClients[clientID].send(msg)
elif clientID==ALL_PLAYERS:
for k in self.allClients.keys():
self.allClients[k].send(msg)
def mainLoop(self):
global nclntlock
try:
while self.controller != None and self.controller.state == WAITING:
print 'awaiting connections'
clientsock, caddy = self.servSock.accept()
nclntlock.acquire()
self.clientsConnected += 1
nclntlock.release()
print 'Client ',self.clientUID,' connected from:',caddy
clientsock.setblocking(0)
clientsock.send(str(self.clientUID))
self.allClients[self.clientUID] = clientsock
t = Thread(target = self.recieve, args = [clientsock,caddy])
t.setName('recieve-' + str(self.clientUID))
self.cliThreads[self.clientUID] = t
self.clientUID += 1
# t.setDaemon(1)
t.start()
finally:
self.servSock.close()
if __name__ == "__main__":
serv = TronServer(control = LocalController(nPlayers = 3, fWidth = 70, fHeight = 10))
t = Thread(target = serv.mainLoop())
t.setName('mainLoop')
# t.setDaemon(1)
t.start()
I think you want to try and set the socket to non-blocking mode:
http://docs.python.org/library/socket.html#socket.socket.setblocking
Set blocking or non-blocking mode of
the socket: if flag is 0, the socket
is set to non-blocking, else to
blocking mode. Initially all sockets
are in blocking mode. In non-blocking
mode, if a recv() call doesn’t find
any data, or if a send() call can’t
immediately dispose of the data, a
error exception is raised; in blocking
mode, the calls block until they can
proceed. s.setblocking(0) is
equivalent to s.settimeout(0);
s.setblocking(1) is equivalent to
s.settimeout(None).
Also, instead of using raw sockets, have you considdered using the multiprocessing module. It is a higher-level abstraction for doing network IO. The section on Pipes & Queues is specific to sending and receiving data between a client/server.