1. Enable Remote Sensor Connections
Open Scratch > Open the Sensors section > Go to the bottom and right-click the "sensor-value" block > Select Enable Remote Sensor Connections
2. Run the Python file provided
Copy the code below into a file and save it as anything with a .py at the end > Run it
3. Get the time by sending a "command" to the Python file then get the sensor-value.
Go back into Scratch > get a broadcast block and set it as "!time 1" (no quotes) > Run the block > Go get the Sensor-value block I talked about earlier and select the drop-down menu (the arrow) and select "time" (no quotes) > Click it once or put it in a variable and it should show the time in this format: HOUR:MINUTE:SECONDS. '!time 2' (no quotes) displays DAY:MONTH:YEAR
# time2scratch.py
# By: Magnie
# Creative Commons
import socket
from time import strftime
from array import array
PORT = 42001
HOST = 127.0.0.1
if HOST == None:
sys.exit()
print("Connecting to Scratch...")
scratchSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
scratchSock.connect((HOST, PORT))
print("Connected!")
def sendScratchCommand(cmd):
n = len(cmd)
a = array('c')
a.append(chr((n >> 24) & 0xFF))
a.append(chr((n >> 16) & 0xFF))
a.append(chr((n >> 8) & 0xFF))
a.append(chr(n & 0xFF))
scratchSock.send(a.tostring() + cmd)
def parse_message(message):
#TODO: parse sensorupdates with quotes in sensor names and values
# make more readable
if not message:
return None
sensors = {}
broadcasts = []
commands = []
i = 0
while True:
length = message[i:i + 4]
length = array("I", length)[0]
print length
command = message[i + 4:i + length + 4]
commands.append(command)
if (i + length + 4) < len(message):
i = (i+4) + length
else:
del command
break
for command in commands:
if command[0] == 'b':
command = command.split('"')
command.pop(0)
command = '"'.join(command[0:])
broadcasts.append(command[:-1])
elif command[0] == 's':
command = command.split('" ')
command[0] = command[0].replace('sensor-update "',
'',
1)
command[0] = command[0]
if command[1][0] == '"':
command[1] = command[1][1:-1]
sensors[command[0]] = '"'.join(command[1:])
return dict([('sensor-update', sensors),
('broadcast', broadcasts)])
while True:
data = scratchSock.recv(1024)
data = parse_message(data)
for broadcast in data['broadcast']:
if broadcast[0] == '!':
broadcast = broadcast.split(' ')
broadcast[0] = broadcast[0][1:]
if broadcast[0] == 'time':
if broadcast[1] == '1':
time = strftime("%H:%M:%S")
elif broadcast[1] == '2':
time = strftime("%d:%m:%y")
else:
time = strftime("%d:%m:%y:%H:%M:%S")
message = 'sensor-update "time" "{0}"'.format(time)
sendScratchCommand(message)Hopefully that will do what you want.
Offline
Magnie wrote:
1. Enable Remote Sensor Connections
Open Scratch > Open the Sensors section > Go to the bottom and right-click the "sensor-value" block > Select Enable Remote Sensor Connections
2. Run the Python file provided
Copy the code below into a file and save it as anything with a .py at the end > Run it
3. Get the time by sending a "command" to the Python file then get the sensor-value.
Go back into Scratch > get a broadcast block and set it as "!time 1" (no quotes) > Run the block > Go get the Sensor-value block I talked about earlier and select the drop-down menu (the arrow) and select "time" (no quotes) > Click it once or put it in a variable and it should show the time in this format: HOUR:MINUTE:SECONDS. '!time 2' (no quotes) displays DAY:MONTH:YEARCode:
# time2scratch.py # By: Magnie # Creative Commons import socket from time import strftime from array import array PORT = 42001 HOST = 127.0.0.1 if HOST == None: sys.exit() print("Connecting to Scratch...") scratchSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) scratchSock.connect((HOST, PORT)) print("Connected!") def sendScratchCommand(cmd): n = len(cmd) a = array('c') a.append(chr((n >> 24) & 0xFF)) a.append(chr((n >> 16) & 0xFF)) a.append(chr((n >> 8) & 0xFF)) a.append(chr(n & 0xFF)) scratchSock.send(a.tostring() + cmd) def parse_message(message): #TODO: parse sensorupdates with quotes in sensor names and values # make more readable if not message: return None sensors = {} broadcasts = [] commands = [] i = 0 while True: length = message[i:i + 4] length = array("I", length)[0] print length command = message[i + 4:i + length + 4] commands.append(command) if (i + length + 4) < len(message): i = (i+4) + length else: del command break for command in commands: if command[0] == 'b': command = command.split('"') command.pop(0) command = '"'.join(command[0:]) broadcasts.append(command[:-1]) elif command[0] == 's': command = command.split('" ') command[0] = command[0].replace('sensor-update "', '', 1) command[0] = command[0] if command[1][0] == '"': command[1] = command[1][1:-1] sensors[command[0]] = '"'.join(command[1:]) return dict([('sensor-update', sensors), ('broadcast', broadcasts)]) while True: data = scratchSock.recv(1024) data = parse_message(data) for broadcast in data['broadcast']: if broadcast[0] == '!': broadcast = broadcast.split(' ') broadcast[0] = broadcast[0][1:] if broadcast[0] == 'time': if broadcast[1] == '1': time = strftime("%H:%M:%S") elif broadcast[1] == '2': time = strftime("%d:%m:%y") else: time = strftime("%d:%m:%y:%H:%M:%S") message = 'sensor-update "time" "{0}"'.format(time) sendScratchCommand(message)Hopefully that will do what you want.
Thank you SO much for the help! But when I went to run the program in the project, it said there was an error in the second zero of "HOST = 127.0.0.1" I think it might have to be a string or something, python might think its a number and can't understand why it would have more than one decimal point.
I took it out to see if there were any more errors, and it said there was a problem with "print length" I am not sure what is wrong with it.
Do you know whats wrong? Again, thank you so much!
Last edited by LEGOengineer261 (2012-04-19 17:24:48)
Offline
Ah, sorry. It's
HOST = '127.0.0.1'
So just replace that line with the above.
Offline
Magnie wrote:
Ah, sorry. It's
Code:
HOST = '127.0.0.1'So just replace that line with the above.
That part works now!
Now its just "print length" that doesn't work...
I'm not experienced enough with python to figure it out
Offline
Are you using Python 3.x or 2.7.x? Cause that program was made in 2.7.x which might be the cause.
Technically print length isn't needed (you can just delete the line) or you can replace it with:
print(length)
Offline
Magnie wrote:
Are you using Python 3.x or 2.7.x? Cause that program was made in 2.7.x which might be the cause.
![]()
Technically print length isn't needed (you can just delete the line) or you can replace it with:Code:
print(length)
![]()
OK, it gets past that part now!
Yes, I am using python 3.1, or maybe some other 3 version.
So I ran the program, it has no errors and it says it connected to scratch. However, it appears it didn't put "time" on the sensor block. Should I use 2.7 to run it instead?
Thank you for all of the help!
Offline
Did you broadcast '!time 1' without any quotes?
Offline
Magnie wrote:
Did you broadcast '!time 1' without any quotes?
Yes I did. I ran it in python 2.7, and it worked!
Thanks for the help!! Everything works great now!
Offline
LEGOengineer261 wrote:
Magnie wrote:
Did you broadcast '!time 1' without any quotes?
Yes I did. I ran it in python 2.7, and it worked!
![]()
Thanks for the help!! Everything works great now!![]()
You're welcome!
I plan on making something like this called "External Blocks" which allows you to have time, and other "blocks" that aren't normally available in Scratch. So you give Python an input and it gives an output. Just some suspense.
Offline