Skip to content

Commit 0752204

Browse files
committed
Merge remote-tracking branch 'parallax/demo' into demo
2 parents d323538 + f3cc093 commit 0752204

File tree

6 files changed

+110
-54
lines changed

6 files changed

+110
-54
lines changed

BlocklyLogger.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@
66

77
import os
88
import logging
9-
from sys import platform
9+
import platform
10+
1011

1112
__author__ = 'Jim Ewald'
1213

14+
1315
# Platform constants
14-
PLATFORM_LINUX = 'linux2'
15-
PLATFORM_MACOS = 'darwin'
16-
PLATFORM_WINDOWS = 'win32'
16+
PLATFORM_LINUX = 'Linux'
17+
PLATFORM_MACOS = 'MacOS'
18+
PLATFORM_DARWIN = 'MacOS'
19+
PLATFORM_WINDOWS = 'Windows'
1720

1821
# Default log path for each platform
1922
DEFAULT_PATH_MACOS = '/Library/Logs/Parallax'
@@ -23,6 +26,8 @@
2326
# Resulting path for log file
2427
path = None
2528

29+
loglevel = logging.DEBUG
30+
2631

2732
def init(filename = 'BlocklyPropClient.log'):
2833
global path
@@ -42,11 +47,12 @@ def emit(self, record):
4247
disable_filelogging = False
4348

4449
# Set correct log file location
45-
if platform == PLATFORM_MACOS:
50+
system = platform.system()
51+
if (system == PLATFORM_MACOS) or (system == PLATFORM_DARWIN):
4652
logfile_name = __set_macos_logpath(filename)
47-
elif platform == PLATFORM_WINDOWS:
53+
elif system == PLATFORM_WINDOWS:
4854
logfile_name = __set_windows_logpath(filename)
49-
elif platform == PLATFORM_LINUX:
55+
elif system == PLATFORM_LINUX:
5056
logfile_name = __set_linux_logpath(filename)
5157

5258
# Verify that we have a valid location
@@ -58,11 +64,11 @@ def emit(self, record):
5864

5965
# Create a logger
6066
logger = logging.getLogger('blockly')
61-
logger.setLevel(logging.DEBUG)
67+
logger.setLevel(loglevel)
6268

6369
# create a console handler for error-level events
6470
console = logging.StreamHandler()
65-
console.setLevel(logging.ERROR)
71+
console.setLevel(loglevel)
6672

6773
# create a logging format
6874
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
@@ -72,7 +78,7 @@ def emit(self, record):
7278
# Log file is overwritten each time the app runs.
7379
if not disable_filelogging:
7480
handler = logging.FileHandler(logfile_name, mode='w')
75-
handler.setLevel(logging.DEBUG)
81+
handler.setLevel(loglevel)
7682
handler.setFormatter(formatter)
7783
logger.addHandler(handler)
7884

BlocklyPropClient.py

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
"""
22
BlocklyProp Client
33
4+
0.5.3 February 22, 2017
5+
- Correct error in path to propeller-load executable.
6+
- Detect condition where serial port has disappeared
7+
- Correct error where browser request for specific port
8+
speed was disregarded.
9+
410
"""
511
import Tkinter as tk
612
import ttk as ttk
@@ -23,19 +29,29 @@
2329
__author__ = 'Michel & Vale'
2430

2531
PORT = 6009
26-
VERSION = "0.5.2"
32+
33+
# -----------------------------------------------------------------------
34+
# NOTE:
35+
#
36+
# Please verify that the version number in the local about.txt and the
37+
# ./package/win0resources/blocklypropclient-installer.iss
38+
# -----------------------------------------------------------------------
39+
VERSION = "0.5.3"
2740

2841

2942
# Enable logging for functions outside of the class definition
30-
module_logger = logging.getLogger('blockly')
43+
module_logger = None
3144

3245

3346
class BlocklyPropClient(tk.Tk):
3447
def __init__(self, *args, **kwargs):
48+
global module_logger
3549

3650
# Enable application logging
3751
BlocklyLogger.init()
3852
self.logger = logging.getLogger('blockly.main')
53+
module_logger = logging.getLogger('blockly')
54+
3955
self.logger.info('Creating logger.')
4056

4157
BlocklyHardware.init()
@@ -45,11 +61,13 @@ def __init__(self, *args, **kwargs):
4561

4662
# initialize values
4763
self.version = 0.0
64+
self.app_version = "0.0"
4865
self.connected = False
4966

50-
# Path
67+
# Path to where application was launched
5168
self.appdir = os.path.dirname(sys.argv[0])
5269
self.logger.info('Logging is enabled')
70+
self.logger.info('Application launched from %s', self.appdir)
5371

5472
# initialize config variables
5573
self.ip_address = tk.StringVar()
@@ -62,21 +80,28 @@ def __init__(self, *args, **kwargs):
6280

6381
self.title("BlocklyProp")
6482

65-
# Set icon
83+
# Set icon for Windows platform
6684
self.logger.info('Operating system is %s', os.name)
6785
if "nt" == os.name:
6886
self.wm_iconbitmap(bitmap='blocklyprop.ico')
69-
else:
70-
#self.wm_iconbitmap(bitmap = "@myicon.xbm")
71-
pass
7287

88+
# Init the system
7389
self.initialize()
7490
self.initialize_menu()
75-
# Verify the hardware is connected and available
7691

92+
# Set the application version and app_version values
7793
def set_version(self, version):
78-
self.logger.info('Application version is %s', version)
79-
self.version = version
94+
# The application version number was converted to a traditional 'major'.'minor'.'patch_level'
95+
# format. There is code in the BlocklyProp Javascript that expects the version number as a
96+
# float. We handle that issue here.
97+
ver_elements = VERSION.split('.')
98+
if len(ver_elements) >= 2:
99+
n_version = float(ver_elements[0] + '.' + ver_elements[1])
100+
else:
101+
n_version = 0.4
102+
103+
self.version = n_version
104+
self.app_version = version
80105

81106
def initialize(self):
82107
self.logger.info('Initializing the UI')
@@ -188,17 +213,19 @@ def handle_connect(self):
188213
self.logger.info('Connect state is: %s', self.connected)
189214

190215
if self.connected:
216+
self.logger.debug('Terminating server process')
191217
BlocklyServer.stop(self.q)
192218
self.server_process.terminate()
193219
self.connected = False
220+
221+
# Set the connect/disconnect button text to the alternate state
194222
self.btn_connect['text'] = "Connect"
195223
else:
196224
# read entered values and start server
197225
self.server_process = multiprocessing.Process(
198226
target=BlocklyServer.main,
199227
args=(int(self.port.get()), self.version, self.q))
200228

201-
# self.server_process = threading.Thread(target=BlocklyServer.main, args=(int(self.port.get()), self.version)) #, kwargs={'out':self.stdoutToQueue})
202229
self.server_process.start()
203230

204231
self.connected = True
@@ -222,23 +249,27 @@ def handle_code_browser(self):
222249
def handle_client_code_browser(self):
223250
webbrowser.open_new('http://github.com/parallaxinc/BlocklyPropClient')
224251

252+
# Open the application About dialog box
225253
def about_info(self):
226254
try:
227255
with open(self.appdir + '/about.txt', 'r') as about_file:
228256
tkMessageBox.showinfo("About BlocklyProp", about_file.read())
229-
except:
257+
except OSError:
230258
tkMessageBox.showinfo("About BlocklyProp", "About file is missing")
231259

260+
# Open the application Quit dialog box and process user selection
232261
def handle_close(self):
233262
self.logger.info('Opening Quit dialog')
234263

235264
if tkMessageBox.askokcancel("Quit?", "Are you sure you want to quit?"):
236-
self.logger.info('Quitting')
237265
# stop server if running
238266
if self.connected:
239-
# BlocklyServer.stop()
267+
self.logger.info('Terminating server process')
240268
self.server_process.terminate()
269+
241270
self.quit()
271+
else:
272+
self.logger.debug('Cancelling application quit request')
242273

243274
def text_catcher(self):
244275
try:
@@ -252,8 +283,8 @@ def text_catcher(self):
252283
self.ent_log.yview_pickplace("end")
253284
self.ent_log['state'] = 'disabled'
254285
except EOFError:
255-
print('EOF Error')
256-
# self.logger.error('Unexpected end of file encountered')
286+
# print('EOF Error')
287+
self.logger.error('Unexpected end of file encountered')
257288

258289

259290
if __name__ == '__main__':

BlocklyServer.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
__author__ = 'Michel'
1414

1515
PORT = 6009
16+
1617
# Enable logging for functions outside of the class definition
1718
module_logger = logging.getLogger('blockly.server')
1819

@@ -32,6 +33,7 @@ def __init__(self, version, queue):
3233
@cherrypy.tools.allow(methods=['GET'])
3334
def index(self):
3435
cherrypy.response.headers['Access-Control-Allow-Origin'] = '*'
36+
3537
serverinfo = {
3638
"server": "BlocklyPropHTTP",
3739
"version": self.version
@@ -50,13 +52,19 @@ def ports(self):
5052
self.logger.debug('Port list retreived')
5153

5254
ports = self.propellerLoad.get_ports()
53-
filtered_ports = []
54-
for port in ports:
55-
self.logger.debug('Port %s discovered.', port)
56-
if ' bt ' not in port.lower() and 'bluetooth' not in port.lower():
57-
self.logger.debug('Port %2 appended to list.', port)
58-
filtered_ports.append(port)
59-
return filtered_ports
55+
if len(ports) > 0:
56+
filtered_ports = []
57+
for port in ports:
58+
self.logger.debug('Port %s discovered.', port)
59+
if ' bt ' not in port.lower() and 'bluetooth' not in port.lower():
60+
self.logger.debug('Port %2 appended to list.', port)
61+
filtered_ports.append(port)
62+
return filtered_ports
63+
else:
64+
# No useable ports detected. Need to determine how the browser
65+
# handles an empty list of available ports.
66+
self.logger.debug('No ports detected. Replying with /dev/null')
67+
return '/dev/null'
6068

6169

6270
@cherrypy.expose(alias='load.action')

PropellerLoad.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ def __init__(self):
1818
self.logger.info('Creating loader logger.')
1919

2020
self.propeller_load_executables = {
21-
"Windows": "/propeller-tools/windows/propeller-load.exe",
22-
"Linux": "/propeller-tools/linux/propeller-load",
23-
"MacOS": "/propeller-tools/mac/propeller-load",
24-
"Darwin": "/propeller-tools/mac/propeller-load"
21+
"Windows": "/propeller-tools/windows/propeller-load.exe",
22+
"Linux": "/propeller-tools/linux/propeller-load",
23+
"MacOS": "/propeller-tools/mac/propeller-load",
24+
"Darwin": "/propeller-tools/mac/propeller-load"
2525
}
2626

2727
self.load_actions = {
@@ -30,12 +30,12 @@ def __init__(self):
3030
}
3131

3232
if not platform.system() in self.propeller_load_executables:
33-
#showerror("Unsupported", platform.system() + " is currently unsupported")
33+
self.logger.error('The %s platform is not supported at this time.', platform.system())
3434
print("Unsupported", platform.system() + " is currently unsupported")
3535
exit(1)
3636

3737
self.appdir = os.getcwd()
38-
self.appdir = os.path.dirname(sys.argv[0])
38+
# self.appdir = os.path.dirname(sys.argv[0])
3939

4040
def get_ports(self):
4141
self.logger.info('Getting ports')
@@ -50,20 +50,14 @@ def get_ports(self):
5050

5151
process = subprocess.Popen([self.appdir + self.propeller_load_executables[platform.system()], "-P"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo)
5252
out, err = process.communicate()
53-
53+
self.logger.debug('Loader complete: Error code %s returned.', err)
5454
self.ports = out.splitlines()
5555
return self.ports
5656
else:
5757
self.logger.info("Enumerating host ports")
58-
ports = [port for (port, driver, usb) in list_ports.comports()]
59-
#self.appdir +
60-
#process = subprocess.Popen([self.appdir + self.propeller_load_executables[platform.system()], "-P"], stdout=subprocess.PIPE)
6158

62-
#out, err = process.communicate()
63-
# return json.dumps(out.splitlines())
64-
#ports = []
65-
#for port in out.splitlines():
66-
# ports.append(port[port.index('/'):])
59+
ports = [port for (port, driver, usb) in list_ports.comports()]
60+
self.logger.debug('Port count: %s', len(ports))
6761

6862
self.ports = ports
6963
return ports
@@ -73,8 +67,11 @@ def load(self, action, file_to_load, com_port):
7367
self.loading = True
7468

7569
executable = self.appdir + self.propeller_load_executables[platform.system()]
70+
self.logger.debug('Loader executable path is: %s)', executable)
71+
7672
executing_data = [executable, "-r"]
7773
executing_data.extend(self.load_actions[action]["compile-options"])
74+
self.logger.debug('Loader commandline is: %s', executing_data)
7875

7976
if com_port is not None:
8077
self.logger.info("Talking to com port.")

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ BlocklyPropClient is written using Python v2.7.
1515

1616
Installations are self-contained; no extra dependencies are required except for USB drivers for Parallax development boards.
1717

18+
## Running on Linux
19+
You will first have to install some python dependencies before you can run BlocklyPropClient.
20+
21+
* ws4py
22+
* pyserial
23+
* cherrypy
24+
25+
These can all be installed using the auto-installer by running the following in the terminal: 'python InstallDependencies.py'
26+
27+
Then execute: python BlocklyPropClient.py
28+
1829

1930
# Developers
2031
------------

0 commit comments

Comments
 (0)