This is a read-only archive of the old Scratch 1.x Forums.
Try searching the current Scratch discussion forums.

#1 2012-04-18 17:50:47

LEGOengineer261
Scratcher
Registered: 2011-11-16
Posts: 100+

Importing time with python?

Is there a way you can import time into a project using python?


http://i1156.photobucket.com/albums/p562/LEGOengineer261/IronmanSERIOUSBOSS.jpg

Offline

 

#2 2012-04-18 18:17:31

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: Importing time with python?

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

Code:

# 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

 

#3 2012-04-19 17:10:27

LEGOengineer261
Scratcher
Registered: 2011-11-16
Posts: 100+

Re: Importing time with python?

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:YEAR

Code:

# 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)


http://i1156.photobucket.com/albums/p562/LEGOengineer261/IronmanSERIOUSBOSS.jpg

Offline

 

#4 2012-04-19 17:23:51

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: Importing time with python?

Ah, sorry. It's

Code:

HOST = '127.0.0.1'

So just replace that line with the above.

Offline

 

#5 2012-04-19 17:28:08

LEGOengineer261
Scratcher
Registered: 2011-11-16
Posts: 100+

Re: Importing time with python?

Magnie wrote:

Ah, sorry. It's

Code:

HOST = '127.0.0.1'

So just replace that line with the above.

That part works now!  smile
Now its just "print length" that doesn't work...
I'm not experienced enough with python to figure it out  tongue


http://i1156.photobucket.com/albums/p562/LEGOengineer261/IronmanSERIOUSBOSS.jpg

Offline

 

#6 2012-04-19 17:40:54

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: Importing time with python?

Are you using Python 3.x or 2.7.x? Cause that program was made in 2.7.x which might be the cause.  hmm

Technically print length isn't needed (you can just delete the line) or you can replace it with:

Code:

print(length)

smile

Offline

 

#7 2012-04-19 17:56:17

LEGOengineer261
Scratcher
Registered: 2011-11-16
Posts: 100+

Re: Importing time with python?

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.  hmm

Technically print length isn't needed (you can just delete the line) or you can replace it with:

Code:

print(length)

smile

OK, it gets past that part now!  smile 
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!  smile


http://i1156.photobucket.com/albums/p562/LEGOengineer261/IronmanSERIOUSBOSS.jpg

Offline

 

#8 2012-04-19 20:29:04

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: Importing time with python?

Did you broadcast '!time 1' without any quotes?

Offline

 

#9 2012-04-19 21:14:28

LEGOengineer261
Scratcher
Registered: 2011-11-16
Posts: 100+

Re: Importing time with python?

Magnie wrote:

Did you broadcast '!time 1' without any quotes?

Yes I did. I ran it in python 2.7, and it worked!  big_smile 
Thanks for the help!! Everything works great now!  smile


http://i1156.photobucket.com/albums/p562/LEGOengineer261/IronmanSERIOUSBOSS.jpg

Offline

 

#10 2012-04-19 21:30:33

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: Importing time with python?

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!  big_smile 
Thanks for the help!! Everything works great now!  smile

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.  smile

Offline

 

Board footer