From b0ffff6d511100d99199d2a5c9f1b1a742be9c0c Mon Sep 17 00:00:00 2001 From: finchiedev Date: Mon, 19 Aug 2019 20:40:17 +0800 Subject: [PATCH 01/11] Implement basic EMANUAL control table parser --- App/JS/createServo.js | 74 ++++++++++++++++ App/createServo.html | 15 ++++ main.js | 21 +---- package.json | 5 +- yarn.lock | 193 ++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 285 insertions(+), 23 deletions(-) create mode 100644 App/JS/createServo.js create mode 100644 App/createServo.html diff --git a/App/JS/createServo.js b/App/JS/createServo.js new file mode 100644 index 0000000..4937774 --- /dev/null +++ b/App/JS/createServo.js @@ -0,0 +1,74 @@ +const rp = require('request-promise'); +const cheerio = require('cheerio'); +const cheerioTableparser = require('cheerio-tableparser'); +const fs = require('fs'); + +/** + * Parses all elements in a given Dynamixel table and converts them to CSV + * @param {Object} table The table returned when executing parsetable + * @param {Boolean} includeHeader If the CSV should include headings - use + * false if this is not the top item in the table + * @return {String} A string of CSV data with the control table + */ +function parseDynamixelTable(table, includeHeader) { + let build = ''; + for (let i = includeHeader? 0 : 1; i < table[0].length; i++) { + for (let x = 0; x < table.length; x++) { + build += table[x][i]; + if (x < table.length - 1) { + build += ', '; + } + } + if (i < table[0].length) { + build += '\n'; + } + } + return build; +} + +function getFile() { + const link = document.getElementById('url').value; + rp(link) + .then(function(html) { + console.log('Successfully downloaded the site!'); + /* + What the Table looks like + +---------+--------------+--------+ + | Address | Size (Bytes) | Name | + +---------+--------------+--------+ + | Integer | Integer | String | + +---------+--------------+--------+ + And so on + */ + console.log('Scraping the table data...'); + const $ = cheerio.load(html); + cheerioTableparser($); + const EEPROMtable = $('table').eq(1).parsetable(true, true, true); + const RAMtable = $('table').eq(2).parsetable(true, true, true); + let fileData = ''; + fileData += parseDynamixelTable(EEPROMtable, true); + fileData += parseDynamixelTable(RAMtable, false); + const linkPieces = link.split('/'); + if (linkPieces[linkPieces.length - 1] == '') { + linkPieces.pop(linkPieces.length - 1); + } + console.log('Done!'); + console.log(fileData); + // const filename = linkPieces[linkPieces.length - 1]; + // fs.writeFile(`./${filename}.csv`, fileData, function(err) { + // if (err) { + // return console.error('Failed to write file! Do you have access?'); + // } + + // console.log(`Saved the file as ${filename}.csv`); + // }); + }) + .catch(function(err) { + console.error('An error has occured!'); + console.error('Check that you have an active internet connection'); + console.error('Additionally, check that you are able to access sites'); + console.log(link) + console.error(err); + }); + +} \ No newline at end of file diff --git a/App/createServo.html b/App/createServo.html new file mode 100644 index 0000000..b8d2db2 --- /dev/null +++ b/App/createServo.html @@ -0,0 +1,15 @@ + + + + + Create a new servo type + + + + +
+ + +
+ + diff --git a/main.js b/main.js index 4001827..bad067c 100644 --- a/main.js +++ b/main.js @@ -9,29 +9,16 @@ function createWindow() { width: 1600, height: 1200 }); - win.loadFile('App/loading.html'); - setTimeout(function() { - win.loadFile('App/index.html'); - }, 3000) + // win.loadFile('App/loading.html'); + // setTimeout(function() { + win.loadFile('App/createServo.html'); + // }, 3000) // win.loadURL('http://localhost:8080') win.webContents.openDevTools(); win.on('closed', () => { win = null; }); - win2 = new BrowserWindow({ - width: 1600, - height: 1200 - }); - win2.loadFile('App/loading.html'); - setTimeout(function() { - win2.loadFile('App/charts.html'); - }, 3000) - // win.loadURL('http://localhost:8080') - - win2.on('closed', () => { - win2 = null; - }); } app.on('ready', createWindow); diff --git a/package.json b/package.json index 4ac7bc0..bad0f3a 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,9 @@ "license": "Apache", "private": false, "dependencies": { - "electron": "^6.0.2" + "cheerio": "^1.0.0-rc.3", + "cheerio-tableparser": "^1.0.1", + "electron": "^6.0.2", + "request-promise": "^4.2.4" } } diff --git a/yarn.lock b/yarn.lock index 8f75f6e..bfe06a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@types/node@*": + version "12.7.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44" + integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg== + "@types/node@^10.12.18": version "10.14.15" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.15.tgz#e8f7729b631be1b02ae130ff0b61f3e018000640" @@ -61,6 +66,16 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bluebird@^3.5.0: + version "3.5.5" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" + integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== + +boolbase@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -84,6 +99,23 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +cheerio-tableparser@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cheerio-tableparser/-/cheerio-tableparser-1.0.1.tgz#e55ad2dcb5361b8c323a6cbb8c0cd46e3cbdf1cd" + integrity sha1-5VrS3LU2G4wyOmy7jAzUbjy98c0= + +cheerio@^1.0.0-rc.3: + version "1.0.0-rc.3" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6" + integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA== + dependencies: + css-select "~1.2.0" + dom-serializer "~0.1.1" + entities "~1.1.1" + htmlparser2 "^3.9.1" + lodash "^4.15.0" + parse5 "^3.0.1" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -111,6 +143,21 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +css-select@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" + integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= + dependencies: + boolbase "~1.0.0" + css-what "2.1" + domutils "1.5.1" + nth-check "~1.0.1" + +css-what@2.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" + integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -154,6 +201,55 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +dom-serializer@0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.1.tgz#13650c850daffea35d8b626a4cfc4d3a17643fdb" + integrity sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q== + dependencies: + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domelementtype@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d" + integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" + integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= + dependencies: + dom-serializer "0" + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -186,6 +282,16 @@ electron@^6.0.2: electron-download "^4.1.0" extract-zip "^1.0.3" +entities@^1.1.1, entities@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" + integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== + env-paths@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0" @@ -306,6 +412,18 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.4.tgz#44119abaf4bc64692a16ace34700fed9c03e2546" integrity sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ== +htmlparser2@^3.9.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + http-signature@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" @@ -322,7 +440,7 @@ indent-string@^2.1.0: dependencies: repeating "^2.0.0" -inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -424,6 +542,11 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" +lodash@^4.15.0, lodash@^4.17.11: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -502,6 +625,13 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" +nth-check@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" + integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== + dependencies: + boolbase "~1.0.0" + nugget@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/nugget/-/nugget-2.0.1.tgz#201095a487e1ad36081b3432fa3cada4f8d071b0" @@ -542,6 +672,13 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" +parse5@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" + integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== + dependencies: + "@types/node" "*" + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -616,7 +753,7 @@ progress-stream@^1.1.0: speedometer "~0.1.2" through2 "~0.2.3" -psl@^1.1.24: +psl@^1.1.24, psl@^1.1.28: version "1.3.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.3.0.tgz#e1ebf6a3b5564fa8376f3da2275da76d875ca1bd" integrity sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag== @@ -626,7 +763,7 @@ punycode@^1.4.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -676,6 +813,15 @@ readable-stream@^2.2.2: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@^3.1.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" + integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readable-stream@~1.1.9: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -701,6 +847,23 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" +request-promise-core@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" + integrity sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag== + dependencies: + lodash "^4.17.11" + +request-promise@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.4.tgz#1c5ed0d71441e38ad58c7ce4ea4ea5b06d54b310" + integrity sha512-8wgMrvE546PzbR5WbYxUQogUnUDfM0S7QIFZMID+J73vdFARkFy+HElj4T+MWYhpXwlLp0EQ8Zoj8xUA0he4Vg== + dependencies: + bluebird "^3.5.0" + request-promise-core "1.1.2" + stealthy-require "^1.1.1" + tough-cookie "^2.3.3" + request@^2.45.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" @@ -734,7 +897,7 @@ resolve@^1.10.0: dependencies: path-parse "^1.0.6" -safe-buffer@^5.0.1, safe-buffer@^5.1.2: +safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== @@ -812,6 +975,11 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +stealthy-require@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -821,6 +989,13 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" @@ -879,6 +1054,14 @@ through2@~0.2.3: readable-stream "~1.1.9" xtend "~2.1.1" +tough-cookie@^2.3.3: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tough-cookie@~2.4.3: version "2.4.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" @@ -921,7 +1104,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -util-deprecate@~1.0.1: +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= From 94979a34a467dbfd72443f3659084c095c02d651 Mon Sep 17 00:00:00 2001 From: finchiedev Date: Mon, 19 Aug 2019 21:16:39 +0800 Subject: [PATCH 02/11] Implement remote control table download --- App/JS/createServo.js | 11 +++++++---- Server/fileServer.js | 21 +++++++++++++++++++++ Server/index.js | 4 ++++ 3 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 Server/fileServer.js diff --git a/App/JS/createServo.js b/App/JS/createServo.js index 4937774..3a1d6b7 100644 --- a/App/JS/createServo.js +++ b/App/JS/createServo.js @@ -1,7 +1,8 @@ const rp = require('request-promise'); const cheerio = require('cheerio'); const cheerioTableparser = require('cheerio-tableparser'); -const fs = require('fs'); +const net = require('net'); +const client = new net.Socket(); /** * Parses all elements in a given Dynamixel table and converts them to CSV @@ -52,9 +53,13 @@ function getFile() { if (linkPieces[linkPieces.length - 1] == '') { linkPieces.pop(linkPieces.length - 1); } + const filename = linkPieces[linkPieces.length - 1]; + client.connect(5004, '127.0.0.1', function() { + client.write(`${filename}\n${fileData}`); + client.destroy(); + }) console.log('Done!'); console.log(fileData); - // const filename = linkPieces[linkPieces.length - 1]; // fs.writeFile(`./${filename}.csv`, fileData, function(err) { // if (err) { // return console.error('Failed to write file! Do you have access?'); @@ -67,8 +72,6 @@ function getFile() { console.error('An error has occured!'); console.error('Check that you have an active internet connection'); console.error('Additionally, check that you are able to access sites'); - console.log(link) console.error(err); }); - } \ No newline at end of file diff --git a/Server/fileServer.js b/Server/fileServer.js new file mode 100644 index 0000000..c19558f --- /dev/null +++ b/Server/fileServer.js @@ -0,0 +1,21 @@ +const fs = require('fs'); +const net = require('net'); +let server = net.createServer() + +server.on('connection', function(socket) { + socket.on('data', function(data) { + let fileData = data.toString().split('\n'); + const filename = fileData[0].replace('-', ''); + fileData.shift(); + fileData = fileData.join('\n'); + + fs.writeFile(`./Driving/Servos/${filename}.csv`, fileData, function(err) { + if (err) { + console.error('Failed to write file! Do you have access?'); + } + console.log(`Saved the file as ${filename}.csv`); + }); + }) +}) + +server.listen(5004, ''); \ No newline at end of file diff --git a/Server/index.js b/Server/index.js index 339daec..6725321 100644 --- a/Server/index.js +++ b/Server/index.js @@ -7,6 +7,10 @@ const commands = { 'Driving': [ 'python3', ['-u', './Driving/server.py'] + ], + 'Fileserver': [ + 'node', + ['./fileServer.js'] ] } From 8eacfcd5c4cf7eea24869d5f5c19e0a8d66fe06e Mon Sep 17 00:00:00 2001 From: finchiedev Date: Mon, 19 Aug 2019 21:48:25 +0800 Subject: [PATCH 03/11] Implement URL matching --- App/JS/createServo.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/App/JS/createServo.js b/App/JS/createServo.js index 3a1d6b7..0591c9e 100644 --- a/App/JS/createServo.js +++ b/App/JS/createServo.js @@ -29,7 +29,11 @@ function parseDynamixelTable(table, includeHeader) { function getFile() { const link = document.getElementById('url').value; - rp(link) + const re = /^https?:\/\/emanual\.robotis\.com\/docs\/en\/dxl\/[a-z0-9]+\/[a-z0-9]+-?[a-z0-9]+/ + const res = link.match(re) + if (res !== null && res !== undefined) { + console.log(`Extracted URL as ${res[0]}`); + rp(link) .then(function(html) { console.log('Successfully downloaded the site!'); /* @@ -53,25 +57,25 @@ function getFile() { if (linkPieces[linkPieces.length - 1] == '') { linkPieces.pop(linkPieces.length - 1); } + const filename = linkPieces[linkPieces.length - 1]; + client.on('error', function(err) { + console.error('Unable to connect to the fileserver!' + '\n' + + 'Ensure that the robot is powered and active.'); + }) client.connect(5004, '127.0.0.1', function() { client.write(`${filename}\n${fileData}`); client.destroy(); }) console.log('Done!'); - console.log(fileData); - // fs.writeFile(`./${filename}.csv`, fileData, function(err) { - // if (err) { - // return console.error('Failed to write file! Do you have access?'); - // } - - // console.log(`Saved the file as ${filename}.csv`); - // }); }) .catch(function(err) { console.error('An error has occured!'); console.error('Check that you have an active internet connection'); console.error('Additionally, check that you are able to access sites'); console.error(err); - }); + }); + } else { + console.error('It seems that your URL is invalid!'); + } } \ No newline at end of file From b2928d3503fa4dce909660033d26b30e7d5baf72 Mon Sep 17 00:00:00 2001 From: finchiedev Date: Tue, 20 Aug 2019 19:10:27 +0800 Subject: [PATCH 04/11] Update servo creation page style --- App/CSS/createServo.css | 17 +++++++++++++++++ App/createServo.html | 11 +++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 App/CSS/createServo.css diff --git a/App/CSS/createServo.css b/App/CSS/createServo.css new file mode 100644 index 0000000..e153973 --- /dev/null +++ b/App/CSS/createServo.css @@ -0,0 +1,17 @@ +.container { + position: absolute; + top: 50%; + left: 50%; + transform: translateX(-50%) translateY(-50%); +} + +#url { + text-align: center; + border: 1px solid; + padding: 5px; +} + +#submit { + text-align: center; + padding: 5px; +} \ No newline at end of file diff --git a/App/createServo.html b/App/createServo.html index b8d2db2..92c9a54 100644 --- a/App/createServo.html +++ b/App/createServo.html @@ -5,11 +5,14 @@ Create a new servo type + -
- - -
+
+
+ + +
+
From e20d811f4228677e5f65560a0e8060a5a783006a Mon Sep 17 00:00:00 2001 From: finchiedev Date: Tue, 20 Aug 2019 19:35:50 +0800 Subject: [PATCH 05/11] Implement table header parsing as function --- App/JS/createServo.js | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/App/JS/createServo.js b/App/JS/createServo.js index 0591c9e..24c6f06 100644 --- a/App/JS/createServo.js +++ b/App/JS/createServo.js @@ -4,6 +4,24 @@ const cheerioTableparser = require('cheerio-tableparser'); const net = require('net'); const client = new net.Socket(); +/** + * Parses the header of a given table + * @param {Array} table + * @returns {String} The header of the specified table + */ +function parseDynamixelHeader(table) { + let build = ''; + for (let col = 0; col < table.length; col++) { + build += table[col][0]; + if (col < table.length - 1) { + build += ', '; + } else { + build += '\n'; + } + } + return build; +} + /** * Parses all elements in a given Dynamixel table and converts them to CSV * @param {Object} table The table returned when executing parsetable @@ -11,9 +29,9 @@ const client = new net.Socket(); * false if this is not the top item in the table * @return {String} A string of CSV data with the control table */ -function parseDynamixelTable(table, includeHeader) { +function parseDynamixelTable(table) { let build = ''; - for (let i = includeHeader? 0 : 1; i < table[0].length; i++) { + for (let i = 1; i < table[0].length; i++) { for (let x = 0; x < table.length; x++) { build += table[x][i]; if (x < table.length - 1) { @@ -28,11 +46,12 @@ function parseDynamixelTable(table, includeHeader) { } function getFile() { - const link = document.getElementById('url').value; + const url = document.getElementById('url').value; const re = /^https?:\/\/emanual\.robotis\.com\/docs\/en\/dxl\/[a-z0-9]+\/[a-z0-9]+-?[a-z0-9]+/ - const res = link.match(re) + const res = url.match(re) if (res !== null && res !== undefined) { - console.log(`Extracted URL as ${res[0]}`); + const link = res[0]; + console.log(`Extracted URL as ${link}`); rp(link) .then(function(html) { console.log('Successfully downloaded the site!'); @@ -51,8 +70,9 @@ function getFile() { const EEPROMtable = $('table').eq(1).parsetable(true, true, true); const RAMtable = $('table').eq(2).parsetable(true, true, true); let fileData = ''; - fileData += parseDynamixelTable(EEPROMtable, true); - fileData += parseDynamixelTable(RAMtable, false); + fileData += parseDynamixelHeader(EEPROMtable); + fileData += parseDynamixelTable(EEPROMtable); + fileData += parseDynamixelTable(RAMtable); const linkPieces = link.split('/'); if (linkPieces[linkPieces.length - 1] == '') { linkPieces.pop(linkPieces.length - 1); From c4b92fc31563acf4ced322aea854d1b85cff20d4 Mon Sep 17 00:00:00 2001 From: finchiedev Date: Tue, 20 Aug 2019 19:48:18 +0800 Subject: [PATCH 06/11] Implement CSV generation as function --- App/JS/createServo.js | 49 +++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/App/JS/createServo.js b/App/JS/createServo.js index 24c6f06..d0b8f00 100644 --- a/App/JS/createServo.js +++ b/App/JS/createServo.js @@ -27,7 +27,7 @@ function parseDynamixelHeader(table) { * @param {Object} table The table returned when executing parsetable * @param {Boolean} includeHeader If the CSV should include headings - use * false if this is not the top item in the table - * @return {String} A string of CSV data with the control table + * @returns {String} A string of CSV data with the control table */ function parseDynamixelTable(table) { let build = ''; @@ -45,6 +45,28 @@ function parseDynamixelTable(table) { return build; } +function generateCSV(html, indexes) { + if (indexes == null || indexes == undefined || indexes.length == 0) { + console.error('Invalid argument!' + + 'Ensure that the argument "indexes" is valid!'); + return ''; + } + + let fileData = ''; + const $ = cheerio.load(html); + cheerioTableparser($); + const cheerioTable = $('table'); + + fileData += parseDynamixelHeader(cheerioTable.eq( + indexes[0]).parsetable(true, true, true)); + for (var i = 0; i < indexes.length; i++) { + fileData += parseDynamixelTable(cheerioTable.eq( + indexes[i]).parsetable(true, true, true)); + } + + return fileData; +} + function getFile() { const url = document.getElementById('url').value; const re = /^https?:\/\/emanual\.robotis\.com\/docs\/en\/dxl\/[a-z0-9]+\/[a-z0-9]+-?[a-z0-9]+/ @@ -54,31 +76,17 @@ function getFile() { console.log(`Extracted URL as ${link}`); rp(link) .then(function(html) { - console.log('Successfully downloaded the site!'); - /* - What the Table looks like - +---------+--------------+--------+ - | Address | Size (Bytes) | Name | - +---------+--------------+--------+ - | Integer | Integer | String | - +---------+--------------+--------+ - And so on - */ - console.log('Scraping the table data...'); - const $ = cheerio.load(html); - cheerioTableparser($); - const EEPROMtable = $('table').eq(1).parsetable(true, true, true); - const RAMtable = $('table').eq(2).parsetable(true, true, true); - let fileData = ''; - fileData += parseDynamixelHeader(EEPROMtable); - fileData += parseDynamixelTable(EEPROMtable); - fileData += parseDynamixelTable(RAMtable); + console.log('Successfully downloaded the site!' + + ' Now scraping the data...'); + const fileData = generateCSV(html, [1, 2]); + const linkPieces = link.split('/'); if (linkPieces[linkPieces.length - 1] == '') { linkPieces.pop(linkPieces.length - 1); } const filename = linkPieces[linkPieces.length - 1]; + client.on('error', function(err) { console.error('Unable to connect to the fileserver!' + '\n' + 'Ensure that the robot is powered and active.'); @@ -87,6 +95,7 @@ function getFile() { client.write(`${filename}\n${fileData}`); client.destroy(); }) + console.log('Done!'); }) .catch(function(err) { From 6dd791fd664ba19ddee6deea4c585b7d51f044f5 Mon Sep 17 00:00:00 2001 From: finchiedev Date: Tue, 20 Aug 2019 19:54:53 +0800 Subject: [PATCH 07/11] Improve network error message --- App/JS/createServo.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/App/JS/createServo.js b/App/JS/createServo.js index d0b8f00..4a0d809 100644 --- a/App/JS/createServo.js +++ b/App/JS/createServo.js @@ -99,10 +99,11 @@ function getFile() { console.log('Done!'); }) .catch(function(err) { - console.error('An error has occured!'); - console.error('Check that you have an active internet connection'); - console.error('Additionally, check that you are able to access sites'); - console.error(err); + console.error('An error has occured!' + '\n' + + 'Check that you have an active internet connection' + '\n' + + 'Additionally, check that you are able to access sites' + '\n' + + 'This may be due to you being connected to the robot' + '\n' + + `Recieved error: \n${err}`); }); } else { console.error('It seems that your URL is invalid!'); From 3dda4c7ee75129a86999d0da3b068bd1f42eedfd Mon Sep 17 00:00:00 2001 From: finchiedev Date: Tue, 20 Aug 2019 20:44:59 +0800 Subject: [PATCH 08/11] Implement download/upload CSV buttons --- App/CSS/createServo.css | 2 +- App/JS/createServo.js | 77 ++++++++++++++++++++++++++--------------- App/createServo.html | 5 +-- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/App/CSS/createServo.css b/App/CSS/createServo.css index e153973..2c6932e 100644 --- a/App/CSS/createServo.css +++ b/App/CSS/createServo.css @@ -11,7 +11,7 @@ padding: 5px; } -#submit { +#download #upload { text-align: center; padding: 5px; } \ No newline at end of file diff --git a/App/JS/createServo.js b/App/JS/createServo.js index 4a0d809..7037b91 100644 --- a/App/JS/createServo.js +++ b/App/JS/createServo.js @@ -2,7 +2,15 @@ const rp = require('request-promise'); const cheerio = require('cheerio'); const cheerioTableparser = require('cheerio-tableparser'); const net = require('net'); +let link = ''; +let fileData = ''; +let filename = ''; + const client = new net.Socket(); +client.on('error', function(err) { + console.error('Unable to connect to the fileserver!' + '\n' + + 'Ensure that the robot is powered and active.'); +}) /** * Parses the header of a given table @@ -51,52 +59,46 @@ function generateCSV(html, indexes) { 'Ensure that the argument "indexes" is valid!'); return ''; } - + let fileData = ''; const $ = cheerio.load(html); cheerioTableparser($); const cheerioTable = $('table'); - + fileData += parseDynamixelHeader(cheerioTable.eq( indexes[0]).parsetable(true, true, true)); for (var i = 0; i < indexes.length; i++) { fileData += parseDynamixelTable(cheerioTable.eq( indexes[i]).parsetable(true, true, true)); + } + + return fileData; } - - return fileData; -} - -function getFile() { - const url = document.getElementById('url').value; - const re = /^https?:\/\/emanual\.robotis\.com\/docs\/en\/dxl\/[a-z0-9]+\/[a-z0-9]+-?[a-z0-9]+/ - const res = url.match(re) - if (res !== null && res !== undefined) { - const link = res[0]; - console.log(`Extracted URL as ${link}`); - rp(link) + + function getFile() { + const url = document.getElementById('url').value; + const re = /^https?:\/\/emanual\.robotis\.com\/docs\/en\/dxl\/[a-z0-9]+\/[a-z0-9]+-?[a-z0-9]+/ + const res = url.match(re) + if (res !== null && res !== undefined) { + link = res[0]; + console.log(`Extracted URL as ${link}`); + rp(link) .then(function(html) { console.log('Successfully downloaded the site!' + ' Now scraping the data...'); - const fileData = generateCSV(html, [1, 2]); + fileData = generateCSV(html, [1, 2]); + console.log('Downloaded table!'); const linkPieces = link.split('/'); if (linkPieces[linkPieces.length - 1] == '') { linkPieces.pop(linkPieces.length - 1); } + filename = linkPieces[linkPieces.length - 1]; - const filename = linkPieces[linkPieces.length - 1]; - - client.on('error', function(err) { - console.error('Unable to connect to the fileserver!' + '\n' + - 'Ensure that the robot is powered and active.'); - }) - client.connect(5004, '127.0.0.1', function() { - client.write(`${filename}\n${fileData}`); - client.destroy(); - }) - - console.log('Done!'); + uploadButton = document.getElementById('upload') + uploadButton.innerHTML = + `Upload ${filename.replace('-', '')}.csv`; + uploadButton.style.display = null; }) .catch(function(err) { console.error('An error has occured!' + '\n' + @@ -104,8 +106,27 @@ function getFile() { 'Additionally, check that you are able to access sites' + '\n' + 'This may be due to you being connected to the robot' + '\n' + `Recieved error: \n${err}`); - }); + }); } else { console.error('It seems that your URL is invalid!'); + } +} + +function uploadFile() { + if (fileData == null || fileData == undefined || fileData == '') { + console.error('There is no downloaded file!'); + return; } + + client.connect({ + port: 5004, + address: '127.0.0.1' + }); + + client.on('connect', function() { + client.write(`${filename}\n${fileData}`); + console.log('Wrote file to server!'); + }) + + console.log('Uploaded table!'); } \ No newline at end of file diff --git a/App/createServo.html b/App/createServo.html index 92c9a54..5c2f7e1 100644 --- a/App/createServo.html +++ b/App/createServo.html @@ -9,10 +9,11 @@
-
+ -
+ +
From 9f1f6975812014512df8f2fd4b0da996689cb26d Mon Sep 17 00:00:00 2001 From: finchiedev Date: Tue, 20 Aug 2019 20:57:05 +0800 Subject: [PATCH 09/11] Implement CSV local file download --- App/JS/Resources/Servos/ax18a.csv | 33 +++++++++++++++++++++++++++++++ App/JS/Resources/Servos/xl320.csv | 32 ++++++++++++++++++++++++++++++ App/JS/createServo.js | 14 ++++++++++--- 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 App/JS/Resources/Servos/ax18a.csv create mode 100644 App/JS/Resources/Servos/xl320.csv diff --git a/App/JS/Resources/Servos/ax18a.csv b/App/JS/Resources/Servos/ax18a.csv new file mode 100644 index 0000000..967b395 --- /dev/null +++ b/App/JS/Resources/Servos/ax18a.csv @@ -0,0 +1,33 @@ +Address, Size(Byte), Data Name, Description, Access, InitialValue +0, 2, Model Number, Model Number, R, 18 +2, 1, Firmware Version, Firmware Version, R, - +3, 1, ID, DYNAMIXEL ID, RW, 1 +4, 1, Baud Rate, Communication Speed, RW, 1 +5, 1, Return Delay Time, Response Delay Time, RW, 250 +6, 2, CW Angle Limit, Clockwise Angle Limit, RW, 0 +8, 2, CCW Angle Limit, Counter-Clockwise Angle Limit, RW, 1023 +11, 1, Temperature Limit, Maximum Internal Temperature Limit, RW, 75 +12, 1, Min Voltage Limit, Minimum Input Voltage Limit, RW, 60 +13, 1, Max Voltage Limit, Maximum Input Voltage Limit, RW, 140 +14, 2, Max Torque, Maximun Torque, RW, 983 +16, 1, Status Return Level, Select Types of Status Return, RW, 2 +17, 1, Alarm LED, LED for Alarm, RW, 36 +18, 1, Shutdown, Shutdown Error Information, RW, 36 +24, 1, Torque Enable, Motor Torque On/Off, RW, 0 +25, 1, LED, Status LED On/Off, RW, 0 +26, 1, CW Compliance Margin, CW Compliance Margin, RW, 1 +27, 1, CCW Compliance Margin, CCW Compliance Margin, RW, 1 +28, 1, CW Compliance Slope, CW Compliance Slope, RW, 32 +29, 1, CCW Compliance Slope, CCW Compliance Slope, RW, 32 +30, 2, Goal Position, Target Position, RW, - +32, 2, Moving Speed, Moving Speed, RW, - +34, 2, Torque Limit, Torque Limit(Goal Torque), RW, ADD 14&15 +36, 2, Present Position, Present Position, R, - +38, 2, Present Speed, Present Speed, R, - +40, 2, Present Load, Present Load, R, - +42, 1, Present Voltage, Present Voltage, R, - +43, 1, Present Temperature, Present Temperature, R, - +44, 1, Registered, If Instruction is registered, R, 0 +46, 1, Moving, Movement Status, R, 0 +47, 1, Lock, Locking EEPROM, RW, 0 +48, 2, Punch, Minimum Current Threshold, RW, 32 diff --git a/App/JS/Resources/Servos/xl320.csv b/App/JS/Resources/Servos/xl320.csv new file mode 100644 index 0000000..9a88966 --- /dev/null +++ b/App/JS/Resources/Servos/xl320.csv @@ -0,0 +1,32 @@ +Address, Size(Byte), Data Name, Description, Access, InitialValue, Min, Max +0, 2, Model Number, Model Number, R, 350, -, - +2, 1, Firmware Version, Firmware Version, R, -, -, - +3, 1, ID, DYNAMIXEL ID, RW, 1, 0, 252 +4, 1, Baud Rate, Communication Speed, RW, 3, 0, 3 +5, 1, Return Delay Time, Response Delay Time, RW, 250, 0, 254 +6, 2, CW Angle Limit, Clockwise Angle Limit, RW, 0, 0, 1023 +8, 2, CCW Angle Limit, Counter-Clockwise Angle Limit, RW, 1023, 0, 1023 +11, 1, Control Mode, Control Mode, RW, 2, 1, 2 +12, 1, Temperature Limit, Maximum Internal Temperature Limit, RW, 65, 0, 150 +13, 1, Min Voltage Limit, Minimum Input Voltage Limit, RW, 60, 50, 250 +14, 1, Max Voltage Limit, Maximum Input Voltage Limit, RW, 90, 50, 250 +15, 2, Max Torque, Maximun Torque, RW, 1023, 0, 1023 +17, 1, Status Return Level, Select Types of Status Return, RW, 2, 0, 2 +18, 1, Shutdown, Shutdown Error Information, RW, 3, 0, 7 +24, 1, Torque Enable, Motor Torque On/Off, RW, 0, 0, 1 +25, 1, LED, Status LED On/Off, RW, 0, 0, 7 +27, 1, D Gain, Derivative Gain, RW, 0, 0, 254 +28, 1, I Gain, Integral Gain, RW, 0, 0, 254 +29, 1, P Gain, Proportional Gain, RW, 32, 0, 254 +30, 2, Goal Position, Desired Position, RW, -, 0, 1023 +32, 2, Moving Speed, Moving Speed(Moving Velocity), RW, -, 0, 2047 +35, 2, Torque Limit, Torque Limit(Goal Torque), RW, -, 0, 1023 +37, 2, Present Position, Present Position, R, -, -, - +39, 2, Present Speed, Present Speed, R, -, -, - +41, 2, Present Load, Present Load, R, -, -, - +45, 1, Present Voltage, Present Voltage, R, -, -, - +46, 1, Present Temperature, Present Temperature, R, -, -, - +47, 1, Registered, If Instruction is registered, R, 0, -, - +49, 1, Moving, Movement Status, R, 0, -, - +50, 1, Hardware Error Status, Hardware Error Status, R, 0, -, - +51, 2, Punch, Minimum Current Threshold, RW, 32, 0, 1023 diff --git a/App/JS/createServo.js b/App/JS/createServo.js index 7037b91..2bc28c7 100644 --- a/App/JS/createServo.js +++ b/App/JS/createServo.js @@ -1,3 +1,4 @@ +const fs = require('fs'); const rp = require('request-promise'); const cheerio = require('cheerio'); const cheerioTableparser = require('cheerio-tableparser'); @@ -88,16 +89,23 @@ function generateCSV(html, indexes) { ' Now scraping the data...'); fileData = generateCSV(html, [1, 2]); console.log('Downloaded table!'); - + const linkPieces = link.split('/'); if (linkPieces[linkPieces.length - 1] == '') { linkPieces.pop(linkPieces.length - 1); } - filename = linkPieces[linkPieces.length - 1]; + filename = linkPieces[linkPieces.length - 1].replace('-', ''); + + fs.writeFile(`App/JS/Resources/Servos/${filename}.csv`, fileData, function(err) { + if (err) { + console.error('Failed to write file! Do you have access?'); + } + console.log(`Saved the file as ${filename}.csv`); + }); uploadButton = document.getElementById('upload') uploadButton.innerHTML = - `Upload ${filename.replace('-', '')}.csv`; + `Upload ${filename}.csv`; uploadButton.style.display = null; }) .catch(function(err) { From f1326d2e748d130bf8607c2e254057f093f59c78 Mon Sep 17 00:00:00 2001 From: finchiedev Date: Tue, 20 Aug 2019 21:51:05 +0800 Subject: [PATCH 10/11] Improve style of createServo.js --- App/JS/createServo.js | 118 +++++++++++++++++++++++------------------- package.json | 1 + yarn.lock | 5 ++ 3 files changed, 72 insertions(+), 52 deletions(-) diff --git a/App/JS/createServo.js b/App/JS/createServo.js index 2bc28c7..f8f334d 100644 --- a/App/JS/createServo.js +++ b/App/JS/createServo.js @@ -9,14 +9,14 @@ let filename = ''; const client = new net.Socket(); client.on('error', function(err) { - console.error('Unable to connect to the fileserver!' + '\n' + - 'Ensure that the robot is powered and active.'); -}) + console.error('Unable to connect to the fileserver!' + '\n' + + ' Ensure that the robot is powered and active.'); +}); /** * Parses the header of a given table - * @param {Array} table - * @returns {String} The header of the specified table + * @param {Array} table + * @return {String} The header of the specified table */ function parseDynamixelHeader(table) { let build = ''; @@ -36,7 +36,7 @@ function parseDynamixelHeader(table) { * @param {Object} table The table returned when executing parsetable * @param {Boolean} includeHeader If the CSV should include headings - use * false if this is not the top item in the table - * @returns {String} A string of CSV data with the control table + * @return {String} A string of CSV data with the control table */ function parseDynamixelTable(table) { let build = ''; @@ -54,72 +54,86 @@ function parseDynamixelTable(table) { return build; } +/** + * Computes all HTML tables from indexes and converts to CSV + * @param {String} html The downloaded e-Manual document as HTML + * @param {Array} indexes The indexes of all tables involving the control table + * @return {String} The CSV-formatted table containing all of the control table + */ function generateCSV(html, indexes) { if (indexes == null || indexes == undefined || indexes.length == 0) { - console.error('Invalid argument!' + + console.error('Invalid argument!' + 'Ensure that the argument "indexes" is valid!'); return ''; } - + let fileData = ''; const $ = cheerio.load(html); cheerioTableparser($); const cheerioTable = $('table'); - + fileData += parseDynamixelHeader(cheerioTable.eq( - indexes[0]).parsetable(true, true, true)); - for (var i = 0; i < indexes.length; i++) { + indexes[0]).parsetable(true, true, true)); + for (let i = 0; i < indexes.length; i++) { fileData += parseDynamixelTable(cheerioTable.eq( - indexes[i]).parsetable(true, true, true)); - } - - return fileData; + indexes[i]).parsetable(true, true, true)); } - - function getFile() { - const url = document.getElementById('url').value; - const re = /^https?:\/\/emanual\.robotis\.com\/docs\/en\/dxl\/[a-z0-9]+\/[a-z0-9]+-?[a-z0-9]+/ - const res = url.match(re) - if (res !== null && res !== undefined) { - link = res[0]; - console.log(`Extracted URL as ${link}`); - rp(link) - .then(function(html) { - console.log('Successfully downloaded the site!' + + + return fileData; +} + +/** + * Downloads and converts the link to a CSV, saving it to Resources/Servos and + * storing it in the variable fileData + */ +function getFile() { + const url = document.getElementById('url').value; + const re = /^https?:\/\/emanual\.robotis\.com\/docs\/en\/dxl\/[a-z0-9]+\/[a-z0-9]+-?[a-z0-9]+/; + const res = url.match(re); + if (res !== null && res !== undefined) { + link = res[0]; + console.log(`Extracted URL as ${link}`); + rp(link) + .then(function(html) { + console.log('Successfully downloaded the site!' + ' Now scraping the data...'); - fileData = generateCSV(html, [1, 2]); - console.log('Downloaded table!'); - - const linkPieces = link.split('/'); - if (linkPieces[linkPieces.length - 1] == '') { - linkPieces.pop(linkPieces.length - 1); - } - filename = linkPieces[linkPieces.length - 1].replace('-', ''); + fileData = generateCSV(html, [1, 2]); + console.log('Downloaded table!'); - fs.writeFile(`App/JS/Resources/Servos/${filename}.csv`, fileData, function(err) { - if (err) { - console.error('Failed to write file! Do you have access?'); + const linkPieces = link.split('/'); + if (linkPieces[linkPieces.length - 1] == '') { + linkPieces.pop(linkPieces.length - 1); } - console.log(`Saved the file as ${filename}.csv`); - }); + filename = linkPieces[linkPieces.length - 1].replace('-', ''); + + fs.writeFile(`App/JS/Resources/Servos/${filename}.csv`, + fileData, function(err) { + if (err) { + console.error('Failed to write file! Do you have access?'); + } + console.log(`Saved the file as ${filename}.csv`); + }); - uploadButton = document.getElementById('upload') - uploadButton.innerHTML = + uploadButton = document.getElementById('upload'); + uploadButton.innerHTML = `Upload ${filename}.csv`; - uploadButton.style.display = null; - }) - .catch(function(err) { - console.error('An error has occured!' + '\n' + + uploadButton.style.display = null; + }) + .catch(function(err) { + console.error('An error has occured!' + '\n' + 'Check that you have an active internet connection' + '\n' + 'Additionally, check that you are able to access sites' + '\n' + 'This may be due to you being connected to the robot' + '\n' + `Recieved error: \n${err}`); - }); + }); } else { console.error('It seems that your URL is invalid!'); - } + } } +/** + * Uploads the data stored in fileData through TCP to a listening fileserver + */ function uploadFile() { if (fileData == null || fileData == undefined || fileData == '') { console.error('There is no downloaded file!'); @@ -128,13 +142,13 @@ function uploadFile() { client.connect({ port: 5004, - address: '127.0.0.1' + address: '127.0.0.1', }); - + client.on('connect', function() { client.write(`${filename}\n${fileData}`); console.log('Wrote file to server!'); - }) - + }); + console.log('Uploaded table!'); -} \ No newline at end of file +} diff --git a/package.json b/package.json index bad0f3a..9f73409 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "cheerio": "^1.0.0-rc.3", "cheerio-tableparser": "^1.0.1", "electron": "^6.0.2", + "eslint-config-google": "^0.13.0", "request-promise": "^4.2.4" } } diff --git a/yarn.lock b/yarn.lock index bfe06a3..6240caf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -304,6 +304,11 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" +eslint-config-google@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/eslint-config-google/-/eslint-config-google-0.13.0.tgz#e277d16d2cb25c1ffd3fd13fb0035ad7421382fe" + integrity sha512-ELgMdOIpn0CFdsQS+FuxO+Ttu4p+aLaXHv9wA9yVnzqlUGV7oN/eRRnJekk7TCur6Cu2FXX0fqfIXRBaM14lpQ== + extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" From a479dc17dc7176f8296e75e482b3366850d543ca Mon Sep 17 00:00:00 2001 From: finchiedev Date: Tue, 20 Aug 2019 21:51:58 +0800 Subject: [PATCH 11/11] Improve style of fileServer.js --- Server/fileServer.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Server/fileServer.js b/Server/fileServer.js index c19558f..419a3f8 100644 --- a/Server/fileServer.js +++ b/Server/fileServer.js @@ -1,6 +1,6 @@ const fs = require('fs'); const net = require('net'); -let server = net.createServer() +const server = net.createServer(); server.on('connection', function(socket) { socket.on('data', function(data) { @@ -15,7 +15,7 @@ server.on('connection', function(socket) { } console.log(`Saved the file as ${filename}.csv`); }); - }) -}) + }); +}); -server.listen(5004, ''); \ No newline at end of file +server.listen(5004, '');