Last active
July 27, 2016 15:18
-
-
Save chap/32e87237c81bd0f2f6dd8700fa4605f5 to your computer and use it in GitHub Desktop.
Sinatra app for particle.io testing and programming.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require 'sinatra' | |
| require 'active_record' | |
| require 'httparty' | |
| COM_PORT = "COM8" | |
| api_host = 'https://...' | |
| api_auth_token = '...' | |
| SYSTEM_FIRMWARE_VERSION = '0.5.3-rc.1' | |
| ActiveRecord::Base.establish_connection( | |
| :adapter => 'sqlite3', | |
| :database => 'mfg-v4.sqlite3.db' | |
| ) | |
| SETUP_STEPS = [ | |
| { name:'save_device_id' }, | |
| { name:'flash_light_test' }, | |
| { name:'light_test', human_required: true }, | |
| { name:'set_ssid' }, | |
| { name:'verify_ssid' }, | |
| { name:'flash_system_update' }, | |
| { name:'flash_wifi_test' }, | |
| { name:'claim_particle_device' }, | |
| { name:'clear_credentials' }, | |
| { name:'flash_production' }, | |
| { name:'setup_complete' } | |
| ] | |
| class Event < ActiveRecord::Base | |
| end | |
| class Device < ActiveRecord::Base | |
| has_many :events | |
| def flash_firmware(firmware) | |
| if firmware.start_with?('system-update') | |
| version = SYSTEM_FIRMWARE_VERSION | |
| version = '0.4.9' if firmware.include?('0.4.9') | |
| if OS.windows? | |
| # force DFU | |
| %x(mode #{COM_PORT} BAUD=14400) | |
| sleep(1) | |
| # require ending with tinker otherwise device remains in DFU | |
| # give it 2 seconds to reset | |
| result = %x(cd \\dependencies && particle flash --usb \\mfg-firmware\\system-part1-#{version}-photon.bin && particle flash --usb \\mfg-firmware\\system-part2-#{version}-photon.bin && particle flash --usb tinker) | |
| sleep(2) | |
| return result | |
| else | |
| # force DFU | |
| %x(stty -f /dev/cu.usbmodem1411 14400) | |
| sleep(1) | |
| # require ending with tinker otherwise device remains in DFU | |
| # give it 2 seconds to reset | |
| result = %x(particle flash --usb ../mfg-firmware/system-part1-#{version}-photon.bin && particle flash --usb ../mfg-firmware/system-part2-#{version}-photon.bin && particle flash --usb tinker) | |
| sleep(2) | |
| return result | |
| end | |
| elsif firmware == 'tinker' | |
| return %x(echo | particle flash --serial tinker) | |
| else | |
| if OS.windows? | |
| return %x(echo | particle flash --serial \\mfg-firmware\\#{firmware}) | |
| else | |
| return %x(echo | particle flash --serial ../mfg-firmware/#{firmware}) | |
| end | |
| end | |
| end | |
| end | |
| before '/devices/:id*' do | |
| @device = Device.find_by! "lower(serial_number) = ?", params['id'].try(:downcase) | |
| end | |
| # STEP 1 | |
| # input serial_number | |
| get '/' do\ | |
| erb :index | |
| end | |
| # STEP 2 | |
| # check serial_number exists in DB | |
| get '/lookup-engraved-url' do\ | |
| @device = Device.find_by "lower(serial_number) = ?", params['serial_number'].try(:downcase) | |
| if @device | |
| redirect to("devices/#{@device.serial_number}") | |
| else | |
| Event.create({ name: "FAIL serial_number lookup", description:params }) | |
| redirect to("/?error=not-found") | |
| end | |
| end | |
| # STEP 3 | |
| # store device id in DB | |
| get '/devices/:id/save_device_id' do\ | |
| identify_output = %x(particle identify) | |
| match = /Your device id is (.+)\n.+/.match(identify_output) | |
| event = @device.events.new({ name: "Saved device id", description:identify_output, step: 'save_device_id' }) | |
| if !match.nil? && match[1] != 'undefined' | |
| @device.update_attributes(device_id:match[1]) | |
| @device.update_attributes(save_device_id:1) | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(save_device_id:-1) | |
| event.event_type = 'fail' | |
| end | |
| event.save! | |
| event.to_json | |
| end | |
| # STEP 4 | |
| # load firmware to test switch and light | |
| get '/devices/:id/flash_light_test' do\ | |
| content_type :json | |
| flash_output = @device.flash_firmware("light-test-ssid.bin") | |
| event = @device.events.new({ name: "Flashed light test", description:flash_output, step: 'flash_light_test' }) | |
| if flash_output.include?('Flash success!') | |
| @device.update_attributes(flash_light_test:1) | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(flash_light_test:-1) | |
| event.event_type = 'fail' | |
| end | |
| event.save! | |
| event.to_json | |
| end | |
| # STEP 5 | |
| # record light test results | |
| get '/devices/:id/light_test' do\ | |
| event = @device.events.new({ name: "Light test", description:params, step: 'light_test' }) | |
| if params['results'] == 'pass' | |
| @device.update_attributes(light_test:1) | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(light_test:-1) | |
| event.event_type = 'fail' | |
| end | |
| event.save! | |
| redirect to("/devices/#{@device.serial_number}") | |
| end | |
| # STEP 6 | |
| # set device SSID | |
| get '/devices/:id/set_ssid' do\ | |
| content_type :json | |
| ssid_param = "ssid#{sprintf('%02d',@device.serial_number.length)}#{@device.serial_number}" | |
| event = @device.events.new({ name: "Set SSID", description:"ssid_param=#{ssid_param}\n#{params}", step: 'set_ssid' }) | |
| if OS.windows? | |
| # %x(set /p x="#{ssid}" <nul >\\\\.\\COM7) | |
| ssid_response = %x(echo #{ssid_param} > "#{COM_PORT}") | |
| @device.update_attributes(set_ssid:1) | |
| # I think this always succeeds | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(set_ssid:1) | |
| event.event_type = 'success' | |
| event.description = "Only works on windows, faking success for now!\n#{event.description}" | |
| end | |
| event.save! | |
| event.to_json | |
| end | |
| # STEP 7 | |
| # verify device SSID | |
| get '/devices/:id/verify_ssid' do\ | |
| content_type :json | |
| description = "No output" | |
| ssid = "#{@device.serial_number}-MAKE" | |
| event = @device.events.new({ name: "Verify SSID", step: 'verify_ssid' }) | |
| if OS.windows? | |
| log_path = "wifi-scans\\#{@device.serial_number}.txt" | |
| %x(\\dependencies\\Homedale.exe /l #{log_path} /e /t 5000 /c) | |
| file = File.open(log_path, "rb") | |
| description = file.read | |
| else | |
| description = %x(/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s) | |
| end | |
| event.description = description | |
| if description.include?(ssid) | |
| @device.update_attributes(verify_ssid:1) | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(verify_ssid:-1) | |
| event.description = "SSID=#{ssid} not found:\r#{description}" | |
| event.event_type = 'fail' | |
| end | |
| event.save! | |
| event.to_json | |
| end | |
| # STEP 8 | |
| # update system firmware | |
| get '/devices/:id/flash_system_update' do\ | |
| content_type :json | |
| # ?system-firmware-version=-0.4.9 | |
| flash_output = @device.flash_firmware('system-update#{params[:system_firmware_version]}') | |
| event = @device.events.new({ name: "Flashed system update", step: 'flash_system_update', description: flash_output }) | |
| if flash_output.include?('Flash success!') | |
| @device.update_attributes(flash_system_update:1) | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(flash_system_update:-1) | |
| event.event_type = 'fail' | |
| end | |
| event.save! | |
| event.to_json | |
| end | |
| # STEP 9 | |
| # flash wifi test | |
| get '/devices/:id/flash_wifi_test' do\ | |
| content_type :json | |
| flash_output = @device.flash_firmware('wifi-test.bin') | |
| event = @device.events.new({ name: "Flashed wifi test", step: 'flash_wifi_test', description: flash_output }) | |
| if flash_output.include?('Flash success!') | |
| @device.update_attributes(flash_wifi_test:1) | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(flash_wifi_test:-1) | |
| event.event_type = 'fail' | |
| end | |
| event.save! | |
| event.to_json | |
| end | |
| # STEP 10 | |
| # claim-particle-device | |
| get '/devices/:id/claim_particle_device' do\ | |
| content_type :json | |
| # give it 10 seconds to connect | |
| sleep(10) | |
| response = ::HTTParty.post("#{api_host}/api/v1/clocks/#{@device.serial_number}/claim", { headers: { "Authorization" => "Token token=#{api_auth_token}" }, body: { device_id: @device.device_id } } ) | |
| event = @device.events.new({ name: "Claim particle device", step: 'claim_particle_device', description: response }) | |
| parsed_response = JSON.parse(response.body) rescue ({}) | |
| if parsed_response['ok'].to_s == 'true' | |
| @device.update_attributes(claim_particle_device:1) | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(claim_particle_device:-1) | |
| event.event_type = 'fail' | |
| end | |
| event.save! | |
| event.to_json | |
| end | |
| # STEP 11 | |
| # flash production | |
| get '/devices/:id/clear_credentials' do\ | |
| content_type :json | |
| flash_output = @device.flash_firmware('clear-credentials.bin') | |
| event = @device.events.new({ name: "Clear credentials", step: 'clear_credentials', description: flash_output }) | |
| if flash_output.include?('Flash success!') | |
| @device.update_attributes(clear_credentials:1) | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(clear_credentials:-1) | |
| event.event_type = 'fail' | |
| end | |
| event.save! | |
| event.to_json | |
| end | |
| # STEP 12 | |
| # flash production | |
| get '/devices/:id/flash_production' do\ | |
| content_type :json | |
| flash_output = @device.flash_firmware('production.bin') | |
| event = @device.events.new({ name: "Flashed production", step: 'flash_wifi_test', description: flash_output }) | |
| if flash_output.include?('Flash success!') | |
| @device.update_attributes(flash_production:1) | |
| event.event_type = 'success' | |
| else | |
| @device.update_attributes(flash_production:-1) | |
| event.event_type = 'fail' | |
| end | |
| event.save! | |
| event.to_json | |
| end | |
| # STEP 13 | |
| # all good | |
| get '/devices/:id/setup_complete' do\ | |
| content_type :json | |
| @device.update_attributes(setup_complete:1) | |
| @device.events.create!({ name: "Setup complete", step: 'setup_complete', event_type: 'success' }).to_json | |
| end | |
| get '/devices/:id' do\ | |
| erb :show | |
| end | |
| module OS | |
| def OS.windows? | |
| (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil | |
| end | |
| def OS.mac? | |
| (/darwin/ =~ RUBY_PLATFORM) != nil | |
| end | |
| def OS.unix? | |
| !OS.windows? | |
| end | |
| def OS.linux? | |
| OS.unix? and not OS.mac? | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment