'bbctrl = bbctrl:run'
]
},
- install_requires = 'tornado sockjs-tornado pyserial smbus2'.split(),
+ install_requires = 'tornado sockjs-tornado pyserial pyudev smbus2'.split(),
zip_safe = False,
)
input#tab3(type="radio", name="tabs")
label(for="tab3") Manual
+ input#tab4(type="radio", name="tabs")
+ label(for="tab4") Console
+
section#content1.tab-content
.toolbar
button.pure-button(title="Upload a new program file.", @click="open",
axis-control(axes="BC", :colors="['cyan', 'purple']",
:enabled="[enabled('b'), enabled('c')]",
v-if="enabled('b') || enabled('c')")
+
+ section#content4.tab-content
+ .toolbar
+ button.pure-button(title="Clear console.", @click="clear_console")
+ .fa.fa-trash
+
+ table.console
+ tr
+ th Level
+ th Location
+ th Code
+ th Repeat
+ th Message
+
+ tr(v-for="msg in console", :class="msg.level || 'info'")
+ td {{msg.level || 'info'}}
+ td {{msg.where || ''}}
+ td {{msg.code || '0'}}
+ td {{msg.repeat}}
+ td {{msg.msg}}
this.sock.onmessage = function (e) {
var msg = e.data;
- if (typeof msg == 'object')
+ if (typeof msg == 'object') {
for (var key in msg)
this.$set('state.' + key, msg[key]);
+
+ if ('msg' in msg) this.$broadcast('message', msg);
+ }
}.bind(this);
this.sock.onopen = function (e) {
var api = require('./api');
-function is_array(x) {
+function _is_array(x) {
return Object.prototype.toString.call(x) === '[object Array]';
}
+function _msg_equal(a, b) {
+ return a.level == b.level && a.location == b.location && a.code == b.code &&
+ a.msg == b.msg;
+}
+
+
module.exports = {
template: '#control-view-template',
props: ['config', 'state'],
axes: 'xyzabc',
gcode: '',
history: '',
+ console: [],
speed_override: 1,
feed_override: 1
}
events: {
// TODO These should all be implemented via the API
- jog: function (axis, move) {this.send('g91 g0' + axis + move)}
+ jog: function (axis, move) {this.send('g91 g0' + axis + move)},
+
+
+ message: function (msg) {
+ if (this.console.length &&
+ _msg_equal(msg, this.console[this.console.length - 1]))
+ this.console[this.console.length - 1].repeat++;
+
+ else {
+ msg.repeat = 1;
+ this.console.push(msg);
+ }
+ }
},
var data = {};
data[axis + 'pl'] = x;
this.send(JSON.stringify(data));
- }
+ },
+
+
+ clear_console: function () {this.console = [];}
},
def _i2c_command(self, cmd, byte = None, word = None):
- if self.i2c_bus is None: return
+ if self.i2c_bus is None or not hasattr(self.i2c_bus, 'write_byte'):
+ return
log.info('I2C: %d' % cmd)
retry = 5
if self.speed == 4: scale = 1.0
self.v = [x * scale for x in self.axes]
+ self.v[ABS_Y] = -self.v[ABS_Y]
+ self.v[ABS_Z] = -self.v[ABS_Z]
import lcd
import atexit
+import logging
+
+
+log = logging.getLogger('LCD')
class LCD:
def __init__(self, ctrl):
self.ctrl = ctrl
-
- self.lcd = lcd.LCD(ctrl.args.lcd_port, ctrl.args.lcd_addr)
+ self.force = False
atexit.register(self.goodbye)
+ self.connect()
+
+
+ def connect(self):
+ try:
+ self.lcd = None
+ self.lcd = lcd.LCD(self.ctrl.args.lcd_port, self.ctrl.args.lcd_addr)
+ self.lcd.clear()
+ self.lcd.display(1, 'Loading', lcd.JUSTIFY_CENTER)
+ self.force = True
+
+ except IOError as e:
+ log.error('Connect failed, retrying: %s' % e)
+ self.ctrl.ioloop.call_later(1, self.connect)
def update(self, msg, force = False):
- def has(name): return force or name in msg
+ def has(name): return self.force or force or name in msg
if has('x') or has('c'):
v = self.ctrl.avr.vars
if has('f'): self.lcd.text('%8uF' % msg['f'], 0, 2)
if has('s'): self.lcd.text('%8dS' % msg['s'], 0, 3)
+ self.force = False
+
def goodbye(self):
- self.lcd.clear()
- self.lcd.display(1, 'Goodbye', lcd.JUSTIFY_CENTER)
+ if self.lcd is None: return
+
+ try:
+ self.lcd.clear()
+ self.lcd.display(1, 'Goodbye', lcd.JUSTIFY_CENTER)
+
+ except IOError as e:
+ log.error('I2C communication failed: %s' % e)
def reset(self):
- self.clear()
+ time.sleep(0.050)
+ self.write_nibble(3 << 4) # Home
+ time.sleep(0.050)
+ self.write_nibble(3 << 4) # Home
+ time.sleep(0.050)
+ self.write_nibble(3 << 4) # Home
+ self.write_nibble(2 << 4) # 4-bit
+
self.write(LCD_FUNCTION_SET | LCD_2_LINE | LCD_5x8_DOTS |
LCD_4_BIT_MODE)
self.write(LCD_DISPLAY_CONTROL | LCD_DISPLAY_ON)
clear both
> *
- margin 0.5em 0
+ margin 0.25em
+
+
+ .tabs
+ section
+ max-height 260px
+ overflow auto
+ padding 0
+ margin 0
.gcode, .history
clear both
max-width 99%
min-width 99%
height 200px
- padding 2px
+ padding 0.25em
white-space pre
&.placeholder
> svg
margin 1em
+ .console
+ width 100%
+
+ tr
+ > td
+ margin 0 0.125em
+ background-color #fff
+
+ &.error td
+ color red
+
+ &.warning td
+ color orange
+
+ &.debug td
+ color green
+
.tabs
clear both
> #tab1:checked ~ #content1,
> #tab2:checked ~ #content2,
- > #tab3:checked ~ #content3
+ > #tab3:checked ~ #content3,
+ > #tab4:checked ~ #content4
display block
[id^="tab"]:checked + label