Initial commit

This commit is contained in:
Jason Harrell
2018-02-17 22:47:44 -07:00
commit 235a77d788
57 changed files with 6615 additions and 0 deletions

22
build/fs/api_adc.js Normal file
View File

@@ -0,0 +1,22 @@
let ADC = {
// ## **`ADC.enable(pin)`**
// Configure and enable ADC for a `pin`,
// return 1 if success, 0 otherwise.
enable: ffi('int mgos_adc_enable(int)'),
// ## **`ADC.read(pin)`**
// Read `pin` analog value, return an integer.
//
// Note for ESP8266 platform:
// with this function, you can also measure the power voltage
// of VDD33 pin 3 and 4. Then:
// 1) TOUT pin has to be floating in the circuit
// (not connected to anything);
// 2) In mos.yaml must be set this feature:
// build_vars:
// MGOS_ADC_MODE_VDD: 1
// 3) The return value may be different in different Wi-Fi modes,
// for example, in Modem-sleep mode or in normal Wi-Fi working
// mode.
// Return value: Power voltage of VDD33; unit: 1/1024 V.
read: ffi('int mgos_adc_read(int)'),
};

34
build/fs/api_arch_uart.js Normal file
View File

@@ -0,0 +1,34 @@
// esp32 architecture-dependent UART wrappers
UART._arch = {
_pins: ffi('void esp32_uart_config_set_pins(int, void *, int, int, int, int)'),
_fifo: ffi('void esp32_uart_config_set_fifo(int, void *, int, int, int, int)'),
// Set arch-dependent UART config
scfg: function(uartNo, cfg, param) {
if (param.esp32 === undefined) return;
// Set GPIO params
if (param.esp32.gpio !== undefined) {
let dgpio = param.esp32.gpio;
let rx = (dgpio.rx !== undefined ? dgpio.rx : -1);
let tx = (dgpio.tx !== undefined ? dgpio.tx : -1);
let cts = (dgpio.cts !== undefined ? dgpio.cts : -1);
let rts = (dgpio.rts !== undefined ? dgpio.rts : -1);
this._pins(uartNo, cfg, rx, tx, cts, rts);
}
// Set FIFO params
if (param.esp32.fifo !== undefined) {
let dfifo = param.esp32.fifo;
let ft = (dfifo.rxFullThresh !== undefined ? dfifo.rxFullThresh : -1);
let fct = (dfifo.rxFcThresh !== undefined ? dfifo.rxFcThresh : -1);
let alarm = (dfifo.rxAlarm !== undefined ? dfifo.rxAlarm : -1);
let et = (dfifo.txEmptyThresh !== undefined ? dfifo.txEmptyThresh : -1);
this._fifo(uartNo, cfg, ft, fct, alarm, et);
}
},
};

19
build/fs/api_bitbang.js Normal file
View File

@@ -0,0 +1,19 @@
let BitBang = {
DELAY_MSEC: 0,
DELAY_USEC: 1,
DELAY_100NSEC: 2,
// ## **`BitBang.write(pin, delay_unit, t0h, t0l, t1h, t1l, ptr, len)`**
// Write bits to a given `pin`. `delay_unit` is one of the:
// `BitBang.DELAY_MSEC`, `BitBang.DELAY_USEC`, `BitBang.DELAY_100NSEC`.
// `ptr, len` is a bit pattern to write. `t0h, t0l` is the time pattern
// for zero bit, `t1h, t1l` is the time pattern for 1. The time pattern
// specifies the number of time units to hold the pin high, and the number
// of units to hold the pin low. Return value: none.
write: function(pin, delay_unit, t0h, t0l, t1h, t1l, ptr, len) {
let t = (t0h << 24) | (t0l << 16) | (t1h << 8) | t1l;
this._wb(pin, delay_unit, t, ptr, len);
},
_wb: ffi('void mgos_bitbang_write_bits_js(int, int, int, void *, int)'),
};

63
build/fs/api_config.js Normal file
View File

@@ -0,0 +1,63 @@
let Cfg = {
_get: ffi('void *mgos_mjs_get_config()'),
_set: ffi('bool mgos_config_apply(char *, bool)'),
_desc: ffi('void *mgos_config_schema()'),
_find: ffi('void *mgos_conf_find_schema_entry(char *, void *)'),
_type: ffi('int mgos_conf_value_type(void *)'),
_str: ffi('char *mgos_conf_value_string_nonnull(void *, void *)'),
_int: ffi('int mgos_conf_value_int(void *, void *)'),
_dbl: ffi('double mgos_conf_value_double(void *, void *)'),
_INT: 0,
_BOOL: 1,
_DBL: 2,
_STR: 3,
_OBJ: 4,
// ## **`Cfg.get(path)`**
// Get the config value by the configuration variable. Currently, only
// simple types are returned: strings, ints, booleans, doubles. Objects
// are not yet supported.
//
// Examples:
// ```javascript
// load('api_config.js');
// Cfg.get('device.id'); // returns a string
// Cfg.get('debug.level'); // returns an integer
// Cfg.get('wifi.sta.enable'); // returns a boolean
// ```
get: function(path) {
let entry = this._find(path, this._desc());
if (entry === null) return undefined;
let type = this._type(entry);
let cfg = this._get();
if (type === this._STR) {
return this._str(cfg, entry);
} else if (type === this._INT) {
return this._int(cfg, entry);
} else if (type === this._DBL) {
return this._dbl(cfg, entry);
} else if (type === this._BOOL) {
return (this._int(cfg, entry) !== 0);
} else if (type === this._OBJ) {
/* TODO */
return undefined;
} else {
/* TODO: an error */
return undefined;
}
},
// ## **`Cfg.set(obj, opt_save)`**
// Set the configuration. `obj` must be a subset of the whole configuation
// tree. `save` is boolean flag that indicating whether the change should
// be saved - it could be omitted, in which case it defaults to `true`.
// Examples:
// ```javascript
// load('api_config.js');
// Cfg.set({wifi: {ap: {enable: false}}}); // Disable WiFi AP mode
// Cfg.set({debug: {level: 3}}); // Set debug level to 3
// ```
set: function(obj, save) {
return this._set(JSON.stringify(obj), save === undefined ? true : save);
},
};

222
build/fs/api_dataview.js Normal file
View File

@@ -0,0 +1,222 @@
// **DataView API**
//
// See the original API definition at [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView).
//
// mJS DataView diverges from the original in the following ways:
//
// - No `ArrayBuffer`; plain pointers should be used instead;
// - Since there are no constructors in mJS, `DataView.create()` should be
// used instead;
// - No float support yet (will be added)
let DataView = {
// ## **`DataView.create(buf, offset, len)`**
// Create a DataView object instance. `buf` is a pointer to a plain byte
// array, `offset` is an offset in in this buffer to start dataview from, and
// `len` is a length managed by dataview.
//
// Return value: an object with the methods described below.
//
// Example:
// ```javascript
// load("api_dataview.js");
// let calloc = ffi('void *calloc(int, int)');
// let ptr = calloc(100, 1);
// let dw = DataView.create(ptr, 0, 100);
//
// dw.setUint8(2, 0xff);
// ```
create: function(buf, off, len) {
let ret = Object.create(this._prot);
if (off !== undefined) {
buf += off;
}
ret._buf = buf;
ret._len = len;
return ret;
},
_prot: {
// ## **`myDW.getInt8(idx)`**
// Get a signed byte value from the dataview's buffer at the given index
// `idx`. Returned value: a number from -128 to 127.
getInt8: function(idx) {
if (!DataView._cl(idx, this._len, 1)) {
return undefined;
}
return DataView._gets(
DataView._pk(this._buf, idx), 1, false
);
},
// ## **`myDW.getUint8(idx)`**
// Get an unsigned byte value from the dataview's buffer at the given index
// `idx`. Returned value: a number from 0 to 255.
getUint8: function(idx) {
if (!DataView._cl(idx, this._len, 1)) {
return undefined;
}
return DataView._getu(
DataView._pk(this._buf, idx), 1, false
);
},
// ## **`myDW.getInt16(idx, le)`**
// Get a signed 2-byte value from the dataview's buffer at the given index
// `idx`. By default the data interpreted as big-endian; if `le` is true,
// then little-endian will be used.
// Returned value: a number from -32768 to 32767.
getInt16: function(idx, le) {
if (!DataView._cl(idx, this._len, 2)) {
return undefined;
}
return DataView._gets(
DataView._pk(this._buf, idx), 2, !le
);
},
// ## **`myDW.getUint16(idx, le)`**
// Get an unsigned 2-byte value from the dataview's buffer at the given
// index `idx`. By default the data interpreted as big-endian; if `le` is
// true, then little-endian will be used.
// Returned value: a number from 0 to 65535.
getUint16: function(idx, le) {
if (!DataView._cl(idx, this._len, 2)) {
return undefined;
}
return DataView._getu(
DataView._pk(this._buf, idx), 2, !le
);
},
// ## **`myDW.getInt32(idx, le)`**
// Get a signed 4-byte value from the dataview's buffer at the given index
// `idx`. By default the data interpreted as big-endian; if `le` is true,
// then little-endian will be used.
// Returned value: a number from -2147483648 to 2147483647.
getInt32: function(idx, le) {
if (!DataView._cl(idx, this._len, 4)) {
return undefined;
}
return DataView._gets(
DataView._pk(this._buf, idx), 4, !le
);
},
// ## **`myDW.getUint32(idx, le)`**
// Get an unsigned 4-byte value from the dataview's buffer at the given
// index `idx`. By default the data interpreted as big-endian; if `le` is
// true, then little-endian will be used.
// Returned value: a number from 0 to 4294967295.
getUint32: function(idx, le) {
if (!DataView._cl(idx, this._len, 4)) {
return undefined;
}
return DataView._getu(
DataView._pk(this._buf, idx), 4, !le
);
},
// ## **`myDW.setInt8(idx, val)`**
// Set a signed byte value into the dataview's buffer at the given index
// `idx`. `val` should be a number from -128 to 127.
// Returned value: none.
setInt8: function(idx, val) {
if (!DataView._cl(idx, this._len, 1)) {
return undefined;
}
DataView._setu(
DataView._pk(this._buf, idx), val, 1, false
);
},
// ## **`myDW.setUint8(idx, val)`**
// Set an unsigned byte value into the dataview's buffer at the given index
// `idx`. `val` should be a number from -128 to 127.
// Returned value: none.
setUint8: function(idx, val) {
if (!DataView._cl(idx, this._len, 1)) {
return undefined;
}
DataView._setu(
DataView._pk(this._buf, idx), val, 1, false
);
},
// ## **`myDW.setInt16(idx, val, le)`**
// Set a signed 2-byte value into the dataview's buffer at the given index
// `idx`. `val` should be a number from -32768 to 32767. By default the
// data is written in big-endian format; if `le` is true, then
// little-endian will be used.
// Returned value: none.
setInt16: function(idx, val, le) {
if (!DataView._cl(idx, this._len, 2)) {
return undefined;
}
DataView._setu(
DataView._pk(this._buf, idx), val, 2, !le
);
},
// ## **`myDW.setUint16(idx, val, le)`**
// Set an unsigned 2-byte value into the dataview's buffer at the given
// index `idx`. `val` should be a number from 0 to 65535. By default the
// data is written in big-endian format; if `le` is true, then
// little-endian will be used.
// Returned value: none.
setUint16: function(idx, val, le) {
if (!DataView._cl(idx, this._len, 2)) {
return undefined;
}
DataView._setu(
DataView._pk(this._buf, idx), val, 2, !le
);
},
// ## **`myDW.setInt32(idx, val, le)`**
// Set a signed 4-byte value into the dataview's buffer at the given index
// `idx`. `val` should be a number from -2147483648 to 2147483647. By
// default the data is written in big-endian format; if `le` is true, then
// little-endian will be used.
// Returned value: none.
setInt32: function(idx, val, le) {
if (!DataView._cl(idx, this._len, 4)) {
return undefined;
}
DataView._setu(
DataView._pk(this._buf, idx), val, 4, !le
);
},
// ## **`myDW.setUint32(idx, val, le)`**
// Set an unsigned 4-byte value into the dataview's buffer at the given
// index `idx`. `val` should be a number from 0 to 4294967295. By default
// the data is written in big-endian format; if `le` is true, then
// little-endian will be used.
// Returned value: none.
setUint32: function(idx, val, le) {
if (!DataView._cl(idx, this._len, 4)) {
return undefined;
}
DataView._setu(
DataView._pk(this._buf, idx), val, 4, !le
);
},
},
_cl: function(idx, len, ilen) {
if (len !== undefined && idx + ilen > len) {
die(DataView._errm);
return false;
}
return true;
},
_p: ffi('void *mjs_mem_to_ptr(int)'),
_pk: ffi('void *mjs_mem_get_ptr(void *, int)'),
_getu: ffi('double mjs_mem_get_uint(void *, int, int)'),
_gets: ffi('double mjs_mem_get_int(void *, int, int)'),
_setu: ffi('void mjs_mem_set_uint(void *, int, int, int)'),
_errm: "Offset is outside of the bounds of the DataView",
};

51
build/fs/api_dht.js Normal file
View File

@@ -0,0 +1,51 @@
// Mongoose OS DHT library API. Source C API is defined at:
// [mgos_dht.h](https://github.com/mongoose-os-libs/dht/tree/master/src/mgos_dht.h)
let DHT = {
_crt: ffi('void *mgos_dht_create(int, int)'),
_cls: ffi('void mgos_dht_close(void *)'),
_gt: ffi('float mgos_dht_get_temp(void *)'),
_gh: ffi('float mgos_dht_get_humidity(void *)'),
// Define type of sensors.
DHT11: 11,
DHT21: 21,
AM2301: 21,
DHT22: 22,
AM2302: 22,
// **`DHT.create(pin, type)`**
// Create a DHT object. `type` could be `DHT.DHT11`, `DHT.DHT21`,
// `DHT.DHT22`. Return value: an object with the methods described below, or
// 'null' in case of a failure.
// Example:
// ```javascript
// let mydht = DHT.create(5, DHT.DHT11);
// print('Temperature:', mydht.getTemp());
// ```
create: function(pin, type) {
let obj = Object.create(DHT._proto);
obj.dht = DHT._crt(pin, type);
return obj;
},
_proto: {
// **`mydht.close()`**
// Close DHT handle. Return value: none.
close: function() {
return DHT._cls(this.dht);
},
// **`mydht.getTemp()`**
// Return temperature in degrees C or 'NaN' in case of a failure.
getTemp: function() {
return DHT._gt(this.dht);
},
// **`mydht.getHumidity()`**
// Return humidity in RH% or 'NaN' in case of a failure.
getHumidity: function() {
return DHT._gh(this.dht);
},
},
};

14
build/fs/api_esp32.js Normal file
View File

@@ -0,0 +1,14 @@
let ESP32 = {
// ## **`ESP32.temp()`**
// Read built-in temperature sensor. Return value: integer.
temp: ffi('int temprature_sens_read(void)'),
// ## **`ESP32.hall()`**
// Read built-in Hall sensor. Return value: integer.
hall: ffi('int hall_sens_read(void)'),
// ## **`ESP32.deepSleep(microseconds)`**
// Deep Sleep given number of microseconds.
// Return value: does not return.
deepSleep: ffi('void mgos_esp_deep_sleep_d(double)'),
};

102
build/fs/api_events.js Normal file
View File

@@ -0,0 +1,102 @@
let Event = {
// ## **`Event.addHandler(ev, callback, userdata)`**
// Add a handler for the given event `ev`. Callback should look like:
//
// function(ev, evdata, userdata) { /* ... */ }
//
// Example:
// ```javascript
//
// Event.addHandler(Event.REBOOT, function(ev, evdata, ud) {
// print("Going to reboot!");
// }, null);
// ```
addHandler: ffi(
'bool mgos_event_add_handler(int, void(*)(int, void *, userdata), userdata)'),
// ## **`Event.addGroupHandler(evgrp, callback, userdata)`**
// Like `Event.addHandler()`, but subscribes on all events in the given
// event group `evgrp`. Event group includes all events from `evgrp & ~0xff`
// to `evgrp | 0xff`.
//
// Example:
// ```javascript
//
// Event.addGroupHandler(Event.SYS, function(ev, evdata, ud) {
// print("Sys event:", ev);
// }, null);
// ```
addGroupHandler: ffi(
'bool mgos_event_add_group_handler(int, void(*)(int, void *, userdata), userdata)'),
// ## **`Event.regBase(base_event_number, name)`**
// Register a base event number in order to prevent event number conflicts.
// Use `Event.baseNumber(id)` to get `base_event_number`; `name` is an
// arbitrary event name.
//
// Example:
// ```javascript
// let bn = Event.baseNumber("ABC");
// if (!Event.regBase(bn, "My module")) {
// die("Failed to register base event number");
// }
//
// let MY_EVENT_FOO = bn + 0;
// let MY_EVENT_BAR = bn + 1;
// let MY_EVENT_BAZ = bn + 2;
// ```
regBase: ffi('bool mgos_event_register_base(int, char *)'),
// ## **`Event.baseNumber(id)`**
// Generates unique base event number (32-bit) by a 3-char string.
// LSB is always zero, and a library can use it to create up to 256 unique
// events.
//
// A library should call `Event.regBase()` in order to claim
// it and prevent event number conflicts. (see example there)
baseNumber: function(id) {
if (id.length !== 3) {
die("Base event id should have exactly 3 chars");
return -1;
}
return (id.at(0) << 24) | (id.at(1) << 16) | (id.at(2) << 8);
},
// ## **`Event.trigger(ev, evdata)`**
// Trigger an event with the given id `ev` and event data `evdata`.
trigger: ffi('int mgos_event_trigger(int, void *)'),
// ## **`Event.evdataLogStr(evdata)`**
// Getter function for the `evdata` given to the event callback for the event
// `Event.LOG`, see `Event.addHandler()`.
evdataLogStr: function(evdata) {
return mkstr(Event._gdd(evdata), 0, Event._gdl(evdata), true);
},
_gdd: ffi('void *mgos_debug_event_get_ptr(void *)'),
_gdl: ffi('int mgos_debug_event_get_len(void *)'),
};
Event.SYS = Event.baseNumber("MOS");
// NOTE: INIT_DONE is unavailable here because init.js is executed in
// INIT_DONE hook
// ## **`Event.LOG`**
// System event which is triggered every time something is printed to the
// log. In the callback, use `Event.evdataLogStr(evdata)` to get string
// which was printed.
Event.LOG = Event.SYS + 1;
// ## **`Event.REBOOT`**
// System event which is triggered right before going to reboot. `evdata`
// is irrelevant for this event.
Event.REBOOT = Event.SYS + 2;
// ## **`Event.OTA_STATUS`**
// System event which is triggered when OTA status changes.
//
// In the callback, use `OTA.evdataOtaStatusMsg(evdata)` from `api_ota.js` to
// get the OTA status message.
Event.OTA_STATUS = Event.SYS + 3;

63
build/fs/api_file.js Normal file
View File

@@ -0,0 +1,63 @@
let File = {
// **`File.read(name)`**
// Read the whole file into a string variable.
//
// Return value: a string contents of the file.
// If file does not exist, an empty string is returned.
//
// Example: read a .json configuration file into a config object:
// ```javascript
// let obj = JSON.parse(File.read('settings.json'));
// ```
read: function(path) {
let n = 0; let res = ''; let buf = 'xxxxxxxxxx'; // Should be > 5
let fp = File.fopen(path, 'r');
if (fp === null) return null;
while ((n = File.fread(buf, 1, buf.length, fp)) > 0) {
res += buf.slice(0, n);
}
File.fclose(fp);
return res;
},
// **`File.remove(name)`**
// Delete file with a given name. Return value: 0
// on success, non-0 on failure.
remove: ffi('int remove(char *)'),
// **`File.rename(old, new)`**
// Rename file `old` to `new`. Return 0 on success, non-0 on failure.
rename: ffi('int rename(char *, char *)'),
// **`File.write(str, name, mode)`**
// Write string `str` into file `name`.
//
// If file does not exist, it is created. `mode` is an optional file open
// mode argument, `'w'` by default, which means that previous content is
// deleted. Set `mode` to `'a'` in order to append to the existing content.
// Return value: number of bytes written.
//
// Example - write a configuration object into a file:
// ```javascript
// File.write(JSON.stringify(obj, 'settings.json'));
// ```
write: function(str, path, oMode) {
let fp = File.fopen(path, oMode || 'w');
if (fp === null) return 0;
let off = 0; let tot = str.length;
while (off < tot) {
let len = 5; // Use light 5-byte strings for writing
if (off + len > tot) len = tot - off;
let n = File.fwrite(str.slice(off, off + len), 1, len, fp);
// if (n <= 0) break;
off += n;
}
File.fclose(fp);
return off;
},
fopen: ffi('void *fopen(char *, char *)'),
fclose: ffi('void fclose(void *)'),
fread: ffi('int fread(char *, int, int, void *)'),
fwrite: ffi('int fwrite(char *, int, int, void *)'),
};

75
build/fs/api_gpio.js Normal file
View File

@@ -0,0 +1,75 @@
let GPIO = {
// ## **`GPIO.set_mode(pin, mode)`**
// Set GPIO pin mode.
// `mode` can be either `GPIO.MODE_INPUT` or `GPIO.MODE_OUTPUT`.
set_mode: ffi('int mgos_gpio_set_mode(int,int)'),
MODE_INPUT: 0,
MODE_OUTPUT: 1,
// ## **`GPIO.set_pull(pin, type)`**
// Set GPIO pin pull type.
// `type` can be either `GPIO.PULL_NONE`, `GPIO.PULL_UP`, or `GPIO.PULL_DOWN`.
set_pull: ffi('int mgos_gpio_set_pull(int,int)'),
PULL_NONE: 0,
PULL_UP: 1,
PULL_DOWN: 2,
// ## **`GPIO.toggle(pin)`**
// Toggle the level of certain GPIO pin.
// Return value: 0 or 1, indicating the resulting pin level.
toggle: ffi('int mgos_gpio_toggle(int)'),
// ## **`GPIO.write(pin, level)`**
// Set GPIO pin level to either 0 or 1. Return value: none.
write: ffi('void mgos_gpio_write(int,int)'),
// ## **`GPIO.read(pin)`**
// Read GPIO pin level. Return value: 0 or 1.
read: ffi('int mgos_gpio_read(int)'),
// ## **`GPIO.enable_int(pin)`**
// Enable interrupts on GPIO pin.
// This function must be called AFTER the interrupt handler is installed.
// Return value: 1 in case of success, 0 otherwise.
enable_int: ffi('int mgos_gpio_enable_int(int)'),
// ## **`GPIO.disable_int(pin)`**
// Disable interrupts on GPIO pin.
// Return value: 1 in case of success, 0 otherwise.
disable_int: ffi('int mgos_gpio_disable_int(int)'),
// ## **`GPIO.set_int_handler(pin, mode, handler)`**
// Install GPIO interrupt handler. `mode` could be one of: `GPIO.INT_NONE`,
// `GPIO.INT_EDGE_POS`, `GPIO.INT_EDGE_NEG`, `GPIO.INT_EDGE_ANY`,
// `GPIO.INT_LEVEL_HI`, `GPIO.INT_LEVEL_LO`.
// Return value: 1 in case of success, 0 otherwise.
// Example:
// ```javascript
// GPIO.set_mode(pin, GPIO.MODE_INPUT);
// GPIO.set_int_handler(pin, GPIO.INT_EDGE_NEG, function(pin) {
// print('Pin', pin, 'got interrupt');
// }, null);
// GPIO.enable_int(pin);
// ```
set_int_handler: ffi('int mgos_gpio_set_int_handler(int,int,void(*)(int,userdata),userdata)'),
INT_NONE: 0,
INT_EDGE_POS: 1,
INT_EDGE_NEG: 2,
INT_EDGE_ANY: 3,
INT_LEVEL_HI: 4,
INT_LEVEL_LO: 5,
// ## **`GPIO.set_button_handler(pin, pull, intmode, period, handler)`**
// Install
// GPIO button handler. `pull` is pull type, `intmode` is interrupt mode,
// `period` is debounce interval in milliseconds, handler is a function that
// receives pin number.
// Return value: 1 in case of success, 0 otherwise.
// Example:
// ```javascript
// GPIO.set_button_handler(pin, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 200, function(x) {
// print('Button press, pin: ', x);
// }, null);
// ```
set_button_handler: ffi('int mgos_gpio_set_button_handler(int,int,int,int,void(*)(int, userdata), userdata)'),
};

88
build/fs/api_grove.js Normal file
View File

@@ -0,0 +1,88 @@
load('api_gpio.js');
load('api_adc.js');
let Grove = {
Button: {
// ## **`Grove.Button.attach(pin, handler)`**
// Attach a handler for the button on the given pin. Example:
// ```javascript
// Grove.Button.attach(pin, function(pin) {
// print('Button event at pin', pin);
// }, null);
// ```
attach: function(pin, handler) {
GPIO.set_button_handler(pin, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 200,
handler, true);
},
},
_motionHandler: undefined,
MotionSensor: {
// ## **`Grove.MotionSensor.attach(pin, handler)`**
// Attach a handler for the motion sensor on the given pin. Example:
// ```javascript
// Grove.MotionSensor.attach(pin, function(pin) {
// print('Motion sensor event at pin', pin);
// }, null);
// ```
attach: function(pin, handler) {
GPIO.set_mode(pin, GPIO.MODE_INPUT);
GPIO.set_int_handler(pin, GPIO.INT_EDGE_POS, handler, null);
GPIO.enable_int(pin);
Grove._motionHandler = handler;
},
},
LightSensor: {
// ## **`Grove.LightSensor.get(pin)`**
// Not implemented yet
get: function(pin) {
return ADC.read(pin);
},
},
MoistureSensor: {
// ## **`Grove.MoistureSensor.get(pin)`**
// Not implemented yet
get: function(pin) {
return ADC.read(pin);
},
},
UVSensor: {
// ## **`Grove.MoistureSensor.get(pin)`**
// Not implemented yet
get: function(pin) {
return ADC.read(pin);
},
},
_relayInited: undefined,
_relayClosed: 0,
Relay: {
_init: function(pin) {
if (Grove._relayInited !== 1) {
GPIO.set_mode(pin, GPIO.MODE_OUTPUT);
GPIO.set_pull(pin, GPIO.PULL_DOWN);
Grove._relayInited = 1;
}
},
// ## **`Grove.Relay.open(pin)`**
// Open relay at the given pin.
open: function(pin) {
this._init(pin);
GPIO.write(pin, 0);
Grove._relayClosed = 0;
},
// ## **`Grove.Relay.close(pin)`**
// Close relay at the given pin.
close: function(pin) {
this._init(pin);
GPIO.write(pin, 1);
Grove._relayClosed = 1;
},
// ## **`Grove.Relay.isClosed(pin)`**
// Returns 0 if relay is opened, or 1 if it's closed.
isClosed: function(pin) {
return Grove._relayClosed;
},
},
};

111
build/fs/api_http.js Normal file
View File

@@ -0,0 +1,111 @@
load('api_net.js');
let URL = {
// ## **`URL.parse(url)`**
// Parse URL string, return and object with `ssl`, `addr`, `uri` keys.
//
// Example:
// ```javascript
// print(JSON.stringify(URL.parse('https://a.b:1234/foo?bar')));
// // Prints: {"uri":"/foo?bar","addr":"a.b:1234","ssl":true}
// ```
parse: function(url) {
let ssl = false, addr, port = '80', uri = '/', app = true;
if (url.slice(0, 8) === 'https://') {
port = '443';
ssl = true;
url = url.slice(8);
}
if (url.slice(0, 7) === 'http://') {
url = url.slice(7);
}
addr = url;
for (let i = 0; i < url.length; i++) {
let ch = url[i];
if (ch === ':') app = false;
if (ch === '/') {
addr = url.slice(0, i);
uri = url.slice(i);
break;
}
}
if (app) addr += ':' + port;
return {ssl: ssl, addr: addr, uri: uri};
},
};
let HTTP = {
_getm: ffi('void *mgos_get_msg_ptr(void *)'),
_getb: ffi('void *mgos_get_body_ptr(void *)'),
_mgp: ffi('void *mgos_get_mgstr_ptr(void *)'),
_mgl: ffi('int mgos_get_mgstr_len(void *)'),
_c: ffi('void *mgos_connect_http(char *, void (*)(void *, int, void *, userdata), userdata)'),
_cs: ffi('void *mgos_connect_http_ssl(char *, void (*)(void *, int, void *, userdata), userdata, char *, char *, char *)'),
_sp: ffi('void mg_set_protocol_http_websocket(void *)'),
_mstr: function(hmptr, func) {
let mgstr = func(hmptr);
return mkstr(this._mgp(mgstr), this._mgl(mgstr));
},
// ## **`HTTP.query(options);`**
// Send HTTP request. Options object accepts the following fields:
// `url` - mandatory URL to fetch, `success` - optional callback function
// that receives reply body, `error` - optional error callback that receives
// error string, `data` - optional object with request parameters.
// By default, `GET` method is used. If `data` is specified, POST method
// is used, the `data` object gets `JSON.stringify()`-ed and used as a
// HTTP message body.
//
// In order to send HTTPS request, use `https://...` URL. Note that in that
// case `ca.pem` file must contain CA certificate of the requested server.
//
// Example:
// ```javascript
// HTTP.query({
// url: 'http://httpbin.org/post',
// headers: { 'X-Foo': 'bar' }, // Optional - headers
// data: {foo: 1, bar: 'baz'}, // Optional. If set, JSON-encoded and POST-ed
// success: function(body, full_http_msg) { print(body); },
// error: function(err) { print(err); }, // Optional
// });
// ```
query: function(opts) {
let url = URL.parse(opts.url || '');
return Net.connect({
addr: url.addr,
ssl: url.ssl,
u: url,
opts: opts,
onconnect: function(conn, edata, ud) {
let opts = ud.opts;
let body = opts.data || '';
if (typeof(body) !== 'string') body = JSON.stringify(body);
let meth = body ? 'POST' : 'GET';
let host = 'Host: ' + ud.u.addr + '\r\n';
let cl = 'Content-Length: ' + JSON.stringify(body.length) + '\r\n';
let hdrs = opts.headers || {};
for (let k in hdrs) {
cl += k + ': ' + hdrs[k] + '\r\n';
}
let req = meth + ' ' + ud.u.uri + ' HTTP/1.0\r\n' + host + cl + '\r\n';
Net.send(conn, req);
Net.send(conn, body);
HTTP._sp(conn);
},
onevent: function(conn, buf, ev, edata, ud) {
if (ev === 101 && ud.opts.success) {
let body = HTTP._mstr(edata, HTTP._getb);
let full = HTTP._mstr(edata, HTTP._getm);
ud.opts.success(body, full);
ud.ok = true;
}
},
onclose: function(conn, ud) {
let opts = ud.opts;
if (!ud.ok && opts.error) opts.error('', 'Request failed', opts);
},
});
},
};

76
build/fs/api_log.js Normal file
View File

@@ -0,0 +1,76 @@
let Log = {
// ## **`Log.print(level, msg)`**
// Print message to stderr if provided
// level is >= `Cfg.get('debug.level')`. Possible levels are:
// - `Log.ERROR` (0)
// - `Log.WARN` (1)
// - `Log.INFO` (2)
// - `Log.DEBUG` (3)
// - `Log.VERBOSE_DEBUG` (4)
print: function(level, msg) {
let mjs = getMJS();
// Frame number: we're starting from the third frame, ignoring the first
// two:
// - this._off() or this._fn()
// - Log.print()
let cfn = 2;
// bcode offset of interest, and the corresponding function:lineno
let offs, fn, ln;
// We'll go up by call trace until we find the frame not from the current
// file
while (true) {
offs = this._off(mjs, cfn) - 1;
fn = this._fn(mjs, offs);
if (fn !== "api_log.js") {
// Found the first frame from other file, we're done.
break;
}
cfn++;
}
ln = this._ln(mjs, offs);
this._pr(fn, ln, level, msg);
},
// ## **`Log.error(msg)`**
// Shortcut for `Log.print(Log.ERROR, msg)`
error: function(msg) {
this.print(this.ERROR, msg);
},
// ## **`Log.warn(msg)`**
// Shortcut for `Log.print(Log.WARN, msg)`
warn: function(msg) {
this.print(this.WARN, msg);
},
// ## **`Log.info(msg)`**
// Shortcut for `Log.print(Log.INFO, msg)`
info: function(msg) {
this.print(this.INFO, msg);
},
// ## **`Log.debug(msg)`**
// Shortcut for `Log.print(Log.DEBUG, msg)`
debug: function(msg) {
this.print(this.DEBUG, msg);
},
// ## **`Log.verboseDebug(msg)`**
// Shortcut for `Log.print(Log.VERBOSE_DEBUG, msg)`
verboseDebug: function(msg) {
this.print(this.VERBOSE_DEBUG, msg);
},
ERROR: 0,
WARN: 1,
INFO: 2,
DEBUG: 3,
VERBOSE_DEBUG: 4,
_pr: ffi('void mgos_log(char *, int, int, char *)'),
_fn: ffi('char *mjs_get_bcode_filename_by_offset(void *, int)'),
_ln: ffi('int mjs_get_lineno_by_offset(void *, int)'),
_off: ffi('int mjs_get_offset_by_call_frame_num(void *, int)'),
};

62
build/fs/api_math.js Normal file
View File

@@ -0,0 +1,62 @@
let Math = {
// ## **`Math.ceil(x)`**
// Rounds x upward, returning the smallest integral value that is not less
// than x.
ceil: ffi('double ceil(double)'),
// ## **`Math.floor(x)`**
// Rounds x downward, returning the largest integral value that is not
// greater than x.
floor: ffi('double floor(double)'),
// ## **`Math.round(x)`**
// Returns the integral value that is nearest to x, with halfway cases
// rounded away from zero.
round: ffi('double round(double)'),
// ## **`Math.max(x, y)`**
// Returns the larger of its arguments: either `x` or `y`.
// If one of the arguments in a NaN, the other is returned.
max: ffi('double fmax(double, double)'),
// ## **`Math.min(x, y)`**
// Returns the smaller of its arguments: either `x` or `y`.
// If one of the arguments in a NaN, the other is returned.
min: ffi('double fmin(double, double)'),
// ## **`Math.abs(x)`**
// Returns the absolute value of `x`: |x|.
abs: ffi('double fabs(double)'),
// ## **`Math.sqrt(x)`**
// Returns the square root of `x`.
sqrt: ffi('double sqrt(double)'),
// ## **`Math.floor(x)`**
// Returns the base-e exponential function of `x`, which is e raised to the
// power `x`.
exp: ffi('double exp(double)'),
// ## **`Math.log(x)`**
// Returns the natural logarithm of `x`.
log: ffi('double log(double)'),
// ## **`Math.pow(base, exponent)`**
// Returns `base` raised to the power `exponent`
pow: ffi('double pow(double, double)'),
// ## **`Math.sin(x)`**
// Returns the sine of an angle of `x` radians.
sin: ffi('double sin(double)'),
// ## **`Math.cos(x)`**
// Returns the cosine of an angle of `x` radians.
cos: ffi('double cos(double)'),
// ## **`Math.random(x)`**
// Returns the pseudo-random number from 0.0 to 1.0
random: function() { return Math.rand() / 0x7fffffff; },
rand: ffi('int rand()'),
};

136
build/fs/api_net.js Normal file
View File

@@ -0,0 +1,136 @@
load('api_events.js');
let Net = {
_rb: ffi('void *mgos_get_recv_mbuf(void *)'),
_mptr: ffi('void *mgos_get_mbuf_ptr(void *)'),
_glen: ffi('int mgos_get_mbuf_len(void *)'),
_mrem: ffi('void mbuf_remove(void *, int)'),
_isin: ffi('bool mgos_is_inbound(void *)'),
_bind: ffi('void *mgos_bind(char *, void (*)(void *, int, void *, userdata), userdata)'),
_c: ffi('void *mgos_connect(char *, void (*)(void *, int, void *, userdata), userdata)'),
_cs: ffi('void *mgos_connect_ssl(char *, void (*)(void *, int, void *, userdata), userdata, char *, char *, char *)'),
_send: ffi('void mg_send(void *, void *, int)'),
_ctos: ffi('int mg_conn_addr_to_str(void *, char *, int, int)'),
// Return string contained in connection's recv_mbuf
_rbuf: function(conn) {
let rb = this._rb(conn);
return mkstr(this._mptr(rb), this._glen(rb));
},
// **`Net.ctos(conn, local, ip, port)`**
// Convert address of a connection `conn` to string. Set `local` to
// `true` to stringify local address, otherwise `false` to stringify remote.
// Set `ip` to `true` to stringify IP, `port` to stringify port. Example:
// ```javascript
// print('Connection from:', Net.ctos(conn, false, true, true));
// ```
ctos: function(conn, local, ip, port) {
let buf = ' ';
let flags = (local ? 0 : 4) | (ip ? 1 : 0) | (port ? 2 : 0);
let n = this._ctos(conn, buf, buf.length, flags);
return buf.slice(0, n);
},
// **`Net.discard(conn, len)`**
// Remove initial `len` bytes of data from the connection's `conn`
// receive buffer in order to discard that data and reclaim RAM to the system.
discard: function(conn, len) {
this._mrem(this._rb(conn), len);
},
// Event handler. Expects an object with connect/data/close/event user funcs.
_evh: function(conn, ev, edata, obj) {
if (ev === 0) return;
if (ev === 1 || ev === 2) {
if (obj.onconnect) obj.onconnect(conn, edata, obj);
} else if (ev === 3) {
if (obj.ondata) obj.ondata(conn, Net._rbuf(conn), obj);
} else if (ev === 5) {
if (obj.onclose) obj.onclose(conn, obj);
let inb = Net._isin(conn); // Is this an inbound connection ?
if (!inb) ffi_cb_free(Net._evh, obj);
} else if (ev >= 6) {
if (obj.onevent) obj.onevent(conn, Net._rbuf(conn), ev, edata, obj);
}
},
// ## **`Net.serve(options)`**
// Start TCP or UDP server. `options` is an object:
// ```javascript
// {
// // Required. Port to listen on, 'tcp://PORT' or `udp://PORT`.
// addr: 'tcp://1234',
// // Optional. Called when connection is established.
// onconnect: function(conn) {},
// // Optional. Called when new data is arrived.
// ondata: function(conn, data) {},
// // Optional. Called when protocol-specific event is triggered.
// onevent: function(conn, data, ev, edata) {},
// // Optional. Called when the connection is about to close.
// onclose: function(conn) {},
// // Optional. Called when on connection error.
// onerror: function(conn) {},
// }
// ```
// Example - a UDP echo server. Change `udp://` to `tcp://` to turn this
// example into the TCP echo server:
// ```javascript
// Net.serve({
// addr: 'udp://1234',
// ondata: function(conn, data) {
// print('Received from:', Net.ctos(conn, false, true, true), ':', data);
// Net.send(conn, data); // Echo received data back
// Net.discard(conn, data.length); // Discard received data
// },
// });
// ```
serve: function(obj) {
return this._bind(obj.addr, this._evh, obj);
},
// ## **`Net.connect(options)`**
// Connect to a remote host. `options` is the same as for the `Net.serve`.
// The addr format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or
// `udp`. `HOST` could be an IP address or a host name. If `HOST` is a name,
// it will be resolved asynchronously.
//
// Examples of valid addresses: `google.com:80`, `udp://1.2.3.4:53`,
// `10.0.0.1:443`, `[::1]:80`.
connect: function(obj) {
if (obj.ssl) {
return this._cs(obj.addr, this._evh, obj, obj.cert || '', obj.key || '', obj.ca_cert || 'ca.pem');
} else {
return this._c(obj.addr, this._evh, obj);
}
},
// ## **`Net.close(conn)`**
// Send all pending data to the remote peer,
// and disconnect when all data is sent.
// Return value: none.
close: ffi('void mgos_disconnect(void *)'),
// ## **`Net.send(conn, data)`**
// Send data to the remote peer. `data` is an mJS string.
// Return value: none.
send: function(c, msg) {
return Net._send(c, msg, msg.length);
},
// ## **`Net.EVENT_GRP`**
// Net events group, to be used with `Event.addGroupHandler()`. Possible
// events are:
// - `Net.STATUS_DISCONNECTED`
// - `Net.STATUS_CONNECTING`
// - `Net.STATUS_CONNECTED`
// - `Net.STATUS_GOT_IP`
EVENT_GRP: Event.baseNumber("NET"),
};
Net.STATUS_DISCONNECTED = Net.EVENT_GRP + 0;
Net.STATUS_CONNECTING = Net.EVENT_GRP + 1;
Net.STATUS_CONNECTED = Net.EVENT_GRP + 2;
Net.STATUS_GOT_IP = Net.EVENT_GRP + 3;

71
build/fs/api_rpc.js Normal file
View File

@@ -0,0 +1,71 @@
let RPC = {
_sdup: ffi('void *strdup(char *)'),
_ah: ffi('void *mgos_rpc_add_handler(void *, void (*)(void *, char *, char *, userdata), userdata)'),
_resp: ffi('bool mgos_rpc_send_response(void *, char *)'),
_call: ffi('bool mgos_rpc_call(char *, char *, char *, void (*)(char *, int, char *, userdata), userdata)'),
_err: ffi('bool mg_rpc_send_errorf(void *, int, char *, char *)'),
_ahcb: function(ri, args, src, ud) {
// NOTE(lsm): not using `this` here deliberately. Calleth from C.
let resp = ud.cb(JSON.parse(args || 'null'), src, ud.ud);
if (typeof(resp) === 'object' && typeof(resp.error) === 'number') {
RPC._err(ri, resp.error, '%s', resp.message || '');
} else {
RPC._resp(ri, JSON.stringify(resp));
}
// NOTE: we don't call ffi_cb_free here because this handler might be used
// more than once
},
_ccb: function(res, code, msg, ud) {
ud.cb(res ? JSON.parse(res) : null, code, msg, ud.ud);
ffi_cb_free(RPC._ccb, ud);
},
LOCAL: "RPC.LOCAL",
// ## **`RPC.addHandler(name, handler)`**
// Add RPC handler. `name` is a string like `'MyMethod'`, `handler`
// is a callback function which takes `args` arguments object.
// If a handler returns an object with a numeric `error` attribute and
// optional `message` string attribute, the caller will get a failure.
//
// Return value: none.
//
// Example:
// ```javascript
// RPC.addHandler('Sum', function(args) {
// if (typeof(args) === 'object' && typeof(args.a) === 'number' &&
// typeof(args.b) === 'number') {
// return args.a + args.b;
// } else {
// return {error: -1, message: 'Bad request. Expected: {"a":N1,"b":N2}'};
// }
// });
// ```
addHandler: function(name, cb, ud) {
let data = {cb: cb, ud: ud};
// TODO(lsm): get rid of this strdup() leak. One-off, but still ugly.
this._ah(this._sdup(name), this._ahcb, data);
},
// ## **`RPC.call(dst, method, args, callback)`**
// Call remote or local RPC service.
// Return value: true in case of success, false otherwise.
//
// If `dst` is empty, connected server is implied. `method` is a string
// like "MyMethod", `callback` is a callback function which takes the following
// arguments: res (results object), err_code (0 means success, or error code
// otherwise), err_msg (error messasge for non-0 error code), userdata. Example:
//
// ```javascript
// RPC.call(RPC.LOCAL, 'Config.Save', {reboot: true}, function (resp, ud) {
// print('Response:', JSON.stringify(resp));
// }, null);
// ```
call: function(dst, name, args, cb, ud) {
let data = {cb: cb, ud: ud};
return this._call(dst, name, JSON.stringify(args), this._ccb, data);
},
};

46
build/fs/api_sys.js Normal file
View File

@@ -0,0 +1,46 @@
let Sys = {
// ## **`Sys._sbuf(len)`**
// Helper function to allocate string of at least given length. Note that
// the resulting string is usually bigger than this, and it is always
// longer than 5 bytes; that's to guarantee that the string data is stored in
// a common buffer and not inlined into mjs_val_t, thus the buffer can be
// used as an "output" buffer: a string can be passed to some function which
// will alter the contents, and these changes will be visible to the caller.
_sbuf: function(len) {
let chunk = ' ', buf = chunk;
while (buf.length < len) buf += chunk;
return buf;
},
// ## **`Sys.calloc(nmemb, size)`**
// Allocate a memory region.
// Note: currently memory allocated this way must be explicitly released with `free()`.
malloc: ffi('void *malloc(int)'),
free: ffi('void free(void *)'),
// ## **`Sys.total_ram()`**
// Return total available RAM in bytes.
total_ram: ffi('int mgos_get_heap_size()'),
// ## **`Sys.free_ram()`**
// Return free available RAM in bytes.
free_ram: ffi('int mgos_get_free_heap_size()'),
// ## **`Sys.reboot(us)`**
// Reboot the system after `us` microseconds. Return value: none.
reboot: ffi('void mgos_system_restart(int)'),
// ## **`Sys.uptime()`**
// Return number of seconds since last reboot.
uptime: ffi('double mgos_uptime()'),
// ## **`Sys.usleep(microseconds)`**
// Sleep given number of microseconds.
// Return value: none.
usleep: ffi('void mgos_usleep(int)'),
// ## **`Sys.wdt_feed()`**
// Feed the watchdog timer.
// Return value: none.
wdt_feed: ffi('void mgos_wdt_feed()')
};

54
build/fs/api_timer.js Normal file
View File

@@ -0,0 +1,54 @@
load('api_math.js');
let Timer = {
_f: ffi('int mgos_strftime(char *, int, char *, int)'),
// ## **`Timer.set(milliseconds, flags, handler, userdata)`**
// Setup timer with `milliseconds` timeout and `handler` as a callback.
// `flags` can be either 0 or `Timer.REPEAT`. In the latter case, the call
// will be repeated indefinitely (but can be cancelled with `Timer.del()`),
// otherwise it's a one-off.
//
// Return value: numeric timer ID.
//
// Example:
// ```javascript
// // Call every second
// Timer.set(1000, Timer.REPEAT, function() {
// let value = GPIO.toggle(2);
// print(value ? 'Tick' : 'Tock');
// }, null);
// ```
set: ffi('int mgos_set_timer(int,int,void(*)(userdata),userdata)'),
REPEAT: 1,
// ## **`Timer.now()`**
// Return current time as double value, UNIX epoch (seconds since 1970).
now: ffi('double mg_time(void)'),
// ## **`Timer.del(id)`**
// Cancel previously installed timer.
del: ffi('void mgos_clear_timer(int)'),
// ## **`Timer.fmt(fmt, time)`**
// Formats the time 'time' according to the strftime-like format
// specification 'fmt'. The strftime reference can be found e.g.
// [here](http://www.cplusplus.com/reference/ctime/strftime/).
// Example:
// ```javascript
// let now = Timer.now();
// let s = Timer.fmt("Now it's %I:%M%p.", now);
// print(s); // Example output: "Now it's 12:01AM."
// ```
fmt: function(fmt, time) {
if (!fmt) return 'invalid format';
let res = 0, t = Math.round(time || Timer.now()), s = ' ';
while (res === 0) {
res = this._f(s, s.length, fmt, t);
if (res === -1) return 'invalid time';
if (res === 0) s += ' ';
}
return s.slice(0, res);
},
};

165
build/fs/api_uart.js Normal file
View File

@@ -0,0 +1,165 @@
// UART API. Source C API is defined at:
// [mgos_uart.h](https://github.com/cesanta/mongoose-os/blob/master/fw/src/mgos_uart.h)
let UART = {
_free: ffi('void free(void *)'),
_cdef: ffi('void *mgos_uart_config_get_default(int)'),
_cbp: ffi('void mgos_uart_config_set_basic_params(void *, int, int, int, int)'),
_crx: ffi('void mgos_uart_config_set_rx_params(void *, int, int, int)'),
_ctx: ffi('void mgos_uart_config_set_tx_params(void *, int, int)'),
_cfg: ffi('int mgos_uart_configure(int, void *)'),
_wr: ffi('int mgos_uart_write(int, char *, int)'),
_rd: ffi('int mgos_uart_read(int, void *, int)'),
// ## **`UART.setConfig(uartNo, param)`**
// Set UART config. `param` is an
// object with the following optional fields:
//
// - `baudRate`: baud rate, integer, default: 115200;
// - `numDataBits`: Number of data bits, default: 8;
// - `parity`: Parity: 0 - none, 1 - even, 2 - odd; default: none;
// - `numStopBits`: Number of stop bits: 1 - 1 bit, 2 - 2 bits, 3 - 1.5; default: 1;
// - `rxBufSize`: size of the Rx buffer, integer, default: 256;
// - `rxFlowControl`: whether Rx flow control (RTS pin) is enabled, boolean,
// default: false;
// - `rxLingerMicros`: how many microseconds to linger after Rx fifo
// is empty, in case more data arrives. Integer, default: 15;
// - `txBufSize`: size of the Tx buffer, integer, default: 256;
// - `txFlowControl`: whether Tx flow control (CTS pin) is enabled, boolean,
// default: false;
//
// Other than that, there are architecture-dependent settings, grouped in
// the objects named with the architecture name: "esp32", "esp8266", etc.
//
// Settings for esp32:
//
// ```
// esp32: {
// /*
// * GPIO pin numbers, default values depend on UART.
// *
// * UART 0: Rx: 3, Tx: 1, CTS: 19, RTS: 22
// * UART 1: Rx: 13, Tx: 14, CTS: 15, RTS: 16
// * UART 2: Rx: 17, Tx: 25, CTS: 26, RTS: 27
// */
// gpio: {
// rx: number,
// tx: number,
// cts: number,
// rts: number,
// },
//
// /* Hardware FIFO tweaks */
// fifo: {
// /*
// * A number of bytes in the hardware Rx fifo, should be between 1 and 127.
// * How full hardware Rx fifo should be before "rx fifo full" interrupt is
// * fired.
// */
// rxFullThresh: number,
//
// /*
// * A number of bytes in the hardware Rx fifo, should be more than
// * rx_fifo_full_thresh.
// *
// * How full hardware Rx fifo should be before CTS is deasserted, telling
// * the other side to stop sending data.
// */
// rxFcThresh: number,
//
// /*
// * Time in uart bit intervals when "rx fifo full" interrupt fires even if
// * it's not full enough
// */
// rxAlarm: number,
//
// /*
// * A number of bytes in the hardware Tx fifo, should be between 1 and 127.
// * When the number of bytes in Tx buffer becomes less than
// * tx_fifo_empty_thresh, "tx fifo empty" interrupt fires.
// */
// txEmptyThresh: number,
// },
// }
// ```
setConfig: function(uartNo, param) {
let cfg = this._cdef(uartNo);
this._cbp(cfg, param.baudRate || 115200,
param.numDataBits || 8,
param.parity || 0,
param.numStopBits || 1);
this._crx(
cfg,
param.rxBufSize || 256,
param.rxFlowControl || false,
param.rxLingerMicros || 15
);
this._ctx(
cfg,
param.txBufSize || 256,
param.txFlowControl || false
);
// Apply arch-specific config
if (this._arch !== undefined) {
this._arch.scfg(uartNo, cfg, param);
}
let res = this._cfg(uartNo, cfg);
this._free(cfg);
cfg = null;
return res;
},
// ## **`UART.setDispatcher(uartNo, callback, userdata)`**
// Set UART dispatcher
// callback which gets invoked when there is a new data in the input buffer
// or when the space becomes available on the output buffer.
//
// Callback receives the following arguments: `(uartNo, userdata)`.
setDispatcher: ffi('void mgos_uart_set_dispatcher(int, void(*)(int, userdata), userdata)'),
// ## **`UART.write(uartNo, data)`**
// Write data to the buffer. Returns number of bytes written.
//
// Example usage: `UART.write(1, "foobar")`, in this case, 6 bytes will be written.
write: function(uartNo, data) {
this._wr(uartNo, data, data.length);
},
// ## **`UART.writeAvail(uartNo)`**
// Return amount of space available in the output buffer.
writeAvail: ffi('int mgos_uart_write_avail(int)'),
// ## **`UART.read(uartNo)`**
// It never blocks, and returns a string containing
// read data (which will be empty if there's no data available).
read: function(uartNo) {
let n = 0; let res = ''; let buf = 'xxxxxxxxxx'; // Should be > 5
while ((n = this._rd(uartNo, buf, buf.length)) > 0) {
res += buf.slice(0, n);
}
return res;
},
// ## **`UART.readAvail(uartNo)`**
// Return amount of data available in the input buffer.
readAvail: ffi('int mgos_uart_read_avail(int)'),
// ## **`UART.setRxEnabled(uartNo)`**
// Set whether Rx is enabled.
setRxEnabled: ffi('void mgos_uart_set_rx_enabled(int, int)'),
// ## **`UART.isRxEnabled(uartNo)`**
// Returns whether Rx is enabled.
isRxEnabled: ffi('int mgos_uart_is_rx_enabled(int)'),
// ## **`UART.flush(uartNo)`**
// Flush the UART output buffer, wait for the data to be sent.
flush: ffi('void mgos_uart_flush(int)'),
};
// Load arch-specific API
load('api_arch_uart.js');

36
build/fs/api_wifi.js Normal file
View File

@@ -0,0 +1,36 @@
// Wifi global object is created during C initialization.
// ## **`Wifi.scan(cb)`**
// Scan WiFi networks, call `cb` when done.
// `cb` accepts a single argument `results`, which is
// either `undefined` in case of error, or an array of object containing:
// ```javascript
// {
// "ssid": "NetworkName",
// "bssid": "12:34:56:78:90:ab",
// "authMode": Wifi.AUTH_MODE_WPA_PSK, // Auth mode, one of AUTH constants.
// "channel": 11,
// "rssi": -70
// }
// ```
// Example:
// ```javascript
// Wifi.scan(function(results) {
// print(JSON.stringify(results));
// });
// ```
// Must be kept in sync with enum mgos_wifi_auth_mode
// ## **Auth modes**
// - `Wifi.AUTH_MODE_OPEN`
// - `Wifi.AUTH_MODE_WEP`
// - `Wifi.AUTH_MODE_WPA_PSK`
// - `Wifi.AUTH_MODE_WPA2_PSK`
// - `Wifi.AUTH_MODE_WPA_WPA2_PSK`
// - `Wifi.AUTH_MODE_WPA2_ENTERPRISE`
Wifi.AUTH_MODE_OPEN = 0;
Wifi.AUTH_MODE_WEP = 1;
Wifi.AUTH_MODE_WPA_PSK = 2;
Wifi.AUTH_MODE_WPA2_PSK = 3;
Wifi.AUTH_MODE_WPA_WPA2_PSK = 4;
Wifi.AUTH_MODE_WPA2_ENTERPRISE = 5;

298
build/fs/ca.pem Normal file
View File

@@ -0,0 +1,298 @@
Subject: O=Digital Signature Trust Co., CN=DST Root CA X3
Not Before: Sep 30 21:12:19 2000 GMT
Not After : Sep 30 14:01:15 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
Not Before: May 12 18:46:00 2000 GMT
Not After : May 12 23:59:00 2025 GMT
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
-----END CERTIFICATE-----
Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
Not Before: May 21 04:00:00 2002 GMT
Not After : May 21 04:00:00 2022 GMT
-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----
Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 ECC 256 bit SSL CA - G2
Not Before: May 12 00:00:00 2015 GMT
Not After : May 11 23:59:59 2025 GMT
-----BEGIN CERTIFICATE-----
MIIEajCCA1KgAwIBAgIQP5KHvp0dpKN6nfYoLndaxDANBgkqhkiG9w0BAQsFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMTUwNTEyMDAwMDAwWhcNMjUwNTExMjM1OTU5WjCBgDEL
MAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8wHQYD
VQQLExZTeW1hbnRlYyBUcnVzdCBOZXR3b3JrMTEwLwYDVQQDEyhTeW1hbnRlYyBD
bGFzcyAzIEVDQyAyNTYgYml0IFNTTCBDQSAtIEcyMFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAEDxukkdfnrOfRTk63ZFvhj39uBNOrONtEt0Bcbb2WljffeYmGZ/ex
Hwie/WM7RoyfvVPoFdyXPiuBRq2Gfw4BOaOCAV0wggFZMC4GCCsGAQUFBwEBBCIw
IDAeBggrBgEFBQcwAYYSaHR0cDovL3Muc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYB
Af8CAQAwZQYDVR0gBF4wXDBaBgpghkgBhvhFAQc2MEwwIwYIKwYBBQUHAgEWF2h0
dHBzOi8vZC5zeW1jYi5jb20vY3BzMCUGCCsGAQUFBwICMBkaF2h0dHBzOi8vZC5z
eW1jYi5jb20vcnBhMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9zLnN5bWNiLmNv
bS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKwYDVR0RBCQwIqQgMB4xHDAa
BgNVBAMTE1NZTUMtRUNDLUNBLXAyNTYtMjIwHQYDVR0OBBYEFCXwiuFLetkBlQrt
xlPxjHgf2fP4MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
SIb3DQEBCwUAA4IBAQAMMGUXBaWTdaLxsTGtcB/naqjIQrLvoV9NG+7MoHpGd/69
dZ/h2zOy7sGFUHoG/0HGRA9rxT/5w5GkEVIVkxtWyIWWq6rs4CTZt8Bej/KHYRbo
jtEDUkCTZSTLiCvguPyvinXgxy+LHT+PmdtEfXsvcdbeBSWUYpOsDYvD2hNtz9dw
Od5nBosMApmdxt+z7LQyZu8wMnfI1U6IMO+RWowxZ8uy0oswdFYd32l9xe+aAE/k
y9alLu/M9pvxiUKufqHJRgDBKA6uDjHLMPX+/nxXaNCPX3SI4KVZ1stHQ/U5oNlM
dHN9umAvlU313g0IgJrjsQ2nIdf9dsdP+6lrmP7s
-----END CERTIFICATE-----
Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5
Not Before: Nov 8 00:00:00 2006 GMT
Not After : Jul 16 23:59:59 2036 GMT
-----BEGIN CERTIFICATE-----
MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
-----END CERTIFICATE-----
Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
Not Before: Jun 29 17:06:20 2004 GMT
Not After : Jun 29 17:06:20 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority
Not Before: Jun 29 17:39:16 2004 GMT
Not After : Jun 29 17:39:16 2034 GMT
-----BEGIN CERTIFICATE-----
MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
-----END CERTIFICATE-----
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2
-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
-----END CERTIFICATE-----
Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2
Not Before: Sep 1 00:00:00 2009 GMT
Not After : Dec 31 23:59:59 2037 GMT
-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
sSi6
-----END CERTIFICATE-----
Subject: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Not Before: Dec 15 08:00:00 2006 GMT
Not After : Dec 15 08:00:00 2021 GMT
-----BEGIN CERTIFICATE-----
MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
-----END CERTIFICATE-----
Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
Not Before: Nov 10 00:00:00 2006 GMT
Not After : Nov 10 00:00:00 2031 GMT
-----BEGIN CERTIFICATE-----
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
+OkuE6N36B9K
-----END CERTIFICATE-----

115
build/fs/conf0.json Normal file
View File

@@ -0,0 +1,115 @@
{
"device": {
"id": "HiGrow_??????",
"password": ""
},
"debug": {
"udp_log_addr": "",
"level": 2,
"filter": "",
"stdout_uart": 0,
"stderr_uart": 0,
"factory_reset_gpio": -1,
"mg_mgr_hexdump_file": "",
"mbedtls_level": 0
},
"sys": {
"mount": {
"path": "",
"dev_type": "",
"dev_opts": "",
"fs_type": "",
"fs_opts": ""
},
"tz_spec": "",
"wdt_timeout": 30,
"pref_ota_lib": "",
"esp32_adc_vref": 0
},
"conf_acl": "*",
"bt": {
"enable": true,
"dev_name": "HiGrowBT_",
"adv_enable": true,
"scan_rsp_data_hex": "",
"keep_enabled": false,
"allow_pairing": true,
"max_paired_devices": -1,
"random_address": true,
"gatts": {
"min_sec_level": 0,
"require_pairing": false
},
"config_svc_enable": true
},
"mjs": {
"generate_jsc": true
},
"rpc": {
"enable": true,
"max_frame_size": 4096,
"max_queue_length": 25,
"default_out_channel_idle_close_timeout": 10,
"acl_file": "",
"auth_domain": "",
"auth_file": "",
"ws": {
"enable": true,
"server_address": "",
"reconnect_interval_min": 1,
"reconnect_interval_max": 60,
"ssl_server_name": "",
"ssl_ca_file": "",
"ssl_client_cert_file": ""
},
"uart": {
"uart_no": 0,
"baud_rate": 115200,
"fc_type": 2,
"wait_for_start_frame": true
}
},
"wifi": {
"sta": {
"enable": false,
"ssid": "",
"pass": "",
"user": "",
"anon_identity": "",
"cert": "",
"key": "",
"ca_cert": "",
"ip": "",
"netmask": "",
"gw": "",
"nameserver": "",
"dhcp_hostname": ""
},
"ap": {
"enable": false,
"ssid": "Mongoose_??????",
"pass": "Mongoose",
"hidden": false,
"channel": 6,
"max_connections": 10,
"ip": "192.168.4.1",
"netmask": "255.255.255.0",
"gw": "192.168.4.1",
"dhcp_start": "192.168.4.2",
"dhcp_end": "192.168.4.100",
"trigger_on_gpio": -1,
"disable_after": 0,
"hostname": "",
"keep_enabled": true
}
},
"higrow": {
"deviceId": "",
"temperature": 0.0,
"humidity": 0.0,
"light": 0,
"moisture": 0,
"connected": false,
"battery_calibration": 2360
}
}

95
build/fs/init.js Normal file
View File

@@ -0,0 +1,95 @@
load('api_config.js');
load('api_events.js');
load('api_gpio.js');
load('api_http.js');
load('api_net.js');
load('api_sys.js');
load('api_timer.js');
load('api_esp32.js');
load('api_dht.js');
load('api_adc.js');
load('api_rpc.js');
//Pins
let ResetPin = 0;
let LedPin = 16;
let DHTpin = 22;
let SOILpin = 32;
let LIGHTpin = 34;
// Turn on status led
GPIO.set_mode(LedPin, GPIO.MODE_OUTPUT);
GPIO.write(LedPin, 0);
//Reset Handler
GPIO.set_mode(ResetPin, GPIO.MODE_INPUT);
GPIO.set_int_handler(ResetPin, GPIO.INT_EDGE_NEG, function(ResetPin) {
print('Pin', ResetPin, 'got interrupt');
GPIO.toggle(LedPin);
Sys.usleep(200000);
GPIO.toggle(LedPin);
Sys.usleep(200000);
GPIO.toggle(LedPin);
Sys.usleep(200000);
GPIO.toggle(LedPin);
Sys.usleep(200000);
GPIO.toggle(LedPin);
Sys.usleep(200000);
GPIO.write(LedPin, 0);
Cfg.set({bt:{enable:true}});
Cfg.set({wifi:{sta:{enable:false}}});
Cfg.set({wifi:{ap:{enable:false}}});
Cfg.set({wifi:{sta:{ssid:'',pass:''}}});
Sys.reboot(1000);
}, null);
GPIO.enable_int(ResetPin);
ADC.enable(SOILpin);
let dht = DHT.create(DHTpin, DHT.DHT11);
let deviceId = Cfg.get("higrow.deviceId");
if (deviceId === "")
{
deviceId = Cfg.get("device.id");
Cfg.set("higrow.devideId", deviceId);
}
let connected = false;
let readSensors = Timer.set(15000, Timer.REPEAT, function() {
let t = dht.getTemp();
let h = dht.getHumidity();
let m = ADC.read(SOILpin);
let l = ADC.read(LIGHTpin);
print("DeviceId:", deviceId,"Temperature:",t,"Humidity:",h,"Moisture:",m,"Light:",l);
//Timer.del(readSensors);
//ESP32.deepSleep(3600000000); //3600 seconds / 60 minutes
/*
Cfg.set({higrow:{temperature:jsonData.Temperature}});
Cfg.set({higrow:{moisture:jsonData.Water}});
Cfg.set({higrow:{humidity:jsonData.Humidity}});
Cfg.set({higrow:{light:jsonData.Light}});
*/
}, null);
// Monitor network connectivity.
Event.addGroupHandler(Net.EVENT_GRP, function(ev, evdata, arg) {
let status = true && connected;
let evs = '???';
if (ev === Net.STATUS_DISCONNECTED) {
evs = 'DISCONNECTED';
connected = false;
} else if (ev === Net.STATUS_CONNECTING) {
evs = 'CONNECTING';
connected = false;
} else if (ev === Net.STATUS_CONNECTED) {
evs = 'CONNECTED';
connected = false;
} else if (ev === Net.STATUS_GOT_IP) {
evs = 'GOT_IP';
connected = true;
}
}, null);