A programming language that understands what a iot device app is.
Gasp (Givelink Application Specification Language) is an extensible DSL (domain-specific language) for building modern iot device apps with less code.
Concepts such as app, attr, metirc, init, loop, setup, etc. are baked into the language, bringing a new level of expressiveness and allowing you to get more work done with fewer lines of code.
NOTE: Gasp is still in alpha, meaning it has bugs, and many critical features are still missing and it is still changing a lot!
// dht.wasp:
app dht {
key: "1234567890abcdef", // product_key
token: "1234567890abcdef", // device_token. commit when you use an random token
addr: "00000000",
start_addr: 0,
ctrl_mode: false
}
GL_SERIAL = Serial
DEBUG_SERIAL = Serial
METRIC_DELAY_MS = attr_delay
// PING_FAILED_CB = noop
// AUTH_DELAY_MS = 1000
// PONG_DELAY_MS = 6000
// PING_DELAY_MS = 300000
// PING_FAILED_CB = noop
// MAX_PING_FAILED = 10
// MAX_GL_PAYLOAD_LENGTH = {= max_gl_len =}
// MAX_BUFFER_LENGTH = {= max_buf_len =}
// MAX_NUM_TOKENS = 10
// MAX_REQUEST_VALUE_LENGTH = {= max_req_len =}
// MAX_TMPL_LENGTH = {= max_tpl_len =}
// METRIC_DELAY_MS = 1800000
// DEBOUNCE_DELAY_MS = 50
setup gl_serial_setup {
GL_SERIAL.begin(115200);
while (!GL_SERIAL) {;}
}
attr delay {
type: unsigned long,
default: 1800,
min: 60,
max: 86400,
scale: 1000
}
metric temperature {
type: float,
max: 100,
min: 0,
threshold: 1,
prec: 2
}
func read_dht {
metric_temperature += 0.1;
if (metric_temperature > 100) {
metric_temperature = 0;
}
}
every read_dht 6000
attr relay_state {
type: uint8_t,
default: 0,
min: 0,
max: 1,
gen_set: false,
keep: false
}
func try_set_attr_relay_state bool {
if (attr_relay_mode == 1) {
return set_attr_relay_state(json, tokens, num_tokens, retval);
}
return false;
}
command set_relay_state {
fn: try_set_attr_relay_state,
error: "only relay_mode is 1 can set this value",
docs: {
name: "Edit attribute relay_state",
command: {
docs: [
- data is between [0, 1]
],
payload: {
method: set_relay_state,
data: 0
}
},
return: {
docs: [
- relay_state is between [0, 1]
],
payload: {
relay_state: 0
}
},
error: {
payload: {
err data must between: [0, 1]
}
}
}
}
// relay_mode 1 manual mode
// 0 auto mode
attr relay_mode {
type: uint8_t,
default: 0,
min: 0,
max: 1
}
func try_toggle_gpio_relay {
if (attr_relay_mode == 1) {
toggle_gpio_relay();
}
}
gpio relay_mode LED_BUILTIN -> link relay_mode
gpio relay 12 -> link relay_state
gpio btn0 11 HIGH -> click try_toggle_gpio_relay
gpio btn1 10 HIGH -> click toggle_gpio_relay_mode
attr high_temperature {
type: float,
default: 30,
min: 0,
max: 100
}
attr low_temperature {
type: float,
default: 20,
min: 0,
max: 100
}
attr open_delay {
type: unsigned long,
default: 5,
min: 0,
max: 3600,
scale: 1000
}
attr close_delay {
type: unsigned long,
default: 5,
min: 0,
max: 3600,
scale: 1000
}
rule metric_temperature < attr_high_temperature && metric_temperature > attr_low_temperature
do later attr_open_delay open_gpio_relay
else later attr_close_delay close_gpio_relay
on attr_relay_mode == 0
import <avr/wdt.h>
want_reboot bool = false
setup wdt_setup {
MCUSR = 0;
wdt_disable();
wdt_enable(WDTO_8S);
}
loop wdt_loop {
wdt_reset();
if (want_reboot) {
reset();
}
}
func reset {
wdt_disable();
wdt_enable(WDTO_15MS);
for (;;) {
}
}
func reset_system bool {
want_reboot = true;
return true;
}
command reset_system {
fn: reset_system
}
func emit_givelink_unauth {
givelink_context_set_auth(false);
}
gpio auth 9 LOW -> click noop
rule gpio_auth_state == HIGH
do later 2000 emit_givelink_unauth
on givelink_context_authed()
- compiled syntax see <doc.md> Template Special.
Source files (.wasp
, .ino
, .c
, .h
, ...) are compiled (transpiled) by gaspc
(Gasp compiler) into the iot technology stack of your choice (e.g. Arduino + sensor + ...).
Why is Gasp awesome:
- Quick start: Due to its expressiveness, you can create and deploy a production-ready iot device app from scratch with very few lines of concise, consistent, declarative code.
- Flexible: When you need more control than Gasp offers, you can write code in existing technologies such as c/h/... and combine it with Gasp code!
- No lock-in: If Gasp becomes too limiting for you, simply eject and continue with the generated source code, which is human-readable.
For more information about Gasp, check docs.
This is the main repo of the Gasp universe, containing core code (mostly gaspc
- Gasp compiler) and the supporting materials.