├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── question.md ├── README.md ├── ch1-gettingstarted ├── helloworld-gui │ ├── main.js │ └── manifest.json ├── helloworld │ ├── example.js │ └── manifest.json └── host │ ├── main.js │ └── manifest.json ├── ch10-piu ├── anchors │ ├── example.js │ └── manifest.json ├── background-color │ ├── example.js │ └── manifest.json ├── color-scheme │ ├── example.js │ └── manifest.json ├── colored-squares │ ├── example.js │ └── manifest.json ├── counter │ ├── example.js │ └── manifest.json ├── graph │ ├── example.js │ └── manifest.json ├── header │ ├── example.js │ ├── js.png │ └── manifest.json ├── helloworld-behavior │ ├── example.js │ └── manifest.json ├── helloworld-color │ ├── example.js │ └── manifest.json ├── helloworld-ticking │ ├── example.js │ └── manifest.json ├── helloworld │ ├── example.js │ └── manifest.json ├── host │ ├── OpenSans-Regular-24.fnt │ ├── OpenSans-Regular-24.png │ ├── OpenSans-Semibold-16.fnt │ ├── OpenSans-Semibold-16.png │ ├── main.js │ └── manifest.json ├── js-icon │ ├── example.js │ ├── js.png │ └── manifest.json ├── keyboard │ ├── example.js │ └── manifest.json ├── mask-icon │ ├── example.js │ ├── manifest.json │ └── settings-mask.png ├── multiple-screens │ ├── assets.js │ ├── button-bkg.png │ ├── example.js │ ├── logo1.png │ ├── logo2.png │ ├── logo3.png │ ├── manifest.json │ ├── restart-arrow.png │ └── screens.js ├── nav-bar-template │ ├── clock.png │ ├── example.js │ ├── manifest.json │ ├── settings.png │ └── sun.png ├── nav-bar │ ├── clock.png │ ├── example.js │ ├── manifest.json │ ├── settings.png │ └── sun.png ├── rounded-buttons │ ├── button.png │ ├── example.js │ └── manifest.json ├── scrolling-text │ ├── example.js │ └── manifest.json ├── tiled-background │ ├── example.js │ ├── manifest.json │ └── tile.png ├── timeline │ ├── example.js │ └── manifest.json ├── transitions │ ├── example.js │ └── manifest.json └── wifi-status │ ├── example.js │ ├── manifest.json │ └── wifi-strip.png ├── ch11-native ├── bitarray-arraybuffer │ ├── bitarray.c │ ├── bitarray.js │ ├── main.js │ └── manifest.json ├── bitarray-calloc │ ├── bitarray.c │ ├── bitarray.js │ ├── main.js │ └── manifest.json ├── random-integer-esp-range │ ├── main.js │ ├── manifest.json │ └── randominteger.c ├── random-integer-esp │ ├── main.js │ ├── manifest.json │ └── randominteger.c ├── random-integer │ ├── main.js │ ├── manifest.json │ └── randominteger.c └── wifi-rssi-notify │ ├── main.js │ ├── manifest.json │ ├── wifirssinotify.c │ └── wifirssinotify.js ├── ch3-network ├── accesspoint │ ├── example.js │ └── manifest.json ├── host │ ├── main.js │ └── manifest.json ├── http-get-json │ ├── example.js │ └── manifest.json ├── http-get-subclass │ ├── example.js │ └── manifest.json ├── http-get-with-promise │ ├── example.js │ └── manifest.json ├── http-get │ ├── example.js │ └── manifest.json ├── http-post │ ├── example.js │ └── manifest.json ├── http-server-get │ ├── example.js │ └── manifest.json ├── http-server-put │ ├── example.js │ └── manifest.json ├── http-server-streaming-get │ ├── example.js │ └── manifest.json ├── http-server-streaming-put │ ├── example.js │ └── manifest.json ├── http-streaming-get │ ├── example.js │ └── manifest.json ├── https-get │ ├── example.js │ └── manifest.json ├── mdns-advertise │ ├── example.js │ └── manifest.json ├── mdns-claim-name │ ├── example.js │ └── manifest.json ├── mdns-discover │ ├── example.js │ └── manifest.json ├── mqtt │ ├── example.js │ └── manifest.json ├── sntp │ ├── example.js │ └── manifest.json ├── websocket-client │ ├── example.js │ └── manifest.json ├── websocket-server │ ├── example.js │ └── manifest.json ├── wifi-code │ ├── main.js │ └── manifest.json ├── wifi-command-line │ ├── main.js │ └── manifest.json └── wifi-open-ap │ ├── main.js │ └── manifest.json ├── ch4-ble ├── host │ ├── bleservices │ │ ├── bs.json │ │ ├── gap.json │ │ └── hrs.json │ ├── main.js │ └── manifest.json ├── hrm-secure │ ├── example.js │ └── manifest.json ├── hrm │ ├── example.js │ └── manifest.json ├── scanner │ ├── example.js │ └── manifest.json ├── text-client │ ├── example.js │ └── manifest.json └── text-server │ ├── bleservices │ └── text.json │ ├── main.js │ └── manifest.json ├── ch5-files ├── files │ ├── example.js │ └── manifest.json ├── flash-frequentupdate │ ├── example.js │ └── manifest.json ├── flash-map │ ├── example.js │ └── manifest.json ├── flash-readwrite │ ├── example.js │ └── manifest.json ├── host │ ├── main.js │ └── manifest.json ├── preferences │ ├── example.js │ └── manifest.json └── resources │ ├── example.js │ ├── manifest.json │ └── mydata.dat ├── ch6-hardware ├── blink │ ├── example.js │ └── manifest.json ├── button │ ├── example.js │ └── manifest.json ├── external-button │ ├── example.js │ └── manifest.json ├── host │ ├── main.js │ └── manifest.json ├── servo │ ├── example.js │ └── manifest.json ├── tmp102 │ ├── example.js │ └── manifest.json ├── tmp36 │ ├── example.js │ └── manifest.json ├── tricolor-led-digital │ ├── example.js │ └── manifest.json └── tricolor-led-pwm │ ├── example.js │ └── manifest.json ├── ch7-audio ├── host-i2s │ ├── bflatmajor.wav │ ├── ding.wav │ ├── main.js │ ├── manifest.json │ ├── tada.wav │ ├── tick-tock.wav │ └── tick.wav ├── host-pdm │ ├── bflatmajor.wav │ ├── ding.wav │ ├── main.js │ ├── manifest.json │ ├── tada.wav │ ├── tick-tock.wav │ └── tick.wav ├── sound-clip │ ├── example.js │ └── manifest.json ├── sound-sequence │ ├── example.js │ └── manifest.json ├── sound-simultaneous │ ├── example.js │ └── manifest.json └── sound │ ├── example.js │ └── manifest.json ├── ch9-poco ├── blended-rectangle │ ├── example.js │ └── manifest.json ├── draw-jpeg │ ├── example.js │ ├── harvard.jpg │ └── manifest.json ├── fade-mask │ ├── example.js │ ├── manifest.json │ └── mask.png ├── host │ ├── OpenSans-Regular-16.fnt │ ├── OpenSans-Regular-16.png │ ├── OpenSans-Semibold-28.fnt │ ├── OpenSans-Semibold-28.png │ ├── main.js │ └── manifest.json ├── masked-image │ ├── example.js │ ├── manifest.json │ ├── mask_circle.bmp │ └── train.png ├── offscreen │ ├── example.js │ └── manifest.json ├── origin │ ├── example.js │ └── manifest.json ├── pattern-fill │ ├── example.js │ ├── manifest.json │ └── tiles.png ├── random-rectangles │ ├── example.js │ └── manifest.json ├── rectangle │ ├── example.js │ └── manifest.json ├── text-shadow │ ├── example.js │ └── manifest.json ├── text-ticker │ ├── example.js │ └── manifest.json ├── text-wrap │ ├── example.js │ └── manifest.json ├── touch │ ├── check.js │ ├── example.js │ └── manifest.json └── wifi-icons │ ├── example.js │ ├── manifest.json │ └── wifi-strip.png ├── corrigendum.md └── images └── cover.jpg /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report a problem with one of the examples 4 | title: "[Bug]" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | > Note: This template is intended to help organize your report. Feel free to modify it as you need. The most important thing is to file a clear, detailed report, not to follow the template. 11 | 12 | **Build environment:** macOS, Windows, or Linux 13 | 14 | **Target device:** NodeMCU ESP8266, NodeMCU ESP32, Moddable One, Moddable Two, desktop simulator, etc. 15 | 16 | **Description** 17 | 18 | A brief summary of the problem. 19 | 20 | If you are reporting a problem with the text, please include the page number. 21 | 22 | If you are reporting a problem with an example, please include the name of the example. 23 | 24 | If you are reporting a problem with a figure, please include the figure number (e.g. 6-12). 25 | 26 | **Steps to Reproduce** 27 | 28 | 1. Build and install the host using this build command: `mcconfig -d -m ...` 29 | 2. Build and install the example using this build command: `mcrun -d -m ...` 30 | 2. Click on '....' 31 | 3. See error 32 | 33 | **Images** 34 | 35 | Screenshots or photos to help explain the problem 36 | 37 | **Other information** 38 | 39 | Any other details you believe may be helpful in understanding the issue, reproducing the unexpected behavior, or fixing the example 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question about the book content 4 | title: "[Question]" 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Do you have questions about an example or a concept discussed in the book? Feel free to ask us here! If you have a question about the Moddable SDK, please open an issue in the [Moddable SDK repository](https://github.com/Moddable-OpenSource/moddable/). 11 | 12 | You can also ping us in the Moddable [chatroom on Gitter](https://gitter.im/embedded-javascript/moddable). This is a great option if you have a project you'd like to talk about or want to have a longer discussion. 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IoT Development for ESP32 and ESP8266 with JavaScript 2 | ### A Practical Guide to XS and the Moddable SDK 3 | 4 | by Peter Hoddie and Lizzie Prader 5 | 6 | ![Book cover](./images/cover.jpg) 7 | 8 | ## About 9 | 10 | This repository contains the source code for example apps from *IoT Development for ESP32 and ESP8266 with JavaScript*. 11 | 12 | You can purchase the book from [Keplers Books](https://www.keplers.com/book/9781484250693), [Amazon](https://www.amazon.com/IoT-Development-ESP8266-ESP32-JavaScript/dp/1484250699/ref=sr_1_2), and [Moddable](https://www.moddable.com/book#purchase). 13 | 14 | ## Table of Contents 15 | 16 | * Chapter 1 - [Getting Started](./ch1-gettingstarted) 17 | * Chapter 2 - JavaScript for Embedded C and C++ Programmers[[1](#footnotes)] 18 | * Chapter 3 - [Networking](./ch3-network) 19 | * Chapter 4 - [Bluetooth Low Energy (BLE)](./ch4-ble) 20 | * Chapter 5 - [Files and Data](./ch5-files) 21 | * Chapter 6 - [Hardware](./ch6-hardware) 22 | * Chapter 7 - [Audio](./ch7-audio) 23 | * Chapter 8 - Graphics Fundamentals[[2](#footnotes)] 24 | * Chapter 9 - [Drawing Graphics with Poco](./ch9-poco) 25 | * Chapter 10 - [Building User Interfaces with Piu](./ch10-piu) 26 | * Chapter 11 - [Adding Native Code](./ch11-native) 27 | 28 | 29 | > [1][2] *These chapters contain short examples in the text, but not in this repository.*
30 | 31 | ## Links 32 | 33 | **Twitter** 34 | 35 | * Peter Hoddie - [@phoddie](https://twitter.com/phoddie) 36 | * Lizzie Prader - [@lizzieprader](https://twitter.com/lizzieprader) 37 | * Moddable - [@moddabletech](https://twitter.com/moddabletech) 38 | 39 | **Moddable** 40 | 41 | * [Moddable website](https://www.moddable.com) 42 | * [Moddable SDK](https://github.com/Moddable-OpenSource/moddable/) 43 | 44 | 45 | ## Moddable Six Support! 46 | [Moddable Six](https://www.moddable.com/moddable-six) is an advanced display powered by the ESP32-S3. It is fully compatible with the examples in our book. This powerful development board replaces Moddable Two. Moddable Six includes a built-in speaker, so you easily use the audio examples in Chapter 7. It also features a faster display, more responsive touch, more RAM, and larger flash storage. 47 | 48 | 49 | ## Nordic nRF52 Support! 50 | 51 | The Moddable SDK 4.0 has added support for the Nordic nRF52 microcontroller. The ultra-low power nRF52 with integrated BLE allows projects to run on a coin cell battery. 52 | 53 | The Moddable SDK APIs are compatible across ESP32, ESP8266, and nRF52 microcontrollers. Therefore, the majority of the content of our book applies to nRF52 too. However, networking (Chapter 3) and audio (chapter 6) are not available on nRF52. 54 | 55 | [Moddable Four](https://www.moddable.com/moddable-four) is an nRF52 development board with BLE, a display, jog dial, and accelerometer. It is a great place to explore nRF52 development in JavaScript. 56 | 57 | ## Questions? We're here to help 58 | 59 | If you have a question or comment about the examples or content in this book, we recommend you send us a message in [our Gitter chatroom](https://gitter.im/embedded-javascript/moddable) or [open an issue](https://github.com/Moddable-OpenSource/iot-product-dev-book/issues) in this repository. Also see the [corrigendum](./corrigendum.md) for corrections to the text. 60 | 61 | If you're having technical issues with the Moddable SDK—for example installing the SDK, building and flashing examples, or using the debugger—please open an issue in the [Moddable SDK repository](https://github.com/Moddable-OpenSource/moddable/). 62 | -------------------------------------------------------------------------------- /ch1-gettingstarted/helloworld-gui/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import parseBMF from "commodetto/parseBMF"; 16 | import Poco from "commodetto/Poco"; 17 | import Resource from "Resource"; 18 | import config from "mc/config"; 19 | 20 | let render = new Poco(screen, { displayListLength: 2048, rotation: config.rotation }); 21 | 22 | let black = render.makeColor(0, 0, 0); 23 | let white = render.makeColor(255, 255, 255); 24 | 25 | let font = parseBMF(new Resource("OpenSans-Regular-24.bf4")); 26 | let text = "Hello, World"; 27 | 28 | render.begin(); 29 | render.fillRectangle(white, 0, 0, render.width, render.height); 30 | render.drawText(text, font, black, 31 | (render.width - render.getTextWidth(text, font)) >> 1, 32 | (render.height - font.height) >> 1); 33 | render.end(); 34 | -------------------------------------------------------------------------------- /ch1-gettingstarted/helloworld-gui/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/examples/manifest_commodetto.json" 5 | ], 6 | "modules": { 7 | "*": [ 8 | "./main" 9 | ] 10 | }, 11 | "resources":{ 12 | "*-mask": [ 13 | "$(MODDABLE)/examples/assets/fonts/OpenSans-Regular-24" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ch1-gettingstarted/helloworld/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | debugger; 16 | let message = "Hello, World"; 17 | trace(message + "\n"); -------------------------------------------------------------------------------- /ch1-gettingstarted/helloworld/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch1-gettingstarted/host/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Modules from "modules"; 16 | 17 | export default function () { 18 | if (Modules.has("check")) { 19 | let check = Modules.importNow("check"); 20 | check(); 21 | if (Modules.has("example")) 22 | Modules.importNow("example"); 23 | } else { 24 | trace("Device flashed. Ready to install apps.\n"); 25 | } 26 | } -------------------------------------------------------------------------------- /ch1-gettingstarted/host/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/modules/base/modules/manifest.json" 5 | ], 6 | "defines": { 7 | "XS_MODS": 1 8 | }, 9 | "modules": { 10 | "*": [ 11 | "./main" 12 | ] 13 | }, 14 | "strip": [], 15 | "build": { 16 | "NAME": "ch1host" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ch10-piu/anchors/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans", 17 | color: "black", 18 | top: 10, bottom: 10, left: 10, right: 10 19 | }); 20 | 21 | const backgroundSkin = new Skin({ 22 | fill: ["white", "gray"] 23 | }); 24 | 25 | const buttonSkin = new Skin({ 26 | fill: ["#dfdfdf", "#909090"] 27 | }); 28 | 29 | const squareSkin = new Skin({ 30 | fill: ["blue", "green"] 31 | }); 32 | 33 | class StartButtonBehavior extends Behavior { 34 | onCreate(label, data) { 35 | this.data = data; 36 | } 37 | onTouchBegan(label) { 38 | label.state = 1; 39 | } 40 | onTouchEnded(label) { 41 | label.state = 0; 42 | this.data.SQUARE.start(); 43 | this.data.BACKGROUND.start(); 44 | } 45 | } 46 | 47 | const StartButton = Label.template($ => ({ 48 | top: 60, height: 40, width: 120, 49 | skin: buttonSkin, 50 | style: textStyle, 51 | string: "Start", 52 | active: true, 53 | Behavior: StartButtonBehavior 54 | })); 55 | 56 | class AnimatedSquareBehavior extends Behavior { 57 | onCreate(content, data) { 58 | content.interval = 500; 59 | } 60 | onTimeChanged(content) { 61 | content.state = !content.state; 62 | } 63 | } 64 | 65 | const AnimatedSquare = Content.template($ => ({ 66 | top: 110, height: 40, width: 40, 67 | anchor: "SQUARE", 68 | skin: squareSkin, 69 | Behavior: AnimatedSquareBehavior 70 | })); 71 | 72 | class MainContainerBehavior extends Behavior { 73 | onCreate(content, data) { 74 | content.interval = 500; 75 | } 76 | onTimeChanged(content) { 77 | content.state = !content.state; 78 | } 79 | } 80 | 81 | const MainContainer = Container.template($ => ({ 82 | top: 0, bottom: 0, left: 0, right: 0, 83 | anchor: "BACKGROUND", 84 | skin: backgroundSkin, 85 | contents: [ 86 | new StartButton($), 87 | new AnimatedSquare($) 88 | ], 89 | Behavior: MainContainerBehavior 90 | })); 91 | 92 | let instantiatingData = {}; 93 | application.add(new MainContainer(instantiatingData)); -------------------------------------------------------------------------------- /ch10-piu/anchors/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/background-color/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans", 17 | color: "black", 18 | top: 10, bottom: 10, left: 10, right: 10 19 | }); 20 | 21 | const whiteSkin = new Skin({ 22 | fill: "white" 23 | }); 24 | 25 | const buttonSkin = new Skin({ 26 | fill: ["#dfdfdf", "#909090"] 27 | }); 28 | 29 | class ColorButtonBehavior extends Behavior { 30 | onTouchBegan(label) { 31 | label.state = 1; 32 | } 33 | onTouchEnded(label) { 34 | label.state = 0; 35 | label.bubble("onColorSelected", label.string); 36 | } 37 | } 38 | 39 | const ColorButton = Label.template($ => ({ 40 | height: 40, left: 10, right: 10, 41 | skin: buttonSkin, 42 | active: true, 43 | Behavior: ColorButtonBehavior 44 | })); 45 | 46 | class ColorScreenBehavior extends Behavior { 47 | onColorSelected(container, color) { 48 | container.skin = new Skin({ fill: color.toLowerCase() }); 49 | } 50 | } 51 | 52 | const colorScreen = new Container(null, { 53 | top: 0, bottom: 0, left: 0, right: 0, 54 | skin: whiteSkin, 55 | style: textStyle, 56 | contents: [ 57 | Row(null, { 58 | height: 50, width: 320, 59 | contents: [ 60 | new ColorButton(null, { string: "Red" }), 61 | new ColorButton(null, { string: "Yellow" }), 62 | new ColorButton(null, { string: "Blue" }) 63 | ] 64 | }) 65 | ], 66 | Behavior: ColorScreenBehavior 67 | }); 68 | 69 | application.add(colorScreen); -------------------------------------------------------------------------------- /ch10-piu/background-color/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/color-scheme/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans", 17 | color: ["black", "white"], 18 | top: 10, bottom: 10, left: 10, right: 10 19 | }); 20 | 21 | const backgroundSkin = new Skin({ 22 | fill: ["white", "black"] 23 | }); 24 | 25 | const buttonSkin = new Skin({ 26 | fill: ["#dfdfdf", "#909090"] 27 | }); 28 | 29 | class ModeButtonBehavior extends Behavior { 30 | onTouchBegan(label) { 31 | label.state = 1; 32 | } 33 | onTouchEnded(label) { 34 | label.state = 0; 35 | application.distribute("onModeChanged", label.string); 36 | } 37 | } 38 | 39 | const ModeButton = Label.template($ => ({ 40 | top: 110, height: 40, width: 120, 41 | skin: buttonSkin, 42 | active: true, 43 | Behavior: ModeButtonBehavior 44 | })); 45 | 46 | class LightDarkScreenBehavior extends Behavior { 47 | onModeChanged(container, mode) { 48 | container.state = (mode === "Dark")? 1 : 0; 49 | } 50 | } 51 | 52 | class TextBehavior extends Behavior { 53 | onModeChanged(label, mode) { 54 | label.state = (mode === "Dark")? 1 : 0; 55 | label.string = mode; 56 | } 57 | } 58 | 59 | const LightDarkScreen = new Container(null, { 60 | top: 0, bottom: 0, left: 0, right: 0, 61 | skin: backgroundSkin, 62 | style: textStyle, 63 | contents: [ 64 | Label(null, { 65 | top: 50, height: 30, left: 0, right: 0, 66 | string: "Light", 67 | Behavior: TextBehavior 68 | }), 69 | ModeButton(null, { 70 | left: 30, 71 | string: "Dark" 72 | }), 73 | ModeButton(null, { 74 | right: 30, 75 | string: "Light" 76 | }) 77 | ], 78 | Behavior: LightDarkScreenBehavior 79 | }); 80 | 81 | application.add(LightDarkScreen); -------------------------------------------------------------------------------- /ch10-piu/color-scheme/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/colored-squares/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const Square = Content.template($ => ({ 16 | width: 80, height: 80, 17 | skin: new Skin({ fill: $ }) 18 | })); 19 | 20 | const redSquare = new Square("red", { left: 20, top: 20 }); 21 | const yellowSquare = new Square("yellow"); 22 | const blueSquare = new Square("blue", { right: 20, bottom: 20 }); 23 | 24 | application.add(redSquare); 25 | application.add(yellowSquare); 26 | application.add(blueSquare); -------------------------------------------------------------------------------- /ch10-piu/colored-squares/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/counter/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans", 17 | color: "black", 18 | top: 10, bottom: 10, left: 10, right: 10 19 | }); 20 | 21 | const buttonSkin = new Skin({ 22 | fill: ["#dfdfdf", "#909090"] 23 | }); 24 | 25 | class CounterBehavior extends Behavior { 26 | onDisplaying(label) { 27 | this.count = 0; 28 | } 29 | increment(label) { 30 | label.string = ++this.count; 31 | } 32 | } 33 | 34 | const counter = new Label(null, { 35 | top: 70, height: 30, left: 0, right: 0, 36 | style: textStyle, 37 | string: "0", 38 | Behavior: CounterBehavior 39 | }); 40 | 41 | class IncrementButtonBehavior extends Behavior { 42 | onTouchBegan(label) { 43 | label.state = 1; 44 | } 45 | onTouchEnded(label) { 46 | label.state = 0; 47 | counter.delegate("increment"); 48 | } 49 | } 50 | 51 | const incrementButton = new Label(null, { 52 | top: 120, height: 40, left: 140, width: 40, 53 | style: textStyle, 54 | string: "+", 55 | skin: buttonSkin, 56 | active: true, 57 | Behavior: IncrementButtonBehavior 58 | }); 59 | 60 | application.add(counter); 61 | application.add(incrementButton); -------------------------------------------------------------------------------- /ch10-piu/counter/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/graph/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const WHITE = "white"; 16 | const GRAY = "#e6e6e6"; 17 | const BLUE = "#1932ab"; 18 | 19 | const textStyle = new Style({ 20 | font: "semibold 16px Open Sans" 21 | }); 22 | 23 | class GraphBehavior extends Behavior { 24 | onDisplaying(port) { 25 | this.values = new Array(20); 26 | this.values.fill(0); 27 | port.interval = 100; 28 | port.start(); 29 | } 30 | onTimeChanged(port) { 31 | this.values.shift(); 32 | this.values.push(Math.random() * 100); 33 | port.invalidate(); 34 | } 35 | onDraw(port, x, y, width, height) { 36 | port.fillColor(WHITE, x, y, width, height); 37 | 38 | for (let i = 100, yOffset = 0; yOffset < height; yOffset += height / 5, i -= 20) { 39 | port.drawString(i, textStyle, "black", 30 - textStyle.measure(i).width, yOffset); 40 | port.fillColor(GRAY, 35, yOffset + 10, width, 1); 41 | } 42 | 43 | let xOffset = 35; 44 | const values = this.values; 45 | for (let i = 0; i < values.length; i++) { 46 | let value = values[i]; 47 | let barHeight = (value / 100) * (height - 10); 48 | port.fillColor(BLUE, xOffset, height - barHeight, 12, barHeight); 49 | xOffset += 14; 50 | } 51 | } 52 | } 53 | 54 | const graph = new Port(null, { 55 | top: 0, bottom: 0, left: 0, right: 0, 56 | Behavior: GraphBehavior 57 | }); 58 | 59 | application.add(graph); -------------------------------------------------------------------------------- /ch10-piu/graph/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/header/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans", 17 | color: "white" 18 | }); 19 | 20 | const headerSkin = new Skin({ 21 | fill: "#1932ab" 22 | }); 23 | 24 | const jsLogoTexture = new Texture({ 25 | path: "js.png" 26 | }); 27 | 28 | const jsLogoSkin = new Skin({ 29 | texture: jsLogoTexture, 30 | height: 40, width: 40 31 | }); 32 | 33 | const jsLogo = new Content(null, { 34 | left: 10, 35 | skin: jsLogoSkin 36 | }); 37 | 38 | const headerText = new Label(null, { 39 | style: textStyle, 40 | string: "Example" 41 | }); 42 | 43 | const header = new Container(null, { 44 | top: 0, height: 50, left: 0, right: 0, 45 | skin: headerSkin, 46 | contents: [ 47 | jsLogo, 48 | headerText 49 | ] 50 | }); 51 | 52 | application.add(header); -------------------------------------------------------------------------------- /ch10-piu/header/js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/header/js.png -------------------------------------------------------------------------------- /ch10-piu/header/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*": "./js" 8 | }, 9 | "platforms": { 10 | "esp": { 11 | "config": { 12 | "rotation": 90 13 | } 14 | }, 15 | "esp32": { 16 | "config": { 17 | "rotation": 90 18 | } 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch10-piu/helloworld-behavior/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans" 17 | }); 18 | 19 | class LabelBehavior extends Behavior { 20 | onTouchBegan(label) { 21 | const message = label.message; 22 | label.string = message.substring(0, label.string.length + 1); 23 | if (label.string === message) 24 | label.active = false; 25 | } 26 | } 27 | 28 | const sampleLabel = new Label(null, { 29 | top: 0, bottom: 0, left: 0, right: 0, 30 | style: textStyle, 31 | string: "", 32 | active: true, 33 | Behavior: LabelBehavior 34 | }); 35 | sampleLabel.message = "Hello, World"; 36 | 37 | application.add(sampleLabel); 38 | -------------------------------------------------------------------------------- /ch10-piu/helloworld-behavior/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/helloworld-color/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans", 17 | color: "yellow" 18 | }); 19 | 20 | const labelBackground = new Skin({ 21 | fill: "#1932ab" 22 | }); 23 | 24 | const sampleLabel = new Label(null, { 25 | left: 0, right: 0, top: 0, bottom: 0, 26 | style: textStyle, 27 | string: "Hello, World", 28 | skin: labelBackground, 29 | }); 30 | 31 | application.add(sampleLabel); -------------------------------------------------------------------------------- /ch10-piu/helloworld-color/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/helloworld-ticking/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans" 17 | }); 18 | 19 | class LabelBehavior extends Behavior { 20 | onDisplaying(label) { 21 | this.index = 0; 22 | label.interval = 250; 23 | label.start(); 24 | } 25 | onTimeChanged(label) { 26 | const message = label.message; 27 | this.index += 1; 28 | if (this.index > message.length) 29 | label.stop(); 30 | else 31 | label.string = message.substring(0, this.index); 32 | } 33 | } 34 | 35 | const sampleLabel = new Label(null, { 36 | top: 0, bottom: 0, left: 0, right: 0, 37 | style: textStyle, 38 | string: "", 39 | Behavior: LabelBehavior 40 | }); 41 | sampleLabel.message = "Hello, World"; 42 | 43 | application.add(sampleLabel); 44 | -------------------------------------------------------------------------------- /ch10-piu/helloworld-ticking/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/helloworld/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans" 17 | }); 18 | 19 | const sampleLabel = new Label(null, { 20 | style: textStyle, 21 | string: "Hello, World", 22 | top: 0, bottom: 0, left: 0, right: 0 23 | }); 24 | 25 | application.add(sampleLabel); -------------------------------------------------------------------------------- /ch10-piu/helloworld/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "build": { 7 | "NAME": "ch10helloworld" 8 | }, 9 | "platforms": { 10 | "esp": { 11 | "config": { 12 | "rotation": 90 13 | } 14 | }, 15 | "esp32": { 16 | "config": { 17 | "rotation": 90 18 | } 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch10-piu/host/OpenSans-Regular-24.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/host/OpenSans-Regular-24.fnt -------------------------------------------------------------------------------- /ch10-piu/host/OpenSans-Regular-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/host/OpenSans-Regular-24.png -------------------------------------------------------------------------------- /ch10-piu/host/OpenSans-Semibold-16.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/host/OpenSans-Semibold-16.fnt -------------------------------------------------------------------------------- /ch10-piu/host/OpenSans-Semibold-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/host/OpenSans-Semibold-16.png -------------------------------------------------------------------------------- /ch10-piu/host/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {} from "piu/MC" 16 | import Modules from "modules"; 17 | import Timer from "timer"; 18 | 19 | const textStyle = new Style({ 20 | font: "24px Open Sans", 21 | color: "black" 22 | }); 23 | const readyText = new Label(null, { 24 | top: 20, bottom: 20, left: 20, right: 20, 25 | style: textStyle, string: "Ready to install apps!" 26 | }); 27 | 28 | class AppBehavior extends Behavior { 29 | onCreate(app) { 30 | if (Modules.has("check")) { 31 | let check = Modules.importNow("check"); 32 | check(); 33 | if (Modules.has("example")) 34 | Timer.set(() => Modules.importNow("example")); 35 | } else { 36 | app.add(readyText); 37 | } 38 | } 39 | } 40 | 41 | export default new Application(null, { 42 | displayListLength: 5632, 43 | commandListLength: 3072, 44 | skin: new Skin({ 45 | fill: "white" 46 | }), 47 | Behavior: AppBehavior 48 | }); 49 | -------------------------------------------------------------------------------- /ch10-piu/host/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/examples/manifest_piu.json", 5 | "$(MODDABLE)/modules/input/expanding-keyboard/horizontal/manifest.json" 6 | ], 7 | "creation": { 8 | "stack": 300, 9 | "keys": { 10 | "available": 96 11 | } 12 | }, 13 | "defines": { 14 | "XS_MODS": 1 15 | }, 16 | "modules": { 17 | "*": [ 18 | "./main", 19 | "$(MODULES)/base/modules/*" 20 | ] 21 | }, 22 | "preload": [ 23 | "modules" 24 | ], 25 | "resources": { 26 | "*-alpha": [ 27 | "./OpenSans-Regular-24", 28 | "./OpenSans-Semibold-16" 29 | ] 30 | }, 31 | "platforms": { 32 | "esp": { 33 | "config": { 34 | "rotation": 90 35 | } 36 | }, 37 | "esp32": { 38 | "config": { 39 | "rotation": 90 40 | } 41 | } 42 | }, 43 | "strip": [ 44 | "RegExp", 45 | "Proxy", 46 | "eval" 47 | ], 48 | "build": { 49 | "NAME": "ch10host" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ch10-piu/js-icon/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const jsLogoTexture = new Texture({ 16 | path: "js.png" 17 | }); 18 | 19 | const jsLogoSkin = new Skin({ 20 | texture: jsLogoTexture, 21 | height: 100, width: 100 22 | }); 23 | 24 | const jsLogo = new Content(null, { 25 | skin: jsLogoSkin 26 | }); 27 | 28 | application.add(jsLogo); -------------------------------------------------------------------------------- /ch10-piu/js-icon/js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/js-icon/js.png -------------------------------------------------------------------------------- /ch10-piu/js-icon/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*-color": "./js" 8 | }, 9 | "platforms": { 10 | "esp": { 11 | "config": { 12 | "rotation": 90 13 | } 14 | }, 15 | "esp32": { 16 | "config": { 17 | "rotation": 90 18 | } 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch10-piu/keyboard/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import { HorizontalExpandingKeyboard } from "keyboard"; 16 | import { KeyboardField } from "common/keyboard"; 17 | 18 | const keyboardStyle = new Style({ 19 | font: "semibold 16px Open Sans", 20 | color: "black" 21 | }); 22 | const fieldStyle = new Style({ 23 | font: "24px Open Sans", 24 | color: "black", 25 | horizontal:"left", 26 | vertical:"middle" 27 | }); 28 | 29 | class KeyboardContainerBehavior extends Behavior { 30 | onCreate(column, data){ 31 | this.data = data; 32 | } 33 | onDisplaying(column) { 34 | this.addKeyboard(); 35 | } 36 | onTouchEnded(column){ 37 | this.addKeyboard(); 38 | } 39 | addKeyboard() { 40 | if (1 !== this.data.KEYBOARD.length) 41 | this.data.KEYBOARD.add(HorizontalExpandingKeyboard(this.data, { 42 | style: keyboardStyle, target: this.data.FIELD, doTransition: true 43 | })); 44 | } 45 | onKeyboardOK(application, string) { 46 | trace(`User entered: ${string}\n`); 47 | this.data.FIELD.visible = false; 48 | } 49 | onKeyboardTransitionFinished(application, out) { 50 | if (out) { 51 | let keyboard = this.data.KEYBOARD; 52 | keyboard.remove(keyboard.first); 53 | } 54 | else 55 | this.data.FIELD.visible = true; 56 | } 57 | } 58 | 59 | const KeyboardContainer = Column.template($ => ({ 60 | left: 0, right: 0, top: 0, bottom: 0, 61 | contents: [ 62 | KeyboardField($, { 63 | anchor: "FIELD", 64 | left: 32, right: 0, top: 0, bottom: 0, 65 | style: fieldStyle 66 | }), 67 | Container($, { 68 | anchor: "KEYBOARD", 69 | left: 0, right: 0, bottom: 0, height: 164 70 | }) 71 | ], 72 | active: true, 73 | Behavior: KeyboardContainerBehavior 74 | })); 75 | 76 | application.add(new KeyboardContainer({})); 77 | 78 | -------------------------------------------------------------------------------- /ch10-piu/keyboard/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/mask-icon/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const maskSettingsTexture = new Texture({ 16 | path: "settings-mask.png" 17 | }); 18 | 19 | const maskSettingsSkin = new Skin({ 20 | texture: maskSettingsTexture, 21 | width: 80, height: 80, 22 | color: ["orange", "yellow"] 23 | }); 24 | 25 | class SettingsIconBehavior extends Behavior { 26 | onTouchBegan(content) { 27 | content.state = 1; 28 | } 29 | onTouchEnded(content) { 30 | content.state = 0; 31 | } 32 | } 33 | 34 | const maskSettingsIcon = new Content(null, { 35 | skin: maskSettingsSkin, 36 | state: 0, 37 | active: true, 38 | Behavior: SettingsIconBehavior 39 | }); 40 | 41 | application.add(maskSettingsIcon); 42 | -------------------------------------------------------------------------------- /ch10-piu/mask-icon/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*-alpha": "./settings-mask" 8 | }, 9 | "platforms": { 10 | "esp": { 11 | "config": { 12 | "rotation": 90 13 | } 14 | }, 15 | "esp32": { 16 | "config": { 17 | "rotation": 90 18 | } 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch10-piu/mask-icon/settings-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/mask-icon/settings-mask.png -------------------------------------------------------------------------------- /ch10-piu/multiple-screens/assets.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const TRANSPARENT = "transparent"; 16 | const BLACK = "black"; 17 | const WHITE = "white"; 18 | 19 | const backgroundSkin = new Skin({ 20 | fill: BLACK 21 | }); 22 | 23 | const bigTextStyle = new Style({ 24 | font: "24px Open Sans", 25 | color: [WHITE, TRANSPARENT] 26 | }); 27 | const smallTextStyle = new Style({ 28 | font: "semibold 16px Open Sans", 29 | color: [WHITE, TRANSPARENT] 30 | }); 31 | 32 | const logoTexture1 = new Texture({ 33 | path: "logo1.png" 34 | }); 35 | const logoSkin1 = new Skin({ 36 | texture: logoTexture1, 37 | color: ["#9c2448af", TRANSPARENT], 38 | height: 117, width: 146 39 | }); 40 | 41 | const logoTexture2 = new Texture({ 42 | path: "logo2.png" 43 | }); 44 | const logoSkin2 = new Skin({ 45 | texture: logoTexture2, 46 | color: ["#6F64E8af", TRANSPARENT], 47 | height: 117, width: 146 48 | }); 49 | 50 | const logoTexture3 = new Texture({ 51 | path: "logo3.png" 52 | }); 53 | const logoSkin3 = new Skin({ 54 | texture: logoTexture3, 55 | color: ["#7AFFE7af", TRANSPARENT], 56 | height: 117, width: 146 57 | }); 58 | 59 | const buttonBackgroundTexture = new Texture({ 60 | path: "button-bkg.png" 61 | }); 62 | const buttonBackgroundSkin = new Skin({ 63 | texture: buttonBackgroundTexture, 64 | color: "#9c2448af", 65 | height: 60, width: 60 66 | }); 67 | 68 | const restartArrowTexture = new Texture({ 69 | path: "restart-arrow.png" 70 | }); 71 | const restartArrowSkin = new Skin({ 72 | texture: restartArrowTexture, 73 | color: [BLACK, TRANSPARENT], 74 | height: 31, width: 34 75 | }); 76 | 77 | export default { 78 | bigTextStyle, 79 | smallTextStyle, 80 | backgroundSkin, 81 | logoSkin1, 82 | logoSkin2, 83 | logoSkin3, 84 | buttonBackgroundSkin, 85 | restartArrowSkin, 86 | } -------------------------------------------------------------------------------- /ch10-piu/multiple-screens/button-bkg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/multiple-screens/button-bkg.png -------------------------------------------------------------------------------- /ch10-piu/multiple-screens/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import SCREENS from "screens"; 16 | 17 | class MainContainerBehavior extends Behavior { 18 | onCreate(container, data) { 19 | this.data = data; 20 | } 21 | onDisplaying(container) { 22 | this.switchScreen(container, "SPLASH"); 23 | } 24 | switchScreen(container, nextScreenName) { 25 | container.defer("doSwitchScreen", nextScreenName); 26 | } 27 | doSwitchScreen(container, nextScreenName) { 28 | container.empty(); 29 | application.purge(); 30 | switch (nextScreenName) { 31 | case "SPLASH": 32 | container.add(new SCREENS.SplashScreen(this.data)); 33 | break; 34 | case "HOME": 35 | container.add(new SCREENS.HomeScreen(this.data)); 36 | break; 37 | } 38 | } 39 | } 40 | 41 | const MainContainer = Container.template($ => ({ 42 | top: 0, bottom: 0, left: 0, right: 0, 43 | Behavior: MainContainerBehavior 44 | })); 45 | 46 | application.add(new MainContainer({})); 47 | -------------------------------------------------------------------------------- /ch10-piu/multiple-screens/logo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/multiple-screens/logo1.png -------------------------------------------------------------------------------- /ch10-piu/multiple-screens/logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/multiple-screens/logo2.png -------------------------------------------------------------------------------- /ch10-piu/multiple-screens/logo3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/multiple-screens/logo3.png -------------------------------------------------------------------------------- /ch10-piu/multiple-screens/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": [ 5 | "./assets", 6 | "./example", 7 | "./screens" 8 | ] 9 | }, 10 | "resources": { 11 | "*-mask": [ 12 | "./logo1", 13 | "./logo2", 14 | "./logo3", 15 | "./button-bkg", 16 | "./restart-arrow" 17 | ] 18 | }, 19 | "platforms": { 20 | "esp": { 21 | "config": { 22 | "rotation": 90 23 | } 24 | }, 25 | "esp32": { 26 | "config": { 27 | "rotation": 90 28 | } 29 | } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /ch10-piu/multiple-screens/restart-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/multiple-screens/restart-arrow.png -------------------------------------------------------------------------------- /ch10-piu/multiple-screens/screens.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import ASSETS from "assets"; 16 | import Timeline from "piu/Timeline"; 17 | 18 | class SplashScreenBehavior extends Behavior { 19 | onCreate(container, data) { 20 | this.data = data; 21 | } 22 | onDisplaying(container) { 23 | let data = this.data; 24 | let timeline = this.timeline = new Timeline(); 25 | // Fade in 26 | timeline.from(data["LOGO1"], { state: 1, y: 10 }, 400, Math.quadEaseOut, 0); 27 | timeline.from(data["LOGO2"], { state: 1, y: 10 }, 300, Math.quadEaseOut, -300); 28 | timeline.from(data["LOGO3"], { state: 1, y: 10 }, 200, Math.quadEaseOut, -200); 29 | timeline.from(data["TITLE"], { state: 1 }, 600, Math.quadEaseOut, -200); 30 | // Fade out 31 | timeline.to(data["LOGO1"], { state: 1 }, 250, Math.quadEaseOut, 1500); 32 | timeline.to(data["LOGO2"], { state: 1 }, 250, Math.quadEaseOut, -250); 33 | timeline.to(data["LOGO3"], { state: 1 }, 250, Math.quadEaseOut, -250); 34 | timeline.to(data["TITLE"], { state: 1 }, 250, Math.quadEaseOut, -250); 35 | timeline.seekTo(0); 36 | container.duration = timeline.duration; 37 | container.time = 0; 38 | container.start(); 39 | } 40 | onTimeChanged(container) { 41 | this.timeline.seekTo(container.time); 42 | } 43 | onFinished(container) { 44 | let data = this.data; 45 | // Remove references to content objects 46 | delete data["LOGO1"]; 47 | delete data["LOGO2"]; 48 | delete data["LOGO3"]; 49 | delete data["TITLE"]; 50 | // Transition to next screen 51 | container.bubble("switchScreen", "HOME"); 52 | } 53 | } 54 | 55 | const SplashScreen = Container.template($ => ({ 56 | top: 0, bottom: 0, left: 0, right: 0, 57 | skin: ASSETS.backgroundSkin, 58 | contents: [ 59 | Content($, { 60 | anchor: "LOGO1", 61 | top: 30, 62 | skin: ASSETS.logoSkin1 63 | }), 64 | Content($, { 65 | anchor: "LOGO2", 66 | top: 30, 67 | skin: ASSETS.logoSkin2 68 | }), 69 | Content($, { 70 | anchor: "LOGO3", 71 | top: 30, 72 | skin: ASSETS.logoSkin3 73 | }), 74 | Label($, { 75 | anchor: "TITLE", 76 | top: 155, 77 | style: ASSETS.bigTextStyle, 78 | string: "lorem ipsum" 79 | }) 80 | ], 81 | Behavior: SplashScreenBehavior 82 | })); 83 | 84 | 85 | class RestartButtonBehavior extends Behavior { 86 | onTouchEnded(content) { 87 | content.container.delegate("animateOut"); 88 | } 89 | } 90 | 91 | class HomeScreenBehavior extends Behavior { 92 | onCreate(container, data) { 93 | this.data = data; 94 | } 95 | onDisplaying(container) { 96 | let data = this.data; 97 | let timeline = this.timeline = new Timeline(); 98 | timeline.from(data["ICON"], { x: -data["ICON"].width }, 350, Math.quadEaseOut, 0); 99 | timeline.from(data["TEXT"], { x: 320 }, 350, Math.quadEaseOut, -350); 100 | timeline.seekTo(0); 101 | container.duration = timeline.duration; 102 | container.time = 0; 103 | container.start(); 104 | } 105 | animateOut(container) { 106 | let data = this.data; 107 | this.transitioningOut = true; 108 | let timeline = this.timeline = new Timeline(); 109 | timeline.to(data["ICON"], { x: -data["ICON"].width }, 350, Math.quadEaseOut, 0); 110 | timeline.to(data["TEXT"], { x: 320 }, 350, Math.quadEaseOut, -350); 111 | container.duration = timeline.duration; 112 | container.time = 0; 113 | container.start(); 114 | } 115 | onTimeChanged(container) { 116 | this.timeline.seekTo(container.time); 117 | } 118 | onFinished(container) { 119 | if (this.transitioningOut) { 120 | let data = this.data; 121 | // Remove references to content objects 122 | delete data["ICON"]; 123 | delete data["TEXT"]; 124 | // Transition to next screen 125 | container.bubble("switchScreen", "SPLASH"); 126 | } 127 | else 128 | delete this.timeline; 129 | } 130 | } 131 | 132 | const HomeScreen = Row.template($ => ({ 133 | top: 0, bottom: 0, left: 0, right: 0, 134 | skin: ASSETS.backgroundSkin, 135 | contents: [ 136 | Content($, { 137 | left: 0, right: 0 138 | }), 139 | Container($, { 140 | anchor: "ICON", 141 | skin: ASSETS.buttonBackgroundSkin, 142 | contents: [ 143 | Content($, { 144 | skin: ASSETS.restartArrowSkin 145 | }) 146 | ], 147 | active: true, 148 | Behavior: RestartButtonBehavior 149 | }), 150 | Label($, { 151 | anchor: "TEXT", 152 | left: 10, 153 | style: ASSETS.bigTextStyle, 154 | string: "Restart" 155 | }), 156 | Content($, { 157 | left: 0, right: 0 158 | }) 159 | ], 160 | Behavior: HomeScreenBehavior 161 | })); 162 | 163 | export default { 164 | SplashScreen, 165 | HomeScreen 166 | } -------------------------------------------------------------------------------- /ch10-piu/nav-bar-template/clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/nav-bar-template/clock.png -------------------------------------------------------------------------------- /ch10-piu/nav-bar-template/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "semibold 16px Open Sans", 17 | color: "black", 18 | top: 5, bottom: 5 19 | }); 20 | 21 | const clockTexture = new Texture({ 22 | path: "clock.png" 23 | }); 24 | 25 | const clockSkin = new Skin({ 26 | texture: clockTexture, 27 | width: 56, height: 56, 28 | color: "#2eb335", 29 | }); 30 | 31 | const settingsTexture = new Texture({ 32 | path: "settings.png" 33 | }); 34 | 35 | const settingsSkin = new Skin({ 36 | texture: settingsTexture, 37 | width: 56, height: 56, 38 | color: "#3474eb", 39 | }); 40 | 41 | const sunTexture = new Texture({ 42 | path: "sun.png" 43 | }); 44 | 45 | const sunSkin = new Skin({ 46 | texture: sunTexture, 47 | width: 56, height: 56, 48 | color: "#fcca4c", 49 | }); 50 | 51 | const outlineSkin = new Skin({ 52 | fill: "transparent", 53 | stroke: "#dedede", 54 | borders: { left: 2, right: 2, top: 2, bottom: 2 } 55 | }); 56 | 57 | const Button = Column.template($ => ({ 58 | skin: outlineSkin, 59 | width: 80, 60 | contents: [ 61 | Content(null, { 62 | top: 5, 63 | skin: $.skin 64 | }), 65 | Label(null, { 66 | top: 0, 67 | style: textStyle, 68 | string: $.string 69 | }) 70 | ] 71 | })); 72 | 73 | const settingsButton = new Button({ 74 | skin: settingsSkin, 75 | string: "Settings" 76 | }); 77 | 78 | const weatherButton = new Button({ 79 | skin: sunSkin, 80 | string: "Weather" 81 | }); 82 | 83 | const timeButton = new Button({ 84 | skin: clockSkin, 85 | string: "Time" 86 | }); 87 | 88 | const navBar = new Row(null, { 89 | left: 0, right: 0, 90 | contents: [ 91 | Content(null, {left: 0, right: 0}), 92 | settingsButton, 93 | Content(null, {left: 0, right: 0}), 94 | weatherButton, 95 | Content(null, {left: 0, right: 0}), 96 | timeButton, 97 | Content(null, {left: 0, right: 0}) 98 | ] 99 | }); 100 | 101 | application.add(navBar); -------------------------------------------------------------------------------- /ch10-piu/nav-bar-template/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*-alpha": [ 8 | "./clock", 9 | "./settings", 10 | "./sun" 11 | ] 12 | }, 13 | "platforms": { 14 | "esp": { 15 | "config": { 16 | "rotation": 90 17 | } 18 | }, 19 | "esp32": { 20 | "config": { 21 | "rotation": 90 22 | } 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /ch10-piu/nav-bar-template/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/nav-bar-template/settings.png -------------------------------------------------------------------------------- /ch10-piu/nav-bar-template/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/nav-bar-template/sun.png -------------------------------------------------------------------------------- /ch10-piu/nav-bar/clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/nav-bar/clock.png -------------------------------------------------------------------------------- /ch10-piu/nav-bar/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "semibold 16px Open Sans", 17 | color: "black", 18 | top: 5, bottom: 5 19 | }); 20 | 21 | const clockTexture = new Texture({ 22 | path: "clock.png" 23 | }); 24 | 25 | const clockSkin = new Skin({ 26 | texture: clockTexture, 27 | width: 56, height: 56, 28 | color: "#2eb335", 29 | }); 30 | 31 | const settingsTexture = new Texture({ 32 | path: "settings.png" 33 | }); 34 | 35 | const settingsSkin = new Skin({ 36 | texture: settingsTexture, 37 | width: 56, height: 56, 38 | color: "#3474eb", 39 | }); 40 | 41 | const sunTexture = new Texture({ 42 | path: "sun.png" 43 | }); 44 | 45 | const sunSkin = new Skin({ 46 | texture: sunTexture, 47 | width: 56, height: 56, 48 | color: "#fcca4c", 49 | }); 50 | 51 | const outlineSkin = new Skin({ 52 | fill: "transparent", 53 | stroke: "#dedede", 54 | borders: { left: 2, right: 2, top: 2, bottom: 2 } 55 | }); 56 | 57 | const settingsButton = new Column(null, { 58 | skin: outlineSkin, width: 80, 59 | contents: [ 60 | Content(null, { 61 | top: 5, 62 | skin: settingsSkin 63 | }), 64 | Label(null, { 65 | top: 0, 66 | style: textStyle, 67 | string: "Settings" 68 | }) 69 | ] 70 | }); 71 | 72 | const weatherButton = new Column(null, { 73 | skin: outlineSkin, width: 80, 74 | contents: [ 75 | Content(null, { 76 | top: 5, skin: sunSkin 77 | }), 78 | Label(null, { 79 | top: 0, style: textStyle, string: "Weather" 80 | }) 81 | ] 82 | }); 83 | 84 | const timeButton = new Column(null, { 85 | skin: outlineSkin, width: 80, 86 | contents: [ 87 | Content(null, { 88 | top: 5, skin: clockSkin 89 | }), 90 | Label(null, { 91 | top: 0, style: textStyle, string: "Time" 92 | }) 93 | ] 94 | }); 95 | 96 | const navBar = new Row(null, { 97 | left: 0, right: 0, 98 | contents: [ 99 | Content(null, {left: 0, right: 0}), 100 | settingsButton, 101 | Content(null, {left: 0, right: 0}), 102 | weatherButton, 103 | Content(null, {left: 0, right: 0}), 104 | timeButton, 105 | Content(null, {left: 0, right: 0}) 106 | ] 107 | }); 108 | 109 | application.add(navBar); -------------------------------------------------------------------------------- /ch10-piu/nav-bar/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*-alpha": [ 8 | "./clock", 9 | "./settings", 10 | "./sun" 11 | ] 12 | }, 13 | "platforms": { 14 | "esp": { 15 | "config": { 16 | "rotation": 90 17 | } 18 | }, 19 | "esp32": { 20 | "config": { 21 | "rotation": 90 22 | } 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /ch10-piu/nav-bar/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/nav-bar/settings.png -------------------------------------------------------------------------------- /ch10-piu/nav-bar/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/nav-bar/sun.png -------------------------------------------------------------------------------- /ch10-piu/rounded-buttons/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/rounded-buttons/button.png -------------------------------------------------------------------------------- /ch10-piu/rounded-buttons/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const textStyle = new Style({ 16 | font: "24px Open Sans", 17 | color: "white", 18 | top: 5, bottom: 5, left: 5, right: 5 19 | }); 20 | const smallTextStyle = new Style({ 21 | font: "semibold 16px Open Sans", 22 | color: "white", 23 | top: 5, bottom: 5, left: 5, right: 5 24 | }); 25 | 26 | const roundedTexture = new Texture({ 27 | path: "button.png" 28 | }); 29 | 30 | const roundedSkin = new Skin({ 31 | texture: roundedTexture, 32 | width: 30, height: 30, 33 | color: ["#ff9900", "#ffd699"], 34 | tiles: { 35 | top: 5, bottom: 5, left: 5, right: 5 36 | } 37 | }); 38 | 39 | class ButtonBehavior extends Behavior { 40 | onTouchBegan(button) { 41 | button.state = 1; 42 | } 43 | onTouchEnded(button) { 44 | button.state = 0; 45 | } 46 | } 47 | 48 | const button1 = new Label(null, { 49 | top: 10, left: 10, 50 | skin: roundedSkin, 51 | style: smallTextStyle, 52 | string: "Option 1", 53 | active: true, 54 | Behavior: ButtonBehavior 55 | }); 56 | 57 | const button2 = new Label(null, { 58 | top: 60, left: 10, 59 | skin: roundedSkin, 60 | style: textStyle, 61 | string: "Option 2", 62 | active: true, 63 | Behavior: ButtonBehavior 64 | }); 65 | 66 | const button3 = new Text(null, { 67 | top: 120, left: 10, width: 90, 68 | skin: roundedSkin, 69 | style: textStyle, 70 | string: "Option 3", 71 | active: true, 72 | Behavior: ButtonBehavior 73 | }); 74 | 75 | application.add(button1); 76 | application.add(button2); 77 | application.add(button3); -------------------------------------------------------------------------------- /ch10-piu/rounded-buttons/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*-mask": "./button" 8 | }, 9 | "platforms": { 10 | "esp": { 11 | "config": { 12 | "rotation": 90 13 | } 14 | }, 15 | "esp32": { 16 | "config": { 17 | "rotation": 90 18 | } 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch10-piu/scrolling-text/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const bigTextStyle = new Style({ 16 | font: "24px Open Sans", 17 | color: "black" 18 | }); 19 | 20 | const smallTextStyle = new Style({ 21 | font: "semibold 16px Open Sans", 22 | color: "black" 23 | }); 24 | 25 | const sampleHeader = new Label(null, { 26 | top: 20, 27 | style: bigTextStyle, 28 | string: "Lorem ipsum" 29 | }); 30 | 31 | const grayBar = new Content(null, { 32 | top: 20, height: 2, left: 20, right: 20, 33 | skin: new Skin({ fill: "#dedede" }) 34 | }); 35 | 36 | const loremIpsum = `Lorem ipsum dolor sit amet, magna ullum ne mea. An mel suas adipiscing, pri at agam adipisci vituperata. Vix at augue molestie, ut mea viderer albucius assentior. Dicta qualisque definitionem ut duo. Pro veniam virtute ad. Sit te oratio eligendi delicatissimi, mundi tritani ius no, mel te dicant euismod ceteros.` 37 | 38 | const sampleText = new Text(null, { 39 | top: 20, left: 20, right: 20, 40 | style: smallTextStyle, string: loremIpsum 41 | }); 42 | 43 | class VerticalScrollerBehavior extends Behavior { 44 | onTouchBegan(scroller, id, x, y, ticks) { 45 | this.initialScrollY = scroller.scroll.y; 46 | this.initialY = y; 47 | scroller.captureTouch(id, x, y, ticks); 48 | } 49 | onTouchMoved(scroller, id, x, y, ticks) { 50 | const dy = y - this.initialY; 51 | scroller.scrollTo(0, this.initialScrollY - dy); 52 | } 53 | } 54 | 55 | const sampleVerticalScroller = new Scroller(null, { 56 | left: 0, right: 0, top: 0, bottom: 0, 57 | contents: [ 58 | Column(null, { 59 | left: 0, right: 0, top: 0, 60 | contents: [ 61 | sampleHeader, 62 | grayBar, 63 | sampleText 64 | ] 65 | }) 66 | ], 67 | active: true, 68 | Behavior: VerticalScrollerBehavior 69 | }); 70 | 71 | application.add(sampleVerticalScroller); -------------------------------------------------------------------------------- /ch10-piu/scrolling-text/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/tiled-background/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const tileTexture = new Texture({ 16 | path: "tile.png" 17 | }); 18 | 19 | const tileSkin = new Skin({ 20 | texture: tileTexture, 21 | height: 50, width: 50, 22 | tiles: { 23 | left: 0, right: 0, top: 0, bottom: 0 24 | } 25 | }); 26 | 27 | const background = new Content(null, { 28 | left: 0, right: 0, top: 0, bottom: 0, 29 | skin: tileSkin 30 | }); 31 | 32 | application.add(background); -------------------------------------------------------------------------------- /ch10-piu/tiled-background/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*": "./tile" 8 | }, 9 | "platforms": { 10 | "esp": { 11 | "config": { 12 | "rotation": 90 13 | } 14 | }, 15 | "esp32": { 16 | "config": { 17 | "rotation": 90 18 | } 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch10-piu/tiled-background/tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/tiled-background/tile.png -------------------------------------------------------------------------------- /ch10-piu/timeline/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Timeline from "piu/Timeline"; 16 | 17 | const WHITE = "white"; 18 | const BLACK = "black"; 19 | const RED = "red"; 20 | const BLUE = "#1932ab"; 21 | const whiteSkin = new Skin({ fill: WHITE }); 22 | const colorfulSkin = new Skin({ fill: [RED, BLUE] }); 23 | const textStyle = new Style({ font: "24px Open Sans", color: [BLACK, WHITE] }); 24 | 25 | class TimelineBehavior extends Behavior { 26 | onDisplaying(container) { 27 | let timeline = this.timeline = new Timeline(); 28 | this.reverse = false; 29 | timeline.from(container.first, { y: -container.first.height, state: 1 }, 750, Math.quadEaseOut, 0); 30 | timeline.from(container.last, { x: -320 }, 750, Math.linearEase, -750); 31 | timeline.to(container.last, { state: 1 }, 750, Math.linearEase, 0); 32 | timeline.seekTo(0); 33 | container.duration = timeline.duration; 34 | container.time = 0; 35 | container.start(); 36 | } 37 | onTimeChanged(container) { 38 | let time = container.time; 39 | if (this.reverse) 40 | time = container.duration - time; 41 | this.timeline.seekTo(time); 42 | } 43 | onFinished(container) { 44 | this.reverse = !this.reverse; 45 | this.timeline.seekTo(0); 46 | container.time = 0; 47 | container.start(); 48 | } 49 | } 50 | 51 | const animatedContainer = new Container(null, { 52 | top: 0, bottom: 0, left: 0, right: 0, 53 | skin: whiteSkin, 54 | contents: [ 55 | new Label(null, { 56 | style: textStyle, 57 | top: 80, left: 0, right: 0, 58 | string: "Hello, World" 59 | }), 60 | new Content(null, { 61 | top: 115, height: 3, left: 0, width: 320, 62 | skin: colorfulSkin 63 | }) 64 | ], 65 | Behavior: TimelineBehavior 66 | }); 67 | 68 | application.add(animatedContainer); -------------------------------------------------------------------------------- /ch10-piu/timeline/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/transitions/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import WipeTransition from "piu/WipeTransition"; 16 | import CombTransition from "piu/CombTransition"; 17 | 18 | const WHITE = "white"; 19 | const BLUE = "#000066"; 20 | 21 | const textStyle = new Style({ 22 | font: "24px Open Sans", 23 | color: [WHITE, BLUE] 24 | }); 25 | 26 | const sampleLabel = new Label(null, { 27 | style: textStyle, 28 | string: "Hello, World", 29 | top: 0, bottom: 0, left: 0, right: 0 30 | }); 31 | 32 | const whiteScreen = new Container(null, { 33 | top: 0, bottom: 0, left: 0, right: 0, 34 | skin: new Skin({ fill: WHITE }), 35 | contents: [ 36 | Label(null, { 37 | state: 1, style: textStyle, 38 | string: "White screen" 39 | }) 40 | ] 41 | }); 42 | const blueScreen = new Container(null, { 43 | top: 0, bottom: 0, left: 0, right: 0, 44 | skin: new Skin({ fill: BLUE }), 45 | contents: [ 46 | Label(null, { 47 | state: 0, style: textStyle, 48 | string: "Blue screen" 49 | }) 50 | ] 51 | }); 52 | 53 | const parameters = [ 54 | { transition:CombTransition, first:"horizontal", last:4 }, 55 | { transition:CombTransition, first:"vertical", last:4 }, 56 | { transition:CombTransition, first:"horizontal", last:8 }, 57 | { transition:CombTransition, first:"vertical", last:8 }, 58 | { transition:WipeTransition, first:"left" }, 59 | { transition:WipeTransition, first:"right" }, 60 | { transition:WipeTransition, last:"top" }, 61 | { transition:WipeTransition, last:"bottom" }, 62 | { transition:WipeTransition, first:"center" }, 63 | { transition:WipeTransition, last:"middle" }, 64 | { transition:WipeTransition, first:"center", last:"middle" }, 65 | { transition:WipeTransition, first:"left", last:"top" }, 66 | { transition:WipeTransition, first:"right", last:"top" }, 67 | { transition:WipeTransition, first:"right", last:"bottom" }, 68 | { transition:WipeTransition, first:"left", last:"bottom" }, 69 | { transition:WipeTransition, first:"center", last:"top" }, 70 | { transition:WipeTransition, first:"right", last:"middle" }, 71 | { transition:WipeTransition, first:"center", last:"bottom" }, 72 | { transition:WipeTransition, first:"left", last:"middle" } 73 | ]; 74 | 75 | class MainContainerBehavior extends Behavior { 76 | onDisplaying(container) { 77 | this.index = 0; 78 | container.duration = 500; 79 | container.start(); 80 | } 81 | onFinished(container) { 82 | let parameter = parameters[this.index % parameters.length]; 83 | let transition = new parameter.transition(250, Math.quadEaseOut, parameter.first, parameter.last); 84 | this.index++; 85 | container.run(transition, container.first, (this.index & 1)? blueScreen : whiteScreen); 86 | } 87 | onTransitionEnded(container) { 88 | container.time = 0; 89 | container.start(); 90 | } 91 | } 92 | 93 | application.add(new Container(null, { 94 | top: 0, bottom: 0, left: 0, right: 0, 95 | contents: [ 96 | whiteScreen 97 | ], 98 | Behavior: MainContainerBehavior 99 | })); 100 | -------------------------------------------------------------------------------- /ch10-piu/transitions/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "platforms": { 7 | "esp": { 8 | "config": { 9 | "rotation": 90 10 | } 11 | }, 12 | "esp32": { 13 | "config": { 14 | "rotation": 90 15 | } 16 | } 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /ch10-piu/wifi-status/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | const wifiTexture = new Texture({ 16 | path: "wifi-strip.png" 17 | }); 18 | 19 | const wifiSkin = new Skin({ 20 | texture: wifiTexture, 21 | width: 28, height: 28, 22 | states: 28, 23 | variants: 28 24 | }); 25 | 26 | class WifiIconBehavior extends Behavior { 27 | onDisplaying(content) { 28 | content.interval = 1000; 29 | content.start(); 30 | } 31 | onTimeChanged(content) { 32 | let variant = content.variant + 1; 33 | if (variant > 4) { 34 | variant = 0; 35 | content.state = content.state ? 0 : 1; 36 | } 37 | content.variant = variant; 38 | } 39 | } 40 | 41 | const wifiIcon = new Content(null, { 42 | skin: wifiSkin, 43 | state: 0, 44 | variant: 0, 45 | Behavior: WifiIconBehavior 46 | }); 47 | 48 | application.add(wifiIcon); 49 | -------------------------------------------------------------------------------- /ch10-piu/wifi-status/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*": "./wifi-strip" 8 | }, 9 | "platforms": { 10 | "esp": { 11 | "config": { 12 | "rotation": 90 13 | } 14 | }, 15 | "esp32": { 16 | "config": { 17 | "rotation": 90 18 | } 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /ch10-piu/wifi-status/wifi-strip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch10-piu/wifi-status/wifi-strip.png -------------------------------------------------------------------------------- /ch11-native/bitarray-arraybuffer/bitarray.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | #include "xsmc.h" 16 | #include "stdint.h" 17 | #include "mc.xs.h" // for xsID_ values 18 | 19 | void xs_bitarray_set(xsMachine *the) 20 | { 21 | int index = xsmcToInteger(xsArg(0)); 22 | int byteIndex = index >> 3; 23 | int bitIndex = index & 0x07; 24 | 25 | xsmcVars(1); 26 | 27 | xsmcGet(xsVar(0), xsThis, xsID_buffer); 28 | uint8_t *buffer = xsmcToArrayBuffer(xsVar(0)); 29 | 30 | int value = xsmcToInteger(xsArg(1)); 31 | if (value) 32 | buffer[byteIndex] |= 1 << bitIndex; 33 | else 34 | buffer[byteIndex] &= ~(1 << bitIndex); 35 | } 36 | 37 | void xs_bitarray_get(xsMachine *the) 38 | { 39 | int index = xsmcToInteger(xsArg(0)); 40 | int byteIndex = index >> 3; 41 | int bitIndex = index & 0x07; 42 | 43 | xsmcVars(1); 44 | 45 | xsmcGet(xsVar(0), xsThis, xsID_buffer); 46 | uint8_t *buffer = xsmcToArrayBuffer(xsVar(0)); 47 | 48 | if (buffer[byteIndex] & (1 << bitIndex)) 49 | xsmcSetInteger(xsResult, 1); 50 | else 51 | xsmcSetInteger(xsResult, 0); 52 | } 53 | -------------------------------------------------------------------------------- /ch11-native/bitarray-arraybuffer/bitarray.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | class BitArray { 16 | constructor(count) { 17 | this.buffer = new ArrayBuffer(Math.ceil(count / 8)); 18 | } 19 | get(index) @ "xs_bitarray_get"; 20 | set(index, value) @ "xs_bitarray_set"; 21 | } 22 | 23 | export default BitArray; 24 | -------------------------------------------------------------------------------- /ch11-native/bitarray-arraybuffer/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import BitArray from "bitarray"; 16 | 17 | let bits = new BitArray(128); 18 | 19 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 20 | bits.set(1, 1); 21 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 22 | bits.set(2, 1); 23 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 24 | bits.set(1, 0); 25 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 26 | bits.set(2, 0); 27 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 28 | -------------------------------------------------------------------------------- /ch11-native/bitarray-arraybuffer/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json" 4 | ], 5 | "modules": { 6 | "*": [ 7 | "./main", 8 | "./bitarray" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch11-native/bitarray-calloc/bitarray.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | #include "xsmc.h" 16 | #include "stdint.h" 17 | #include "stdlib.h" 18 | #include "mc.xs.h" // for xsID_ values 19 | 20 | void xs_bitarray_constructor(xsMachine *the) 21 | { 22 | int bitCount = xsmcToInteger(xsArg(0)); 23 | int byteCount = (bitCount + 7) / 8; 24 | uint8_t *bytes = calloc(byteCount + sizeof(int), 1); 25 | if (!bytes) 26 | xsUnknownError("no memory"); 27 | 28 | *(int *)bytes = bitCount; 29 | xsmcSetHostData(xsThis, bytes); 30 | } 31 | 32 | void xs_bitarray_destructor(void *data) 33 | { 34 | if (data) 35 | free(data); 36 | } 37 | 38 | void xs_bitarray_close(xsMachine *the) 39 | { 40 | uint8_t *buffer = xsmcGetHostData(xsThis); 41 | xs_bitarray_destructor(buffer); 42 | xsmcSetHostData(xsThis, NULL); 43 | } 44 | 45 | void xs_bitarray_set(xsMachine *the) 46 | { 47 | int index = xsmcToInteger(xsArg(0)); 48 | int byteIndex = index >> 3; 49 | int bitIndex = index & 0x07; 50 | 51 | uint8_t *buffer = xsmcGetHostData(xsThis); 52 | if (NULL == buffer) 53 | xsUnknownError("closed"); 54 | 55 | int bitCount = *(int *)buffer; 56 | buffer += sizeof(int); 57 | if ((index >= bitCount) || (index < 0)) 58 | xsRangeError("invalid bit index"); 59 | 60 | int value = xsmcToInteger(xsArg(1)); 61 | if (value) 62 | buffer[byteIndex] |= 1 << bitIndex; 63 | else 64 | buffer[byteIndex] &= ~(1 << bitIndex); 65 | } 66 | 67 | void xs_bitarray_get(xsMachine *the) 68 | { 69 | int index = xsmcToInteger(xsArg(0)); 70 | int byteIndex = index >> 3; 71 | int bitIndex = index & 0x07; 72 | 73 | uint8_t *buffer = xsmcGetHostData(xsThis); 74 | if (NULL == buffer) 75 | xsUnknownError("closed"); 76 | 77 | int bitCount = *(int *)buffer; 78 | buffer += sizeof(int); 79 | if ((index >= bitCount) || (index < 0)) 80 | xsRangeError("invalid bit index"); 81 | 82 | if (buffer[byteIndex] & (1 << bitIndex)) 83 | xsmcSetInteger(xsResult, 1); 84 | else 85 | xsmcSetInteger(xsResult, 0); 86 | } 87 | 88 | void xs_bitarray_get_length(xsMachine *the) 89 | { 90 | uint8_t *buffer = xsmcGetHostData(xsThis); 91 | if (NULL == buffer) 92 | xsUnknownError("closed"); 93 | 94 | int bitCount = *(int *)buffer; 95 | xsmcSetInteger(xsResult, bitCount); 96 | } 97 | -------------------------------------------------------------------------------- /ch11-native/bitarray-calloc/bitarray.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | class BitArray @ "xs_bitarray_destructor" { 16 | constructor(count) @ "xs_bitarray_constructor"; 17 | close() @ "xs_bitarray_close"; 18 | get(index) @ "xs_bitarray_get"; 19 | set(index, value) @ "xs_bitarray_set"; 20 | 21 | get length() @ "xs_bitarray_get_length"; 22 | set length(value) { 23 | throw new Error("read-only"); 24 | } 25 | } 26 | 27 | export default BitArray; 28 | -------------------------------------------------------------------------------- /ch11-native/bitarray-calloc/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import BitArray from "bitarray"; 16 | 17 | let bits = new BitArray(128); 18 | 19 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 20 | bits.set(1, 1); 21 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 22 | bits.set(2, 1); 23 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 24 | bits.set(1, 0); 25 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 26 | bits.set(2, 0); 27 | trace(`${bits.get(0)}, ${bits.get(1)}, ${bits.get(2)}\n`) 28 | -------------------------------------------------------------------------------- /ch11-native/bitarray-calloc/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json" 4 | ], 5 | "modules": { 6 | "*": [ 7 | "./main", 8 | "./bitarray" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch11-native/random-integer-esp-range/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | for (let i = 0; i < 100; i++) 16 | trace(randomIntRange(1000), "\n"); 17 | 18 | function randomIntRange(max) @ "xs_randomIntRange"; 19 | -------------------------------------------------------------------------------- /ch11-native/random-integer-esp-range/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json" 4 | ], 5 | "modules": { 6 | "*": [ 7 | "./main", 8 | "./randominteger" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch11-native/random-integer-esp-range/randominteger.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2023 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | #include "xsmc.h" 16 | #include "stdint.h" 17 | 18 | #if nrf52 19 | #include "nrf_crypto.h" 20 | #endif 21 | 22 | void xs_randomIntRange(xsMachine *the) 23 | { 24 | int range = xsmcToInteger(xsArg(0)); 25 | if (range < 2) 26 | xsRangeError("invalid range"); 27 | 28 | #if ESP32 29 | xsmcSetInteger(xsResult, esp_random() % range); 30 | #elif defined(__ets__) 31 | xsmcSetInteger(xsResult, (*(volatile uint32_t *)0x3FF20E44) % range); 32 | #elif nrf52 33 | static uint8_t inited = 0; 34 | if (!inited) { 35 | nrf_crypto_init(); 36 | inited = 1; 37 | } 38 | uint32_t random; 39 | nrf_crypto_rng_vector_generate((uint8_t *)&random, sizeof(random)); 40 | xsmcSetInteger(xsResult, random % range); 41 | #else 42 | #error Unsupported platform 43 | #endif 44 | } 45 | -------------------------------------------------------------------------------- /ch11-native/random-integer-esp/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | for (let i = 0; i < 100; i++) 16 | trace(randomInt(), "\n"); 17 | 18 | function randomInt() @ "xs_randomInt"; 19 | -------------------------------------------------------------------------------- /ch11-native/random-integer-esp/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json" 4 | ], 5 | "modules": { 6 | "*": [ 7 | "./main", 8 | "./randominteger" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch11-native/random-integer-esp/randominteger.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2023 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | #include "xsmc.h" 16 | #include "stdint.h" 17 | 18 | #if nrf52 19 | #include "nrf_crypto.h" 20 | #endif 21 | 22 | void xs_randomInt(xsMachine *the) 23 | { 24 | #if ESP32 25 | xsmcSetInteger(xsResult, esp_random()); 26 | #elif defined(__ets__) 27 | xsmcSetInteger(xsResult, (*(volatile int32_t *)0x3FF20E44)); 28 | #elif nrf52 29 | static uint8_t inited = 0; 30 | if (!inited) { 31 | nrf_crypto_init(); 32 | inited = 1; 33 | } 34 | int32_t random; 35 | nrf_crypto_rng_vector_generate((uint8_t *)&random, sizeof(random)); 36 | xsmcSetInteger(xsResult, random); 37 | #else 38 | #error Unsupported platform 39 | #endif 40 | } 41 | -------------------------------------------------------------------------------- /ch11-native/random-integer/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | for (let i = 0; i < 100; i++) 16 | trace(randomInt(), "\n"); 17 | 18 | function randomInt() @ "xs_randomInt"; 19 | -------------------------------------------------------------------------------- /ch11-native/random-integer/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json" 4 | ], 5 | "modules": { 6 | "*": [ 7 | "./main", 8 | "./randominteger" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch11-native/random-integer/randominteger.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2023 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | #include "xsmc.h" 16 | #include "xsHost.h" 17 | 18 | void xs_randomInt(xsMachine *the) 19 | { 20 | xsmcSetInteger(xsResult, rand()); 21 | } 22 | -------------------------------------------------------------------------------- /ch11-native/wifi-rssi-notify/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import WiFiRSSINotify from "wifirssinotify"; 16 | 17 | let notify = new WiFiRSSINotify({ 18 | threshold: -66, 19 | poll: 1000 20 | }); 21 | 22 | notify.onWeakSignal = function(rssi) { 23 | trace(`Weak Wi-Fi signal. RSSI ${rssi}.\n`); 24 | } 25 | notify.onStrongSignal = function(rssi) { 26 | trace(`Strong Wi-Fi signal. RSSI ${rssi}.\n`); 27 | } 28 | -------------------------------------------------------------------------------- /ch11-native/wifi-rssi-notify/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/examples/manifest_net.json" 5 | ], 6 | "modules": { 7 | "*": [ 8 | "./main", 9 | "./wifirssinotify" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ch11-native/wifi-rssi-notify/wifirssinotify.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | #include "xsmc.h" 16 | #include "mc.xs.h" // for xsID_ values 17 | #include "xsHost.h" 18 | #include "modTimer.h" 19 | 20 | #if ESP32 21 | #include "esp_wifi.h" 22 | #endif 23 | 24 | typedef struct RSSINotifyRecord RSSINotifyRecord; 25 | typedef struct RSSINotifyRecord *RSSINotify; 26 | 27 | enum { 28 | kRSSIUnknown, 29 | kRSSIWeak, 30 | kRSSIStrong, 31 | }; 32 | 33 | struct RSSINotifyRecord { 34 | int threshold; 35 | int state; 36 | modTimer timer; 37 | xsMachine *the; 38 | xsSlot obj; 39 | }; 40 | 41 | static void checkRSSI(modTimer timer, void *refcon, int refconSize); 42 | 43 | void xs_wifirssinotify_constructor(xsMachine *the) 44 | { 45 | RSSINotify rn = calloc(sizeof(RSSINotifyRecord), 1); 46 | if (!rn) 47 | xsUnknownError("no memory"); 48 | 49 | rn->state = kRSSIUnknown; 50 | rn->obj = xsThis; 51 | rn->the = the; 52 | 53 | xsTry { 54 | int poll; 55 | 56 | xsmcVars(1); 57 | 58 | if (xsmcHas(xsArg(0), xsID_poll)) { 59 | xsmcGet(xsVar(0), xsArg(0), xsID_poll); 60 | poll = xsmcToInteger(xsVar(0)); 61 | } 62 | else 63 | poll = 5000; 64 | 65 | if (!xsmcHas(xsArg(0), xsID_threshold)) 66 | xsUnknownError("threshold required"); 67 | xsmcGet(xsVar(0), xsArg(0), xsID_threshold); 68 | rn->threshold = xsmcToInteger(xsVar(0)); 69 | 70 | rn->timer = modTimerAdd(1, poll, checkRSSI, &rn, sizeof(rn)); 71 | if (!rn->timer) 72 | xsUnknownError("no timer"); 73 | } 74 | xsCatch { 75 | free(rn); 76 | xsThrow(xsException); 77 | } 78 | 79 | xsmcSetHostData(xsThis, rn); 80 | xsRemember(rn->obj); 81 | } 82 | 83 | void xs_wifirssinotify_destructor(void *data) 84 | { 85 | RSSINotify rn = data; 86 | if (rn) { 87 | modTimerRemove(rn->timer); 88 | free(rn); 89 | } 90 | } 91 | 92 | void xs_wifirssinotify_close(xsMachine *the) 93 | { 94 | RSSINotify rn = xsmcGetHostData(xsThis); 95 | if (rn) { 96 | xsForget(rn->obj); 97 | xs_wifirssinotify_destructor(rn); 98 | xsmcSetHostData(xsThis, NULL); 99 | } 100 | } 101 | 102 | void checkRSSI(modTimer timer, void *refcon, int refconSize) 103 | { 104 | RSSINotify rn = *(RSSINotify *)refcon; 105 | int rssi = 0; 106 | xsIndex callbackID; 107 | 108 | #if ESP32 109 | wifi_ap_record_t config; 110 | 111 | if (ESP_OK == esp_wifi_sta_get_ap_info(&config)) 112 | rssi = config.rssi; 113 | #elif defined(__ets__) 114 | rssi = wifi_station_get_rssi(); 115 | #else 116 | #error Unsupported target 117 | #endif 118 | xsBeginHost(rn->the); 119 | xsLog("rssi %d\n", rssi); 120 | xsEndHost(rn->the); 121 | 122 | if (rssi > rn->threshold) { 123 | if (kRSSIStrong == rn->state) 124 | return; 125 | rn->state = kRSSIStrong; 126 | callbackID = xsID_onStrongSignal; 127 | } 128 | else { 129 | if (kRSSIWeak == rn->state) 130 | return; 131 | rn->state = kRSSIWeak; 132 | callbackID = xsID_onWeakSignal; 133 | } 134 | 135 | xsBeginHost(rn->the); 136 | xsmcVars(1); 137 | xsmcSetInteger(xsVar(0), rssi); 138 | if (xsmcHas(rn->obj, callbackID)) 139 | xsCall1(rn->obj, callbackID, xsVar(0)); 140 | xsEndHost(rn->the); 141 | } 142 | -------------------------------------------------------------------------------- /ch11-native/wifi-rssi-notify/wifirssinotify.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | class WiFiRSSINotify @ "xs_wifirssinotify_destructor" { 16 | constructor(options) @ "xs_wifirssinotify_constructor"; 17 | close() @ "xs_wifirssinotify_close"; 18 | } 19 | 20 | export default WiFiRSSINotify; 21 | -------------------------------------------------------------------------------- /ch3-network/accesspoint/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import WiFi from "wifi"; 16 | import Net from "net"; 17 | import DNSServer from "dns/server"; 18 | import {Server as HTTPServer} from "http"; 19 | 20 | WiFi.accessPoint({ 21 | ssid: "South Village", 22 | }); 23 | 24 | new DNSServer(function(msg, value) { 25 | if (DNSServer.resolve === msg) 26 | return Net.get("IP"); 27 | }); 28 | 29 | (new HTTPServer).callback = function(msg, value) { 30 | if (HTTPServer.prepareResponse === msg) { 31 | return { 32 | headers: ["Content-Type", "text/plain"], 33 | body: "hello" 34 | }; 35 | } 36 | } -------------------------------------------------------------------------------- /ch3-network/accesspoint/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/host/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Modules from "modules"; 16 | import WiFi from "wifi"; 17 | import Net from "net"; 18 | import config from "mc/config"; 19 | 20 | export default function () { 21 | if (!Modules.has("check") || !Modules.has("example")) 22 | return trace("Host installed. Ready for mods.\n"); 23 | 24 | (Modules.importNow("check"))(); 25 | 26 | let credentials; 27 | if (Modules.has("mod/config")) { 28 | credentials = Modules.importNow("mod/config"); 29 | if (!credentials.ssid) 30 | credentials = undefined; 31 | } 32 | credentials ??= config; 33 | if (!credentials.ssid) 34 | return trace("This example requires Wi-Fi. When executing mcrun specify ssid and password.\n"); 35 | 36 | trace(`Wi-Fi trying to connect to "${credentials.ssid}"\n`); 37 | 38 | WiFi.mode = 1; 39 | 40 | const monitor = new WiFi({ssid: credentials.ssid, password: credentials.password}, function(msg, code) { 41 | switch (msg) { 42 | case WiFi.gotIP: 43 | trace(`IP address ${Net.get("IP")}\n`); 44 | monitor.close(); 45 | 46 | Modules.importNow("example"); 47 | break; 48 | 49 | case WiFi.connected: 50 | trace(`Wi-Fi connected to "${Net.get("SSID")}"\n`); 51 | break; 52 | 53 | case WiFi.disconnected: 54 | trace((-1 === code) ? "Wi-Fi password rejected\n" : "Wi-Fi disconnected\n"); 55 | break; 56 | } 57 | }); 58 | } 59 | -------------------------------------------------------------------------------- /ch3-network/host/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/examples/manifest_net.json", 5 | "$(MODDABLE)/modules/network/mdns/manifest.json", 6 | "$(MODDABLE)/modules/crypt/tls.json" 7 | ], 8 | "creation": { 9 | "keys": { 10 | "available": 96 11 | } 12 | }, 13 | "defines": { 14 | "XS_MODS": 1 15 | }, 16 | "modules": { 17 | "*": [ 18 | "./main", 19 | "$(MODULES)/base/modules/*", 20 | "$(MODULES)/network/http/*", 21 | "$(MODULES)/network/sntp/*", 22 | "$(MODULES)/network/websocket/*", 23 | "$(MODULES)/data/base64/*", 24 | "$(MODULES)/data/logical/*", 25 | "$(MODULES)/crypt/digest/*", 26 | "$(MODULES)/crypt/digest/kcl/*", 27 | "$(MODULES)/network/mqtt/*" 28 | ], 29 | "dns/server": "$(MODULES)/network/dns/dnsserver" 30 | }, 31 | "preload": [ 32 | "http", 33 | "sntp", 34 | "websocket", 35 | "base64", 36 | "digest", 37 | "logical", 38 | "mqtt", 39 | "modules" 40 | ], 41 | "strip": [ 42 | "Atomics", 43 | "eval", 44 | "Function", 45 | "Generator", 46 | "Map", 47 | "Proxy", 48 | "Reflect", 49 | "RegExp", 50 | "Set", 51 | "SharedArrayBuffer", 52 | "WeakMap", 53 | "WeakSet" 54 | ], 55 | "build": { 56 | "NAME": "ch3host" 57 | }, 58 | "platforms": { 59 | "esp": { 60 | "modules": { 61 | "~": [ 62 | "$(BUILD)/devices/esp/setup/network" 63 | ] 64 | } 65 | }, 66 | "esp32": { 67 | "modules": { 68 | "~": [ 69 | "$(BUILD)/devices/esp32/setup/network" 70 | ] 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ch3-network/http-get-json/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Request} from "http"; 16 | 17 | const APPID = "94de4cda19a2ba07d3fa6450eb80f091"; 18 | const zip = "94303"; 19 | const country = "us"; 20 | 21 | let request = new Request({ 22 | host: "api.openweathermap.org", 23 | path: `/data/2.5/weather?appid=${APPID}&` + 24 | `zip=${zip},${country}&units=imperial`, 25 | response: String 26 | }); 27 | 28 | request.callback = function(msg, value) { 29 | if (Request.responseComplete === msg) { 30 | value = JSON.parse(value); 31 | trace(`Location: ${value.name}\n`); 32 | trace(`Temperature: ${value.main.temp} F\n`); 33 | trace(`Weather: ${value.weather[0].main}.\n`); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ch3-network/http-get-json/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/http-get-subclass/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Request} from "http"; 16 | 17 | const APPID = "94de4cda19a2ba07d3fa6450eb80f091"; 18 | 19 | class WeatherRequest extends Request { 20 | constructor(zip, country) { 21 | super({ 22 | host: "api.openweathermap.org", 23 | path: `/data/2.5/weather?appid=${APPID}&zip=${zip},${country}&units=imperial`, 24 | response: String 25 | }); 26 | } 27 | callback(msg, value) { 28 | if (Request.responseComplete === msg) { 29 | value = JSON.parse(value, 30 | ["main", "name", "temp", "weather"]); 31 | this.onReceived({ 32 | temperature: value.main.temp, 33 | condition: value.weather[0].main} 34 | ); 35 | } 36 | } 37 | } 38 | 39 | let weather = new WeatherRequest(94025, "us"); 40 | 41 | weather.onReceived = function(result) { 42 | trace(`Temperature is ${result.temperature}\n`); 43 | trace(`Condition is ${result.condition}\n`); 44 | } 45 | -------------------------------------------------------------------------------- /ch3-network/http-get-subclass/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/http-get-with-promise/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Request} from "http"; 16 | 17 | function fetch(host, path = "/") { 18 | return new Promise((resolve, reject) => { 19 | let request = new Request({host, path, response: String}); 20 | request.callback = function(msg, value) { 21 | if (Request.responseComplete === msg) 22 | resolve(value); 23 | else if (Request.error === msg) 24 | reject(-1); 25 | } 26 | }); 27 | } 28 | 29 | async function httpTrace(host, path) { 30 | try { 31 | let body = await fetch(host, path); 32 | trace(body, "\n"); 33 | } 34 | catch { 35 | trace("http get failed\n"); 36 | } 37 | } 38 | 39 | httpTrace("www.example.com"); 40 | -------------------------------------------------------------------------------- /ch3-network/http-get-with-promise/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/http-get/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Request} from "http"; 16 | 17 | let request = new Request({ 18 | host: "www.example.com", 19 | path: "/", 20 | response: String 21 | }); 22 | 23 | request.callback = function(msg, value) { 24 | if (Request.responseComplete === msg) 25 | trace(value, "\n"); 26 | } 27 | -------------------------------------------------------------------------------- /ch3-network/http-get/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/http-post/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Request} from "http"; 16 | 17 | let request = new Request({ 18 | host: "httpbin.org", 19 | path: "/post", 20 | method: "POST", 21 | body: JSON.stringify({string: "test", number: 123}), 22 | response: String 23 | }); 24 | 25 | request.callback = function(msg, value) { 26 | if (Request.responseComplete === msg) { 27 | value = JSON.parse(value); 28 | trace(`name: ${value.json.string}\n`); 29 | trace(`value: ${value.json.number}\n`); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ch3-network/http-post/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/http-server-get/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Server} from "http"; 16 | 17 | let server = new Server({port: 80}); 18 | server.callback = function(msg, value, etc) { 19 | if (Server.status === msg) { 20 | this.path = value; 21 | this.method = etc; 22 | } 23 | else if (Server.prepareResponse === msg) 24 | return { 25 | headers: ["Content-Type", "text/plain"], 26 | body: `hello. path "${this.path}". method "${this.method}".` 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /ch3-network/http-server-get/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/http-server-put/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Server} from "http"; 16 | 17 | let server = new Server; 18 | 19 | server.callback = function(msg, value, etc) { 20 | switch (msg) { 21 | case Server.status: 22 | if ("PUT" !== etc) 23 | this.close(); 24 | return; 25 | 26 | case Server.headersComplete: 27 | return String; 28 | 29 | case Server.requestComplete: 30 | this.json = { 31 | error: "none", 32 | when: (new Date).toString(), 33 | request: JSON.parse(value) 34 | }; 35 | break; 36 | 37 | case Server.prepareResponse: 38 | return { 39 | headers: ["Content-Type", "application/json"], 40 | body: JSON.stringify(this.json) 41 | }; 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /ch3-network/http-server-put/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/http-server-streaming-get/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Server} from "http"; 16 | 17 | let server = new Server; 18 | 19 | server.callback = function(msg, value) { 20 | if (Server.prepareResponse === msg) 21 | return { 22 | headers:["Content-Type", "text/plain"], 23 | body: true 24 | }; 25 | else if (Server.responseFragment === msg) { 26 | let i = Math.round(Math.random() * 100); 27 | if (0 === i) 28 | return; 29 | return i + "\n"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ch3-network/http-server-streaming-get/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/http-server-streaming-put/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Server} from "http"; 16 | 17 | let server = new Server; 18 | 19 | server.callback = function(msg, value) { 20 | switch (msg) { 21 | case Server.status: 22 | trace(`\n ** begin upload to ${value} **\n`); 23 | break; 24 | 25 | case Server.headersComplete: // prepare for request body 26 | return true; // provide request body in fragments 27 | 28 | case Server.requestFragment: 29 | trace(this.read(String)); 30 | break; 31 | 32 | case Server.requestComplete: 33 | trace("\n ** end of file **\n"); 34 | break; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ch3-network/http-server-streaming-put/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/http-streaming-get/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Request} from "http"; 16 | 17 | let request = new Request({ 18 | host: "www.bing.com", 19 | path: "/" 20 | }); 21 | 22 | request.callback = function(msg, value, etc) { 23 | if (Request.responseFragment === msg) 24 | trace(this.read(String), "\n"); 25 | else if (Request.responseComplete === msg) 26 | trace(`\n\nTransfer complete.\n\n`); 27 | } 28 | -------------------------------------------------------------------------------- /ch3-network/http-streaming-get/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/https-get/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Request} from "http"; 16 | import SecureSocket from "securesocket"; 17 | 18 | let request = new Request({ 19 | host: "www.example.com", 20 | path: "/", 21 | response: String, 22 | Socket: SecureSocket, 23 | port: 443 24 | }); 25 | 26 | request.callback = function(msg, value) { 27 | if (Request.responseComplete === msg) 28 | trace(value, "\n"); 29 | } 30 | -------------------------------------------------------------------------------- /ch3-network/https-get/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*": [ 8 | "$(MODDABLE)/modules/crypt/data/ca106", 9 | "$(MODDABLE)/modules/crypt/data/ca107" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ch3-network/mdns-advertise/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import MDNS from "mdns"; 16 | import {Server} from "http"; 17 | 18 | let httpService = { 19 | name: "http", 20 | protocol: "tcp", 21 | port: 80 22 | }; 23 | 24 | let mdns = new MDNS({ 25 | hostName: "server" 26 | }, 27 | function(msg, value) { 28 | if ((MDNS.hostName === msg) && value) 29 | mdns.add(httpService); 30 | } 31 | ); 32 | 33 | let server = new Server({port: 80}); 34 | server.callback = function(msg, value, etc) { 35 | if (Server.status === msg) { 36 | this.path = value; 37 | this.method = etc; 38 | } 39 | else if (Server.prepareResponse === msg) 40 | return { 41 | headers: ["Content-Type", "text/plain"], 42 | body: `Hello. ${new Date}` 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /ch3-network/mdns-advertise/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/mdns-claim-name/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import MDNS from "mdns"; 16 | 17 | let mdns = new MDNS({ 18 | hostName: "iotdevice" 19 | }, 20 | function(msg, value) { 21 | if ((MDNS.hostName === msg) && value) 22 | trace(`Claimed name ${value}.\n`); 23 | } 24 | ); -------------------------------------------------------------------------------- /ch3-network/mdns-claim-name/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/mdns-discover/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | import MDNS from "mdns"; 15 | import {Request} from "http"; 16 | 17 | let mdns = new MDNS; 18 | mdns.monitor("_http._tcp", function (service, instance) { 19 | trace(`Found ${service}: "${instance.name}" @ ` + 20 | `${instance.target} ` + 21 | `(${instance.address}:${instance.port})\n`); 22 | 23 | let request = new Request({ 24 | host: instance.address, 25 | port: instance.port, 26 | path: "/" 27 | }); 28 | request.callback = function(msg, value, etc) { 29 | if (Request.header === msg) 30 | trace(` ${value}: ${etc}\n`); 31 | else if (Request.responseComplete === msg) 32 | trace("\n\n"); 33 | else if (Request.error === msg) 34 | trace("error \n\n"); 35 | }; 36 | }); -------------------------------------------------------------------------------- /ch3-network/mdns-discover/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/mqtt/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import MQTT from "mqtt"; 16 | import Net from "net"; 17 | 18 | let mqtt = new MQTT({ 19 | host: "test.mosquitto.org", 20 | port: 1883, 21 | id: "iot_" + Net.get("MAC") 22 | }) 23 | 24 | mqtt.onReady = function () { 25 | trace("connection established\n"); 26 | mqtt.subscribe("test/json"); 27 | 28 | mqtt.publish("test/json", JSON.stringify({ 29 | message: "hello", 30 | version: 1 31 | })); 32 | } 33 | 34 | mqtt.onMessage = function (topic, data) { 35 | trace(`received message on topic "${topic}"\n`); 36 | trace(`${String.fromArrayBuffer(data)}\n`); 37 | } 38 | 39 | mqtt.onClose = function() { 40 | trace("connection lost\n"); 41 | }; 42 | -------------------------------------------------------------------------------- /ch3-network/mqtt/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/sntp/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import SNTP from "sntp"; 16 | import Time from "time"; 17 | 18 | new SNTP({ 19 | host: "pool.ntp.org" 20 | }, 21 | function(msg, value) { 22 | if (SNTP.time !== msg) 23 | return; 24 | 25 | Time.set(value); 26 | trace("UTC time now: ", 27 | (new Date).toUTCString(), "\n"); 28 | } 29 | ); -------------------------------------------------------------------------------- /ch3-network/sntp/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/websocket-client/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Client} from "websocket"; 16 | 17 | let ws = new Client({ 18 | host: "websockets.chilkat.io", 19 | path: "/wsChilkatEcho.ashx" 20 | }); 21 | 22 | ws.callback = function(msg, value) { 23 | switch (msg) { 24 | case Client.connect: 25 | trace("connected\n"); 26 | break; 27 | 28 | case Client.handshake: 29 | trace("handshake success\n"); 30 | this.write(JSON.stringify({ 31 | count: 1, 32 | toggle: true 33 | })); 34 | break; 35 | 36 | case Client.receive: 37 | trace(`received: ${value}\n`); 38 | value = JSON.parse(value); 39 | value.count += 1; 40 | value.toggle = !value.toggle; 41 | this.write(JSON.stringify(value)); 42 | break; 43 | 44 | case Client.disconnect: 45 | trace("disconnected\n"); 46 | break; 47 | } 48 | } -------------------------------------------------------------------------------- /ch3-network/websocket-client/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/websocket-server/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Server} from "websocket"; 16 | 17 | let server = new Server; 18 | 19 | server.callback = function (msg, value) { 20 | switch (msg) { 21 | case Server.connect: 22 | trace("connected\n"); 23 | break; 24 | 25 | case Server.handshake: 26 | trace("handshake success\n"); 27 | break; 28 | 29 | case Server.receive: 30 | trace(`received: ${value}\n`); 31 | this.write(value); 32 | break; 33 | 34 | case Server.disconnect: 35 | trace("closed\n"); 36 | break; 37 | } 38 | } -------------------------------------------------------------------------------- /ch3-network/websocket-server/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch3-network/wifi-code/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import WiFi from "wifi"; 16 | 17 | let wifiMonitor = new WiFi({ 18 | ssid: "my wi-fi", 19 | password: "secret" 20 | }, 21 | function(msg) { 22 | switch (msg) { 23 | case WiFi.gotIP: 24 | trace("network ready\n"); 25 | break; 26 | 27 | case WiFi.connected: 28 | trace("connected\n"); 29 | break; 30 | 31 | case WiFi.disconnected: 32 | trace("connection lost\n"); 33 | break; 34 | } 35 | } 36 | ); 37 | -------------------------------------------------------------------------------- /ch3-network/wifi-code/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/examples/manifest_net.json" 5 | ], 6 | "modules": { 7 | "*": [ 8 | "./main" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch3-network/wifi-command-line/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Net from "net"; 16 | 17 | trace(`Connected to Wi-Fi. IP Address is: ${Net.get("IP")}\n`); 18 | -------------------------------------------------------------------------------- /ch3-network/wifi-command-line/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/examples/manifest_net.json" 5 | ], 6 | "modules": { 7 | "*": [ 8 | "./main" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch3-network/wifi-open-ap/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import WiFi from "wifi"; 16 | 17 | let best; 18 | 19 | WiFi.scan({}, accessPoint => { 20 | if (!accessPoint) { 21 | if (!best) { 22 | trace("no open access points found\n"); 23 | return; 24 | } 25 | trace(`connecting to ${best.ssid}\n`); 26 | WiFi.connect({ssid: best.ssid}); 27 | return; 28 | } 29 | 30 | if ("none" !== accessPoint.authentication) 31 | return; // not open 32 | 33 | if (!best) { 34 | best = accessPoint; // first open access point found 35 | return; 36 | } 37 | 38 | if (best.rssi < accessPoint.rssi) 39 | best = accessPoint; // new best 40 | }); -------------------------------------------------------------------------------- /ch3-network/wifi-open-ap/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/examples/manifest_net.json" 5 | ], 6 | "modules": { 7 | "*": [ 8 | "./main" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch4-ble/host/bleservices/bs.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": { 3 | "uuid": "180F", 4 | "characteristics": { 5 | "battery": { 6 | "uuid": "2A19", 7 | "maxBytes": 1, 8 | "type": "Uint8", 9 | "permissions": "read", 10 | "properties": "read" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ch4-ble/host/bleservices/gap.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": { 3 | "uuid": "1800", 4 | "characteristics": { 5 | "device_name": { 6 | "uuid": "2A00", 7 | "maxBytes": 12, 8 | "type": "String", 9 | "permissions": "read", 10 | "properties": "read", 11 | "value": "Heart Rate Monitor" 12 | }, 13 | "appearance": { 14 | "uuid": "2A01", 15 | "maxBytes": 2, 16 | "type": "Uint16", 17 | "permissions": "read", 18 | "properties": "read", 19 | "value": 832 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ch4-ble/host/bleservices/hrs.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": { 3 | "uuid": "180D", 4 | "characteristics": { 5 | "bpm": { 6 | "uuid": "2A37", 7 | "maxBytes": 2, 8 | "type": "Array", 9 | "permissions": "read", 10 | "properties": "notify" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ch4-ble/host/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Modules from "modules"; 16 | 17 | export default function () { 18 | if (Modules.has("check")) { 19 | let check = Modules.importNow("check"); 20 | check(); 21 | if (Modules.has("example")) 22 | Modules.importNow("example"); 23 | } else { 24 | trace("Device flashed. Ready to install apps.\n"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ch4-ble/host/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/modules/network/ble/manifest_server.json", 5 | "$(MODDABLE)/modules/network/ble/manifest_client.json" 6 | ], 7 | "defines": { 8 | "XS_MODS": 1 9 | }, 10 | "modules": { 11 | "*": [ 12 | "./main", 13 | "$(MODULES)/base/modules/*" 14 | ] 15 | }, 16 | "preload": [ 17 | "main", 18 | "modules" 19 | ], 20 | "ble":{ 21 | "*": [ 22 | "./bleservices/*" 23 | ] 24 | }, 25 | "strip": [], 26 | "build": { 27 | "NAME": "ch4host" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ch4-ble/hrm-secure/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import BLEServer from "bleserver"; 16 | import {uuid} from "btutils"; 17 | import Timer from "timer"; 18 | import {IOCapability} from "sm"; 19 | 20 | class HeartRateService extends BLEServer { 21 | onReady() { 22 | this.deviceName = "Heart Rate Monitor"; 23 | this.securityParameters = { 24 | bonding: true, 25 | mitm: true, 26 | ioCapability: IOCapability.DisplayOnly 27 | }; 28 | this.onDisconnected(); 29 | this.battery = 100; 30 | } 31 | onPasskeyDisplay(params) { 32 | let passkey = this.passkeyToString(params.passkey); 33 | trace(`server display passkey: ${passkey}\n`); 34 | } 35 | onAuthenticated() { 36 | this.authenticated = true; 37 | } 38 | passkeyToString(passkey) { 39 | return passkey.toString().padStart(6, "0"); 40 | } 41 | onConnected() { 42 | this.stopAdvertising(); 43 | } 44 | onDisconnected() { 45 | this.stopMeasurements(); 46 | this.startAdvertising({ 47 | advertisingData: { 48 | flags: 6, 49 | completeName: this.deviceName, 50 | completeUUID16List: [uuid`180D`, uuid`180F`] 51 | } 52 | }); 53 | } 54 | onCharacteristicNotifyEnabled(characteristic) { 55 | if (this.authenticated) { 56 | this.bump = +1; 57 | this.timer = Timer.repeat(id => { 58 | this.notifyValue(characteristic, this.bpm); 59 | this.bpm[1] += this.bump; 60 | if (this.bpm[1] === 65) { 61 | this.bump = -1; 62 | this.bpm[1] = 64; 63 | } 64 | else if (this.bpm[1] === 55) { 65 | this.bump = +1; 66 | this.bpm[1] = 56; 67 | } 68 | }, 1000); 69 | } 70 | } 71 | onCharacteristicNotifyDisabled(characteristic) { 72 | this.stopMeasurements(); 73 | } 74 | onCharacteristicRead(params) { 75 | if (params.name === "battery") { 76 | if (this.battery === 0) this.battery = 100; 77 | return this.battery--; 78 | } 79 | } 80 | stopMeasurements() { 81 | if (this.timer) { 82 | Timer.clear(this.timer); 83 | delete this.timer; 84 | } 85 | this.bpm = [0, 60]; // flags, beats per minute 86 | } 87 | } 88 | 89 | let hrs = new HeartRateService; 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /ch4-ble/hrm-secure/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch4-ble/hrm/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import BLEServer from "bleserver"; 16 | import {uuid} from "btutils"; 17 | import Timer from "timer"; 18 | 19 | class HeartRateService extends BLEServer { 20 | onReady() { 21 | this.deviceName = "Heart Rate Monitor"; 22 | this.onDisconnected(); 23 | this.battery = 100; 24 | } 25 | onConnected() { 26 | this.stopAdvertising(); 27 | } 28 | onDisconnected() { 29 | this.stopMeasurements(); 30 | this.startAdvertising({ 31 | advertisingData: { 32 | flags: 6, 33 | completeName: this.deviceName, 34 | completeUUID16List: [uuid`180D`, uuid`180F`] 35 | } 36 | }); 37 | } 38 | onCharacteristicNotifyEnabled(characteristic) { 39 | this.bump = +1; 40 | this.timer = Timer.repeat(id => { 41 | this.notifyValue(characteristic, this.bpm); 42 | this.bpm[1] += this.bump; 43 | if (this.bpm[1] === 65) { 44 | this.bump = -1; 45 | this.bpm[1] = 64; 46 | } 47 | else if (this.bpm[1] === 55) { 48 | this.bump = +1; 49 | this.bpm[1] = 56; 50 | } 51 | }, 1000); 52 | } 53 | onCharacteristicNotifyDisabled(characteristic) { 54 | this.stopMeasurements(); 55 | } 56 | onCharacteristicRead(params) { 57 | if (params.name === "battery") { 58 | if (this.battery === 0) this.battery = 100; 59 | return this.battery--; 60 | } 61 | } 62 | stopMeasurements() { 63 | if (this.timer) { 64 | Timer.clear(this.timer); 65 | delete this.timer; 66 | } 67 | this.bpm = [0, 60]; // flags, beats per minute 68 | } 69 | } 70 | 71 | let hrs = new HeartRateService; 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /ch4-ble/hrm/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch4-ble/scanner/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import BLEClient from "bleclient"; 16 | 17 | class Scanner extends BLEClient { 18 | onReady() { 19 | this.startScanning(); 20 | } 21 | onDiscovered(device) { 22 | let scanResponse = device.scanResponse; 23 | let completeName = scanResponse.completeName; 24 | if (completeName) 25 | trace(`${completeName}\n`); 26 | } 27 | } 28 | 29 | let scanner = new Scanner; -------------------------------------------------------------------------------- /ch4-ble/scanner/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch4-ble/text-client/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import BLEClient from "bleclient"; 16 | import {uuid} from "btutils"; 17 | 18 | const PERIPHERAL_NAME = 'esp'; 19 | const SERVICE_UUID = uuid`6E400001B5A3F393E0A9E50E24DCCA9E`; 20 | const CHARACTERISTIC_UUID = uuid`6E400003B5A3F393E0A9E50E24DCCA9E`; 21 | 22 | class TextClient extends BLEClient { 23 | onReady() { 24 | this.startScanning(); 25 | } 26 | onDiscovered(device) { 27 | if (PERIPHERAL_NAME === device.scanResponse.completeName) { 28 | this.stopScanning(); 29 | this.connect(device); 30 | } 31 | } 32 | onConnected(device) { 33 | device.discoverPrimaryService(SERVICE_UUID); 34 | } 35 | onServices(services) { 36 | let service = services.find(service => service.uuid.equals(SERVICE_UUID)); 37 | if (service) { 38 | trace(`Found service\n`); 39 | service.discoverCharacteristic(CHARACTERISTIC_UUID); 40 | } else 41 | trace(`Service not found\n`); 42 | } 43 | onCharacteristics(characteristics) { 44 | let characteristic = characteristics.find(characteristic => characteristic.uuid.equals(CHARACTERISTIC_UUID)); 45 | if (characteristic) { 46 | trace(`Enabling notifications\n`); 47 | characteristic.enableNotifications(); 48 | } else 49 | trace(`Characteristic not found\n`); 50 | } 51 | onCharacteristicNotification(characteristic, buffer) { 52 | trace(String.fromArrayBuffer(buffer)); 53 | } 54 | } 55 | 56 | let textClient = new TextClient; -------------------------------------------------------------------------------- /ch4-ble/text-client/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch4-ble/text-server/bleservices/text.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": { 3 | "uuid": "6E400001-B5A3-F393-E0A9-E50E24DCCA9E", 4 | "characteristics": { 5 | "text": { 6 | "uuid": "6E400003-B5A3-F393-E0A9-E50E24DCCA9E", 7 | "type": "String", 8 | "maxBytes": 20, 9 | "permissions": "read", 10 | "properties": "notify" 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ch4-ble/text-server/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import BLEServer from "bleserver"; 16 | import {uuid} from "btutils"; 17 | import Timer from "timer"; 18 | 19 | const SERVICE_UUID = uuid`6E400001B5A3F393E0A9E50E24DCCA9E`; 20 | 21 | const strings = [ 22 | "Hello", 23 | "World" 24 | ] 25 | 26 | class TextServer extends BLEServer { 27 | onReady() { 28 | this.deviceName = "esp"; 29 | this.onDisconnected(); 30 | } 31 | onConnected() { 32 | this.stopAdvertising(); 33 | } 34 | onDisconnected() { 35 | this.startAdvertising({ 36 | advertisingData: { 37 | flags: 6, 38 | completeName: this.deviceName, 39 | completeUUID128List: [SERVICE_UUID] 40 | } 41 | }); 42 | } 43 | onCharacteristicNotifyEnabled(characteristic) { 44 | let index = 0; 45 | this.timer = Timer.repeat(id => { 46 | this.text = strings[index]; 47 | this.notifyValue(characteristic, this.text); 48 | index++; 49 | if (index === strings.length) 50 | index = 0; 51 | }, 1000); 52 | } 53 | onCharacteristicNotifyDisabled(characteristic) { 54 | if (this.timer) { 55 | Timer.clear(this.timer); 56 | delete this.timer; 57 | } 58 | } 59 | } 60 | 61 | let server = new TextServer; 62 | -------------------------------------------------------------------------------- /ch4-ble/text-server/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/modules/network/ble/manifest_server.json" 5 | ], 6 | "modules": { 7 | "*": [ 8 | "./main" 9 | ] 10 | }, 11 | "ble":{ 12 | "*": [ 13 | "./bleservices/*" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ch5-files/files/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import { File, Iterator } from "file"; 16 | import config from "mc/config"; 17 | 18 | const root = config.file.root; 19 | 20 | File.delete(root + "test.txt"); 21 | File.delete(root + "test.bin"); 22 | 23 | /* Reading and writing text */ 24 | let file = new File(root + "test.txt", true); 25 | file.write("this is a test"); 26 | file.close(); 27 | 28 | file = new File(root + "test.txt"); 29 | let string = file.read(String); 30 | trace(string + "\n"); 31 | file.close(); 32 | trace("\n"); 33 | 34 | /* Reading and writing binary data */ 35 | let bytes = Uint32Array.of(0, 1, 2, 3, 4); 36 | file = new File(root + "test.bin", true); 37 | file.write(bytes.buffer); 38 | file.close(); 39 | 40 | file = new File(config.file.root + "test.bin"); 41 | let buffer = file.read(ArrayBuffer); 42 | file.close(); 43 | 44 | bytes = new Uint8Array(buffer); 45 | for (let i = 0; i < bytes.length; i++) 46 | trace(bytes[i].toString(16).padStart(2, "0"), "\n"); 47 | trace("\n"); 48 | 49 | /* Iterating */ 50 | let iterator = new Iterator(root); 51 | let item; 52 | while (item = iterator.next()) { 53 | if (undefined === item.length) 54 | trace(`${item.name.padEnd(32)} directory\n`); 55 | else 56 | trace(`${item.name.padEnd(32)} file ${item.length} bytes\n`); 57 | } -------------------------------------------------------------------------------- /ch5-files/files/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch5-files/flash-frequentupdate/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Flash from "flash"; 16 | 17 | let partition = new Flash("storage"); 18 | 19 | const SIGNATURE = 0xa82aa82a; 20 | 21 | let signature = partition.read(0, 4); 22 | signature = (new Uint32Array(signature))[0]; 23 | if (signature !== SIGNATURE) 24 | initialize(partition); 25 | 26 | 27 | function initialize(partition) { 28 | let signature = Uint32Array.of(SIGNATURE); 29 | 30 | partition.erase(0); 31 | partition.write(0, 4, signature.buffer); 32 | } 33 | 34 | function write(partition, newValue) { 35 | for (let i = 1; i < 1024; i++) { 36 | let currentValue = partition.read(i * 4, 4); 37 | currentValue = (new Uint32Array(currentValue))[0]; 38 | if (0xFFFFFFFF === currentValue) { 39 | partition.write(i * 4, 4, Uint32Array.of(newValue).buffer); 40 | return; 41 | } 42 | } 43 | initialize(partition); 44 | partition.write(4, 4, Uint32Array.of(newValue).buffer); 45 | } 46 | 47 | function read(partition) { 48 | let i; 49 | 50 | for (i = 1; i < 1024; i++) { 51 | let currentValue = partition.read(i * 4, 4); 52 | currentValue = (new Uint32Array(currentValue))[0]; 53 | if (0xFFFFFFFF === currentValue) 54 | break; 55 | } 56 | 57 | let result = partition.read((i - 1) * 4, 4); 58 | return (new Uint32Array(result))[0]; 59 | } -------------------------------------------------------------------------------- /ch5-files/flash-frequentupdate/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch5-files/flash-map/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Flash from "flash"; 16 | 17 | let partition = new Flash("storage"); 18 | let buffer = partition.map(); 19 | let bytes = new Uint8Array(buffer); 20 | 21 | for (let i=0; i<8; i++) 22 | trace(`${bytes[i].toString(16).padStart(2, 0)} `); 23 | trace("\n"); 24 | -------------------------------------------------------------------------------- /ch5-files/flash-map/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch5-files/flash-readwrite/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Flash from "flash"; 16 | 17 | let partition = new Flash("storage"); 18 | 19 | partition.erase(0); 20 | 21 | let buffer = Uint8Array.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).buffer; 22 | partition.write(0, 10, buffer); 23 | 24 | buffer = partition.read(0, 10); 25 | let bytes = new Uint8Array(buffer); 26 | for (let i = 0; i < bytes.byteLength; i++) 27 | trace(bytes[i] + "\n"); 28 | -------------------------------------------------------------------------------- /ch5-files/flash-readwrite/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch5-files/host/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2023 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Modules from "modules"; 16 | 17 | export default function () { 18 | if (!Modules.has("check") || !Modules.has("example")) 19 | return trace("Host installed. Ready for mods.\n"); 20 | 21 | (Modules.importNow("check"))(); 22 | 23 | if (Modules.has("wifi") && Modules.has("net") && Modules.has("mod/config")) { 24 | const WiFi = Modules.importNow("wifi"); 25 | const Net = Modules.importNow("net"); 26 | const config = Modules.importNow("mod/config"); 27 | if (config.ssid) { 28 | trace(`Wi-Fi trying to connect to "${config.ssid}"\n`); 29 | 30 | WiFi.mode = 1; 31 | 32 | let monitor = new WiFi({ssid: config.ssid, password: config.password}, function(msg, code) { 33 | switch (msg) { 34 | case WiFi.gotIP: 35 | trace(`IP address ${Net.get("IP")}\n`); 36 | monitor.close(); 37 | 38 | Modules.importNow("example"); 39 | break; 40 | 41 | case WiFi.connected: 42 | trace(`Wi-Fi connected to "${Net.get("SSID")}"\n`); 43 | break; 44 | 45 | case WiFi.disconnected: 46 | trace((-1 === code) ? "Wi-Fi password rejected\n" : "Wi-Fi disconnected\n"); 47 | break; 48 | } 49 | }); 50 | return; 51 | } 52 | if (config.wifi && !Net.get("SSID")) 53 | throw new Error(`This example requires Wi-Fi. When executing mcrun specify ssid and password.\n`); 54 | } 55 | 56 | Modules.importNow("example"); 57 | } 58 | -------------------------------------------------------------------------------- /ch5-files/host/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/modules/files/preference/manifest.json", 5 | "$(MODDABLE)/modules/files/flash/manifest.json", 6 | "$(MODDABLE)/modules/files/file/manifest.json", 7 | "$(MODDABLE)/modules/base/modules/manifest.json" 8 | ], 9 | "defines": { 10 | "XS_MODS": 1 11 | }, 12 | "modules": { 13 | "*": "./main" 14 | }, 15 | "platforms": { 16 | "sim": { 17 | "include": "$(MODDABLE)/examples/manifest_net.json" 18 | }, 19 | "esp": { 20 | "include": [ 21 | "$(MODDABLE)/examples/manifest_net.json", 22 | "$(MODDABLE)/modules/network/http/manifest.json" 23 | ], 24 | "modules": { 25 | "~": [ 26 | "$(BUILD)/devices/esp/setup/network" 27 | ] 28 | } 29 | }, 30 | "esp32": { 31 | "include": [ 32 | "$(MODDABLE)/examples/manifest_net.json", 33 | "$(MODDABLE)/modules/network/http/manifest.json" 34 | ], 35 | "~": [ 36 | "$(BUILD)/devices/esp32/setup/network" 37 | ] 38 | }, 39 | "pico": { 40 | "include": [ 41 | "$(MODDABLE)/examples/manifest_net.json", 42 | "$(MODDABLE)/modules/network/http/manifest.json" 43 | ], 44 | "~": [ 45 | "$(BUILD)/devices/pico/setup/network" 46 | ] 47 | } 48 | }, 49 | "strip": [], 50 | "build": { 51 | "NAME": "ch5host" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ch5-files/preferences/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2023 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Preference from "preference"; 16 | 17 | Preference.set("example", "boolean", true); 18 | Preference.set("example", "integer", 1); 19 | Preference.set("example", "string", "my value"); 20 | Preference.set("example", "arraybuffer", Uint8Array.of(1, 2, 3).buffer); 21 | 22 | let a = Preference.get("example", "boolean"); // true 23 | let b = Preference.get("example", "integer"); // 1 24 | let c = Preference.get("example", "string"); // "my value" 25 | let d = Preference.get("example", "arraybuffer"); // ArrayBuffer of [1, 2, 3] 26 | 27 | trace(`boolean: ${a}\n`); 28 | trace(`integer: ${b}\n`); 29 | trace(`string: ${c}\n`); 30 | trace(`arraybuffer: ${new Uint8Array(d)}\n`); 31 | -------------------------------------------------------------------------------- /ch5-files/preferences/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch5-files/resources/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import {Server} from "http"; 16 | import Resource from "Resource"; 17 | 18 | let data = new Resource("mydata.dat"); 19 | 20 | let server = new Server(); 21 | server.callback = function(message, value, etc) { 22 | switch (message) { 23 | case Server.prepareResponse: 24 | return {headers: ["Content-type", "text/html"], body: data}; 25 | } 26 | } -------------------------------------------------------------------------------- /ch5-files/resources/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*": [ 8 | "./mydata" 9 | ] 10 | }, 11 | "config": { 12 | "wifi": true 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /ch5-files/resources/mydata.dat: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Hello, world 7 | 8 | 9 |

Hello, world

10 | 11 | -------------------------------------------------------------------------------- /ch6-hardware/blink/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Timer from "timer"; 16 | import Digital from "pins/digital"; 17 | 18 | let blink = 1; 19 | Timer.repeat(() => { 20 | blink = blink ^ 1; 21 | Digital.write(2, blink); 22 | }, 200); -------------------------------------------------------------------------------- /ch6-hardware/blink/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch6-hardware/button/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Timer from "timer"; 16 | import Digital from "pins/digital"; 17 | 18 | let previous = 1; 19 | let count = 0; 20 | Timer.repeat(id => { 21 | let value = Digital.read(0); 22 | if (value !== previous) { 23 | if (value) 24 | trace(`button pressed: ${++count}\n`); 25 | previous = value; 26 | } 27 | }, 100); -------------------------------------------------------------------------------- /ch6-hardware/button/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch6-hardware/external-button/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Timer from "timer"; 16 | import Digital from "pins/digital"; 17 | 18 | let button = new Digital({ 19 | pin: 16, 20 | mode: Digital.InputPullDown 21 | }); 22 | let previous = 0; 23 | let count = 0; 24 | Timer.repeat(id => { 25 | let value = button.read(); 26 | if (value !== previous) { 27 | if (!value) 28 | trace(`button pressed: ${++count}\n`); 29 | previous = value; 30 | } 31 | }, 100); -------------------------------------------------------------------------------- /ch6-hardware/external-button/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch6-hardware/host/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Modules from "modules"; 16 | 17 | export default function () { 18 | if (Modules.has("check")) { 19 | let check = Modules.importNow("check"); 20 | check(); 21 | if (Modules.has("example")) 22 | Modules.importNow("example"); 23 | } else { 24 | trace("Device flashed. Ready to install apps.\n"); 25 | } 26 | } -------------------------------------------------------------------------------- /ch6-hardware/host/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODULES)/pins/digital/manifest.json", 5 | "$(MODULES)/pins/digital/monitor/manifest.json", 6 | "$(MODULES)/pins/analog/manifest.json", 7 | "$(MODULES)/pins/servo/manifest.json", 8 | "$(MODULES)/pins/i2c/manifest.json", 9 | "$(MODULES)/pins/pwm/manifest.json", 10 | "$(MODULES)/pins/smbus/manifest.json" 11 | ], 12 | "defines": { 13 | "XS_MODS": 1 14 | }, 15 | "modules": { 16 | "*": [ 17 | "./main", 18 | "$(MODULES)/base/modules/*" 19 | ] 20 | }, 21 | "preload": [ 22 | "modules" 23 | ], 24 | "platforms": { 25 | "esp": { 26 | "defines": { 27 | "i2c": { 28 | "sda_pin": 5, 29 | "scl_pin": 4 30 | } 31 | } 32 | }, 33 | "esp32": { 34 | "defines": { 35 | "i2c": { 36 | "sda_pin": 21, 37 | "scl_pin": 22 38 | } 39 | } 40 | }, 41 | "nrf52": { 42 | "defines": { 43 | "i2c": { 44 | "sda_pin": 26, 45 | "scl_pin": 27 46 | } 47 | } 48 | }, 49 | "...": { 50 | "error": "Platform not supported" 51 | } 52 | }, 53 | "strip": [], 54 | "build": { 55 | "NAME": "ch6host" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ch6-hardware/servo/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Timer from "timer"; 16 | import Servo from "pins/servo"; 17 | 18 | let servo = new Servo({pin: 14}); 19 | let angle = 0; 20 | Timer.repeat(() => { 21 | angle += 2.5; 22 | if (angle > 180) 23 | angle -= 180; 24 | servo.write(angle); 25 | }, 250); -------------------------------------------------------------------------------- /ch6-hardware/servo/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch6-hardware/tmp102/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Timer from "timer"; 16 | import I2C from "pins/i2c"; 17 | 18 | let sensor = new I2C({address: 0x48}); 19 | 20 | const TEMPERATURE_REG = 0; 21 | sensor.write(TEMPERATURE_REG); 22 | let value = sensor.read(2); 23 | value = (value[0] << 4) | (value[1] >> 4); 24 | if (value & 0x800) { 25 | value -= 1; 26 | value = ~value & 0xFFF; 27 | value = -value; 28 | } 29 | value /= 16; 30 | trace(`Celsius temperature: ${value}\n`); -------------------------------------------------------------------------------- /ch6-hardware/tmp102/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch6-hardware/tmp36/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Analog from "pins/analog"; 16 | 17 | let value = (Analog.read(0) / 1023) * 330 - 50; 18 | trace(`Celsius temperature: ${value}\n`); -------------------------------------------------------------------------------- /ch6-hardware/tmp36/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch6-hardware/tricolor-led-digital/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Timer from "timer"; 16 | import Digital from "pins/digital"; 17 | 18 | let r = new Digital(12, Digital.Output) 19 | let g = new Digital(13, Digital.Output) 20 | let b = new Digital(14, Digital.Output) 21 | Timer.repeat(() => { 22 | // black (all off) 23 | r.write(1); 24 | g.write(1); 25 | b.write(1); 26 | Timer.delay(100); 27 | 28 | // red (red on) 29 | r.write(0); 30 | Timer.delay(100); 31 | 32 | // magenta (red and blue on) 33 | b.write(0); 34 | Timer.delay(100); 35 | 36 | // white (all on) 37 | g.write(0); 38 | Timer.delay(100); 39 | }, 1); -------------------------------------------------------------------------------- /ch6-hardware/tricolor-led-digital/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch6-hardware/tricolor-led-pwm/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Timer from "timer"; 16 | import PWM from "pins/pwm"; 17 | 18 | let r = new PWM({ pin: 12 }); 19 | let g = new PWM({ pin: 13 }); 20 | let b = new PWM({ pin: 14 }); 21 | 22 | r.write(1023); 23 | g.write(0); 24 | b.write(1023); 25 | 26 | let rVal=1023, gVal=0, bVal=1023; 27 | 28 | while (bVal >= 21) { 29 | bVal -= 20; 30 | b.write(bVal); 31 | Timer.delay(50); 32 | } 33 | b.write(1); 34 | 35 | while (gVal <= 1003) { 36 | gVal += 20; 37 | g.write(gVal); 38 | Timer.delay(50); 39 | } 40 | g.write(1023); 41 | 42 | while (rVal >= 21) { 43 | rVal -= 20; 44 | r.write(rVal); 45 | Timer.delay(50); 46 | } 47 | r.write(1); 48 | 49 | while (bVal <= 1003) { 50 | bVal += 20; 51 | b.write(bVal); 52 | Timer.delay(50); 53 | } 54 | b.write(1023); -------------------------------------------------------------------------------- /ch6-hardware/tricolor-led-pwm/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch7-audio/host-i2s/bflatmajor.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-i2s/bflatmajor.wav -------------------------------------------------------------------------------- /ch7-audio/host-i2s/ding.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-i2s/ding.wav -------------------------------------------------------------------------------- /ch7-audio/host-i2s/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Modules from "modules"; 16 | 17 | export default function () { 18 | if (Modules.has("check")) { 19 | let check = Modules.importNow("check"); 20 | check(); 21 | if (Modules.has("example")) 22 | Modules.importNow("example"); 23 | } else { 24 | trace("Device flashed. Ready to install apps.\n"); 25 | } 26 | } -------------------------------------------------------------------------------- /ch7-audio/host-i2s/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json" 4 | ], 5 | "defines": { 6 | "XS_MODS": 1 7 | }, 8 | "modules": { 9 | "*": [ 10 | "./main", 11 | "$(MODULES)/base/modules/*" 12 | ], 13 | "pins/audioout": "$(MODULES)/pins/i2s/*" 14 | }, 15 | "preload": [ 16 | "modules" 17 | ], 18 | "resources": { 19 | "*": [ 20 | "./bflatmajor", 21 | "./tada", 22 | "./tick", 23 | "./tick-tock", 24 | "./ding" 25 | ] 26 | }, 27 | "platforms": { 28 | "esp": { 29 | "defines": { 30 | "audioOut": { 31 | "streams": 2, 32 | "bitsPerSample": 16, 33 | "numChannels": 1, 34 | "sampleRate": 11025, 35 | "volume_divider": 1, 36 | "i2s": { 37 | "pdm": 0 38 | } 39 | } 40 | } 41 | }, 42 | "esp32": { 43 | "defines": { 44 | "audioOut": { 45 | "streams": 2, 46 | "bitsPerSample": 16, 47 | "numChannels": 1, 48 | "sampleRate": 11025, 49 | "volume_divider": 1, 50 | "i2s": { 51 | "bck_pin": 13, 52 | "lr_pin": 12, 53 | "dataout_pin": 14, 54 | "bitsPerSample": 16 55 | } 56 | } 57 | } 58 | }, 59 | "...": { 60 | "error": "Platform not supported" 61 | } 62 | }, 63 | "strip": [ 64 | "Atomics", 65 | "BigInt", 66 | "eval", 67 | "Generator", 68 | "Proxy", 69 | "Reflect", 70 | "RegExp", 71 | "Set", 72 | "SharedArrayBuffer", 73 | "WeakMap", 74 | "WeakSet" 75 | ], 76 | "build": { 77 | "NAME": "ch7hosti2s" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /ch7-audio/host-i2s/tada.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-i2s/tada.wav -------------------------------------------------------------------------------- /ch7-audio/host-i2s/tick-tock.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-i2s/tick-tock.wav -------------------------------------------------------------------------------- /ch7-audio/host-i2s/tick.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-i2s/tick.wav -------------------------------------------------------------------------------- /ch7-audio/host-pdm/bflatmajor.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-pdm/bflatmajor.wav -------------------------------------------------------------------------------- /ch7-audio/host-pdm/ding.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-pdm/ding.wav -------------------------------------------------------------------------------- /ch7-audio/host-pdm/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | // Sound from https://freesound.org/s/264498/ 16 | 17 | import Modules from "modules"; 18 | 19 | export default function () { 20 | if (Modules.has("check")) { 21 | let check = Modules.importNow("check"); 22 | check(); 23 | if (Modules.has("example")) 24 | Modules.importNow("example"); 25 | } else { 26 | trace("Device flashed. Ready to install apps.\n"); 27 | } 28 | } -------------------------------------------------------------------------------- /ch7-audio/host-pdm/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json" 4 | ], 5 | "defines": { 6 | "XS_MODS": 1 7 | }, 8 | "modules": { 9 | "*": [ 10 | "./main", 11 | "$(MODULES)/base/modules/*" 12 | ], 13 | "pins/audioout": "$(MODULES)/pins/i2s/*" 14 | }, 15 | "preload": [ 16 | "modules" 17 | ], 18 | "resources": { 19 | "*": [ 20 | "./bflatmajor", 21 | "./tada", 22 | "./tick", 23 | "./tick-tock", 24 | "./ding" 25 | ] 26 | }, 27 | "platforms": { 28 | "esp": { 29 | "defines": { 30 | "audioOut": { 31 | "streams": 2, 32 | "bitsPerSample": 16, 33 | "numChannels": 1, 34 | "sampleRate": 11025, 35 | "volume_divider": 1, 36 | "i2s": { 37 | "pdm": 32, 38 | "bitsPerSample": 16 39 | } 40 | } 41 | } 42 | }, 43 | "esp32": { 44 | "defines": { 45 | "audioOut": { 46 | "streams": 2, 47 | "bitsPerSample": 16, 48 | "numChannels": 1, 49 | "sampleRate": 11025, 50 | "volume_divider": 1, 51 | "i2s": { 52 | "DAC": 1 53 | } 54 | } 55 | } 56 | }, 57 | "...": { 58 | "error": "Platform not supported" 59 | } 60 | }, 61 | "strip": [ 62 | "Atomics", 63 | "BigInt", 64 | "eval", 65 | "Generator", 66 | "Proxy", 67 | "Reflect", 68 | "RegExp", 69 | "Set", 70 | "SharedArrayBuffer", 71 | "WeakMap", 72 | "WeakSet" 73 | ], 74 | "build": { 75 | "NAME": "ch7hostpdm" 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /ch7-audio/host-pdm/tada.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-pdm/tada.wav -------------------------------------------------------------------------------- /ch7-audio/host-pdm/tick-tock.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-pdm/tick-tock.wav -------------------------------------------------------------------------------- /ch7-audio/host-pdm/tick.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch7-audio/host-pdm/tick.wav -------------------------------------------------------------------------------- /ch7-audio/sound-clip/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import AudioOut from "pins/audioout"; 16 | import Resource from "Resource"; 17 | 18 | let speaker = new AudioOut({streams: 1}); 19 | 20 | let tickTock = new Resource("tick-tock.maud"); 21 | speaker.enqueue(0, AudioOut.Samples, tickTock); 22 | speaker.enqueue(0, AudioOut.Samples, tickTock, 2, 0, 11025/2); 23 | speaker.start(); -------------------------------------------------------------------------------- /ch7-audio/sound-clip/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch7-audio/sound-sequence/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import AudioOut from "pins/audioout"; 16 | import Resource from "Resource"; 17 | 18 | let speaker = new AudioOut({sampleRate: 11025, bitsPerSample: 16, numChannels: 1, streams: 1}); 19 | 20 | speaker.callback = function() { 21 | speaker.enqueue(0, AudioOut.Samples, 22 | new Resource("ding.maud")); 23 | speaker.enqueue(0, AudioOut.Samples, 24 | new Resource("tick-tock.maud")); 25 | speaker.enqueue(0, AudioOut.Samples, 26 | new Resource("tada.maud")); 27 | speaker.enqueue(0, AudioOut.Callback, 0); 28 | } 29 | speaker.callback(); 30 | speaker.start(); -------------------------------------------------------------------------------- /ch7-audio/sound-sequence/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch7-audio/sound-simultaneous/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import AudioOut from "pins/audioout"; 16 | import Resource from "Resource"; 17 | import Timer from "timer"; 18 | 19 | let speaker = new AudioOut({streams: 2}); 20 | speaker.enqueue(0, AudioOut.Samples, 21 | new Resource("tick.maud"), Infinity); 22 | speaker.start(); 23 | 24 | Timer.repeat(() => { 25 | speaker.enqueue(1, AudioOut.Samples, 26 | new Resource("ding.maud")); 27 | }, 5000); -------------------------------------------------------------------------------- /ch7-audio/sound-simultaneous/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch7-audio/sound/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import AudioOut from "pins/audioout"; 16 | import Resource from "Resource"; 17 | 18 | let speaker = new AudioOut({streams: 1}); 19 | speaker.enqueue(0, AudioOut.Samples, 20 | new Resource("bflatmajor.maud")); 21 | speaker.start(); -------------------------------------------------------------------------------- /ch7-audio/sound/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch9-poco/blended-rectangle/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Timer from "timer"; 17 | import config from "mc/config"; 18 | 19 | let poco = new Poco(screen, {rotation: config.rotation}); 20 | poco.begin(); 21 | drawBars(poco); 22 | poco.end(); 23 | 24 | let boxSize = 30; 25 | let boxBlend = 64; 26 | let boxStep = 2; 27 | let boxColor = poco.makeColor(0, 0, 0); 28 | let x = (poco.width - boxSize) / 2, y = 0; 29 | Timer.repeat(function() { 30 | poco.begin(x, y - boxStep, boxSize, boxSize + boxStep * 2); 31 | drawBars(poco); 32 | poco.blendRectangle(boxColor, boxBlend, x, y, boxSize, boxSize); 33 | poco.end(); 34 | 35 | y += boxStep; 36 | if (y >= poco.height) 37 | y = 0; 38 | }, 16); 39 | 40 | function drawBars(poco) { 41 | let w = poco.width; 42 | let h = poco.height / 4; 43 | poco.fillRectangle(poco.makeColor(255, 255, 255), 44 | 0, 0, w, h); 45 | poco.fillRectangle(poco.makeColor(255, 0, 0), 46 | 0, h, w, h); 47 | poco.fillRectangle(poco.makeColor(0, 255, 0), 48 | 0, h * 2, w, h); 49 | poco.fillRectangle(poco.makeColor(0, 0, 255), 50 | 0, h * 3, w, h); 51 | } 52 | -------------------------------------------------------------------------------- /ch9-poco/blended-rectangle/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch9-poco/draw-jpeg/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import JPEG from "commodetto/readJPEG"; 17 | import Resource from "Resource"; 18 | import config from "mc/config"; 19 | if (config.rotation !== 0) 20 | throw new Error("Rotation must be 0 for this example"); 21 | 22 | let poco = new Poco(screen); 23 | let jpeg = new JPEG(new Resource("harvard.jpg")); 24 | while (jpeg.ready) { 25 | let block = jpeg.read(); 26 | poco.begin(block.x, block.y, block.width, block.height); 27 | poco.drawBitmap(block, block.x, block.y); 28 | poco.end(); 29 | } 30 | -------------------------------------------------------------------------------- /ch9-poco/draw-jpeg/harvard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/draw-jpeg/harvard.jpg -------------------------------------------------------------------------------- /ch9-poco/draw-jpeg/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "data": { 7 | "*": [ 8 | "./harvard" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch9-poco/fade-mask/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Resource from "Resource"; 17 | import Timer from "timer"; 18 | import parseRLE from "commodetto/parseRLE"; 19 | import config from "mc/config"; 20 | 21 | let poco = new Poco(screen, {rotation: config.rotation}); 22 | poco.begin(); 23 | drawBars(poco); 24 | poco.end(); 25 | 26 | let mask = parseRLE(new Resource("mask-alpha.bm4")); 27 | let maskBlend = 0; 28 | let blendStep = 4; 29 | let maskColor = poco.makeColor(0, 0, 255); 30 | Timer.repeat(function() { 31 | let y = (poco.height / 4) - (mask.height / 2); 32 | poco.begin(30, y, mask.width, mask.height); 33 | drawBars(poco); 34 | poco.drawGray(mask, maskColor, 30, y, 0, 0, mask.width, mask.height, maskBlend); 35 | poco.end(); 36 | 37 | maskBlend += blendStep; 38 | if (maskBlend > 255) 39 | maskBlend = 0; 40 | }, 16); 41 | 42 | function drawBars(poco) { 43 | let w = poco.width; 44 | let h = poco.height / 4; 45 | poco.fillRectangle(poco.makeColor(255, 255, 255), 46 | 0, 0, w, h); 47 | poco.fillRectangle(poco.makeColor(255, 0, 0), 48 | 0, h, w, h); 49 | poco.fillRectangle(poco.makeColor(0, 255, 0), 50 | 0, h * 2, w, h); 51 | poco.fillRectangle(poco.makeColor(0, 0, 255), 52 | 0, h * 3, w, h); 53 | } 54 | -------------------------------------------------------------------------------- /ch9-poco/fade-mask/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*-mask": "./mask" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ch9-poco/fade-mask/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/fade-mask/mask.png -------------------------------------------------------------------------------- /ch9-poco/host/OpenSans-Regular-16.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/host/OpenSans-Regular-16.fnt -------------------------------------------------------------------------------- /ch9-poco/host/OpenSans-Regular-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/host/OpenSans-Regular-16.png -------------------------------------------------------------------------------- /ch9-poco/host/OpenSans-Semibold-28.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/host/OpenSans-Semibold-28.fnt -------------------------------------------------------------------------------- /ch9-poco/host/OpenSans-Semibold-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/host/OpenSans-Semibold-28.png -------------------------------------------------------------------------------- /ch9-poco/host/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Modules from "modules"; 16 | 17 | export default function () { 18 | if (Modules.has("check")) { 19 | let check = Modules.importNow("check"); 20 | check(); 21 | if (Modules.has("example")) 22 | Modules.importNow("example"); 23 | } else { 24 | trace("Device flashed. Ready to install apps.\n"); 25 | } 26 | } -------------------------------------------------------------------------------- /ch9-poco/host/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "$(MODDABLE)/examples/manifest_base.json", 4 | "$(MODDABLE)/examples/manifest_commodetto.json" 5 | ], 6 | "defines": { 7 | "XS_MODS": 1 8 | }, 9 | "modules": { 10 | "*": [ 11 | "./main", 12 | "$(MODULES)/base/modules/*" 13 | ], 14 | "commodetto/readJPEG": "$(COMMODETTO)/commodettoReadJPEG", 15 | "commodetto/BufferOut": "$(COMMODETTO)/commodettoBufferOut", 16 | "commodetto/PixelsOut": "$(COMMODETTO)/commodettoPixelsOut" 17 | }, 18 | "preload": [ 19 | "modules" 20 | ], 21 | "resources": { 22 | "*-mask": [ 23 | "./OpenSans-Regular-16", 24 | "./OpenSans-Semibold-28" 25 | ] 26 | }, 27 | "strip": [ 28 | "RegExp", 29 | "Proxy", 30 | "eval" 31 | ], 32 | "build": { 33 | "NAME": "ch9host" 34 | } 35 | } -------------------------------------------------------------------------------- /ch9-poco/masked-image/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Resource from "Resource"; 17 | import parseBMP from "commodetto/parseBMP"; 18 | import Timer from "timer"; 19 | import config from "mc/config"; 20 | 21 | let poco = new Poco(screen, {rotation: config.rotation}); 22 | 23 | let image = parseBMP(new Resource("train-color.bmp")); 24 | let mask = parseBMP(new Resource("mask_circle.bmp")); 25 | 26 | let gray = poco.makeColor(128, 128, 128); 27 | poco.begin(); 28 | poco.fillRectangle(gray, 0, 0, poco.width, poco.height); 29 | poco.end(); 30 | 31 | let x = 30, y = 30; 32 | let sx = image.width - mask.width; 33 | let step = 2; 34 | 35 | Timer.repeat(function() { 36 | poco.begin(x, y, mask.width, mask.height); 37 | poco.fillRectangle(gray, x, y, mask.width, mask.height); 38 | poco.drawMasked(image, x, y, sx, 0, mask.width, mask.height, mask, 0, 0); 39 | poco.end(); 40 | 41 | sx -= step; 42 | if (sx <= 0) 43 | sx = image.width - mask.width; 44 | }, 16); 45 | -------------------------------------------------------------------------------- /ch9-poco/masked-image/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*": [ 8 | "./mask_circle", 9 | "./train" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /ch9-poco/masked-image/mask_circle.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/masked-image/mask_circle.bmp -------------------------------------------------------------------------------- /ch9-poco/masked-image/train.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/masked-image/train.png -------------------------------------------------------------------------------- /ch9-poco/offscreen/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Timer from "timer"; 17 | import BufferOut from "commodetto/BufferOut"; 18 | import config from "mc/config"; 19 | 20 | let poco = new Poco(screen, {rotation: config.rotation}); 21 | 22 | let offscreen = new BufferOut({width: 64, height: 64, pixelFormat: poco.pixelsOut.pixelFormat}); 23 | let pocoOff = new Poco(offscreen, {rotation: config.rotation}); 24 | pocoOff.begin(); 25 | for (let i = 64; i >= 1; i--) { 26 | let gray = (i * 4) - 1; 27 | let color = pocoOff.makeColor(gray, gray, gray); 28 | pocoOff.fillRectangle(color, 0, 0, i, i); 29 | } 30 | pocoOff.end(); 31 | 32 | let white = poco.makeColor(255, 255, 255); 33 | poco.begin(); 34 | poco.fillRectangle(white, 0, 0, poco.width, poco.height); 35 | poco.end(); 36 | 37 | let step = 1; 38 | let direction = +1; 39 | Timer.repeat(function() { 40 | poco.begin(0, 0, 240, 240); 41 | poco.fillRectangle(white, 0, 0, poco.width, poco.height); 42 | for (let i = 0; i < 19; i += 1) 43 | poco.drawBitmap(offscreen.bitmap, i * step, i * 10); 44 | 45 | step += direction; 46 | if (step > 40) { 47 | step = 40; 48 | direction = -1; 49 | } 50 | else if (step < 1) { 51 | step = 0; 52 | direction = +1; 53 | } 54 | poco.end(); 55 | }, 33); 56 | -------------------------------------------------------------------------------- /ch9-poco/offscreen/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch9-poco/origin/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Timer from "timer"; 17 | import config from "mc/config"; 18 | 19 | let poco = new Poco(screen, {rotation: config.rotation}); 20 | let black = poco.makeColor(0, 0, 0); 21 | let white = poco.makeColor(255, 255, 255); 22 | let yellow = poco.makeColor(255, 255, 0); 23 | poco.begin(); 24 | poco.fillRectangle(white, 0, 0, poco.width, poco.height); 25 | 26 | drawFrame(); 27 | poco.origin(20, 20); 28 | drawFrame(); 29 | poco.origin(20, 20); 30 | drawFrame(); 31 | poco.origin(); 32 | poco.origin(); 33 | poco.origin(0, 65); 34 | drawFrame(); 35 | poco.origin(); 36 | poco.end(); 37 | 38 | function drawFrame() { 39 | poco.fillRectangle(black, 0, 0, 40, 40); 40 | poco.fillRectangle(yellow, 4, 4, 32, 32); 41 | } 42 | -------------------------------------------------------------------------------- /ch9-poco/origin/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch9-poco/pattern-fill/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import parseBMP from "commodetto/parseBMP"; 17 | import Resource from "Resource"; 18 | import Timer from "timer"; 19 | import config from "mc/config"; 20 | 21 | let poco = new Poco(screen, {rotation: config.rotation}); 22 | let white = poco.makeColor(255, 255, 255); 23 | poco.begin(); 24 | poco.fillRectangle(white, 0, 0, poco.width, poco.height); 25 | poco.end(); 26 | 27 | let tile = parseBMP(new Resource("tiles-color.bmp")); 28 | let size = 30; 29 | let x = 40, y = 50; 30 | let phase = 0; 31 | Timer.repeat(function() { 32 | poco.begin(x, y, size * 5, size * 5); 33 | poco.fillPattern(tile, x, y, size * 5, size * 5, phase * size, 0, size, size); 34 | poco.end(); 35 | phase = (phase + 1) % 8; 36 | }, 66); -------------------------------------------------------------------------------- /ch9-poco/pattern-fill/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*-color": [ 8 | "./tiles" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ch9-poco/pattern-fill/tiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/pattern-fill/tiles.png -------------------------------------------------------------------------------- /ch9-poco/random-rectangles/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Timer from "timer"; 17 | import config from "mc/config"; 18 | 19 | let poco = new Poco(screen, {rotation: config.rotation}); 20 | let black = poco.makeColor(0, 0, 0); 21 | poco.begin(); 22 | poco.fillRectangle(black, 0, 0, poco.width, poco.height); 23 | poco.end(); 24 | 25 | Timer.repeat(function() { 26 | let x = Math.random() * poco.width; 27 | let y = Math.random() * poco.height; 28 | let width = (Math.random() * 50) + 5; 29 | let height = (Math.random() * 50) + 5; 30 | let color = poco.makeColor(255 * Math.random(), 31 | 255 * Math.random(), 255 * Math.random()); 32 | poco.begin(x, y, width, height); 33 | poco.fillRectangle(color, 0, 0, poco.width, poco.height); 34 | poco.end(); 35 | }, 16); -------------------------------------------------------------------------------- /ch9-poco/random-rectangles/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch9-poco/rectangle/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import config from "mc/config"; 17 | 18 | let poco = new Poco(screen, {rotation: config.rotation}); 19 | let white = poco.makeColor(255, 255, 255); 20 | poco.begin(); 21 | poco.fillRectangle(white, 0, 0, poco.width, poco.height); 22 | poco.end(); -------------------------------------------------------------------------------- /ch9-poco/rectangle/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | 8 | -------------------------------------------------------------------------------- /ch9-poco/text-shadow/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Resource from "Resource"; 17 | import parseBMF from "commodetto/parseBMF"; 18 | import config from "mc/config"; 19 | 20 | let poco = new Poco(screen, {rotation: config.rotation}); 21 | 22 | let regular16 = parseBMF(new Resource("OpenSans-Regular-16.bf4")); 23 | let bold28 = parseBMF(new Resource("OpenSans-Semibold-28.bf4")); 24 | 25 | let white = poco.makeColor(255, 255, 255); 26 | let lightGray = poco.makeColor(192, 192, 192); 27 | let blue = poco.makeColor(0, 0, 255); 28 | 29 | poco.begin(); 30 | poco.fillRectangle(white, 0, 0, poco.width, poco.height); 31 | 32 | let text = "Drop Shadow"; 33 | poco.drawText(text, bold28, lightGray, 0 + 2, 100 + 2); 34 | poco.drawText(text, bold28, blue, 0, 100); 35 | poco.end(); 36 | -------------------------------------------------------------------------------- /ch9-poco/text-shadow/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch9-poco/text-ticker/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Resource from "Resource"; 17 | import parseBMF from "commodetto/parseBMF"; 18 | import Timer from "timer"; 19 | import config from "mc/config"; 20 | 21 | let poco = new Poco(screen, {displayListLength: 4000, rotation: config.rotation}); 22 | 23 | let white = poco.makeColor(255, 255, 255); 24 | let black = poco.makeColor(0, 0, 0); 25 | let yellow = poco.makeColor(255, 255, 0); 26 | 27 | poco.begin(); 28 | poco.fillRectangle(white, 0, 0, poco.width, poco.height); 29 | poco.end(); 30 | 31 | let regular16 = parseBMF(new Resource("OpenSans-Regular-16.bf4")); 32 | 33 | let frame = 3; 34 | let margin = 2; 35 | let x = 10, y = 60; 36 | let tickerWidth = 200; 37 | let width = tickerWidth + frame * 2 + margin * 2; 38 | let height = regular16.height + frame * 2 + margin * 2; 39 | let text = "JavaScript is one of the world's most widely used programming languages."; 40 | let textWidth = poco.getTextWidth(text, regular16); 41 | let dx = tickerWidth; 42 | Timer.repeat(function() { 43 | poco.begin(x, y, width, height); 44 | poco.fillRectangle(black, x, y, width, height); 45 | poco.fillRectangle(yellow, x + frame, y + frame, tickerWidth + margin * 2, regular16.height + margin * 2); 46 | 47 | poco.clip(x + frame + margin, y + frame + margin, tickerWidth, regular16.height); 48 | poco.drawText(text, regular16, black, x + frame + margin + dx, y + frame); 49 | poco.clip(); 50 | 51 | dx -= 2; 52 | if (dx < -textWidth) 53 | dx = tickerWidth; 54 | poco.end(); 55 | }, 16); 56 | -------------------------------------------------------------------------------- /ch9-poco/text-ticker/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch9-poco/text-wrap/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Resource from "Resource"; 17 | import parseBMF from "commodetto/parseBMF"; 18 | import config from "mc/config"; 19 | 20 | let poco = new Poco(screen, {displayListLength: 4000, rotation: config.rotation}); 21 | 22 | let regular16 = parseBMF(new Resource("OpenSans-Regular-16.bf4")); 23 | let bold28 = parseBMF(new Resource("OpenSans-Semibold-28.bf4")); 24 | 25 | let white = poco.makeColor(255, 255, 255); 26 | let black = poco.makeColor(0, 0, 0); 27 | poco.begin(); 28 | poco.fillRectangle(white, 0, 0, poco.width, poco.height); 29 | 30 | let text = "JavaScript is one of the world's most widely used programming languages."; 31 | text = text.split(" "); 32 | let width = poco.width; 33 | let y = 0; 34 | let font = bold28; 35 | let spaceWidth = poco.getTextWidth(" ", font); 36 | while (text.length) { 37 | let wordWidth = poco.getTextWidth(text[0], font); 38 | if ((wordWidth < width) || (width === poco.width)) { 39 | poco.drawText(text[0], font, black, poco.width - width, y); 40 | text.shift(); 41 | } 42 | width -= wordWidth + spaceWidth; 43 | if (width <= 0) { 44 | width = poco.width; 45 | y += font.height; 46 | } 47 | } 48 | poco.end(); 49 | -------------------------------------------------------------------------------- /ch9-poco/text-wrap/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ch9-poco/touch/check.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Modules from "modules"; 16 | 17 | export default function () { 18 | if (!Modules.has("pins/i2c")) 19 | throw new Error("This device does not have an FT6206 touch sensor.") 20 | 21 | const I2C = Modules.importNow("pins/i2c"); 22 | const probe = new I2C({ 23 | hz: 600000, 24 | address: 0x38, 25 | throw: false, 26 | }); 27 | 28 | probe.write(Uint8Array.of(0xA8), false); 29 | if (17 !== (new Uint8Array(probe.read(1)))[0]) 30 | throw new Error("This device does not have an FT6206 touch sensor."); 31 | 32 | probe.close(); 33 | }; 34 | -------------------------------------------------------------------------------- /ch9-poco/touch/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Timer from "timer"; 16 | import FT6206 from "ft6206"; 17 | 18 | let touch = new FT6206; 19 | touch.points = [{}]; 20 | 21 | Timer.repeat(function() { 22 | let points = touch.points; 23 | let point = points[0]; 24 | touch.read(points); 25 | switch (point.state) { 26 | case 0: 27 | trace("no touch\n"); 28 | break; 29 | case 1: 30 | trace(`touch begin @ ${point.x}, ${point.y}\n`); 31 | break; 32 | case 2: 33 | trace(`touch continue @ ${point.x}, ${point.y}\n`); 34 | break; 35 | case 3: 36 | trace(`touch end @ ${point.x}, ${point.y}\n`); 37 | break; 38 | } 39 | }, 33); 40 | -------------------------------------------------------------------------------- /ch9-poco/touch/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": [ 5 | "./check", 6 | "./example" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ch9-poco/wifi-icons/example.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016-2020 Moddable Tech, Inc. 3 | * 4 | * This file is part of the Moddable SDK. 5 | * 6 | * This work is licensed under the 7 | * Creative Commons Attribution 4.0 International License. 8 | * To view a copy of this license, visit 9 | * 10 | * or send a letter to Creative Commons, PO Box 1866, 11 | * Mountain View, CA 94042, USA. 12 | * 13 | */ 14 | 15 | import Poco from "commodetto/Poco"; 16 | import Resource from "Resource"; 17 | import parseBMP from "commodetto/parseBMP"; 18 | import config from "mc/config"; 19 | 20 | let poco = new Poco(screen, {rotation: config.rotation}); 21 | let black = poco.makeColor(0, 0, 0); 22 | let white = poco.makeColor(255, 255, 255); 23 | 24 | let mask = parseBMP(new Resource("wifi-strip-alpha.bmp")); 25 | 26 | poco.begin(); 27 | poco.fillRectangle(white, 0, 0, poco.width, poco.height); 28 | poco.drawGray(mask, black, 10, 20, 0, 0, 27, 27); // top left 29 | poco.drawGray(mask, black, 37, 20, 0, 27, 27, 27); // bottom left 30 | poco.drawGray(mask, black, 10, 47, 112, 0, 27, 27); // top right 31 | poco.drawGray(mask, black, 37, 47, 112, 27, 27, 27); // bottom right 32 | poco.end(); 33 | -------------------------------------------------------------------------------- /ch9-poco/wifi-icons/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": "$(MODDABLE)/examples/manifest_mod.json", 3 | "modules": { 4 | "*": "./example" 5 | }, 6 | "resources": { 7 | "*-alpha": "./wifi-strip" 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /ch9-poco/wifi-icons/wifi-strip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/ch9-poco/wifi-icons/wifi-strip.png -------------------------------------------------------------------------------- /corrigendum.md: -------------------------------------------------------------------------------- 1 | # Corrigendum 2 | 3 | This document lists errors discovered after the publication of the book. If you find an error that is not listed here, please [open an issue](https://github.com/Moddable-OpenSource/iot-product-dev-book/issues) in this repository. 4 | 5 | *** 6 | 7 | ### Page 152 8 | 9 | Listing 3-15 does not match the [`https-get` example](./ch3-network/https-get). The listing leaves out the `port` property in the dictionary passed to the `Request` constructor; it should be as follows: 10 | 11 | ```js 12 | let request = new Request({ 13 | host: "www.example.com", 14 | path: "/", 15 | response: String, 16 | Socket: SecureSocket, 17 | port: 443 18 | }); 19 | ``` 20 | 21 | *** 22 | 23 | ### Page 159 24 | 25 | Listing 3-21 returns `String` for the `Server.status` message instead of the `Server.headersComplete` message. The full corrected listing is as follows: 26 | 27 | ``` 28 | let server = new Server; 29 | 30 | server.callback = function(msg, value, etc) { 31 | switch (msg) { 32 | case Server.status: 33 | if ("PUT" !== etc) 34 | this.close(); 35 | return; 36 | 37 | case Server.headersComplete: 38 | return String; 39 | 40 | case Server.requestComplete: 41 | this.json = { 42 | error: "none", 43 | when: (new Date).toString(), 44 | request: JSON.parse(value) 45 | }; 46 | break; 47 | 48 | case Server.prepareResponse: 49 | return { 50 | headers: ["Content-Type", "application/json"], 51 | body: JSON.stringify(this.json) 52 | }; 53 | } 54 | } 55 | ``` 56 | 57 | 58 | *** 59 | 60 | ### Page 160-161 61 | 62 | > To ask the HTTP `Server` class to deliver the request body in fragments, the callback returns `true` to the `prepareRequest` message. 63 | 64 | This sentence is incorrect. The callback returns true to the `headersComplete` message, not the `prepareRequest` message. 65 | 66 | In addition, Listing 3-22 does not match the [`https-server-streaming-put` example](./ch3-network/http-server-streaming-put). The listing uses quotation marks instead of backticks in the first trace statement and the `prepareRequest` message instead of the `headersComplete` message; it should be as follows: 67 | 68 | ```js 69 | let server = new Server; 70 | 71 | server.callback = function(msg, value) { 72 | switch (msg) { 73 | case Server.status: 74 | trace(`\n ** begin upload to ${value} **\n`); 75 | break; 76 | 77 | case Server.headersComplete: // prepare for request body 78 | return true; // provide request body in fragments 79 | 80 | case Server.requestFragment: 81 | trace(this.read(String)); 82 | break; 83 | 84 | case Server.requestComplete: 85 | trace("\n ** end of file **\n"); 86 | break; 87 | } 88 | } 89 | ``` 90 | 91 | *** 92 | 93 | ### Page 169 94 | 95 | The [`websocket-client` example](ch3-network/websocket-client) originally connected to the server at `echo.websocket.org`. This service is no longer available, so the example now connects to `websockets.chilkat.io`. 96 | 97 | This code snippet on page 169 no longer matches the `websocket-client` example: 98 | 99 | ```js 100 | let ws = new Client({ 101 | host: "echo.websocket.org" 102 | }); 103 | ``` 104 | 105 | It should be as follows: 106 | 107 | ```js 108 | let ws = new Client({ 109 | host: "websockets.chilkat.io", 110 | path: "/wsChilkatEcho.ashx" 111 | }); 112 | ``` 113 | 114 | In addition, the following sentence is no longer accurate: 115 | 116 | > This process repeats indefinitely, with count increasing each time. 117 | 118 | The server at `websockets.chilkat.io` limits each connection to a maximum of 16 echoed messages. After the 16th message, it disconnects from the client. 119 | 120 | *** 121 | 122 | ### Page 193-200 123 | 124 | The **Creating Two-Way Communication** section explains how to use the Bluefruit mobile app to create a peripheral. However, the Bluefruit mobile app no longer has the **Peripheral Mode** feature described in the text, so the instructions in this section are no longer valid. 125 | 126 | The [`text-server` example](./ch4-ble/text-server) may be used as a replacement if you have a second ESP32 device. To use this example, follow these steps: 127 | 128 | - Connect one of your ESP32 devices to your computer with a USB cable. 129 | 130 | - Install the `text-server` example on the ESP32 using `mcconfig`. 131 | 132 | ```text 133 | cd $EXAMPLES/ch4-ble/text-server 134 | mcconfig -m -p esp32 135 | ``` 136 | 137 | - Disconnect the first ESP32 and connect the other ESP32. 138 | 139 | - Install the `text-client` example as described in the book. 140 | 141 | - Connect the first ESP32 to a power source. 142 | 143 | The devices will automatically pair, and the `text-client` will subscribe to notifications from the `text-server` as described. However, instead of typing in messages and manually sending them from your phone, the `text-server` app will automatically sends a message every second. 144 | 145 | *** 146 | 147 | ### Page 243 148 | 149 | In this example, the second parameter to `slice` is incorrect. 150 | 151 | ``` 152 | let r1 = new Resource("myData.dat"); 153 | let values = new Uint16Array(r1.slice(32, 10, false)); 154 | ``` 155 | 156 | The second parameter is the end position of the slice, not the byte length of the slice. The correct code is: 157 | 158 | ``` 159 | let r1 = new Resource("myData.dat"); 160 | let values = new Uint16Array(r1.slice(32, 32 + 10, false)); 161 | ``` 162 | 163 | *** 164 | 165 | ### Page 266 166 | 167 | The **Monitoring for Changes** section does not provide the import statement for the `Monitor` class used in Listing 6-5. 168 | 169 | ```js 170 | import Monitor from "pins/digital/monitor"; 171 | ``` 172 | 173 | *** 174 | 175 | ### Page 338 176 | 177 | > Figure 8-8 shows the same circle mask drawn in blue (which appears gray in printed versions of this book). 178 | 179 | The comment in parentheses is incorrect. The book is published in color, though it was planned to be published in grayscale. 180 | -------------------------------------------------------------------------------- /images/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Moddable-OpenSource/iot-product-dev-book/acdbbe64b4015f7dd9212b65ac2188cdbeb6d908/images/cover.jpg --------------------------------------------------------------------------------