def device_guided_add_mdns(request, mdns_id): # TODO - Add user permissioning # if not request.user.has_perm('app.add_device'): # messages.error(request, 'Your account is not permissioned to add devices. Please contact an admin') # return redirect("/") # Originally I thought we needed to rescan the network, but so long as ESP8266 is the only device that supports WiFi # We can use mdns_id alone to handle the initial values # installed_devices, available_devices = mdnsLocator.find_mdns_devices() # # mdns_device = None # # for this_device in available_devices: # if this_device['mDNSname'] == mdns_id: # mdns_device = this_device # # if mdns_device is None: # redirect('device_guided_mdns') if request.POST: form = device_forms.DeviceForm(request.POST) if form.is_valid(): new_device = BrewPiDevice( device_name=form.cleaned_data['device_name'], temp_format=form.cleaned_data['temp_format'], data_point_log_interval=form.cleaned_data['data_point_log_interval'], useInetSocket=form.cleaned_data['useInetSocket'], socketPort=form.cleaned_data['socketPort'], socketHost=form.cleaned_data['socketHost'], serial_port=form.cleaned_data['serial_port'], serial_alt_port=form.cleaned_data['serial_alt_port'], board_type=form.cleaned_data['board_type'], socket_name=form.cleaned_data['socket_name'], connection_type=form.cleaned_data['connection_type'], wifi_host=form.cleaned_data['wifi_host'], wifi_port=form.cleaned_data['wifi_port'], ) new_device.save() messages.success(request, u'Device {} Added. Please wait a few seconds for controller to start'.format(new_device)) return redirect("/") else: return render_with_devices(request, template_name='setup/device_guided_add_mdns.html', context={'form': form}) else: random_port = random.randint(2000,3000) # If we were just passed to the form, provide the initial values initial_values = {'board_type': 'esp8266', 'wifi_host': mdns_id, 'wifi_port': 23, 'connection_type': 'wifi', 'socketPort': random_port, 'temp_format': config.TEMPERATURE_FORMAT} form = device_forms.DeviceForm(initial=initial_values) return render_with_devices(request, template_name='setup/device_guided_add_mdns.html', context={'form': form})
def add_device(request): # TODO - Add user permissioning # if not request.user.has_perm('app.add_device'): # messages.error(request, 'Your account is not permissioned to add devices. Please contact an admin') # return redirect("/") if request.POST: form = device_forms.DeviceForm(request.POST) if form.is_valid(): # TODO - Add support for editing to this new_device = BrewPiDevice( device_name=form.cleaned_data['device_name'], temp_format=form.cleaned_data['temp_format'], data_point_log_interval=form. cleaned_data['data_point_log_interval'], useInetSocket=form.cleaned_data['useInetSocket'], socketPort=form.cleaned_data['socketPort'], socketHost=form.cleaned_data['socketHost'], serial_port=form.cleaned_data['serial_port'], serial_alt_port=form.cleaned_data['serial_alt_port'], board_type=form.cleaned_data['board_type'], socket_name=form.cleaned_data['socket_name'], connection_type=form.cleaned_data['connection_type'], wifi_host=form.cleaned_data['wifi_host'], wifi_port=form.cleaned_data['wifi_port'], ) new_device.save() messages.success( request, 'Device {} Added.<br>Please wait a few seconds for controller to start' .format(new_device.device_name)) return redirect("/") else: return render_with_devices(request, template_name='device_add.html', context={'form': form}) else: # We don't want two devices to have the same port, and the port number doesn't really matter. Just # randomize it. random_port = random.randint(2000, 3000) initial_values = { 'socketPort': random_port, 'temp_format': config.TEMPERATURE_FORMAT } form = device_forms.DeviceForm(initial=initial_values) return render_with_devices(request, template_name='device_add.html', context={'form': form})
def device_guided_serial_autodetect(request, device_family): # TODO - Add user permissioning # if not request.user.has_perm('app.add_device'): # messages.error(request, 'Your account is not permissioned to add devices. Please contact an admin') # return redirect("/") # device_guided_serial_autodetect contains all 4 steps in the Serial autodetection guided setup. if not request.POST: # If we haven't had something posted to us, provide the instructions page. (Step 1) return render( request, template_name='setup/device_guided_serial_autodetect_1.html', context={'device_family': device_family}) else: # Something was posted - figure out what step we're on by looking at the "step" field if 'step' not in request.POST: # We received a form, but not the right form. Redirect to the start of the autodetection flow. return render( request, template_name='setup/device_guided_serial_autodetect_1.html', context={'device_family': device_family}) elif request.POST['step'] == "2": # Step 2 - Cache the current devices & present the next set of instructions to the user current_devices = serial_integration.cache_current_devices() return render( request, template_name='setup/device_guided_serial_autodetect_2.html', context={ 'device_family': device_family, 'current_devices': current_devices }) elif request.POST['step'] == "3": # Step 3 - Detect newly-connected devices & prompt the user to select the one that corresponds to the # device they want to configure. _, _, _, new_devices_enriched = serial_integration.compare_current_devices_against_cache( device_family) return render( request, template_name='setup/device_guided_serial_autodetect_3.html', context={ 'device_family': device_family, 'new_devices': new_devices_enriched }) elif request.POST['step'] == "4": # Step 4 - MAGIC. if 'serial_port' in request.POST: form = device_forms.DeviceForm(request.POST) if form.is_valid(): new_device = BrewPiDevice( device_name=form.cleaned_data['device_name'], temp_format=form.cleaned_data['temp_format'], data_point_log_interval=form. cleaned_data['data_point_log_interval'], useInetSocket=form.cleaned_data['useInetSocket'], socketPort=form.cleaned_data['socketPort'], socketHost=form.cleaned_data['socketHost'], serial_port=form.cleaned_data['serial_port'], serial_alt_port=form.cleaned_data['serial_alt_port'], board_type=form.cleaned_data['board_type'], socket_name=form.cleaned_data['socket_name'], connection_type=form.cleaned_data['connection_type'], wifi_host=form.cleaned_data['wifi_host'], wifi_port=form.cleaned_data['wifi_port'], prefer_connecting_via_udev=form. cleaned_data['prefer_connecting_via_udev'], ) new_device.save() # Once the device is added, go ahead and autodetect the udev serial number. if new_device.connection_type == BrewPiDevice.CONNECTION_SERIAL: new_device.set_udev_from_port() messages.success( request, u'Device {} Added. Please wait a few seconds for controller to start' .format(new_device)) return redirect("/") else: return render( request, template_name= 'setup/device_guided_serial_autodetect_4_add.html', context={ 'form': form, 'device_family': device_family }) else: random_port = random.randint(2000, 3000) # If we were just passed to the form, provide the initial values # TODO - Correctly determine 'board_type' if device_family == 'ESP8266': board_type = 'esp8266' elif device_family == 'Arduino': board_type = 'uno' else: # Invalid board type - shouldn't ever get here. messages.error( request, "Invalid board type for serial autodetection") return redirect("/") initial_values = { 'board_type': board_type, 'serial_port': request.POST['device'], 'connection_type': 'serial', 'socketPort': random_port, 'temp_format': config.TEMPERATURE_FORMAT, 'modify_not_create': False } form = device_forms.DeviceForm(initial=initial_values) return render( request, template_name= 'setup/device_guided_serial_autodetect_4_add.html', context={ 'form': form, 'device_family': device_family }) elif request.POST['step'] == "5": pass else: # The step number we received was invalid. Redirect to the start of the autodetection flow. return render( request, template_name='setup/device_guided_serial_autodetect_1.html', context={'device_family': device_family})
def setupSerial(dbConfig: models.BrewPiDevice, baud_rate: int = 57600, time_out=0.1): ser = None # dumpSerial = config.get('dumpSerial', False) dumpSerial = False error = None # open serial port tries = 0 connection_type = dbConfig.connection_type if connection_type == "serial" or connection_type == "auto": if connection_type == "auto": logMessage( "Connection type set to 'auto' - Attempting serial first") else: logMessage("Connection type Serial selected. Opening serial port.") while tries < 10: error = "" ports_to_try = [] # If we have a udevPort (from a dbconfig object, found via the udev serial number) use that as the first # option - replacing config['port']. udevPort = dbConfig.get_port_from_udev() if udevPort is not None: ports_to_try.append(udevPort) else: ports_to_try.append(dbConfig.serial_port) # Regardless of if we have 'udevPort', add altport as well if dbConfig.serial_alt_port: ports_to_try.append(dbConfig.serial_alt_port) for portSetting in ports_to_try: if portSetting == None or portSetting == 'None' or portSetting == "none": continue # skip None setting if portSetting == "auto": port = findSerialPort(bootLoader=False) if not port: error = "Could not find compatible serial devices \n" continue # continue with altport else: port = portSetting try: ser = serial.Serial(port, baudrate=baud_rate, timeout=time_out, write_timeout=0) if ser: logMessage( "Connected via serial to port {}".format(port)) break except (IOError, OSError, serial.SerialException) as e: # error += '0}.\n({1})'.format(portSetting, str(e)) error += str(e) + '\n' if ser: break tries += 1 time.sleep(1) if connection_type == "wifi" or connection_type == "auto": if not (ser): tries = 0 if connection_type == "auto": logMessage( "No serial attached BrewPi found. Trying TCP serial (WiFi)" ) else: logMessage( "Connection type WiFi selected. Trying TCP serial (WiFi)") while tries < 10: error = "" if dbConfig.wifi_port is None: logMessage( "Invalid WiFi configuration - Port '{}' cannot be converted to integer" .format(config['wifiPort'])) logMessage("Exiting.") exit(1) port = dbConfig.wifi_port if dbConfig.wifi_host_ip is None or len( dbConfig.wifi_host_ip) < 7: if dbConfig.wifi_host is None or len( dbConfig.wifi_host) <= 4: logMessage( "Invalid WiFi configuration - No wifi_host or wifi_host_ip set" ) logMessage("Exiting.") exit(1) connect_to = dbConfig.wifi_host else: # the wifi_host_ip is set - use that as the host to connect to connect_to = dbConfig.wifi_host_ip if dbConfig.wifi_host is None or len(dbConfig.wifi_host) <= 4: # If we don't have a hostname at all, set it to None hostname = None else: hostname = dbConfig.wifi_host ser = tcpSerial.TCPSerial(host=connect_to, port=port, hostname=hostname) if ser: break tries += 1 time.sleep(1) if not (ser ): # At this point, we've tried both serial & WiFi. Need to die. logMessage("Unable to connect via Serial or WiFi. Exiting.") exit(1) if ser: # discard everything in serial buffers ser.flushInput() ser.flushOutput() else: logMessage("Errors while opening serial port: \n" + error) sys.exit(0) # Die if we weren't able to connect # yes this is monkey patching, but I don't see how to replace the methods on a dynamically instantiated type any other way if dumpSerial: ser.readOriginal = ser.read ser.writeOriginal = ser.write def readAndDump(size=1): r = ser.readOriginal(size) sys.stdout.write(r) return r def writeAndDump(data): ser.writeOriginal(data) sys.stderr.write(data) ser.read = readAndDump ser.write = writeAndDump return ser