We have decided to kit a large number of ultra-small servers ** OpenBlocks ** for IoT gateways. The OpenBlocks IoT family has Web UI, a dedicated GUI application provided by Plat'Home, installed. According to FAQ of Platt Home, items that can be set from the Web UI such as network settings can be set from the Web UI. It is supposed to be set, and it seems that it should not be set with CUI (Linux command). If you include the scp transfer and execution of the application program, it will take 15 minutes per device. I decided to write a kitting script in Python because it is possible to reduce the total man-hours by creating an automation program from the beginning rather than repeating troublesome GUI operations dozens of times. It sounds good to say that it reduces man-hours, but in reality, I really didn't want to do simple work.
Automated browser operations with Selenium. It's a simple web application, so you're not doing anything special just by making a GET request, typing in a text box, or clicking the save button.
Python
"""
OpenBlocks IoT BX1 Kitting Script stage1
"""
__author__ = "MindWood"
__version__ = "1.00"
__date__ = "13 Mar 2020"
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
import sys
admin_id = 'adminUser'
admin_pw = 'adminPass'
passphrase = 'passPhrase'
id_rsa = 'ssh-rsa XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX== mw'
domain = 'example.com'
options = webdriver.ChromeOptions()
options.add_argument('--no-sandbox')
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(10)
#Connect to the OpenBlocks IoT Web UI
driver.get('http://192.168.254.254:880')
#If there is an consent button first, it is judged as the device to be used for the first time
ar = driver.find_elements_by_id('eula_agree')
if len(ar) == 0:
#Login screen
driver.find_element_by_name('name').send_keys(admin_id)
driver.find_element_by_name('password').send_keys(admin_pw)
driver.find_element_by_name('_act').click() #Login
else:
#Administrator account settings and consent screen
driver.find_element_by_id('eula_agree').click() #I agree
time.sleep(1)
driver.find_element_by_name('_name').send_keys(admin_id)
driver.find_element_by_name('_password').send_keys(admin_pw)
driver.find_element_by_name('_password_confirm').send_keys(admin_pw)
driver.find_element_by_id('save').click() #save
time.sleep(1)
#system>>Serial screen
driver.get('http://192.168.254.254:880/system/serial.php')
sq = driver.find_element_by_class_name('sq') #Get serial number
serial_num = sq.find_element_by_xpath('pre').text.strip()
print('Serial number[' + serial_num + ']')
#service>>Basic screen
driver.get('http://192.168.254.254:880/apps/m2miot/basic.php')
time.sleep(1)
driver.find_element_by_id('enable_bluetooth').click() #Bluetooth permission
driver.find_element_by_id('save').click() #save
time.sleep(1)
#service>>Status screen
driver.get('http://192.168.254.254:880/apps/m2miot/status.php')
time.sleep(1)
sq = driver.find_element_by_class_name('sq')
hcconfig = sq.find_element_by_xpath('pre').text
p = hcconfig.find('BD Address: ')
bd_adrs = hcconfig[p+12:p+29].replace(':', '') #BD address acquisition
print('BD address[' + bd_adrs + ']')
#system>>Filter screen
driver.get('http://192.168.254.254:880/system/ipfilter.php')
time.sleep(1)
this_checkbox = driver.find_element_by_id('filter_hold_true')
if not this_checkbox.is_selected(): this_checkbox.click() #If not checked, check
driver.find_element_by_id('mode_ssh_true').click() #SSH enabled
driver.find_element_by_id('save').click() #save
time.sleep(1)
#system>>SSH related screen
driver.get('http://192.168.254.254:880/system/sshd_config.php')
time.sleep(1)
driver.find_element_by_id('deny_passwd_login').click() #Password authentication prohibited
elm = driver.find_element_by_id('pubkey')
elm.clear()
elm.send_keys(id_rsa)
driver.find_element_by_id('save').click() #save
time.sleep(1)
#system>>My page screen
driver.get('http://192.168.254.254:880/system/mypage.php')
time.sleep(1)
driver.find_element_by_id('password').send_keys(admin_pw)
driver.find_element_by_id('save').click() #save
time.sleep(1)
#network>>Basic screen
driver.get('http://192.168.254.254:880/network/basic.php')
time.sleep(1)
elm = driver.find_element_by_id('domainname')
elm.clear()
elm.send_keys(domain) #domain
elm = driver.find_element_by_id('wlan0_ssid')
elm.clear()
ssid = serial_num + '_MindWood'
elm.send_keys(ssid) # SSID
elm = driver.find_element_by_id('wlan0_passphrase')
elm.clear()
elm.send_keys(passphrase) #Passphrase
driver.find_element_by_id('enable_ppp0').click() #Use PPP
time.sleep(1)
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)') #Scroll to the bottom line
time.sleep(1)
#SIM settings for SORACOM data only
driver.find_element_by_id('ppp0_apn').send_keys('soracom.io') # APN
driver.find_element_by_id('ppp0_user').send_keys('sora') #User name
driver.find_element_by_id('ppp0_pass').send_keys('sora') #password
driver.find_element_by_id('ppp0_autotype_false').click() #Do not connect automatically
driver.find_element_by_id('ppp0_set_reconnect_false').click() #Do not reconnect regularly
driver.find_element_by_id('save').click() #save
time.sleep(1)
#system>>Password screen
driver.get('http://192.168.254.254:880/system/passwd.php')
time.sleep(1)
driver.find_element_by_id('password').send_keys(admin_pw)
driver.find_element_by_id('password_confirm').send_keys(admin_pw)
driver.find_element_by_id('save').click() #save
#maintenance>>Reboot screen
driver.get('http://192.168.254.254:880/maintenance/shutdown.php')
time.sleep(1)
sq = driver.find_element_by_class_name('sq')
sq.find_element_by_xpath('//input[@onclick="pre_reboot()"]').click() #Reboot
driver.find_element_by_id('reboot_btn').click() #Run
time.sleep(2)
alert = driver.switch_to.alert
alert.accept() #Respond OK to alert
sys.exit()
Using paramiko and scp packages, we automated the transfer and execution of the application deployment shell. If you try to do it manually, setting the key is a hassle.
Python
"""
OpenBlocks IoT BX1 Kitting Script stage2
"""
__author__ = "MindWood"
__version__ = "1.00"
__date__ = "13 Mar 2020"
import paramiko
import scp
import time
def exec_cmd(cmd, ssh):
"""Execute command with ssh"""
print('# ' + cmd)
stdin, stdout, stderr = ssh.exec_command(cmd)
for out_line in stdout:
print(out_line.strip('\n'))
for err_line in stderr:
print(err_line.strip('\n'))
with paramiko.SSHClient() as ssh:
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
pkey = paramiko.RSAKey.from_private_key_file('bx1_rsa.key')
ssh.connect(hostname='192.168.254.254', port=22, username='root', password='adminPass', pkey=pkey)
exec_cmd('rm -f write_firmware.sh; ls -l', ssh)
with scp.SCPClient(ssh.get_transport()) as scp:
scp.put('write_firmware.sh', 'write_firmware.sh')
time.sleep(1)
exec_cmd('chmod 755 write_firmware.sh; ./write_firmware.sh', ssh)
time.sleep(2)
exec_cmd('reboot', ssh)
If you find this helpful!
Recommended Posts