How to use waitForLine method in Playwright Internal

Best JavaScript code snippet using playwright-internal

data-logger-bg96-mqtt.js

Source:data-logger-bg96-mqtt.js Github

copy

Full Screen

1/*2 Example how to send telemetry data to the Bosch IoT Suite using the Quectel BG96 modem and built-in MQTT client.3 Uses a simple Finite State Machine to introduce robustness against communication errors.4 Note: If you have chosen to upload the code to RAM (default) in the Espruino IDE, you need5 to interactively call "onInit();" on the device's JavaScript console after uploading.6 Debug output to console can be controlled via variable connection_options.debug7 Low memory is an issue!8 Use the "online minification" feature of the Espruino IDE if you run short on9 memory (e.g. "Closure (online))10 Although not completely reproduced: For standalone operation, please turn off debug output to console,11 (debug: false) as this might lead to the system freezing up.12 Copyright (C) 2019 Wolfgang Klenk <wolfgang.klenk@gmail.com>13 This program is free software: you can redistribute it and/or modify14 it under the terms of the GNU General Public License as published by15 the Free Software Foundation, either version 3 of the License, or16 (at your option) any later version.17 This program is distributed in the hope that it will be useful,18 but WITHOUT ANY WARRANTY; without even the implied warranty of19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the20 GNU General Public License for more details.21 You should have received a copy of the GNU General Public License22 along with this program. If not, see <https://www.gnu.org/licenses/>.23*/24var ENTERING_STATE = 'Entering State';25var ERROR_IN_STATE = 'Error in State';26var STATE_SETUP_EXTERNAL_HARDWARE = 'Setup External Hardware';27var STATE_CONFIGURE_MODEM = 'Configure Modem';28var STATE_REGISTER_TO_NETWORK = 'Register To Network';29var STATE_OPEN_MQTT_NETWORK = 'Open MQTT Network';30var STATE_CONNECT_TO_SERVER = 'Connect To Server';31var STATE_REQUEST_DESIRED_IL_CONFIG = 'Request desired indicator light config';32var STATE_PUBLISH_TELEMETRY_DATA = 'Publish Telemetry Data';33var STATE_SUBSCRIBE_TO_COMMANDS = "Subscribe To Commands";34var STATE_SLEEP = 'Sleep';35var STATE_RESET_MODEM = 'Reset Modem';36var STATE_POWER_DOWN = 'Power Down';37var at;38var bme280;39var errCnt = 0;40var updateCnt = 1;41var smRestartCnt = 0;42var qmtstat = 0;43var indicatorLightOn = false;44var indicatorLightReportedVersion = -1;45var indicatorLightDesiredVersion = 0;46var msgId = 1; // Increase msgId each time a message with QoS=1 is sent47var sm = require("StateMachine").FSM();48// NB1 connectivity settings for 1NCE49/*50var connection_options = {51 band: "B8",52 apn: "iot.1nce.net",53 operator: "26201",54 debug: false55};56*/57// NB1 connectivity settings for Vodafone Germany58var connection_options = {59 band: "B20",60 apn: "vgesace.nb.iot",61 operator: "26202",62 debug: true // Print communication with BG96 module to console.63};64// Use MQTT adapter of Bosch IoT Suite Hub65var mqtt_options = {66 server: 'mqtt.bosch-iot-hub.com',67 port: 8883,68 username: 'my.name.space_myDeviceId', // value returned from device provisioning69 hubTenantId: 'my-hub-tenant-id',70 password: 'my-device-secret'71};72var band_values = {73 "B1": "1",74 "B2": "2",75 "B3": "4",76 "B4": "8",77 "B5": "10",78 "B8": "80",79 "B12": "800",80 "B13": "1000",81 "B18": "20000",82 "B19": "40000",83 "B20": "80000",84 "B26": "2000000",85 "B28": "8000000"86};87sendAtCommand = function (command, timeoutMs, waitForLine) {88 return new Promise((resolve, reject) => {89 var answer = "";90 at.cmd(command + "\r\n", timeoutMs || 1E3, function processResponse(response) {91 if (undefined === response || "ERROR" === response || response.startsWith("+CME ERROR")) {92 reject(response ? (command + ": " + response) : (command + ": TIMEOUT"));93 } else if (waitForLine ? (response.startsWith(waitForLine)) : ("OK" === response)) {94 resolve(waitForLine ? response : answer);95 } else {96 answer += (answer ? "\n" : "") + response;97 return processResponse;98 }99 });100 });101};102sendAtCommandAndWaitForPrompt = function (command, timeoutMs, sendLineAfterPrompt, waitForLine) {103 return new Promise((resolve, reject) => {104 var prompt = '> ';105 var answer = "";106 if (sendLineAfterPrompt) {107 at.register(prompt, (line) => {108 at.unregister(prompt);109 at.write(sendLineAfterPrompt + '\x1A');110 return line.substr(2);111 });112 }113 at.cmd(command + "\r\n", timeoutMs, function processResponse(response) {114 if (undefined === response || "ERROR" === response || response.startsWith("+CME ERROR")) {115 // Unregister the prompt '> ' in case something went wrong.116 // If we don't, we get follow up errors when it is tried to again register the prompt.117 at.unregister(prompt);118 reject(response ? (command + ": " + response) : (command + ": TIMEOUT"));119 } else if (waitForLine ? (response.startsWith(waitForLine)) : ("OK" === response)) {120 resolve(waitForLine ? response : answer);121 } else {122 answer += (answer ? "\n" : "") + response;123 return processResponse;124 }125 });126 });127};128// Switch LED on/off129function controlLed(desiredIndicatorLightMode) {130 if (desiredIndicatorLightMode === 'off') {131 digitalWrite(LED1, false);132 indicatorLightOn = false;133 } else if (desiredIndicatorLightMode === 'on') {134 digitalWrite(LED1, true);135 indicatorLightOn = true;136 }137}138//139// Finite State Machine: States140//141// Setup external hardware.142function e_SetupExternalHardware() {143 if (connection_options.debug) console.log(ENTERING_STATE, STATE_SETUP_EXTERNAL_HARDWARE);144 return new Promise((resolve, reject) => {145 require("iTracker").setCellOn(true, (usart) => {146 resolve(usart);147 });148 })149 .then((usart) => {150 if (connection_options.debug) console.log("External modules connected.");151 at = require("AT").connect(usart);152 if (connection_options.debug) {153 at.debug(true);154 }155 return new Promise((resolve, reject) => {156 bme280 = require("iTracker").setEnvOn(true, () => {157 if (connection_options.debug) console.log("BME280 wiring set up.");158 resolve();159 });160 });161 })162 .then(() => {163 sm.signal('ok');164 })165 .catch((err) => {166 if (connection_options.debug) console.log(ERROR_IN_STATE, STATE_SETUP_EXTERNAL_HARDWARE, err);167 sm.signal('fail');168 });169}170// Configure BG96 module and MQTT software stack171function e_ConfigureModem() {172 if (connection_options.debug) console.log(ENTERING_STATE, STATE_CONFIGURE_MODEM);173 sendAtCommand('AT&F0')174 .then(() => sendAtCommand('ATE0'))175 .then(() => sendAtCommand('AT+CPIN?')) // Fails on locked PIN176 .then(() => {177 var band_value = band_values[connection_options.band];178 if (undefined === band_value) throw ("Unknown band: " + connection_options.band);179 return sendAtCommand('AT+QCFG="band",0,0,' + band_value + ',1');180 })181 .then(() => sendAtCommand('AT+QCFG="nwscanmode",3,1')) // Network Search Mode, LTE only182 .then(() => sendAtCommand('AT+QCFG="nwscanseq",030102,1')) // Network Search Sequence, NB-Iot, GSM, CatM1183 .then(() => sendAtCommand('AT+QCFG="iotopmode",1,1')) // LTE Search Mode: NB-IoT only184 .then(() => sendAtCommand('AT+QCFG="servicedomain",1,1')) // Set PS domain, PS only185 .then(() => sendAtCommand('AT+CGDCONT=1,"IP",' + JSON.stringify(connection_options.apn)))186 .then(() => sendAtCommand('AT+CFUN=1'))187 // Send keepalive message every 30 seconds188 .then(() => sendAtCommand('AT+QMTCFG="keepalive",0,30'))189 // SSL: Configure MQTT session into SSL mode190 .then(() => sendAtCommand('AT+QMTCFG="SSL",0,1,0'))191 .then(() => sendAtCommand('AT+QSSLCFG="sslversion",0,3')) // Require TLS 1.2192 // SSL: Configure trusted CA certificate193 // .then(() => sendAtCommand('AT+QSSLCFG="cacert",2,"cacert.pem"'))194 // SSL: Configure client certificate195 //.then(() => sendAtCommand('AT+QSSLCFG="clientcert",2,"cert.pem"'))196 // SSL: Configure private key197 //.then(() => sendAtCommand('AT+QSSLCFG="clientkey",2,"key.pem"'))198 // SSL: Authentication mode: Server and client authentication199 // .then(() => sendAtCommand('AT+QSSLCFG="seclevel",2,0')) // 0 = Neither server nor client authentication200 // SSL: Authentication version. Accept all SSL versions201 // .then(() => sendAtCommand('AT+QSSLCFG="sslversion",2,4')) // Support all SSL versions202 // SSL: Cipher suite: Support all cipher suites203 // .then(() => sendAtCommand('AT+QSSLCFG="ciphersuite",2,0xFFFF')) // Support all Ciphersuites204 // SSL: Ignore the time of authentication.205 .then(() => sendAtCommand('AT+QSSLCFG="ignorelocaltime",1'))206 .then(() => {207 sm.signal('ok');208 })209 .catch((err) => {210 if (connection_options.debug) console.log(ERROR_IN_STATE, STATE_CONFIGURE_MODEM, err);211 sm.signal('fail');212 });213}214// Register to network215function e_RegisterToNetwork() {216 if (connection_options.debug) console.log(ENTERING_STATE, STATE_REGISTER_TO_NETWORK);217 // Manually register to network.218 // Modem LED should flash on-off-off-off periodically to indicate network search219 sendAtCommand('AT+COPS=1,2,' + JSON.stringify(connection_options.operator) + ',9', 1800000)220 .then(() => {221 sm.signal('ok');222 })223 .catch((err) => {224 if (connection_options.debug) console.log('Error in state', STATE_REGISTER_TO_NETWORK, err);225 sm.signal('fail');226 });227}228// Open a network for MQTT client229function e_OpenMQTTNetwork() {230 if (connection_options.debug) console.log(ENTERING_STATE, STATE_OPEN_MQTT_NETWORK);231 sendAtCommand(232 'AT+QMTOPEN=0,' + JSON.stringify(mqtt_options.server) + ',' + mqtt_options.port,233 30000,234 '+QMTOPEN:')235 .then((line) => {236 if (connection_options.debug) console.log("+QMTOPEN line:", line);237 var qmtstat = '+QMTSTAT: ';238 at.unregisterLine(qmtstat);239 at.registerLine(qmtstat, (line) => {240 line = line.split(",");241 qmtstat = parseInt(line[1]);242 if (connection_options.debug) console.log("+QMTSTAT Error Code:", qmtstat);243 });244 sm.signal('ok');245 })246 .catch((err) => {247 if (connection_options.debug) console.log(ERROR_IN_STATE, STATE_OPEN_MQTT_NETWORK, err);248 sm.signal('fail');249 });250}251// Connect this client to MQTT server252function e_ConnectToServer() {253 if (connection_options.debug) console.log(ENTERING_STATE, STATE_CONNECT_TO_SERVER);254 sendAtCommand('AT+QMTCONN=0,' +255 JSON.stringify('some-client-id') +256 ',' +257 JSON.stringify(mqtt_options.username +258 '@' +259 mqtt_options.hubTenantId) +260 ',' +261 JSON.stringify(mqtt_options.password),262 15000,263 '+QMTCONN:')264 .then((line) => {265 if (connection_options.debug) console.log("+QMTCONN line:", line);266 sm.signal('ok');267 })268 .catch((err) => {269 if (connection_options.debug) console.log(ERROR_IN_STATE, STATE_CONNECT_TO_SERVER, err);270 sm.signal('fail');271 });272}273// Subscribe to the command channel of the Hub.274function e_SubscribeToCommands() {275 if (connection_options.debug) console.log(ENTERING_STATE, STATE_SUBSCRIBE_TO_COMMANDS);276 // Handler for incoming commands from the Hub277 var qmtrecv = '+QMTRECV: ';278 at.unregisterLine(qmtrecv);279 at.registerLine(qmtrecv, (line) => {280 // This callback is called whenever a line starting with "+QMTRECV:" is detected. A "line" means281 // a number of characters until a "\r" character is received. But this means, this WON'T WORK if the282 // payload itself contains a "\r" character. Keep that in mind.283 var openingBrace = line.indexOf('{');284 var payloadJson = JSON.parse(line.substr(openingBrace));285 if (connection_options.debug) console.log('Incoming Ditto message:', payloadJson);286 if (payloadJson.path === '/features/indicatorLight@desired/properties') {287 indicatorLightDesiredVersion = payloadJson.value.config.version;288 controlLed(payloadJson.value.config.mode);289 } else if (payloadJson.path === '/features/indicatorLight@desired/properties/config') {290 indicatorLightDesiredVersion = payloadJson.value.version;291 controlLed(payloadJson.value.mode);292 }293 });294 // Subscribe to incoming command messages from the Hub295 sendAtCommand('AT+QMTSUB=0,1,' +296 JSON.stringify("command/+/+/req/#") +297 ',1',298 15000,299 '+QMTSUB:')300 .then((line) => {301 if (connection_options.debug) console.log("+QMTSUB line:", line);302 // Wait 5 seconds in order to let the backend establish the connection to the device.303 return new Promise((resolve, reject) => {304 setTimeout(() => {305 resolve();306 }, 5000);307 });308 })309 .then((line) => {310 sm.signal('ok');311 })312 .catch((err) => {313 if (connection_options.debug) console.log(ERROR_IN_STATE, STATE_SUBSCRIBE_TO_COMMANDS, err);314 sm.signal('fail');315 });316}317// Publish telemetry data via MQTT318function e_PublishTelemetryData() {319 if (connection_options.debug) console.log(ENTERING_STATE, STATE_PUBLISH_TELEMETRY_DATA);320 var currentEnvironmentData = bme280.getData();321 var indicatorLightModeString = '"off"';322 if (indicatorLightOn === true) {323 indicatorLightModeString = '"on"';324 }325 // TODO: This actually only needs to be sent if desiredVersion != reportedVersion326 // Eclipse Ditto modify command for feature "indicatorLight"327 sendAtCommandAndWaitForPrompt('AT+QMTPUB=0,' + (msgId++) + ',1,0,' + // QoS = 1328 JSON.stringify("event"),329 5000,330 '{' +331 ' "topic": "org.klenk.connectivity.iot/rak8212/things/twin/commands/modify",' +332 ' "headers": {},' +333 ' "path": "/features/indicatorLight/properties",' +334 ' "value": {' +335 ' "config": {' +336 ' "version": ' + indicatorLightDesiredVersion + ',' +337 ' "mode": ' + indicatorLightModeString +338 ' }' +339 ' }' +340 '}',341 '+QMTPUB:'342 )343 .then((line) => {344 indicatorLightReportedVersion = indicatorLightDesiredVersion;345 // Eclipse Ditto modify command for feature "temperature"346 return sendAtCommandAndWaitForPrompt('AT+QMTPUB=0,0,0,0,' + // QoS = 0347 JSON.stringify("telemetry"),348 5000,349 '{' +350 ' "topic": "org.klenk.connectivity.iot/rak8212/things/twin/commands/modify",' +351 ' "headers": {},' +352 ' "path": "/features/temperature/properties",' +353 ' "value": {' +354 ' "status": {' +355 ' "value": ' + currentEnvironmentData.temp.toFixed(2) + ',' +356 ' "unit": "Degree Celsius"' +357 ' }' +358 ' }' +359 '}',360 '+QMTPUB:'361 );362 })363 .then((line) => {364 if (connection_options.debug) console.log("+QMTPUB line:", line);365 // Eclipse Ditto modify command for feature "humidity"366 return sendAtCommandAndWaitForPrompt('AT+QMTPUB=0,0,0,0,' + // QoS = 0367 JSON.stringify("telemetry"),368 5000,369 '{' +370 ' "topic": "org.klenk.connectivity.iot/rak8212/things/twin/commands/modify",' +371 ' "headers": {},' +372 ' "path": "/features/humidity/properties",' +373 ' "value": {' +374 ' "status": {' +375 ' "currentMeasured": ' + currentEnvironmentData.humidity.toFixed(2) +376 ' }' +377 ' }' +378 '}',379 '+QMTPUB:'380 );381 })382 .then((line) => {383 if (connection_options.debug) console.log("+QMTPUB line:", line);384 // Eclipse Ditto modify command for feature "barometricPressure"385 return sendAtCommandAndWaitForPrompt('AT+QMTPUB=0,0,0,0,' + // QoS = 0386 JSON.stringify("telemetry"),387 5000,388 '{' +389 ' "topic": "org.klenk.connectivity.iot/rak8212/things/twin/commands/modify",' +390 ' "headers": {},' +391 ' "path": "/features/barometricPressure/properties",' +392 ' "value": {' +393 ' "status": {' +394 ' "currentMeasured": ' + currentEnvironmentData.pressure.toFixed(2) +395 ' }' +396 ' }' +397 '}',398 '+QMTPUB:'399 );400 })401 .then((line) => {402 if (connection_options.debug) console.log("+QMTPUB line:", line);403 // Query the current bytes sent and received404 return sendAtCommand('AT+QGDCNT?', 1000, '+QGDCNT:');405 })406 .then((line) => {407 if (connection_options.debug) console.log("+QGDCNT line:", line);408 // Example: "+QGDCNT: 3708,5910"409 line = (line.split(':'))[1].split(',');410 // Eclipse Ditto modify command for feature "networkTraffic"411 return sendAtCommandAndWaitForPrompt('AT+QMTPUB=0,0,0,0,' + // QoS = 0412 JSON.stringify("telemetry"),413 5000,414 '{' +415 ' "topic": "org.klenk.connectivity.iot/rak8212/things/twin/commands/modify",' +416 ' "headers": {},' +417 ' "path": "/features/networkTraffic/properties",' +418 ' "value": {' +419 ' "totalBytesSent": ' + parseInt(line[0]) + ',' +420 ' "totalBytesReceived": ' + parseInt(line[1]) +421 ' }' +422 '}',423 '+QMTPUB:'424 );425 })426 .then((line) => {427 if (connection_options.debug) console.log("+QMTPUB line:", line);428 sm.signal('ok');429 })430 .catch((err) => {431 if (connection_options.debug) console.log(ERROR_IN_STATE, STATE_PUBLISH_TELEMETRY_DATA, err);432 sm.signal('fail');433 });434}435// Request feature "indicatorLight@desired" from Digital Twin436function e_RequestDesiredIndicatorLightConfig() {437 if (connection_options.debug) console.log(ENTERING_STATE, STATE_REQUEST_DESIRED_IL_CONFIG);438 return sendAtCommandAndWaitForPrompt('AT+QMTPUB=0,' + (msgId++) + ',1,0,' + // QoS = 1439 JSON.stringify("event"),440 5000,441 '{' +442 ' "topic": "org.klenk.connectivity.iot/rak8212/things/twin/commands/retrieve",' +443 ' "headers": {},' +444 ' "path": "/features/indicatorLight@desired/properties",' +445 ' "value": {}' +446 '}',447 '+QMTPUB:'448 )449 .then((line) => {450 if (connection_options.debug) console.log("+QMTPUB line:", line);451 // Wait 5 seconds in order to let the backend process the request before continuing452 return new Promise((resolve, reject) => {453 setTimeout(() => {454 resolve();455 }, 5000);456 });457 })458 .then((line) => {459 sm.signal('ok');460 })461 .catch((err) => {462 if (connection_options.debug) console.log(ERROR_IN_STATE, STATE_REQUEST_DESIRED_IL_CONFIG, err);463 sm.signal('fail');464 });465}466function e_Sleep(result) {467 if (connection_options.debug) console.log(ENTERING_STATE, STATE_SLEEP);468 return new Promise((resolve, reject) => {469 setTimeout(() => {470 resolve();471 }, 300000);472 })473 .then(() => {474 sm.signal('ok');475 });476}477function e_ResetModem(result) {478 if (connection_options.debug) console.log(ENTERING_STATE, STATE_RESET_MODEM);479 sendAtCommand('AT+QPOWD', 10000, 'POWERED DOWN')480 .then(() => {481 return new Promise((resolve, reject) => {482 setTimeout(() => {483 resolve();484 }, 10000);485 });486 })487 .then(() => {488 if (connection_options.debug) console.log('Powered down');489 sm.signal('ok');490 })491 .catch((err) => {492 if (connection_options.debug) console.log(ERROR_IN_STATE, STATE_RESET_MODEM, err);493 sm.signal('ok');494 });495}496//497// Finite State Machine: Transitions498//499function t_SetupExternalHardware(result) {500 return { state: STATE_CONFIGURE_MODEM };501}502function t_ConfigureModem(result) {503 return { state: STATE_REGISTER_TO_NETWORK };504}505function t_RegisterToNetwork(result) {506 switch (result) {507 case ('ok'):508 return { state: STATE_OPEN_MQTT_NETWORK };509 default:510 return { state: STATE_RESET_MODEM };511 }512}513function t_OpenMQTTNetwork(result) {514 if (qmtstat > 0) {515 return { state: STATE_RESET_MODEM };516 }517 switch (result) {518 case ('ok'):519 return { state: STATE_CONNECT_TO_SERVER };520 default:521 return { state: STATE_RESET_MODEM };522 }523}524function t_ConnectToServer(result) {525 if (qmtstat > 0) {526 return { state: STATE_RESET_MODEM };527 }528 switch (result) {529 case ('ok'):530 return { state: STATE_SUBSCRIBE_TO_COMMANDS };531 default:532 return { state: STATE_RESET_MODEM };533 }534}535function t_SubscribeToCommands(result) {536 if (qmtstat > 0) {537 return { state: STATE_RESET_MODEM };538 }539 switch (result) {540 case ('ok'):541 return { state: STATE_REQUEST_DESIRED_IL_CONFIG };542 default:543 return { state: STATE_RESET_MODEM };544 }545}546function t_PublishTelemetryData(result) {547 if (qmtstat > 0) {548 return { state: STATE_RESET_MODEM };549 }550 switch (result) {551 case ('ok'):552 errCnt = 0; // Reset error counter553 updateCnt++;554 return { state: STATE_SLEEP };555 default:556 errCnt++;557 if (errCnt >= 3) {558 errCnt = 0;559 return { state: STATE_RESET_MODEM };560 }561 else {562 return { state: STATE_SLEEP };563 }564 }565}566function t_RequestDesiredIndicatorLightConfig(result) {567 if (qmtstat > 0) {568 return { state: STATE_RESET_MODEM };569 }570 switch (result) {571 case ('ok'):572 return { state: STATE_PUBLISH_TELEMETRY_DATA };573 default:574 return { state: STATE_RESET_MODEM };575 }576}577function t_Sleep(result) {578 if (qmtstat > 0) {579 return { state: STATE_RESET_MODEM };580 }581 return { state: STATE_PUBLISH_TELEMETRY_DATA };582}583function t_ResetModem(result) {584 return { state: STATE_POWER_DOWN };585}586function onInit() {587 Bluetooth.setConsole(true); // Don't want to have console on "Serial1" that is used for modem.588 sm.define({ name: STATE_SETUP_EXTERNAL_HARDWARE, enter: e_SetupExternalHardware, signal: t_SetupExternalHardware });589 sm.define({ name: STATE_CONFIGURE_MODEM, enter: e_ConfigureModem, signal: t_ConfigureModem });590 sm.define({ name: STATE_REGISTER_TO_NETWORK, enter: e_RegisterToNetwork, signal: t_RegisterToNetwork });591 sm.define({ name: STATE_OPEN_MQTT_NETWORK, enter: e_OpenMQTTNetwork, signal: t_OpenMQTTNetwork });592 sm.define({ name: STATE_CONNECT_TO_SERVER, enter: e_ConnectToServer, signal: t_ConnectToServer });593 sm.define({ name: STATE_REQUEST_DESIRED_IL_CONFIG, enter: e_RequestDesiredIndicatorLightConfig, signal: t_RequestDesiredIndicatorLightConfig });594 sm.define({ name: STATE_SUBSCRIBE_TO_COMMANDS, enter: e_SubscribeToCommands, signal: t_SubscribeToCommands });595 sm.define({ name: STATE_PUBLISH_TELEMETRY_DATA, enter: e_PublishTelemetryData, signal: t_PublishTelemetryData });596 sm.define({ name: STATE_SLEEP, enter: e_Sleep, signal: t_Sleep });597 sm.define({ name: STATE_RESET_MODEM, enter: e_ResetModem, signal: t_ResetModem });598 sm.define({ name: STATE_POWER_DOWN });599 sm.init(STATE_SETUP_EXTERNAL_HARDWARE);600 // If the state machine is in state "Power Down", then restart the state machine.601 setInterval(() => {602 if (connection_options.debug) console.log("Checking state machine state");603 if (sm.state === STATE_POWER_DOWN) {604 if (connection_options.debug) console.log('Restarting State Machine');605 smRestartCnt++;606 sm.init(STATE_SETUP_EXTERNAL_HARDWARE);607 }608 }, 600000);...

Full Screen

Full Screen

data-logger-device-setup.js

Source:data-logger-device-setup.js Github

copy

Full Screen

...214 'AT+QHTTPGET=60,' + headers.length,215 60000,216 headers);217 })218 .then(() => waitForLine('+QHTTPGET'))219 .then((line) => {220 console.log('+QHTTPGET response line:', line);221 // Returns something like "+QHTTPGET: 0,404,0"222 var responseValues = line.substr(10).split(',');223 var errorCode = parseInt(responseValues[0], 10);224 var httpResponseCode = parseInt(responseValues[1], 10);225 var contentLength = parseInt(responseValues[2], 10);226 console.log('Error code:', errorCode, 'HTTP response code:', httpResponseCode, 'Content length:', contentLength);227 if (contentLength > 0) {228 return sendAtCommand('AT+QHTTPREAD=80');229 } else {230 return httpResponseCode;231 }232 });233}234// HTTP POST Request on /registration/{tenant-id}235function postDeviceRegistration() {236 // Set URL of resource to request.237 var urlRegistration = binding_credentials["device-registry"]["registration-endpoint"];238 console.log('Registration URL:', urlRegistration);239 return sendAtCommandAndWaitForConnect('AT+QHTTPURL=' + urlRegistration.length, 10000, urlRegistration)240 // Send HTTP POST request.241 .then(() => {242 var body = '{ "device-id": "' + deviceId + '", "enabled": true }';243 var urlParts = url.parse(urlRegistration);244 var headers = 'POST ' + urlParts.path + ' HTTP/1.1'245 + '\r\n'246 + 'Host: ' + urlParts.host247 + '\r\n'248 + 'Authorization: Basic '249 + btoa(binding_credentials["device-registry"]["username"] + ":" + binding_credentials["device-registry"]["password"])250 + '\r\n'251 + 'Accept: application/json'252 + '\r\n'253 + 'Content-Type: application/json'254 + '\r\n'255 + 'Content-Length: ' + body.length256 + '\r\n'257 + 'User-Agent: Quectel BG96 module on RAK8212'258 + '\r\n'259 + '\r\n'; // Additional empty line to mark end of headers260 console.log('now sending post request', headers);261 return sendAtCommandAndWaitForConnect(262 'AT+QHTTPPOST=' + (headers.length + body.length),263 60000,264 headers + body);265 })266 .then(() => waitForLine('+QHTTPPOST'))267 .then((line) => {268 console.log('+QHTTPPOST response line:', line);269 // Returns something like "+QHTTPPOST: 0,201,0"270 var responseValues = line.substr(11).split(',');271 var errorCode = parseInt(responseValues[0], 10);272 var httpResponseCode = parseInt(responseValues[1], 10);273 var contentLength = parseInt(responseValues[2], 10);274 console.log('Error code:', errorCode, 'HTTP response code:', httpResponseCode, 'Content length:', contentLength);275 if (contentLength > 0) {276 return sendAtCommand('AT+QHTTPREAD=80');277 } else {278 return httpResponseCode;279 }280 });281}282// HTTP DELETE Request on /registration/{tenant-id}/{device-id}283function deleteDeviceRegistration() {284 // Set URL of resource to request.285 var urlRegistration = binding_credentials["device-registry"]["registration-endpoint"] + '/' + deviceId;286 console.log('Registration URL:', urlRegistration);287 return sendAtCommandAndWaitForConnect('AT+QHTTPURL=' + urlRegistration.length, 10000, urlRegistration)288 // Send HTTP DELETE request.289 .then(() => {290 var urlParts = url.parse(urlRegistration);291 var headers = 'DELETE ' + urlParts.path + ' HTTP/1.1'292 + '\r\n'293 + 'Host: ' + urlParts.host294 + '\r\n'295 + 'Authorization: Basic '296 + btoa(binding_credentials["device-registry"]["username"] + ":" + binding_credentials["device-registry"]["password"])297 + '\r\n'298 + 'Accept: application/json'299 + '\r\n'300 + 'User-Agent: Quectel BG96 module on RAK8212'301 + '\r\n'302 + '\r\n'; // Additional empty line to mark end of headers303 return sendAtCommandAndWaitForConnect(304 'AT+QHTTPGET=60,' + headers.length,305 60000,306 headers);307 })308 .then(() => waitForLine('+QHTTPGET'))309 .then((line) => {310 console.log('+QHTTPGET response line:', line);311 // Returns something like "+QHTTPGET: 0,404,0"312 var responseValues = line.substr(10).split(',');313 var errorCode = parseInt(responseValues[0], 10);314 var httpResponseCode = parseInt(responseValues[1], 10);315 var contentLength = parseInt(responseValues[2], 10);316 console.log('Error code:', errorCode, 'HTTP response code:', httpResponseCode, 'Content length:', contentLength);317 if (contentLength > 0) {318 return sendAtCommand('AT+QHTTPREAD=80');319 } else {320 return httpResponseCode;321 }322 });323}324// HTTP GET Request on /credentials/{tenant-id}325// Let auth-id be the same as device-id326function getDeviceCredentials() {327 // Set URL of resource to request.328 var urlCredentials = binding_credentials["device-registry"]["credentials-endpoint"]329 + '?auth-id=' + deviceId + '&type=hashed-password';330 console.log('Credentials URL:', urlCredentials);331 return sendAtCommandAndWaitForConnect('AT+QHTTPURL=' + urlCredentials.length, 10000, urlCredentials)332 // Send HTTP GET request.333 .then(() => {334 var urlParts = url.parse(urlCredentials);335 var headers = 'GET ' + urlParts.path + ' HTTP/1.1'336 + '\r\n'337 + 'Host: ' + urlParts.host338 + '\r\n'339 + 'Authorization: Basic '340 + btoa(binding_credentials["device-registry"]["username"] + ":" + binding_credentials["device-registry"]["password"])341 + '\r\n'342 + 'Accept: application/json'343 + '\r\n'344 + 'User-Agent: Quectel BG96 module on RAK8212'345 + '\r\n'346 + '\r\n'; // Additional empty line to mark end of headers347 return sendAtCommandAndWaitForConnect(348 'AT+QHTTPGET=60,' + headers.length,349 60000,350 headers);351 })352 .then(() => waitForLine('+QHTTPGET'))353 .then((line) => {354 console.log('+QHTTPGET response line:', line);355 // Returns something like "+QHTTPGET: 0,404,0"356 var responseValues = line.substr(10).split(',');357 var errorCode = parseInt(responseValues[0], 10);358 var httpResponseCode = parseInt(responseValues[1], 10);359 var contentLength = parseInt(responseValues[2], 10);360 console.log('Error code:', errorCode, 'HTTP response code:', httpResponseCode, 'Content length:', contentLength);361 if (contentLength > 0) {362 return sendAtCommand('AT+QHTTPREAD=80');363 } else {364 return httpResponseCode;365 }366 });367}368// HTTP POST Request on /credentials/{tenant-id}369// Let auth-id be the same as device-id370function postDeviceCredentials() {371 // Set URL of resource to request.372 var urlCredentials = binding_credentials["device-registry"]["credentials-endpoint"];373 console.log('Registration URL:', urlCredentials);374 return sendAtCommandAndWaitForConnect('AT+QHTTPURL=' + urlCredentials.length, 10000, urlCredentials)375 // Send HTTP POST request.376 .then(() => {377 var body = '{'378 + '"device-id": "' + deviceId + '",'379 + '"type": "hashed-password",'380 + '"auth-id": "' + deviceId + '",'381 + '"enabled": true,'382 + '"secrets": ['383 + '{'384 + ' "password": "secret"' // Password is "secret"385 + '}'386 + ']'387 + '}';388 var urlParts = url.parse(urlCredentials);389 var headers = 'POST ' + urlParts.path + ' HTTP/1.1'390 + '\r\n'391 + 'Host: ' + urlParts.host392 + '\r\n'393 + 'Authorization: Basic '394 + btoa(binding_credentials["device-registry"]["username"] + ":" + binding_credentials["device-registry"]["password"])395 + '\r\n'396 + 'Accept: application/json'397 + '\r\n'398 + 'Content-Type: application/json'399 + '\r\n'400 + 'Content-Length: ' + body.length401 + '\r\n'402 + 'User-Agent: Quectel BG96 module on RAK8212'403 + '\r\n'404 + '\r\n'; // Additional empty line to mark end of headers405 console.log('now sending post request', headers);406 return sendAtCommandAndWaitForConnect(407 'AT+QHTTPPOST=' + (headers.length + body.length),408 60000,409 headers + body);410 })411 .then(() => waitForLine('+QHTTPPOST'))412 .then((line) => {413 console.log('+QHTTPPOST response line:', line);414 // Returns something like "+QHTTPPOST: 0,201,0"415 var responseValues = line.substr(11).split(',');416 var errorCode = parseInt(responseValues[0], 10);417 var httpResponseCode = parseInt(responseValues[1], 10);418 var contentLength = parseInt(responseValues[2], 10);419 console.log('Error code:', errorCode, 'HTTP response code:', httpResponseCode, 'Content length:', contentLength);420 if (contentLength > 0) {421 return sendAtCommand('AT+QHTTPREAD=80');422 } else {423 return httpResponseCode;424 }425 });426}427// HTTP DELETE Request on /credentials/{tenant-id}428// Let auth-id be the same as device-id429function deleteDeviceCredentials() {430 // Set URL of resource to request.431 var urlCredentials = binding_credentials["device-registry"]["credentials-endpoint"]432 + '?auth-id=' + deviceId + '&type=hashed-password';433 console.log('Credentials URL:', urlCredentials);434 return sendAtCommandAndWaitForConnect('AT+QHTTPURL=' + urlCredentials.length, 10000, urlCredentials)435 // Send HTTP DELETE request.436 .then(() => {437 var urlParts = url.parse(urlCredentials);438 var headers = 'DELETE ' + urlParts.path + ' HTTP/1.1'439 + '\r\n'440 + 'Host: ' + urlParts.host441 + '\r\n'442 + 'Authorization: Basic '443 + btoa(binding_credentials["device-registry"]["username"] + ":" + binding_credentials["device-registry"]["password"])444 + '\r\n'445 + 'Accept: application/json'446 + '\r\n'447 + 'User-Agent: Quectel BG96 module on RAK8212'448 + '\r\n'449 + '\r\n'; // Additional empty line to mark end of headers450 return sendAtCommandAndWaitForConnect(451 'AT+QHTTPGET=60,' + headers.length,452 60000,453 headers);454 })455 .then(() => waitForLine('+QHTTPGET'))456 .then((line) => {457 console.log('+QHTTPGET response line:', line);458 // Returns something like "+QHTTPGET: 0,404,0"459 var responseValues = line.substr(10).split(',');460 var errorCode = parseInt(responseValues[0], 10);461 var httpResponseCode = parseInt(responseValues[1], 10);462 var contentLength = parseInt(responseValues[2], 10);463 console.log('Error code:', errorCode, 'HTTP response code:', httpResponseCode, 'Content length:', contentLength);464 if (contentLength > 0) {465 return sendAtCommand('AT+QHTTPREAD=80');466 } else {467 return httpResponseCode;468 }469 });...

Full Screen

Full Screen

electron.js

Source:electron.js Github

copy

Full Screen

...167 handleSIGHUP: true,168 onExit: () => {}169 });170 const waitForXserverError = new Promise(async (resolve, reject) => {171 waitForLine(progress, launchedProcess, /Unable to open X display/).then(() => reject(new Error(['Unable to open X display!', `================================`, 'Most likely this is because there is no X server available.', "Use 'xvfb-run' on Linux to launch your tests with an emulated display server.", "For example: 'xvfb-run npm run test:e2e'", `================================`, progress.metadata.log].join('\n')))).catch(() => {});172 });173 const nodeMatch = await waitForLine(progress, launchedProcess, /^Debugger listening on (ws:\/\/.*)$/);174 const nodeTransport = await _transport.WebSocketTransport.connect(progress, nodeMatch[1]);175 const nodeConnection = new _crConnection.CRConnection(nodeTransport, _helper.helper.debugProtocolLogger(), browserLogsCollector); // Immediately release exiting process under debug.176 waitForLine(progress, launchedProcess, /Waiting for the debugger to disconnect\.\.\./).then(() => {177 nodeTransport.close();178 }).catch(() => {});179 const chromeMatch = await Promise.race([waitForLine(progress, launchedProcess, /^DevTools listening on (ws:\/\/.*)$/), waitForXserverError]);180 const chromeTransport = await _transport.WebSocketTransport.connect(progress, chromeMatch[1]);181 const browserProcess = {182 onclose: undefined,183 process: launchedProcess,184 close: gracefullyClose,185 kill186 };187 const contextOptions = { ...options,188 noDefaultViewport: true189 };190 const browserOptions = { ...this._playwrightOptions,191 name: 'electron',192 isChromium: true,193 headful: true,194 persistent: contextOptions,195 browserProcess,196 protocolLogger: _helper.helper.debugProtocolLogger(),197 browserLogsCollector,198 artifactsDir,199 downloadsPath: artifactsDir,200 tracesDir: artifactsDir201 };202 (0, _browserContext.validateBrowserContextOptions)(contextOptions, browserOptions);203 const browser = await _crBrowser.CRBrowser.connect(chromeTransport, browserOptions);204 app = new ElectronApplication(this, browser, nodeConnection, launchedProcess);205 return app;206 }, _timeoutSettings.TimeoutSettings.timeout(options));207 }208}209exports.Electron = Electron;210function waitForLine(progress, process, regex) {211 return new Promise((resolve, reject) => {212 const rl = readline.createInterface({213 input: process.stderr214 });215 const failError = new Error('Process failed to launch!');216 const listeners = [_eventsHelper.eventsHelper.addEventListener(rl, 'line', onLine), _eventsHelper.eventsHelper.addEventListener(rl, 'close', reject.bind(null, failError)), _eventsHelper.eventsHelper.addEventListener(process, 'exit', reject.bind(null, failError)), // It is Ok to remove error handler because we did not create process and there is another listener.217 _eventsHelper.eventsHelper.addEventListener(process, 'error', reject.bind(null, failError))];218 progress.cleanupWhenAborted(cleanup);219 function onLine(line) {220 const match = line.match(regex);221 if (!match) return;222 cleanup();223 resolve(match);224 }...

Full Screen

Full Screen

upload-ssl-certs-to-bg96.js

Source:upload-ssl-certs-to-bg96.js Github

copy

Full Screen

1/*2 Example how to upload SSL certificates to the Quectel BG96 module using AT commands.3 Steps:4 Cut and paste your certificates in PEM format to the code.5 Interactively call "uploadCertificates();" on the device's JavaScript console after6 uploading the code to the device.7 Copyright (C) 2019 Wolfgang Klenk <wolfgang.klenk@gmail.com>8 This program is free software: you can redistribute it and/or modify9 it under the terms of the GNU General Public License as published by10 the Free Software Foundation, either version 3 of the License, or11 (at your option) any later version.12 This program is distributed in the hope that it will be useful,13 but WITHOUT ANY WARRANTY; without even the implied warranty of14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15 GNU General Public License for more details.16 You should have received a copy of the GNU General Public License17 along with this program. If not, see <https://www.gnu.org/licenses/>.18*/19var debug = false;20var FILENAME_CLIENT_CERT = "cert.pem";21var FILENAME_PRIVATE_KEY = "key.pem";22var FILENAME_TRUSTED_ROOT_CA = "cacert.pem";23var at;24// 3a34634a38-certificate.pem.crt - Cut and paste25var client_cert = '-----BEGIN CERTIFICATE-----\n' +26 'MIIDWjCCAkKgAwIBAgIVAJZ543Y5NgA10ni3ARw3huZhA01OMA0GCSqGSIb3DQEB\n' +27 'CwUAME0xSzBJBgNVBAsMQkFtYXpvbiBXZWIgU2VydmljZXMgTz1BbWF6b24uY29t\n' +28 'IEluYy4gTD1TZWF0dGxlIFNUPVdhc2hpbmd0b24gQz1VUzAeFw0xOTAzMjUyMDMw\n' +29 'NDZaFw00OTEyMzEyMzU5NTlaMB4xHDAaBgNVBAMME0FXUyBJb1QgQ2VydGlmaWNh\n' +30 'dGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCrFmv9kMjJ0Jhucd3\n' +31 'hThnHwjI1vvYWfHqho4yZhy5kFlot0e0GwtdInMYdiKISlTDQz90iK2dnp6U1aW3\n' +32 'IajR93MFI7Vj9hyOr/cci98zqnOxnvcXf4Lxi6zrcw/aMSB3WIFRWPnzpERIeZJO\n' +33 '+PK7YAnJ0ynZo4ir3c8IuDX8u8pj6PB4ohrkHz0O4i8qN7WNFgRgmR8oAf4D6nzC\n' +34 'gLmemN/xaEB54C2lnSTIpFmyp7qHQBg2lULqDOQkig6bV8K1qrfsLXLECTa+rhoF\n' +35 'VqFrqXqJw9djyj93LAkTjMdXQu8mWVKnvYi0TLXpf1m4H+UMbgQNgsMRg/CoHPmy\n' +36 'lq4tAgMBAAGjYDBeMB8GA1UdIwQYMBaAFPYoAgVcRLr4N6NKDWJpQ6NWJKKHMB0G\n' +37 'A1UdDgQWBBTVKpy0Jrf8M6UVSyAV5qPEtDVrsTAMBgNVHRMBAf8EAjAAMA4GA1Ud\n' +38 'DwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAYvr983hMVoUgd3WXQsW74AI0\n' +39 '4ycas0hPAUSLW6i5J4RkLY9rOH+ppnycmKCD3oOfVCpBlWf5nhsJ12p7NCgYJSa8\n' +40 'Cl3GjWdXpoYX+Sv7BiMBHFfzNQjZf6A/vk+9bCg1hTfWY2+wWsvqQ/u/xWG9rgaF\n' +41 'rtvdZ3dYbrXVKjq5QvKqxuLmM0Wbsf7gmo9WxF7wDF5uZHGKNH++qn9Id7txGbyO\n' +42 'nTlJ4447tguozlbTMl9Bup9+iUMeXOZwhzHI45uqnA4AYVUDB2fu+TBz1ogwnXOD\n' +43 'ZlkWZNh/iBObuNC4J8/njsXP7R0eCNj9K4FFoInQ776COPe9hSQhnMequlw2MQ==\n' +44 '-----END CERTIFICATE-----\n';45// 3a34634a38-private.pem.key - Cut and paste46var client_private_key = '-----BEGIN RSA PRIVATE KEY-----\n' +47 'MIIEpAIBAAKCAQEAwqxZr/ZDIydCYbnHd4U4Zx8IyNb72Fnx6oaOMmYcuZBZaLdH\n' +48 'tBsLXSJzGHYiiEpUw0M/dIitnZ6elNWltyGo0fdzBSO1Y/Ycjq/3HIvfM6pzsZ73\n' +49 '72mTAlFiF2lPDId+kkFDiuSp6lkz30f5/Nl+LZwUGtPaANykjocIdOWGoi+Z2lNe\n' +50 'q6QT+CyUCX7I40wIkPfujsYoBGvM/MDRqnN36J4Kjc/RdnXPs25tLw==\n' +51 '-----END RSA PRIVATE KEY-----\n';52// RSA 2048 bit key: Amazon Root CA 153var trusted_root_ca = '-----BEGIN CERTIFICATE-----\n' +54 'MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n' +55 'ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n' +56 'b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n' +57 'MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n' +58 'b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n' +59 'ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n' +60 '9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n' +61 'IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n' +62 'VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n' +63 '93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n' +64 'jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n' +65 'AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n' +66 'A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n' +67 'U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n' +68 'N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n' +69 'o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n' +70 '5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n' +71 'rqXRfboQnoZsG4q5WTP468SQvvG5\n' +72 '-----END CERTIFICATE-----';73sendAtCommand = function (command, timeoutMs, waitForLine) {74 return new Promise((resolve, reject) => {75 var answer = "";76 at.cmd(command + "\r\n", timeoutMs || 1E3, function processResponse(response) {77 if (undefined === response || "ERROR" === response || response.startsWith("+CME ERROR")) {78 reject(response ? (command + ": " + response) : (command + ": TIMEOUT"));79 } else if (waitForLine ? (response.startsWith(waitForLine)) : ("OK" === response)) {80 resolve(waitForLine ? response : answer);81 } else {82 answer += (answer ? "\n" : "") + response;83 return processResponse;84 }85 });86 });87};88sendAtCommandAndWaitForPrompt = function (command, timeoutMs, sendLineAfterPrompt, waitForLine) {89 return new Promise((resolve, reject) => {90 var prompt = 'CONNECT';91 var answer = "";92 if (sendLineAfterPrompt) {93 at.register(prompt, (line) => {94 at.unregister(prompt);95 at.write(sendLineAfterPrompt);96 return line.substr(prompt.length);97 });98 }99 at.cmd(command + "\r\n", timeoutMs, function processResponse(response) {100 if (undefined === response || "ERROR" === response || response.startsWith("+CME ERROR")) {101 // Unregister the prompt '> ' in case something went wrong.102 // If we don't, we get follow up errors when it is tried to again register the prompt.103 at.unregister(prompt);104 reject(response ? (command + ": " + response) : (command + ": TIMEOUT"));105 } else if (waitForLine ? (response.startsWith(waitForLine)) : ("OK" === response)) {106 resolve(waitForLine ? response : answer);107 } else {108 answer += (answer ? "\n" : "") + response;109 return processResponse;110 }111 });112 });113};114// Calculate a checksum of the file.115// Checksum is calculated by doing a XOR operation for every 2 bytes116function calculateChecksum(data) {117 var checksum = [0x00, 0x00];118 for(var i = 0; i < data.length; i+=2) {119 checksum[0] ^= data.charCodeAt(i);120 if ((i+1) >= data.length) {121 checksum[1] ^= 0x00;122 } else {123 checksum[1] ^= data.charCodeAt(i+1);124 }125 }126 var checksumAsNumber = (checksum[0] << 8) | checksum[1];127 return checksumAsNumber;128}129// Upload certificates130function uploadCertificates() {131 console.log("Connecting Cellular Modem ...");132 require("iTracker").setCellOn(true, function (usart) {133 console.log("Cellular Modem connected.");134 at = require("AT").connect(usart);135 at.debug(debug);136 sendAtCommand('AT&F0')137 .then(() => sendAtCommand('ATE0'))138 // List all files in UFS directory139 .then(() => sendAtCommand('AT+QFLST="*"'))140 .then((line) => {141 console.log("Files in file system: " + line);142 })143 // Delete all files in UFS directory144 .then(() => sendAtCommand('AT+QFDEL="*"'))145 .then( () => sendAtCommandAndWaitForPrompt(146 'AT+QFUPL="' + FILENAME_CLIENT_CERT +'",' + client_cert.length + ',100',147 1000,148 client_cert,149 '+QFUPL:'150 )151 )152 .then((line) => {153 console.log("+QFUPL line:", line, "Uploaded", FILENAME_CLIENT_CERT);154 var returnedChecksum = parseInt(line.split(',')[1], 16);155 var expectedChecksum = calculateChecksum(client_cert);156 if (returnedChecksum !== expectedChecksum) {157 throw new Error('Checksums do not match.');158 }159 })160 .then( () => sendAtCommandAndWaitForPrompt(161 'AT+QFUPL="' + FILENAME_PRIVATE_KEY + '",' + client_private_key.length + ',100',162 1000,163 client_private_key,164 '+QFUPL:'165 )166 )167 .then((line) => {168 console.log("+QFUPL line:", line, "Uploaded", FILENAME_PRIVATE_KEY);169 var returnedChecksum = parseInt(line.split(',')[1], 16);170 var expectedChecksum = calculateChecksum(client_private_key);171 if (returnedChecksum !== expectedChecksum) {172 throw new Error('Checksums do not match.');173 }174 })175 .then( () => sendAtCommandAndWaitForPrompt(176 'AT+QFUPL="' + FILENAME_TRUSTED_ROOT_CA + '",' + trusted_root_ca.length + ',100',177 1000,178 trusted_root_ca,179 '+QFUPL:'180 )181 )182 .then((line) => {183 console.log("+QFUPL line:", line, "Uploaded", FILENAME_TRUSTED_ROOT_CA);184 var returnedChecksum = parseInt(line.split(',')[1], 16);185 var expectedChecksum = calculateChecksum(trusted_root_ca);186 if (returnedChecksum !== expectedChecksum) {187 throw new Error('Checksums do not match.');188 }189 console.log("\nSuccessfully uploaded SSL certificates to BG96 module.");190 })191 .catch((err) => {192 console.log('Could not upload SSL certificates to BG96 module:', err);193 });194 });...

Full Screen

Full Screen

player.js

Source:player.js Github

copy

Full Screen

...36 // regexes for matching player state and controller37 const stateRegExp = /BP_PlayerState_C .+?PersistentLevel\.(?<state>BP_PlayerState_C_\d+)\.PlayerName = (?<name>.+)$/;38 const controllerRegExp = /BP_PlayerState_C .+?PersistentLevel\.(?<state>BP_PlayerState_C_\d+)\.Owner = BP_PlayerController_C'.+?:PersistentLevel.(?<controller>BP_PlayerController_C_\d+)'/;39 // wait for this players' state40 const statePromise = brickadia.waitForLine(line => {41 const match = line.match(stateRegExp);42 // no match, return null43 if (!match) return null;44 const { name, state } = match.groups;45 // a player under the same name is using this state, ignore46 if (this._brikkit._players.some(p => p._connected && p._username === this._username && state === p._state)) {47 return null;48 }49 // return the state if the name matches50 return name === this._username ? state : null;51 });52 // request all states and players from brickadia53 brickadia.write(`GetAll BRPlayerState PlayerName\n`);54 const state = await statePromise;55 // wait for this players' controller56 const controllerPromise = brickadia.waitForLine(line => {57 const match = line.match(controllerRegExp);58 // if no match, return null59 if (!match) return null;60 return match.groups.state === state ? match.groups.controller : null;61 });62 // request the owner for this state63 brickadia.write(`GetAll BRPlayerState Owner Name=${state}\n`);64 const controller = await controllerPromise;65 if (!controller || !state)66 return null;67 // the controller and state exist, so this player is connected68 this._state = state;69 this._controller = controller;70 this._connected = true;71 return controller;72 }73 // get player's position74 async getPosition() {75 if (!this._brikkit)76 return null;77 const controller = this._controller || await this.getController();78 if (!controller)79 return;80 const brickadia = this._brikkit._brickadia;81 // regexes for matching player state and controller82 const pawnRegExp = /BP_PlayerController_C .+?PersistentLevel\.(?<controller>BP_PlayerController_C_\d+)\.Pawn = BP_FigureV2_C'.+?:PersistentLevel.(?<pawn>BP_FigureV2_C_\d+)'/;83 const posRegExp = /CapsuleComponent .+?PersistentLevel\.(?<pawn>BP_FigureV2_C_\d+)\.CollisionCylinder\.RelativeLocation = \(X=(?<x>[\d\.-]+),Y=(?<y>[\d\.-]+),Z=(?<z>[\d\.-]+)\)/;84 // wait for this players' pawn85 const pawnPromise = brickadia.waitForLine(line => {86 const match = line.match(pawnRegExp);87 // if no match, return null88 if (!match) return null;89 return match.groups.controller === controller ? match.groups.pawn : null;90 });91 // request all states and players from brickadia92 brickadia.write(`GetAll BP_PlayerController_C Pawn Name=${controller}\n`);93 const pawn = await pawnPromise;94 // wait for this players' pawn95 const posPromise = brickadia.waitForLine(line => {96 const match = line.match(posRegExp);97 // if no match, return null98 if (!match) return null;99 const { x, y, z } = match.groups;100 return match.groups.pawn === pawn ? [x, y, z].map(Number) : null;101 });102 // request the owner for this state103 brickadia.write(`GetAll SceneComponent RelativeLocation Name=CollisionCylinder Outer=${pawn}\n`);104 const pos = await posPromise;105 if (!pawn || !pos)106 return null;107 // the player exists, return the position108 return pos;109 }...

Full Screen

Full Screen

avd_test.js

Source:avd_test.js Github

copy

Full Screen

...31 }32 });33 proc.stdout.on('data', data => console.log(data.toString()));34 proc.stderr.on('data', data => console.log(data.toString()));35 await waitForLine(proc, /boot completed/);36 const context = await _clank.launchPersistentContext('');37 const [page] = context.pages();38 await page.goto('data:text/html,<title>Hello world</title>');39 assert(await page.title() === 'Hello world');40 await context.close();41 process.exit(0);42})();43async function waitForLine(proc, regex) {44 return new Promise((resolve, reject) => {45 const rl = readline.createInterface({ input: proc.stdout });46 const failError = new Error('Process failed to launch!');47 rl.on('line', onLine);48 rl.on('close', reject.bind(null, failError));49 proc.on('exit', reject.bind(null, failError));50 proc.on('error', reject.bind(null, failError));51 function onLine(line) {52 const match = line.match(regex);53 if (!match)54 return;55 resolve(match);56 }57 });...

Full Screen

Full Screen

keyboard.js

Source:keyboard.js Github

copy

Full Screen

1/////editor2//var doCommand = null;3var enterFlag = false;4window.doOutput = false;5const display = require("/js/display.js");6var eline = "> ";7var lastWaiter = null;8var key = function(k) {9 //console.log("KK", k);10 if (k == 7) {11 //recall last12 eline += lastWaiter;13 } else if (k == 13) {14 //if (doOutput && eline.length > 2) display.clearSameLine(eline + " ");15 //if (doOutput) display.clearSameLine(eline + " ");16 waiter = eline.substr(2).trim();17 enterFlag = true;18 if (waiter) lastWaiter = eline.substr(2).trim();19 //console.log("WA", waiter);20 //doCommand(eline.substr(2).trim());21 eline = "> ";22 return;23 } else if (k == 8) {24 if (eline.length > 2) {25 eline = eline.substr(0, eline.length - 1);26 if (window.doOutput) display.printSameLine(eline + "_ ");27 }28 } else if (!k) {29 eline = "> ";30 //console.log("KEY 0", window.doOutput, eline);31 if (window.doOutput) display.printSameLine(eline + "_ ");32 } else {33 eline += String.fromCharCode(k);34 }35 if (window.doOutput) display.printSameLine(eline + "_");36};37var waiter = null;38var waitForLine = () => {39 var line = waiter;40 waiter = null;41 return line;42};43var wasEnterPressed = () => {44 if (enterFlag) {45 enterFlag = false;46 return true;47 }48 return false;49};50module.exports = {51 init() {},52 key,53 doOutput(d) {54 window.doOutput = d;55 },56 waitForLine,57 wasEnterPressed...

Full Screen

Full Screen

start-with-folder.js

Source:start-with-folder.js Github

copy

Full Screen

...12 t.error(err)13 t.equal(Object.keys(instance.services).length, 2, 'number of services')14 t.ok(instance.services.a, 'service a exists')15 t.ok(instance.services.b, 'service b exists')16 waitForLine(instance.services.a, `a (${instance.services.a.id}): hello from a`)17 waitForLine(instance.services.b, `b (${instance.services.b.id}): hello from b`)18 function waitForLine (s, expected) {19 s.output20 .pipe(split())21 .once('data', (line) => {22 line = chalk.stripColor(line)23 t.equal(line, expected, 'line matches')24 })25 }...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.waitForLine('input[name="q"]');7 await browser.close();8})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2(async () => {3 const browser = await playwright.chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const [consoleMessage] = await Promise.all([7 page.waitForEvent('console'),8 page.evaluate(() => console.log('hello', 5, {foo: 'bar'})),9 ]);10 console.log(consoleMessage.text());11 await browser.close();12})();13const playwright = require('playwright');14(async () => {15 const browser = await playwright.chromium.launch();16 const context = await browser.newContext();17 const page = await context.newPage();18 const [consoleMessage] = await Promise.all([19 page.waitForEvent('console'),20 page.evaluate(() => console.log('hello', 5, {foo: 'bar'})),21 ]);22 console.log(consoleMessage.text());23 await browser.close();24})();25const playwright = require('playwright');26(async () => {27 const browser = await playwright.chromium.launch();28 const context = await browser.newContext();29 const page = await context.newPage();30 const [consoleMessage] = await Promise.all([31 page.waitForEvent('console'),32 page.evaluate(() => console.log('hello', 5, {foo: 'bar'})),33 ]);34 console.log(consoleMessage.text());35 await browser.close();36})();37const playwright = require('playwright');38(async () => {39 const browser = await playwright.chromium.launch();40 const context = await browser.newContext();41 const page = await context.newPage();42 const [consoleMessage] = await Promise.all([43 page.waitForEvent('console'),44 page.evaluate(() => console.log('hello', 5, {foo: 'bar'})),45 ]);46 console.log(consoleMessage.text());47 await browser.close();48})();49const playwright = require('

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2(async () => {3 const browser = await playwright.chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const console = page.context().console();7 const message = await console.waitForLine(line => line.text().includes('API'));8 console.log(message.text());9 await browser.close();10})();11const playwright = require('playwright');12(async () => {13 const browser = await playwright.chromium.launch();14 const context = await browser.newContext();15 const page = await context.newPage();16 const console = page.context().console();17 const message = await console.waitForLine(line => line.text().includes('API'));18 console.log(message.text());19 await browser.close();20})();21const playwright = require('playwright');22(async () => {23 const browser = await playwright.chromium.launch();24 const context = await browser.newContext();25 const page = await context.newPage();26 const console = page.context().console();27 const message = await console.waitForLine(line => line.text().includes('API'));28 console.log(message.text());29 await browser.close();30})();31const playwright = require('playwright');32(async () => {33 const browser = await playwright.chromium.launch();34 const context = await browser.newContext();35 const page = await context.newPage();36 const console = page.context().console();37 const message = await console.waitForLine(line => line.text().includes('API'));38 console.log(message.text());39 await browser.close();40})();41const playwright = require('playwright');42(async () => {43 const browser = await playwright.chromium.launch();44 const context = await browser.newContext();45 const page = await context.newPage();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { Playwright } = require('playwright-core/lib/server/playwright.js');2const playwright = new Playwright();3const browser = await playwright.chromium.launch({ headless: false });4const context = await browser.newContext();5const page = await context.newPage();6const { Playwright } = require('playwright-core/lib/server/playwright.js');7const playwright = new Playwright();8const browser = await playwright.chromium.launch({ headless: false });9const context = await browser.newContext();10const page = await context.newPage();11const { Playwright } = require('playwright-core/lib/server/playwright.js');12const playwright = new Playwright();13const browser = await playwright.chromium.launch({ headless: false });14const context = await browser.newContext();15const page = await context.newPage();16const { Playwright } = require('playwright-core/lib/server/playwright.js');17const playwright = new Playwright();18const browser = await playwright.chromium.launch({ headless: false });19const context = await browser.newContext();20const page = await context.newPage();21const { Playwright } = require('playwright-core/lib/server/playwright.js');22const playwright = new Playwright();23const browser = await playwright.chromium.launch({ headless: false });24const context = await browser.newContext();25const page = await context.newPage();26const { Playwright } = require('playwright-core/lib/server/playwright.js');27const playwright = new Playwright();28const browser = await playwright.chromium.launch({ headless: false });29const context = await browser.newContext();30const page = await context.newPage();

Full Screen

Using AI Code Generation

copy

Full Screen

1const playwright = require('playwright');2const { waitForLine } = require('playwright/lib/internal/stdio');3(async () => {4 const browser = await playwright.chromium.launch({headless: false});5 const context = await browser.newContext();6 const page = await context.newPage();7 const waitforline = await waitForLine();8 console.log(waitforline);9 await browser.close();10})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { waitForLine } = require('@playwright/test/lib/server/processLauncher');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch({headless: false});5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.click('text=Get started');8 await page.close();9 await context.close();10 await browser.close();11})();12const { test } = require('@playwright/test');13test('should wait for line', async ({ page }) => {14 await page.click('text=Get started');15 await page.waitForSelector('text=Docs');16});

Full Screen

Using AI Code Generation

copy

Full Screen

1const { _electron } = require('playwright');2(async () => {3 const { electron } = _electron;4 const app = await electron.launch({ args: ['path/to/app'] });5 const page = await app.firstWindow();6 const { waitForLine } = require('playwright/lib/server/electron');7 await waitForLine(page, 'Listening on port 3000');8 await app.close();9})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { waitForLine } = require('playwright/lib/internal/stdio');2(async () => {3 await waitForLine(process.stdout, 'Server is listening');4 console.log('Server is listening');5})()6const { waitForLine } = require('playwright/lib/internal/stdio');7(async () => {8 await waitForLine(process.stdout, 'Server is listening');9 console.log('Server is listening');10})()11const { waitForLine } = require('playwright/lib/internal/stdio');12(async () => {13 await waitForLine(process.stdout, 'Server is listening');14 console.log('Server is listening');15})()16const { waitForLine } = require('playwright/lib/internal/stdio');17(async () => {18 await waitForLine(process.stdout, 'Server is listening');19 console.log('Server is listening');20})()21const { waitForLine } = require('playwright/lib/internal/stdio');22(async () => {23 await waitForLine(process.stdout, 'Server is listening');24 console.log('Server is listening');25})()26const { waitForLine } = require('playwright/lib/internal/stdio');27(async () => {28 await waitForLine(process.stdout, 'Server is listening');29 console.log('Server is listening');30})()31const { waitForLine } = require('playwright/lib/internal/stdio');32(async () => {33 await waitForLine(process.stdout, 'Server is listening');34 console.log('Server is listening');35})()36const { waitForLine } = require('playwright/lib/internal/stdio');37(async () => {38 await waitForLine(process.stdout, 'Server is listening');39 console.log('Server is listening');40})()41const { waitForLine } = require('playwright/lib/internal/stdio');

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful