forked from mi8882255/3dprinteros-client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
beeverycreative.py
120 lines (110 loc) · 4.57 KB
/
beeverycreative.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import usb.core
import usb.util
import sys
import os
import time
import logging
import paths
import printrun_sender
import base_sender
import config
READ_TIMEOUT = 1000
DEFAULT_READ_LENGTH = 512
class Sender(printrun_sender.Sender):
def __init__(self, profile, usb_info):
base_sender.BaseSender.__init__(self, profile, usb_info)
self.usb_info = usb_info
self.printcore = None # for sake of printrun_senders status and percentage reports
self.logger = logging.getLogger(__name__)
if not sys.platform.startswith('linux'):
raise RuntimeError("BeeVeryCreative don't supported by your OS... for now.")
if usb_info.get('COM'):
printrun_sender.Sender.__init__(self, profile, usb_info)
else:
if self.init_raw_usb_device():
self.flash_firmware()
def find_firmware_file(self):
firmware_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "firmware")
for file_name in os.listdir(firmware_dir):
if file_name.lower().startswith('beetf'):
firmware = os.path.join(firmware_dir, file_name)
return firmware
def get_firmware_version(self, firmware_filename):
version = firmware_filename.lower().replace('beetf-', '')
return version.replace('.bin', '')
def init_raw_usb_device(self):
print "Starting flashing initialization"
# find our device
int_vid = int(self.usb_info['VID'], 16)
int_pid = int(self.usb_info['PID'], 16)
backend_from_our_directory = usb.backend.libusb1.get_backend(find_library=paths.get_libusb_path)
dev = usb.core.find(idVendor=int_vid, idProduct=int_pid, backend=backend_from_our_directory)
# set the active configuration. With no arguments, the first
# configuration will be the active one
dev.set_configuration()
# get an endpoint instance
cfg = dev.get_active_configuration()
intf = cfg[(0,0)]
ep_out = usb.util.find_descriptor(
intf,
# match the first OUT endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_OUT)
ep_in = usb.util.find_descriptor(
intf,
# match the first in endpoint
custom_match = \
lambda e: \
usb.util.endpoint_direction(e.bEndpointAddress) == \
usb.util.ENDPOINT_IN)
# Verify that the end points exist
self.dev = dev
self.ep_in = ep_in
self.ep_out = ep_out
return ep_in and ep_out
#used only in raw usb mode, which we use only to flash firmware in printer
def dispatch(self, message):
time.sleep(0.001)
self.ep_out.write(message)
time.sleep(0.009)
try:
ret = self.ep_in.read(DEFAULT_READ_LENGTH, READ_TIMEOUT)
sret = ''.join([chr(x) for x in ret])
except:
sret = "USB read timeout"
return sret
def flash_firmware(self):
firmware = self.find_firmware_file()
if firmware:
self.logger.info("Prepare to flash device with firmware:{0}.".format(firmware))
file_size = os.path.getsize(firmware)
version = "0.0.0"
ret1 = self.dispatch("M114 A{0}\n".format(version))
message = "M650 A{0}\n".format(file_size)
ret2 = self.dispatch(message)
if 'ok' in ret1 and 'ok' in ret2:
with open(firmware, 'rb') as f:
while True:
buf = f.read(64)
if not buf: break
self.ep_out.write(buf)
ret = []
while (len(ret) != len(buf)):
ret += self.ep_in.read(len(buf), READ_TIMEOUT)
assert (''.join([chr(x) for x in ret]) in buf)
self.logger.debug(".")
self.logger.info("Flashing complete.")
new_version = self.get_firmware_version(os.path.basename(firmware))
self.dispatch("M114 A{0}\n".format(new_version))
self.dispatch("M630\n")
self.dev.reset()
self.logger.info("Rebooting to new firmware...")
else:
config.create_error_report(601, "Error - no firmware found.", self.usb_info, self.logger, is_blocking=True)
def cancel(self):
if self.profile.get('COM'):
self.cancel()
else:
self.dispatch("M609\n")