├── .gitmodules ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── README.rst ├── contrib ├── README.md ├── examples │ ├── FirebaseSerialHost_ESP8266 │ │ └── FirebaseSerialHost_ESP8266.ino │ ├── FirebaseSerialTerminal_ESP8266 │ │ ├── FirebaseSerialTerminal_ESP8266.ino │ │ ├── begin.txt │ │ ├── begin_stream.txt │ │ ├── end_stream.txt │ │ ├── get.txt │ │ ├── get_push.txt │ │ ├── push.txt │ │ ├── remove.txt │ │ └── set.txt │ └── Firething_ESP8266 │ │ └── Firething_ESP8266.ino ├── hardware │ └── firethings │ │ ├── firethings-kicad-libs │ │ ├── esp-12-smd.kicad_mod │ │ ├── esp-12.dcm │ │ ├── esp-12.lib │ │ ├── firethings-logo.kicad_mod │ │ ├── firethings-mini.kicad_mod │ │ └── firethings-mini.lib │ │ └── ft1.3 │ │ ├── back-3d.png │ │ ├── fab │ │ ├── raw-B.Cu.gbr │ │ ├── raw-B.Mask.gbr │ │ ├── raw-B.SilkS.gbr │ │ ├── raw-Edge.Cuts.gbr │ │ ├── raw-F.Cu.gbr │ │ ├── raw-F.Mask.gbr │ │ ├── raw-F.Paste.gbr │ │ ├── raw-F.SilkS.gbr │ │ └── raw.drl │ │ ├── fp-lib-table │ │ ├── front-3d.png │ │ ├── raw-cache.lib │ │ ├── raw-gerbers1.3.zip │ │ ├── raw-schematic.pdf │ │ ├── raw.bin │ │ ├── raw.csv │ │ ├── raw.dsn │ │ ├── raw.kicad_pcb │ │ ├── raw.net │ │ ├── raw.pro │ │ ├── raw.rules │ │ ├── raw.sch │ │ └── raw.ses ├── src │ ├── SerialTransceiver.h │ ├── Thing.h │ ├── modem │ │ ├── SerialProtocol.h │ │ ├── SerialTransceiver.cpp │ │ ├── SerialTransceiver.h │ │ ├── command.h │ │ ├── db │ │ │ ├── DatabaseProtocol.cpp │ │ │ ├── DatabaseProtocol.h │ │ │ ├── begin-command.cpp │ │ │ ├── commands.h │ │ │ ├── get-command.cpp │ │ │ ├── push-command.cpp │ │ │ ├── remove-command.cpp │ │ │ ├── set-command.cpp │ │ │ └── stream-command.cpp │ │ ├── design.md │ │ ├── diagram.png │ │ ├── input-stream.h │ │ ├── json_util.h │ │ ├── output-stream.h │ │ └── serial_protocol.md │ └── thing │ │ ├── Config.cpp │ │ ├── Config.h │ │ ├── FireThing.cpp │ │ ├── FireThing.h │ │ ├── Portal.cpp │ │ ├── Portal.h │ │ ├── Transcriber.cpp │ │ ├── Transcriber.h │ │ ├── WiFiManager.cpp │ │ └── WiFiManager.h └── test │ ├── FirebaseArduino_test.cpp │ ├── Makefile │ ├── WString.h │ ├── dummies │ ├── ESP8266HTTPClient.h │ ├── FirebaseHttpClient_dummy.cpp │ ├── Stream.h │ └── WString.h │ ├── mock-firebase.h │ ├── modem │ ├── Makefile │ ├── WString.h │ ├── begin-command_test.cpp │ ├── get-command_test.cpp │ ├── mock-input-stream.h │ ├── mock-output-stream.h │ ├── push-command_test.cpp │ ├── remove-command_test.cpp │ ├── serial-transceiver_test.cpp │ ├── set-command_test.cpp │ └── stream-command_test.cpp │ └── travis │ ├── check_all_examples_use_standard_init.sh │ ├── firebase_init.cc.snip │ ├── no_config_init.cc.snip │ └── no_firebase_init.cc.snip ├── docs └── read_the_docs │ ├── Doxyfile │ ├── conf.py │ ├── index.rst │ └── requirements.txt ├── examples ├── FirebaseCloudMessaging_Send_ESP8266 │ └── FirebaseCloudMessaging_Send_ESP8266.ino ├── FirebaseDemo_ESP8266 │ ├── FirebaseDemo_ESP8266.ino │ └── README.md ├── FirebaseNeoPixel_ESP8266 │ ├── .gitignore │ ├── FirebaseNeoPixel_ESP8266.ino │ ├── README.md │ └── public │ │ ├── .gitignore │ │ ├── bower.json │ │ └── index.html ├── FirebaseRoom_ESP8266 │ ├── FirebaseRoom_ESP8266.ino │ └── README.md └── FirebaseStream_ESP8266 │ ├── FirebaseStream_ESP8266.ino │ └── README.md ├── library.properties └── src ├── Firebase.cpp ├── Firebase.h ├── FirebaseArduino.cpp ├── FirebaseArduino.h ├── FirebaseCloudMessaging.cpp ├── FirebaseCloudMessaging.h ├── FirebaseError.h ├── FirebaseHttpClient.h ├── FirebaseHttpClient_Esp8266.cpp ├── FirebaseObject.cpp ├── FirebaseObject.h └── throw_out_of_range.cpp /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "contrib/test/googletest"] 2 | path = contrib/test/googletest 3 | url = https://github.com/google/googletest.git 4 | [submodule "contrib/test/arduino-mock"] 5 | path = contrib/test/arduino-mock 6 | url = https://github.com/ed7coyne/arduino-mock.git 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c++ 2 | cache: ccache 3 | sudo: false 4 | addons: 5 | apt: 6 | sources: 7 | - ubuntu-toolchain-r-test 8 | packages: 9 | - g++-4.8 10 | env: 11 | - ARDUINO_VERSION=1.6.9 ARDUINO_ESP8266_VERSION=2.3.0 LIB_NEOPIXEL_VERSION=v1.0.5 LIB_GFX_VERSION=v1.1.5 LIB_SSD1306_VERSION=1.1.0 LIB_JSON_VERSION=v5.11.2 ARDUINO_ROOT=${HOME}/arduino-${ARDUINO_VERSION} ARDUINO_ESP8266_ROOT=${ARDUINO_ROOT}/hardware/esp8266com/esp8266 ARDUINO_HOME=${HOME}/Arduino 12 | - ARDUINO_VERSION=nightly ARDUINO_ESP8266_VERSION=master LIB_NEOPIXEL_VERSION=master LIB_GFX_VERSION=master LIB_SSD1306_VERSION=master LIB_JSON_VERSION=master ARDUINO_ROOT=${HOME}/arduino-${ARDUINO_VERSION} ARDUINO_ESP8266_ROOT=${ARDUINO_ROOT}/hardware/esp8266com/esp8266 ARDUINO_HOME=${HOME}/Arduino 13 | install: 14 | - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8" CC="gcc-4.8"; fi 15 | - ( cd ${HOME} && wget https://downloads.arduino.cc/arduino-${ARDUINO_VERSION}-linux64.tar.xz && tar xf arduino-${ARDUINO_VERSION}-linux64.tar.xz ) 16 | - ( LIB=SoftwareSerial VERSION=097712eb07f5b3a70ef419b6e7a7ed2ada5aab85 && cd ${HOME} && wget https://github.com/plerup/espsoftwareserial/archive/${VERSION}.zip -q -O ${LIB}.zip && unzip -q ${LIB}.zip && rm ${LIB}.zip && mv espsoftwareserial-* ${LIB} ) 17 | - ( LIB=Adafruit_NeoPixel VERSION=${LIB_NEOPIXEL_VERSION} && cd ${HOME} && wget https://github.com/adafruit/${LIB}/archive/${VERSION}.zip -q -O ${LIB}.zip && unzip -q ${LIB}.zip && rm ${LIB}.zip && mv ${LIB}-* ${LIB} ) 18 | - ( LIB=Adafruit-GFX-Library VERSION=${LIB_GFX_VERSION} && cd ${HOME} && wget https://github.com/adafruit/${LIB}/archive/${VERSION}.zip -q -O ${LIB}.zip && unzip -q ${LIB}.zip && rm ${LIB}.zip && mv ${LIB}-* ${LIB} ) 19 | - ( LIB=Adafruit_SSD1306 VERSION=${LIB_SSD1306_VERSION} && cd ${HOME} && wget https://github.com/adafruit/${LIB}/archive/${VERSION}.zip -q -O ${LIB}.zip && unzip -q ${LIB}.zip && rm ${LIB}.zip && mv ${LIB}-* ${LIB} ) 20 | - ( LIB=ArduinoJson VERSION=${LIB_JSON_VERSION} && cd ${HOME} && wget https://github.com/bblanchon/${LIB}/archive/${VERSION}.zip -q -O ${LIB}.zip && unzip -q ${LIB}.zip && rm ${LIB}.zip && mv ${LIB}-* ${LIB} ) 21 | - git clone --branch ${ARDUINO_ESP8266_VERSION} https://github.com/esp8266/Arduino.git ${ARDUINO_ESP8266_ROOT} 22 | - git submodule init && git submodule update 23 | - ( cd ${ARDUINO_ESP8266_ROOT}/tools && python get.py ) 24 | before_script: 25 | - mkdir -p ${ARDUINO_HOME}/libraries 26 | - ( cd ${ARDUINO_HOME}/libraries && ln -s ${TRAVIS_BUILD_DIR} firebase-arduino && ln -s ${HOME}/SoftwareSerial ./ && ln -s ${HOME}/Adafruit_NeoPixel ./ && ln -s ${HOME}/Adafruit-GFX-Library ./ && ln -s ${HOME}/Adafruit_SSD1306 ./ && ln -s ${HOME}/ArduinoJson ./) 27 | script: 28 | - ${ARDUINO_ROOT}/arduino-builder -verbose -hardware ${ARDUINO_ROOT}/hardware/ -tools ${ARDUINO_ESP8266_ROOT}/tools/ -tools ${ARDUINO_ROOT}/tools-builder/ -fqbn esp8266com:esp8266:nodemcuv2 -libraries ${ARDUINO_HOME}/libraries/ -prefs build.flash_ld=${ARDUINO_ESP8266_ROOT}/tools/sdk/ld/eagle.flash.4m.ld -prefs build.flash_freq=40 -prefs build.flash_size=4M -prefs build.f_cpu=80000000 examples/FirebaseDemo_ESP8266/FirebaseDemo_ESP8266.ino 29 | - ${ARDUINO_ROOT}/arduino-builder -verbose -hardware ${ARDUINO_ROOT}/hardware/ -tools ${ARDUINO_ESP8266_ROOT}/tools/ -tools ${ARDUINO_ROOT}/tools-builder/ -fqbn esp8266com:esp8266:nodemcuv2 -libraries ${ARDUINO_HOME}/libraries/ -prefs build.flash_ld=${ARDUINO_ESP8266_ROOT}/tools/sdk/ld/eagle.flash.4m.ld -prefs build.flash_freq=40 -prefs build.flash_size=4M -prefs build.f_cpu=80000000 examples/FirebaseNeoPixel_ESP8266/FirebaseNeoPixel_ESP8266.ino 30 | - ${ARDUINO_ROOT}/arduino-builder -verbose -hardware ${ARDUINO_ROOT}/hardware/ -tools ${ARDUINO_ESP8266_ROOT}/tools/ -tools ${ARDUINO_ROOT}/tools-builder/ -fqbn esp8266com:esp8266:nodemcuv2 -libraries ${ARDUINO_HOME}/libraries/ -prefs build.flash_ld=${ARDUINO_ESP8266_ROOT}/tools/sdk/ld/eagle.flash.4m.ld -prefs build.flash_freq=40 -prefs build.flash_size=4M -prefs build.f_cpu=80000000 examples/FirebaseStream_ESP8266/FirebaseStream_ESP8266.ino 31 | - ${ARDUINO_ROOT}/arduino-builder -verbose -hardware ${ARDUINO_ROOT}/hardware/ -tools ${ARDUINO_ESP8266_ROOT}/tools/ -tools ${ARDUINO_ROOT}/tools-builder/ -fqbn esp8266com:esp8266:nodemcuv2 -libraries ${ARDUINO_HOME}/libraries/ -prefs build.flash_ld=${ARDUINO_ESP8266_ROOT}/tools/sdk/ld/eagle.flash.4m.ld -prefs build.flash_freq=40 -prefs build.flash_size=4M -prefs build.f_cpu=80000000 examples/FirebaseRoom_ESP8266/FirebaseRoom_ESP8266.ino 32 | - ( cd contrib/test && make check ) 33 | - ( cd contrib/test/modem/ && make test ) 34 | - contrib/test/travis/check_all_examples_use_standard_init.sh 35 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to become a contributor and submit your own code 2 | 3 | ## Contributor License Agreements 4 | 5 | We'd love to accept your sample apps and patches! Before we can take them, we 6 | have to jump a couple of legal hurdles. 7 | 8 | Please fill out either the individual or corporate Contributor License Agreement 9 | (CLA). 10 | 11 | * If you are an individual writing original source code and you're sure you 12 | own the intellectual property, then you'll need to sign an [individual CLA] 13 | (http://code.google.com/legal/individual-cla-v1.0.html). 14 | * If you work for a company that wants to allow you to contribute your work, 15 | then you'll need to sign a [corporate CLA] 16 | (http://code.google.com/legal/corporate-cla-v1.0.html). 17 | 18 | Follow either of the two links above to access the appropriate CLA and 19 | instructions for how to sign and return it. Once we receive it, we'll be able to 20 | accept your pull requests. 21 | 22 | ## Contributing a Patch 23 | 24 | 1. Sign a Contributor License Agreement, if you have not yet done so (see 25 | details above). 26 | 1. Create your change to the repo in question. 27 | * Fork the desired repo, develop and test your code changes. 28 | * Ensure that your code is clear and comprehensible. 29 | * Ensure that your code has an appropriate set of unit tests which all pass. 30 | 1. Submit a pull request. 31 | 1. The repo owner will review your request. If it is approved, the change will 32 | be merged. If it needs additional work, the repo owner will respond with 33 | useful comments. 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FirebaseArduino 2 | 3 | [![Build Status](https://travis-ci.org/firebase/firebase-arduino.svg?branch=master)](https://travis-ci.org/firebase/firebase-arduino) 4 | [![Join the chat at https://gitter.im/googlesamples/firebase-arduino](https://badges.gitter.im/googlesamples/firebase-arduino.svg)](https://gitter.im/googlesamples/firebase-arduino?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 5 | [![Documentation Status](https://readthedocs.org/projects/firebase-arduino/badge/?version=latest)](http://firebase-arduino.readthedocs.io/en/latest/?badge=latest) 6 | 7 | This repo contains a collection of samples and an Arduino library that show how to call the [Firebase](https://www.firebase.com/) API from the [ESP8266 Arduino core](https://github.com/esp8266/Arduino). 8 | 9 | 10 | ## Status 11 | 12 | ![Status: Frozen](https://img.shields.io/badge/Status-Frozen-yellow) 13 | 14 | This repository is no longer under active development. No new features will be added and issues are not actively triaged. Pull Requests which fix bugs are welcome and will be reviewed on a best-effort basis. 15 | 16 | If you maintain a fork of this repository that you believe is healthier than the official version, we may consider recommending your fork. Please open a Pull Request if you believe that is the case. 17 | 18 | 19 | ## Samples 20 | 21 | - [FirebaseDemo](https://github.com/googlesamples/firebase-arduino/tree/master/examples/FirebaseDemo_ESP8266) - shows the FirebaseArduino API methods. 22 | - [FirebaseRoom](https://github.com/googlesamples/firebase-arduino/tree/master/examples/FirebaseRoom_ESP8266) - shows how to push sensor data and trigger actuator from Firebase. 23 | - [FirebaseStream](https://github.com/googlesamples/firebase-arduino/tree/master/examples/FirebaseStream_ESP8266) - shows the FirebaseArduino streaming API. 24 | - [FirebaseNeoPixel](https://github.com/googlesamples/firebase-arduino/tree/master/examples/FirebaseNeoPixel_ESP8266) - shows how to control an array of LEDs from a Firebase web app. 25 | 26 | ## Documentation 27 | 28 | - [FirebaseArduino API Reference](http://firebase-arduino.readthedocs.io/) 29 | 30 | ## Dependencies 31 | - FirebaseArduino now depends on [ArduinoJson library](https://github.com/bblanchon/ArduinoJson) instead of containing it's own version of it. Please either use Library Manager or download specific version of the library from github. We recommend that ArduinoJson is at least version [5.13.1](https://github.com/bblanchon/ArduinoJson/tree/v5.13.1) 32 | 33 | - ESP8266 Core SDK. We recommend using officially tagged releases and it should be at least [2.4.1](https://github.com/esp8266/Arduino/tree/2.4.1) 34 | 35 | ## Disclaimer 36 | 37 | *This is not an official Google product*. 38 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | FirebaseArduino is a library to simplify connecting to the Firebase database from 2 | arduino clients. 3 | 4 | It is a full abstraction of Firebase's REST API exposed through C++ calls in a wiring 5 | friendly way. 6 | 7 | ArduinoJson is no longer part of this library and you will have to install latest version 8 | in Arduino environment yourself. (through Board manager or download+unpack from master: 9 | https://github.com/bblanchon/ArduinoJson) 10 | 11 | ---------------------------------- 12 | -------------------------------------------------------------------------------- /contrib/README.md: -------------------------------------------------------------------------------- 1 | # firebase-arduino contrib 2 | 3 | The `contrib` features projects around `firebase-arduino` library: 4 | 5 | - `modem`: a firmware implementing a `UART` modem for firebase 6 | - `firethings`: a firmware implementing `GPIO` state syncing with firebase 7 | - `hardware`: hardware design for `ESP8266` reference boards 8 | - `test`: test suite and mocks 9 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialHost_ESP8266/FirebaseSerialHost_ESP8266.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2015 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | 18 | // A sample that will start our serial transciever listening on a software 19 | // port and allow debug over the main serial port. 20 | // 21 | // A suggested setup for testing this example would be to connect a board 22 | // with integrated usb and open a serial monitor to see debug messages. 23 | // Then connect another board on pin4 and pin5 to communicate over serial. 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | // Set these to run example. 32 | #define WIFI_SSID "SSID" 33 | #define WIFI_PASSWORD "PASSWORD" 34 | 35 | SoftwareSerial data_serial(5 /*RX*/, 4/*TX*/); 36 | firebase::modem::SerialTransceiver transceiver; 37 | 38 | void setup() { 39 | Serial.begin(9600); 40 | 41 | // connect to wifi. 42 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 43 | Serial.print("connecting"); 44 | while (WiFi.status() != WL_CONNECTED) { 45 | Serial.print("."); 46 | delay(500); 47 | } 48 | Serial.println(); 49 | Serial.print("connected: "); 50 | Serial.println(WiFi.localIP()); 51 | 52 | data_serial.begin(9600); 53 | while (!data_serial) { 54 | Serial.println("Error initilizing serial."); 55 | delay(5000); 56 | } 57 | 58 | transceiver.RegisterProtocol(new DatabaseProtocol()); 59 | transceiver.begin(&data_serial); 60 | } 61 | 62 | void loop() { 63 | transceiver.loop(); 64 | } 65 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialTerminal_ESP8266/FirebaseSerialTerminal_ESP8266.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2015 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | 18 | // A sample that will start our serial transciever listening on the primary 19 | // Serial port. 20 | // 21 | // A suggested setup for testing this example would be a esp8266 with built 22 | // in usb connected. 23 | // First edit begin.txt and put in your host and secret. 24 | // Then run the following commands to setup the serial port (assuming ttyUSB0) 25 | // in linux: 26 | // stty -F /dev/ttyUSB0 9600 raw -echo -echoe -echok 27 | // Then on one console do: 28 | // cat /dev/ttyUSB0 & 29 | // This console will now read all responses from the modem. Then do: 30 | // cat begin.txt > /dev/ttyUSB0 31 | // You should see +OK and you can now feed in the other example commmands. 32 | 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | // Set these to run example. 39 | #define WIFI_SSID "SSID" 40 | #define WIFI_PASSWORD "PASSWORD" 41 | 42 | firebase::modem::SerialTransceiver transceiver; 43 | 44 | void setup() { 45 | Serial.begin(9600); 46 | 47 | // connect to wifi. 48 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 49 | Serial.print("connecting"); 50 | while (WiFi.status() != WL_CONNECTED) { 51 | Serial.print("."); 52 | delay(500); 53 | } 54 | Serial.println(); 55 | Serial.print("connected: "); 56 | Serial.println(WiFi.localIP()); 57 | 58 | transceiver.RegisterProtocol(new DatabaseProtocol()); 59 | transceiver.begin(&Serial); 60 | } 61 | 62 | void loop() { 63 | transceiver.loop(); 64 | } 65 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialTerminal_ESP8266/begin.txt: -------------------------------------------------------------------------------- 1 | BEGIN_DB $YOUR_HOST $YOUR_SECRET 2 | 3 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialTerminal_ESP8266/begin_stream.txt: -------------------------------------------------------------------------------- 1 | BEGIN_STREAM /serial/test 2 | 3 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialTerminal_ESP8266/end_stream.txt: -------------------------------------------------------------------------------- 1 | END_STREAM 2 | 3 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialTerminal_ESP8266/get.txt: -------------------------------------------------------------------------------- 1 | GET /serial/test 2 | 3 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialTerminal_ESP8266/get_push.txt: -------------------------------------------------------------------------------- 1 | GET /serial/push_test 2 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialTerminal_ESP8266/push.txt: -------------------------------------------------------------------------------- 1 | PUSH /serial/push_test "this is a test string \ " 2 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialTerminal_ESP8266/remove.txt: -------------------------------------------------------------------------------- 1 | REMOVE /serial/test 2 | -------------------------------------------------------------------------------- /contrib/examples/FirebaseSerialTerminal_ESP8266/set.txt: -------------------------------------------------------------------------------- 1 | SET /serial/test this is a test string \ " 2 | 3 | -------------------------------------------------------------------------------- /contrib/examples/Firething_ESP8266/Firething_ESP8266.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2016 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // FirethingDemo_ESP8266 is a sample that demos operation of the firething 18 | // portion of this library. This is a firmware for the esp that acts as 19 | // a bridge between pins on the esp and a firebase database. This includes 20 | // a captive configuration portal. 21 | 22 | 23 | #include 24 | #include 25 | 26 | // No config variables. 27 | // Everything is handled through portal. 28 | 29 | thing::FireThing fire_thing; 30 | 31 | void setup() { 32 | Serial.begin(9600); 33 | Serial.println("Firething starting up..."); 34 | fire_thing.SetDebugHandler([](const char* message) { Serial.println(message); }); 35 | fire_thing.Setup(); 36 | } 37 | 38 | void loop() { 39 | fire_thing.Loop(); 40 | 41 | Serial.println("."); 42 | delay(250); 43 | } 44 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/firethings-kicad-libs/esp-12-smd.kicad_mod: -------------------------------------------------------------------------------- 1 | (module afshar-kicad-libraries:ESP-12-SMD locked (layer F.Cu) (tedit 577D20FD) 2 | (descr "Module, ESP-8266, ESP-12, 16 pad, SMD") 3 | (tags "Module ESP-8266 ESP8266") 4 | (fp_text reference U1 (at 1.5 16.6) (layer F.SilkS) hide 5 | (effects (font (size 1 1) (thickness 0.15))) 6 | ) 7 | (fp_text value ESP-12 (at 6.992 1) (layer F.SilkS) 8 | (effects (font (size 1 1) (thickness 0.15))) 9 | ) 10 | (fp_line (start -2.25 -0.5) (end -2.25 -8.75) (layer F.CrtYd) (width 0.05)) 11 | (fp_line (start -2.25 -8.75) (end 15.25 -8.75) (layer F.CrtYd) (width 0.05)) 12 | (fp_line (start 15.25 -8.75) (end 16.25 -8.75) (layer F.CrtYd) (width 0.05)) 13 | (fp_line (start 16.25 -8.75) (end 16.25 16) (layer F.CrtYd) (width 0.05)) 14 | (fp_line (start 16.25 16) (end -2.25 16) (layer F.CrtYd) (width 0.05)) 15 | (fp_line (start -2.25 16) (end -2.25 -0.5) (layer F.CrtYd) (width 0.05)) 16 | (fp_line (start -1.016 -8.382) (end 14.986 -8.382) (layer F.CrtYd) (width 0.1524)) 17 | (fp_line (start 14.986 -8.382) (end 14.986 -0.889) (layer F.CrtYd) (width 0.1524)) 18 | (fp_line (start -1.016 -8.382) (end -1.016 -1.016) (layer F.CrtYd) (width 0.1524)) 19 | (fp_line (start -1.016 14.859) (end -1.016 15.621) (layer F.SilkS) (width 0.1524)) 20 | (fp_line (start -1.016 15.621) (end 14.986 15.621) (layer F.SilkS) (width 0.1524)) 21 | (fp_line (start 14.986 15.621) (end 14.986 14.859) (layer F.SilkS) (width 0.1524)) 22 | (fp_line (start 14.992 -8.4) (end -1.008 -2.6) (layer F.CrtYd) (width 0.1524)) 23 | (fp_line (start -1.008 -8.4) (end 14.992 -2.6) (layer F.CrtYd) (width 0.1524)) 24 | (fp_line (start -1.008 -2.6) (end 14.992 -2.6) (layer F.CrtYd) (width 0.1524)) 25 | (fp_line (start 15 -8.4) (end 15 15.6) (layer F.Fab) (width 0.05)) 26 | (fp_line (start 14.992 15.6) (end -1.008 15.6) (layer F.Fab) (width 0.05)) 27 | (fp_line (start -1.008 15.6) (end -1.008 -8.4) (layer F.Fab) (width 0.05)) 28 | (fp_line (start -1.008 -8.4) (end 14.992 -8.4) (layer F.Fab) (width 0.05)) 29 | (pad 1 smd roundrect (at 0 0) (size 2.5 1.1) (drill (offset -0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 30 | (pad 2 smd roundrect (at 0 2) (size 2.5 1.1) (drill (offset -0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 31 | (pad 3 smd roundrect (at 0 4) (size 2.5 1.1) (drill (offset -0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 32 | (pad 4 smd roundrect (at 0 6) (size 2.5 1.1) (drill (offset -0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 33 | (pad 5 smd roundrect (at 0 8) (size 2.5 1.1) (drill (offset -0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 34 | (pad 6 smd roundrect (at 0 10) (size 2.5 1.1) (drill (offset -0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 35 | (pad 7 smd roundrect (at 0 12) (size 2.5 1.1) (drill (offset -0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 36 | (pad 8 smd roundrect (at 0 14) (size 2.5 1.1) (drill (offset -0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 37 | (pad 9 smd roundrect (at 14 14) (size 2.5 1.1) (drill (offset 0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 38 | (pad 10 smd roundrect (at 14 12) (size 2.5 1.1) (drill (offset 0.6 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 39 | (pad 11 smd roundrect (at 14 10) (size 2.5 1.1) (drill (offset 0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 40 | (pad 12 smd roundrect (at 14 8) (size 2.5 1.1) (drill (offset 0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 41 | (pad 13 smd roundrect (at 14 6) (size 2.5 1.1) (drill (offset 0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 42 | (pad 14 smd roundrect (at 14 4) (size 2.5 1.1) (drill (offset 0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 43 | (pad 15 smd roundrect (at 14 2) (size 2.5 1.1) (drill (offset 0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 44 | (pad 16 smd roundrect (at 14 0) (size 2.5 1.1) (drill (offset 0.7 0)) (layers F.Cu F.Paste F.Mask)(roundrect_rratio 0.25)) 45 | (model ${ESPLIB}/ESP8266.3dshapes/ESP-12.wrl 46 | (at (xyz 0 0 0)) 47 | (scale (xyz 0.3937 0.3937 0.3937)) 48 | (rotate (xyz 0 0 0)) 49 | ) 50 | ) 51 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/firethings-kicad-libs/esp-12.dcm: -------------------------------------------------------------------------------- 1 | EESchema-DOCLIB Version 2.0 2 | # 3 | $CMP ESP-07v2 4 | D ESP8266, ESP-07v2 module, 16 pin, 2mm, ceramic antenna 5 | K MODULE ESP8266 ESP-8266 6 | F http://l0l.org.uk/2014/12/esp8266-modules-hardware-guide-gotta-catch-em-all/ 7 | $ENDCMP 8 | # 9 | $CMP ESP-12 10 | D ESP8622 ESP-12 module, 16 pins, 2mm, PCB antenna 11 | K MODULE ESP8266 ESP-8266 12 | F http://l0l.org.uk/2014/12/esp8266-modules-hardware-guide-gotta-catch-em-all/ 13 | $ENDCMP 14 | # 15 | #End Doc Library 16 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/firethings-kicad-libs/esp-12.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # ESP-12 5 | # 6 | DEF ESP-12 U 0 40 Y Y 1 F N 7 | F0 "U" 0 -100 50 H V C CNN 8 | F1 "ESP-12" 0 100 50 H V C CNN 9 | F2 "" 0 0 50 H I C CNN 10 | F3 "" 0 0 50 H I C CNN 11 | ALIAS ESP-07v2 12 | $FPLIST 13 | ESP-07* 14 | ESP-12* 15 | $ENDFPLIST 16 | DRAW 17 | S -600 -600 600 600 1 0 0 N 18 | X REST 1 -900 300 300 R 50 50 1 1 I 19 | X ADC 2 -900 200 300 R 50 50 1 1 P 20 | X CH_PD 3 -900 100 300 R 50 50 1 1 I 21 | X GPIO16 4 -900 0 300 R 50 50 1 1 B 22 | X GPIO14 5 -900 -100 300 R 50 50 1 1 B 23 | X GPIO12 6 -900 -200 300 R 50 50 1 1 B 24 | X GPIO13 7 -900 -300 300 R 50 50 1 1 B 25 | X VCC 8 0 900 300 D 50 50 1 1 W 26 | X GND 9 0 -900 300 U 50 50 1 1 W 27 | X GPIO15 10 900 -300 300 L 50 50 1 1 B 28 | X GPIO2 11 900 -200 300 L 50 50 1 1 B 29 | X GPIO0 12 900 -100 300 L 50 50 1 1 B 30 | X GPIO4 13 900 0 300 L 50 50 1 1 B 31 | X GPIO5 14 900 100 300 L 50 50 1 1 B 32 | X RXD 15 900 200 300 L 50 50 1 1 I 33 | X TXD 16 900 300 300 L 50 50 1 1 O 34 | ENDDRAW 35 | ENDDEF 36 | # 37 | #End Library 38 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/firethings-kicad-libs/firethings-logo.kicad_mod: -------------------------------------------------------------------------------- 1 | (module firethings-kicad-libs:firethings-logo (layer F.Cu) (tedit 579D5BCB) 2 | (descr "Firethings Logo") 3 | (tags "Firethings Logo") 4 | (fp_text reference LOGO1 (at 0 0) (layer F.SilkS) hide 5 | (effects (font (thickness 0.3))) 6 | ) 7 | (fp_text value LOGO (at 0.75 0) (layer F.SilkS) hide 8 | (effects (font (thickness 0.3))) 9 | ) 10 | (fp_text user FT (at 0 0.381) (layer F.SilkS) 11 | (effects (font (size 0.7 0.7) (thickness 0.15))) 12 | ) 13 | (fp_poly (pts (xy -0.574604 -1.476515) (xy -0.558033 -1.468449) (xy -0.550001 -1.4369) (xy -0.517621 -1.365863) 14 | (xy -0.471526 -1.277472) (xy -0.400473 -1.144797) (xy -0.325556 -1.000674) (xy -0.2869 -0.92421) 15 | (xy -0.200406 -0.7503) (xy -0.162664 -0.864659) (xy -0.120581 -0.957124) (xy -0.068336 -1.029951) 16 | (xy -0.063058 -1.035005) (xy -0.017049 -1.065382) (xy 0.026056 -1.062444) (xy 0.072889 -1.019941) 17 | (xy 0.13008 -0.931627) (xy 0.204262 -0.791252) (xy 0.212009 -0.775829) (xy 0.330508 -0.539265) 18 | (xy 0.51279 -0.719645) (xy 0.616531 -0.814409) (xy 0.695537 -0.870327) (xy 0.741407 -0.882246) 19 | (xy 0.762025 -0.84687) (xy 0.789995 -0.761738) (xy 0.822479 -0.639934) (xy 0.856636 -0.494539) 20 | (xy 0.889625 -0.338635) (xy 0.918606 -0.185306) (xy 0.94074 -0.047633) (xy 0.953185 0.061301) 21 | (xy 0.954887 0.101075) (xy 0.961194 0.167594) (xy 0.978129 0.277953) (xy 1.002715 0.413807) 22 | (xy 1.018547 0.493359) (xy 1.052243 0.660556) (xy 1.071613 0.777125) (xy 1.075317 0.854755) 23 | (xy 1.062015 0.905139) (xy 1.030369 0.939966) (xy 0.979038 0.970929) (xy 0.962845 0.979503) 24 | (xy 0.82474 1.053556) (xy 0.643429 1.152812) (xy 0.430879 1.270716) (xy 0.413785 1.280255) 25 | (xy 0.26925 1.359953) (xy 0.167244 1.412853) (xy 0.095333 1.444272) (xy 0.041081 1.459528) 26 | (xy -0.007947 1.463938) (xy -0.015915 1.463992) (xy -0.106331 1.447003) (xy -0.206156 1.405247) 27 | (xy -0.222807 1.395621) (xy -0.326144 1.334349) (xy -0.439833 1.269795) (xy -0.461529 1.257863) 28 | (xy -0.575948 1.1945) (xy -0.69549 1.126955) (xy -0.716165 1.115093) (xy -0.827434 1.052501) 29 | (xy -0.941391 0.990542) (xy -0.962844 0.979205) (xy -1.036872 0.932558) (xy -1.079085 0.890787) 30 | (xy -1.082792 0.880057) (xy -1.078065 0.835896) (xy -1.077221 0.829971) (xy -0.877459 0.829971) 31 | (xy -0.871322 0.851223) (xy -0.834895 0.870156) (xy -0.754276 0.914888) (xy -0.640349 0.979298) 32 | (xy -0.503999 1.057265) (xy -0.461529 1.081703) (xy -0.317978 1.162262) (xy -0.19044 1.229832) 33 | (xy -0.09075 1.278431) (xy -0.030745 1.302076) (xy -0.022894 1.303406) (xy 0.024008 1.289381) 34 | (xy 0.115136 1.249697) (xy 0.239134 1.189728) (xy 0.384645 1.114849) (xy 0.45455 1.077486) 35 | (xy 0.60164 0.997854) (xy 0.727352 0.929619) (xy 0.821773 0.878176) (xy 0.874991 0.848917) 36 | (xy 0.883035 0.844305) (xy 0.881051 0.812701) (xy 0.869778 0.731299) (xy 0.851126 0.612964) 37 | (xy 0.83055 0.490942) (xy 0.797679 0.297919) (xy 0.761168 0.078555) (xy 0.727079 -0.130579) 38 | (xy 0.71489 -0.206892) (xy 0.69038 -0.35267) (xy 0.66676 -0.477486) (xy 0.647013 -0.566434) 39 | (xy 0.635817 -0.602121) (xy 0.611699 -0.615366) (xy 0.565129 -0.592586) (xy 0.488176 -0.529004) 40 | (xy 0.4395 -0.483897) (xy 0.266805 -0.320569) (xy 0.147076 -0.542239) (xy 0.086115 -0.646441) 41 | (xy 0.03163 -0.724337) (xy -0.006561 -0.762269) (xy -0.012261 -0.76391) (xy -0.050178 -0.737735) 42 | (xy -0.094646 -0.672812) (xy -0.104993 -0.652506) (xy -0.14462 -0.581386) (xy -0.176898 -0.543453) 43 | (xy -0.182505 -0.541493) (xy -0.206783 -0.567998) (xy -0.252511 -0.639066) (xy -0.312203 -0.742553) 44 | (xy -0.354178 -0.820002) (xy -0.438789 -0.971385) (xy -0.503334 -1.065088) (xy -0.551037 -1.102673) 45 | (xy -0.585124 -1.085704) (xy -0.608819 -1.015747) (xy -0.619432 -0.948643) (xy -0.632146 -0.855914) 46 | (xy -0.652601 -0.716865) (xy -0.678309 -0.548006) (xy -0.706779 -0.365849) (xy -0.716876 -0.302381) 47 | (xy -0.749307 -0.099409) (xy -0.783586 0.11531) (xy -0.815948 0.318186) (xy -0.84263 0.485634) 48 | (xy -0.846183 0.507951) (xy -0.865426 0.645225) (xy -0.876179 0.757035) (xy -0.877459 0.829971) 49 | (xy -1.077221 0.829971) (xy -1.06476 0.742597) (xy -1.044911 0.61379) (xy -1.020554 0.463106) 50 | (xy -1.020293 0.461529) (xy -0.991753 0.286377) (xy -0.957473 0.072379) (xy -0.921282 -0.156372) 51 | (xy -0.887007 -0.375785) (xy -0.878671 -0.429699) (xy -0.848481 -0.625246) (xy -0.818358 -0.819974) 52 | (xy -0.791109 -0.995751) (xy -0.769546 -1.134444) (xy -0.762794 -1.177694) (xy -0.744555 -1.296676) 53 | (xy -0.730659 -1.391794) (xy -0.72374 -1.444942) (xy -0.723462 -1.448245) (xy -0.694422 -1.471389) 54 | (xy -0.633939 -1.480075) (xy -0.574604 -1.476515)) (layer F.SilkS) (width 0.01)) 55 | ) 56 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/firethings-kicad-libs/firethings-mini.kicad_mod: -------------------------------------------------------------------------------- 1 | (module firethings-mini locked (layer F.Cu) (tedit 57AFB6F9) 2 | (fp_text reference U2 (at 0 11.43) (layer F.SilkS) hide 3 | (effects (font (size 1 1) (thickness 0.15))) 4 | ) 5 | (fp_text value Firethings_Mini (at 0 3.81) (layer F.Fab) hide 6 | (effects (font (size 1 1) (thickness 0.15))) 7 | ) 8 | (fp_text user 5V (at -9.906 7.62 90) (layer B.SilkS) 9 | (effects (font (size 0.7 0.7) (thickness 0.15)) (justify mirror)) 10 | ) 11 | (fp_text user 5V (at -9.906 7.62 90) (layer F.SilkS) 12 | (effects (font (size 0.7 0.7) (thickness 0.15))) 13 | ) 14 | (fp_line (start -13.335 8.255) (end -13.335 -12.065) (layer F.Fab) (width 0.15)) 15 | (fp_line (start -13.335 8.255) (end -12.065 9.525) (layer F.Fab) (width 0.15)) 16 | (fp_line (start -12.065 9.525) (end 12.065 9.525) (layer F.Fab) (width 0.15)) 17 | (fp_line (start 12.065 9.525) (end 13.335 8.255) (layer F.Fab) (width 0.15)) 18 | (fp_line (start 13.335 8.255) (end 13.335 -12.065) (layer F.Fab) (width 0.15)) 19 | (fp_line (start 13.335 -12.065) (end 9.525 -15.875) (layer F.Fab) (width 0.15)) 20 | (fp_line (start 9.525 -15.875) (end -9.525 -15.875) (layer F.Fab) (width 0.15)) 21 | (fp_line (start -9.525 -15.875) (end -13.335 -12.065) (layer F.Fab) (width 0.15)) 22 | (fp_text user 3.3V (at 9.906 7.62 90) (layer B.SilkS) 23 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 24 | ) 25 | (fp_text user 15 (at 9.906 5.08 90) (layer B.SilkS) 26 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 27 | ) 28 | (fp_text user 13 (at 9.906 2.54 90) (layer B.SilkS) 29 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 30 | ) 31 | (fp_text user 12 (at 9.906 0 90) (layer B.SilkS) 32 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 33 | ) 34 | (fp_text user 14 (at 9.906 -2.54 90) (layer B.SilkS) 35 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 36 | ) 37 | (fp_text user 16 (at 9.906 -5.08 90) (layer B.SilkS) 38 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 39 | ) 40 | (fp_text user ADC (at 9.906 -7.62 90) (layer B.SilkS) 41 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 42 | ) 43 | (fp_text user RST (at 9.906 -10.16 90) (layer B.SilkS) 44 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 45 | ) 46 | (fp_text user GND (at -9.906 5.08 90) (layer B.SilkS) 47 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 48 | ) 49 | (fp_text user 02 (at -9.906 2.54 90) (layer B.SilkS) 50 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 51 | ) 52 | (fp_text user 0 (at -9.906 0 90) (layer B.SilkS) 53 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 54 | ) 55 | (fp_text user 04 (at -9.906 -2.54 90) (layer B.SilkS) 56 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 57 | ) 58 | (fp_text user 05 (at -9.906 -5.08 90) (layer B.SilkS) 59 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 60 | ) 61 | (fp_text user RXD (at -9.906 -7.62 90) (layer B.SilkS) 62 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 63 | ) 64 | (fp_text user TXD (at -9.906 -10.16 90) (layer B.SilkS) 65 | (effects (font (size 0.7 0.7) (thickness 0.125)) (justify mirror)) 66 | ) 67 | (fp_text user 14 (at 9.906 -2.54 90) (layer F.SilkS) 68 | (effects (font (size 0.7 0.7) (thickness 0.125))) 69 | ) 70 | (fp_text user 12 (at 9.906 0 90) (layer F.SilkS) 71 | (effects (font (size 0.7 0.7) (thickness 0.125))) 72 | ) 73 | (fp_text user 13 (at 9.906 2.54 90) (layer F.SilkS) 74 | (effects (font (size 0.7 0.7) (thickness 0.125))) 75 | ) 76 | (fp_text user 15 (at 9.906 5.08 90) (layer F.SilkS) 77 | (effects (font (size 0.7 0.7) (thickness 0.125))) 78 | ) 79 | (fp_text user 05 (at -9.906 -5.08 90) (layer F.SilkS) 80 | (effects (font (size 0.7 0.7) (thickness 0.125))) 81 | ) 82 | (fp_text user 04 (at -9.906 -2.54 90) (layer F.SilkS) 83 | (effects (font (size 0.7 0.7) (thickness 0.125))) 84 | ) 85 | (fp_text user 00 (at -9.906 0 90) (layer F.SilkS) 86 | (effects (font (size 0.7 0.7) (thickness 0.125))) 87 | ) 88 | (fp_text user 3.3V (at 9.906 7.62 90) (layer F.SilkS) 89 | (effects (font (size 0.7 0.7) (thickness 0.125))) 90 | ) 91 | (fp_text user 16 (at 9.906 -5.08 90) (layer F.SilkS) 92 | (effects (font (size 0.7 0.7) (thickness 0.125))) 93 | ) 94 | (fp_text user ADC (at 9.906 -7.62 90) (layer F.SilkS) 95 | (effects (font (size 0.7 0.7) (thickness 0.125))) 96 | ) 97 | (fp_text user RST (at 9.906 -10.16 90) (layer F.SilkS) 98 | (effects (font (size 0.7 0.7) (thickness 0.125))) 99 | ) 100 | (fp_text user GND (at -9.906 5.08 90) (layer F.SilkS) 101 | (effects (font (size 0.7 0.7) (thickness 0.125))) 102 | ) 103 | (fp_text user 02 (at -9.906 2.54 90) (layer F.SilkS) 104 | (effects (font (size 0.7 0.7) (thickness 0.125))) 105 | ) 106 | (fp_text user RXD (at -9.906 -7.62 90) (layer F.SilkS) 107 | (effects (font (size 0.7 0.7) (thickness 0.125))) 108 | ) 109 | (fp_text user TXD (at -9.906 -10.16 90) (layer F.SilkS) 110 | (effects (font (size 0.7 0.7) (thickness 0.125))) 111 | ) 112 | (pad 8 thru_hole circle (at -11.43 -10.16) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 113 | (pad 7 thru_hole circle (at -11.43 -7.62) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 114 | (pad 6 thru_hole circle (at -11.43 -5.08) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 115 | (pad 5 thru_hole circle (at -11.43 -2.54) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 116 | (pad 4 thru_hole circle (at -11.43 0) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 117 | (pad 3 thru_hole circle (at -11.43 2.54) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 118 | (pad 2 thru_hole circle (at -11.43 5.08) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 119 | (pad 1 thru_hole circle (at -11.43 7.62) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 120 | (pad 16 thru_hole circle (at 11.43 7.62) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 121 | (pad 15 thru_hole circle (at 11.43 5.08) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 122 | (pad 14 thru_hole circle (at 11.43 2.54) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 123 | (pad 13 thru_hole circle (at 11.43 0) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 124 | (pad 12 thru_hole circle (at 11.43 -2.54) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 125 | (pad 11 thru_hole circle (at 11.43 -5.08) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 126 | (pad 10 thru_hole circle (at 11.43 -7.62) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 127 | (pad 9 thru_hole circle (at 11.43 -10.16) (size 1.8 1.8) (drill 1.016) (layers *.Cu *.Mask F.SilkS)) 128 | (model ${KISYS3DMOD}/Pin_Headers.3dshapes/Pin_Header_Straight_1x08.wrl 129 | (at (xyz -0.455 0.05 -0.05)) 130 | (scale (xyz 1 1 1)) 131 | (rotate (xyz 180 0 90)) 132 | ) 133 | (model ${KISYS3DMOD}/Pin_Headers.3dshapes/Pin_Header_Straight_1x08.wrl 134 | (at (xyz 0.455 0.05 -0.05)) 135 | (scale (xyz 1 1 1)) 136 | (rotate (xyz 180 0 90)) 137 | ) 138 | ) 139 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/firethings-kicad-libs/firethings-mini.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # Firethings_Mini 5 | # 6 | DEF Firethings_Mini U 0 40 Y Y 1 F N 7 | F0 "U" 0 500 60 H V C CNN 8 | F1 "Firethings_Mini" 0 -500 60 H V C CNN 9 | F2 "" 550 -700 60 H V C CNN 10 | F3 "" 550 -700 60 H V C CNN 11 | DRAW 12 | S -300 450 300 -550 0 1 0 N 13 | X 5V 1 150 650 200 D 50 50 1 1 W 14 | X GND 2 0 -750 200 U 50 50 1 1 W 15 | X IO2 3 -500 150 200 R 50 50 1 1 B 16 | X IO0 4 -500 50 200 R 50 50 1 1 B 17 | X IO4 5 -500 -50 200 R 50 50 1 1 B 18 | X IO5 6 -500 -150 200 R 50 50 1 1 B 19 | X RXD 7 -500 -250 200 R 50 50 1 1 B 20 | X TXD 8 -500 -350 200 R 50 50 1 1 B 21 | X Rst 9 500 -350 200 L 50 50 1 1 B 22 | X A0 10 500 -250 200 L 50 50 1 1 B 23 | X IO16 11 500 -150 200 L 50 50 1 1 B 24 | X IO14 12 500 -50 200 L 50 50 1 1 B 25 | X IO12 13 500 50 200 L 50 50 1 1 B 26 | X IO13 14 500 150 200 L 50 50 1 1 B 27 | X IO15 15 500 250 200 L 50 50 1 1 B 28 | X 3.3V 16 -150 650 200 D 50 50 1 1 w 29 | ENDDRAW 30 | ENDDEF 31 | # 32 | #End Library 33 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/back-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FirebaseExtended/firebase-arduino/c2b39a3afd55af27e0c39318b89bab71148517b2/contrib/hardware/firethings/ft1.3/back-3d.png -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/fab/raw-Edge.Cuts.gbr: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Profile,NP* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW (2016-07-11 BZR 6975, Git 98ad509)-product) date Sat Aug 13 17:34:52 2016* 5 | %MOMM*% 6 | %LPD*% 7 | G01* 8 | G04 APERTURE LIST* 9 | %ADD10C,0.100000*% 10 | G04 APERTURE END LIST* 11 | D10* 12 | X201930000Y-75565000D02* 13 | X205740000Y-79375000D01* 14 | X194310000Y-75565000D02* 15 | X201930000Y-75565000D01* 16 | X194310000Y-75565000D02* 17 | X182880000Y-75565000D01* 18 | X205740000Y-99695000D02* 19 | X205740000Y-79375000D01* 20 | X205740000Y-99695000D02* 21 | X204470000Y-100965000D01* 22 | X179070000Y-79375000D02* 23 | X179070000Y-99695000D01* 24 | X180340000Y-100965000D02* 25 | X204470000Y-100965000D01* 26 | X179070000Y-99695000D02* 27 | X180340000Y-100965000D01* 28 | X182880000Y-75565000D02* 29 | X179070000Y-79375000D01* 30 | M02* 31 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/fab/raw-F.Cu.gbr: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Copper,L1,Top,Signal* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW (2016-07-11 BZR 6975, Git 98ad509)-product) date Sat Aug 13 17:34:52 2016* 5 | %MOMM*% 6 | %LPD*% 7 | G01* 8 | G04 APERTURE LIST* 9 | %ADD10C,0.100000*% 10 | %ADD11C,1.800000*% 11 | %ADD12R,1.597660X1.800860*% 12 | %ADD13R,1.000000X1.600000*% 13 | %ADD14R,0.650000X1.060000*% 14 | %ADD15R,0.900000X1.700000*% 15 | %ADD16C,0.800000*% 16 | %ADD17C,0.250000*% 17 | G04 APERTURE END LIST* 18 | D10* 19 | X201930000Y-75565000D02* 20 | X205740000Y-79375000D01* 21 | X194310000Y-75565000D02* 22 | X201930000Y-75565000D01* 23 | X194310000Y-75565000D02* 24 | X182880000Y-75565000D01* 25 | X205740000Y-99695000D02* 26 | X205740000Y-79375000D01* 27 | X205740000Y-99695000D02* 28 | X204470000Y-100965000D01* 29 | X179070000Y-79375000D02* 30 | X179070000Y-99695000D01* 31 | X180340000Y-100965000D02* 32 | X204470000Y-100965000D01* 33 | X179070000Y-99695000D02* 34 | X180340000Y-100965000D01* 35 | X182880000Y-75565000D02* 36 | X179070000Y-79375000D01* 37 | D11* 38 | X180975000Y-81280000D03* 39 | X180975000Y-83820000D03* 40 | X180975000Y-86360000D03* 41 | X180975000Y-88900000D03* 42 | X180975000Y-91440000D03* 43 | X180975000Y-93980000D03* 44 | X180975000Y-96520000D03* 45 | X180975000Y-99060000D03* 46 | X203835000Y-99060000D03* 47 | X203835000Y-96520000D03* 48 | X203835000Y-93980000D03* 49 | X203835000Y-91440000D03* 50 | X203835000Y-88900000D03* 51 | X203835000Y-86360000D03* 52 | X203835000Y-83820000D03* 53 | X203835000Y-81280000D03* 54 | D12* 55 | X194459860Y-84455000D03* 56 | X191620140Y-84455000D03* 57 | X194459860Y-86995000D03* 58 | X191620140Y-86995000D03* 59 | D13* 60 | X191540000Y-90170000D03* 61 | X194540000Y-90170000D03* 62 | X197255000Y-90170000D03* 63 | X200255000Y-90170000D03* 64 | D14* 65 | X191455000Y-95715000D03* 66 | X192405000Y-95715000D03* 67 | X193355000Y-95715000D03* 68 | X193355000Y-93515000D03* 69 | X191455000Y-93515000D03* 70 | D15* 71 | X187505000Y-84455000D03* 72 | X184605000Y-84455000D03* 73 | X184605000Y-86995000D03* 74 | X187505000Y-86995000D03* 75 | X184605000Y-89535000D03* 76 | X187505000Y-89535000D03* 77 | X184605000Y-92075000D03* 78 | X187505000Y-92075000D03* 79 | X197305000Y-92710000D03* 80 | X200205000Y-92710000D03* 81 | X197305000Y-84455000D03* 82 | X200205000Y-84455000D03* 83 | X197305000Y-86995000D03* 84 | X200205000Y-86995000D03* 85 | X199185000Y-98425000D03* 86 | X195785000Y-98425000D03* 87 | X185625000Y-98425000D03* 88 | X189025000Y-98425000D03* 89 | D16* 90 | X188849000Y-84328000D03* 91 | X201930000Y-97790000D03* 92 | X194818000Y-94107000D03* 93 | X194691000Y-96647000D03* 94 | X192405000Y-97536000D03* 95 | X188849000Y-86995000D03* 96 | X188849000Y-89408000D03* 97 | X194818000Y-95377000D03* 98 | X187325000Y-94615000D03* 99 | X190246000Y-93218000D03* 100 | X186563000Y-93853000D03* 101 | X195580000Y-92075000D03* 102 | X193548000Y-97536000D03* 103 | D17* 104 | X187505000Y-84455000D02* 105 | X188722000Y-84455000D01* 106 | X188722000Y-84455000D02* 107 | X188849000Y-84328000D01* 108 | X187505000Y-84402000D02* 109 | X187505000Y-84455000D01* 110 | X201930000Y-97790000D02* 111 | X199390000Y-97790000D01* 112 | X199390000Y-97790000D02* 113 | X199185000Y-98425000D01* 114 | X203835000Y-81280000D02* 115 | X203200000Y-81280000D01* 116 | X194818000Y-94107000D02* 117 | X195908000Y-94107000D01* 118 | X195908000Y-94107000D02* 119 | X197305000Y-92710000D01* 120 | X194540000Y-90170000D02* 121 | X194540000Y-93829000D01* 122 | X194540000Y-93829000D02* 123 | X194818000Y-94107000D01* 124 | X195785000Y-97741000D02* 125 | X194691000Y-96647000D01* 126 | X194818000Y-94107000D02* 127 | X194564000Y-93853000D01* 128 | X194564000Y-93853000D02* 129 | X194564000Y-93218000D01* 130 | X195785000Y-98425000D02* 131 | X195785000Y-97741000D01* 132 | X194564000Y-93218000D02* 133 | X194540000Y-93194000D01* 134 | X194540000Y-93194000D02* 135 | X194564000Y-93218000D01* 136 | X189025000Y-98425000D02* 137 | X191516000Y-98425000D01* 138 | X191516000Y-98425000D02* 139 | X192405000Y-97536000D01* 140 | X195785000Y-98425000D02* 141 | X193294000Y-98425000D01* 142 | X193294000Y-98425000D02* 143 | X192405000Y-97536000D01* 144 | X192405000Y-95715000D02* 145 | X192405000Y-97536000D01* 146 | X189025000Y-98601000D02* 147 | X189025000Y-98425000D01* 148 | X197305000Y-92710000D02* 149 | X197305000Y-92255000D01* 150 | X197305000Y-92255000D02* 151 | X199390000Y-90170000D01* 152 | X199390000Y-90170000D02* 153 | X200255000Y-90170000D01* 154 | X191620140Y-86995000D02* 155 | X191620140Y-87250140D01* 156 | X191620140Y-87250140D02* 157 | X194540000Y-90170000D01* 158 | X191620140Y-84455000D02* 159 | X191620140Y-86995000D01* 160 | X187505000Y-86995000D02* 161 | X188849000Y-86995000D01* 162 | X187505000Y-86995000D02* 163 | X187505000Y-87302000D01* 164 | X187505000Y-89535000D02* 165 | X188722000Y-89535000D01* 166 | X188722000Y-89535000D02* 167 | X188849000Y-89408000D01* 168 | X187325000Y-88900000D02* 169 | X187505000Y-89535000D01* 170 | X195961000Y-96520000D02* 171 | X203835000Y-96520000D01* 172 | X194818000Y-95377000D02* 173 | X195961000Y-96520000D01* 174 | X203835000Y-96520000D02* 175 | X203200000Y-96520000D01* 176 | X203835000Y-96520000D02* 177 | X203835000Y-96340000D01* 178 | X203835000Y-96340000D02* 179 | X200205000Y-92710000D01* 180 | X203835000Y-90805000D02* 181 | X200205000Y-87175000D01* 182 | X200205000Y-87175000D02* 183 | X200205000Y-86159000D01* 184 | X185625000Y-98425000D02* 185 | X185625000Y-96315000D01* 186 | X185625000Y-96315000D02* 187 | X187325000Y-94615000D01* 188 | X187505000Y-92075000D02* 189 | X187505000Y-94435000D01* 190 | X187505000Y-94435000D02* 191 | X187325000Y-94615000D01* 192 | X204279500Y-88836500D02* 193 | X200205000Y-84762000D01* 194 | X200205000Y-84455000D02* 195 | X200205000Y-84455000D01* 196 | X200205000Y-84762000D02* 197 | X200205000Y-84455000D01* 198 | X190543000Y-93515000D02* 199 | X191455000Y-93515000D01* 200 | X190246000Y-93218000D02* 201 | X190543000Y-93515000D01* 202 | X186563000Y-93853000D02* 203 | X184785000Y-92075000D01* 204 | X184785000Y-92075000D02* 205 | X184605000Y-92075000D01* 206 | X184605000Y-92075000D02* 207 | X184785000Y-92075000D01* 208 | X197255000Y-90170000D02* 209 | X197255000Y-90400000D01* 210 | X197255000Y-90400000D02* 211 | X195580000Y-92075000D01* 212 | X191305000Y-93515000D02* 213 | X191455000Y-93515000D01* 214 | X184605000Y-89535000D02* 215 | X184605000Y-92075000D01* 216 | X184605000Y-86995000D02* 217 | X184605000Y-89535000D01* 218 | X184605000Y-84455000D02* 219 | X184605000Y-86995000D01* 220 | X197255000Y-90170000D02* 221 | X196850000Y-90170000D01* 222 | X197305000Y-84455000D02* 223 | X194459860Y-84455000D01* 224 | X194459860Y-86995000D02* 225 | X197305000Y-86995000D01* 226 | X193355000Y-97343000D02* 227 | X193355000Y-95715000D01* 228 | X193548000Y-97536000D02* 229 | X193355000Y-97343000D01* 230 | X191540000Y-90170000D02* 231 | X191770000Y-90170000D01* 232 | X191770000Y-90170000D02* 233 | X192405000Y-90805000D01* 234 | X192405000Y-90805000D02* 235 | X192405000Y-94615000D01* 236 | X191455000Y-95715000D02* 237 | X191455000Y-94930000D01* 238 | X193355000Y-94930000D02* 239 | X193355000Y-95715000D01* 240 | X193040000Y-94615000D02* 241 | X193355000Y-94930000D01* 242 | X191770000Y-94615000D02* 243 | X192405000Y-94615000D01* 244 | X192405000Y-94615000D02* 245 | X193040000Y-94615000D01* 246 | X191455000Y-94930000D02* 247 | X191770000Y-94615000D01* 248 | X191540000Y-90170000D02* 249 | X191540000Y-90400000D01* 250 | M02* 251 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/fab/raw-F.Mask.gbr: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Soldermask,Top* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW (2016-07-11 BZR 6975, Git 98ad509)-product) date Sat Aug 13 17:34:52 2016* 5 | %MOMM*% 6 | %LPD*% 7 | G01* 8 | G04 APERTURE LIST* 9 | %ADD10C,0.100000*% 10 | %ADD11C,1.800000*% 11 | %ADD12R,1.597660X1.800860*% 12 | %ADD13R,1.000000X1.600000*% 13 | %ADD14R,0.650000X1.060000*% 14 | %ADD15R,0.900000X1.700000*% 15 | %ADD16C,0.800000*% 16 | G04 APERTURE END LIST* 17 | D10* 18 | X201930000Y-75565000D02* 19 | X205740000Y-79375000D01* 20 | X194310000Y-75565000D02* 21 | X201930000Y-75565000D01* 22 | X194310000Y-75565000D02* 23 | X182880000Y-75565000D01* 24 | X205740000Y-99695000D02* 25 | X205740000Y-79375000D01* 26 | X205740000Y-99695000D02* 27 | X204470000Y-100965000D01* 28 | X179070000Y-79375000D02* 29 | X179070000Y-99695000D01* 30 | X180340000Y-100965000D02* 31 | X204470000Y-100965000D01* 32 | X179070000Y-99695000D02* 33 | X180340000Y-100965000D01* 34 | X182880000Y-75565000D02* 35 | X179070000Y-79375000D01* 36 | D11* 37 | X180975000Y-81280000D03* 38 | X180975000Y-83820000D03* 39 | X180975000Y-86360000D03* 40 | X180975000Y-88900000D03* 41 | X180975000Y-91440000D03* 42 | X180975000Y-93980000D03* 43 | X180975000Y-96520000D03* 44 | X180975000Y-99060000D03* 45 | X203835000Y-99060000D03* 46 | X203835000Y-96520000D03* 47 | X203835000Y-93980000D03* 48 | X203835000Y-91440000D03* 49 | X203835000Y-88900000D03* 50 | X203835000Y-86360000D03* 51 | X203835000Y-83820000D03* 52 | X203835000Y-81280000D03* 53 | D12* 54 | X194459860Y-84455000D03* 55 | X191620140Y-84455000D03* 56 | X194459860Y-86995000D03* 57 | X191620140Y-86995000D03* 58 | D13* 59 | X191540000Y-90170000D03* 60 | X194540000Y-90170000D03* 61 | X197255000Y-90170000D03* 62 | X200255000Y-90170000D03* 63 | D14* 64 | X191455000Y-95715000D03* 65 | X192405000Y-95715000D03* 66 | X193355000Y-95715000D03* 67 | X193355000Y-93515000D03* 68 | X191455000Y-93515000D03* 69 | D15* 70 | X187505000Y-84455000D03* 71 | X184605000Y-84455000D03* 72 | X184605000Y-86995000D03* 73 | X187505000Y-86995000D03* 74 | X184605000Y-89535000D03* 75 | X187505000Y-89535000D03* 76 | X184605000Y-92075000D03* 77 | X187505000Y-92075000D03* 78 | X197305000Y-92710000D03* 79 | X200205000Y-92710000D03* 80 | X197305000Y-84455000D03* 81 | X200205000Y-84455000D03* 82 | X197305000Y-86995000D03* 83 | X200205000Y-86995000D03* 84 | X199185000Y-98425000D03* 85 | X195785000Y-98425000D03* 86 | D16* 87 | X197485000Y-98425000D03* 88 | D15* 89 | X185625000Y-98425000D03* 90 | X189025000Y-98425000D03* 91 | D16* 92 | X187325000Y-98425000D03* 93 | M02* 94 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/fab/raw-F.Paste.gbr: -------------------------------------------------------------------------------- 1 | G04 #@! TF.FileFunction,Paste,Top* 2 | %FSLAX46Y46*% 3 | G04 Gerber Fmt 4.6, Leading zero omitted, Abs format (unit mm)* 4 | G04 Created by KiCad (PCBNEW (2016-07-11 BZR 6975, Git 98ad509)-product) date Sat Aug 13 17:34:52 2016* 5 | %MOMM*% 6 | %LPD*% 7 | G01* 8 | G04 APERTURE LIST* 9 | %ADD10C,0.100000*% 10 | %ADD11R,1.597660X1.800860*% 11 | %ADD12R,1.000000X1.600000*% 12 | %ADD13R,0.650000X1.060000*% 13 | %ADD14R,0.900000X1.700000*% 14 | G04 APERTURE END LIST* 15 | D10* 16 | X201930000Y-75565000D02* 17 | X205740000Y-79375000D01* 18 | X194310000Y-75565000D02* 19 | X201930000Y-75565000D01* 20 | X194310000Y-75565000D02* 21 | X182880000Y-75565000D01* 22 | X205740000Y-99695000D02* 23 | X205740000Y-79375000D01* 24 | X205740000Y-99695000D02* 25 | X204470000Y-100965000D01* 26 | X179070000Y-79375000D02* 27 | X179070000Y-99695000D01* 28 | X180340000Y-100965000D02* 29 | X204470000Y-100965000D01* 30 | X179070000Y-99695000D02* 31 | X180340000Y-100965000D01* 32 | X182880000Y-75565000D02* 33 | X179070000Y-79375000D01* 34 | D11* 35 | X194459860Y-84455000D03* 36 | X191620140Y-84455000D03* 37 | X194459860Y-86995000D03* 38 | X191620140Y-86995000D03* 39 | D12* 40 | X191540000Y-90170000D03* 41 | X194540000Y-90170000D03* 42 | X197255000Y-90170000D03* 43 | X200255000Y-90170000D03* 44 | D13* 45 | X191455000Y-95715000D03* 46 | X192405000Y-95715000D03* 47 | X193355000Y-95715000D03* 48 | X193355000Y-93515000D03* 49 | X191455000Y-93515000D03* 50 | D14* 51 | X187505000Y-84455000D03* 52 | X184605000Y-84455000D03* 53 | X184605000Y-86995000D03* 54 | X187505000Y-86995000D03* 55 | X184605000Y-89535000D03* 56 | X187505000Y-89535000D03* 57 | X184605000Y-92075000D03* 58 | X187505000Y-92075000D03* 59 | X197305000Y-92710000D03* 60 | X200205000Y-92710000D03* 61 | X197305000Y-84455000D03* 62 | X200205000Y-84455000D03* 63 | X197305000Y-86995000D03* 64 | X200205000Y-86995000D03* 65 | X199185000Y-98425000D03* 66 | X195785000Y-98425000D03* 67 | X185625000Y-98425000D03* 68 | X189025000Y-98425000D03* 69 | M02* 70 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/fab/raw.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ;DRILL file {KiCad (2016-07-11 BZR 6975, Git 98ad509)-product} date Sat Aug 13 17:32:40 2016 3 | ;FORMAT={-:-/ absolute / inch / decimal} 4 | FMAT,2 5 | INCH,TZ 6 | T1C0.016 7 | T2C0.040 8 | T3C0.031 9 | % 10 | G90 11 | G05 12 | M72 13 | T1 14 | X7.345Y-3.695 15 | X7.375Y-3.725 16 | X7.435Y-3.32 17 | X7.435Y-3.425 18 | X7.435Y-3.52 19 | X7.49Y-3.67 20 | X7.575Y-3.84 21 | X7.62Y-3.84 22 | X7.665Y-3.805 23 | X7.67Y-3.705 24 | X7.67Y-3.755 25 | X7.7Y-3.625 26 | X7.95Y-3.85 27 | T2 28 | X7.125Y-3.2 29 | X7.125Y-3.3 30 | X7.125Y-3.4 31 | X7.125Y-3.5 32 | X7.125Y-3.6 33 | X7.125Y-3.7 34 | X7.125Y-3.8 35 | X7.125Y-3.9 36 | X8.025Y-3.2 37 | X8.025Y-3.3 38 | X8.025Y-3.4 39 | X8.025Y-3.5 40 | X8.025Y-3.6 41 | X8.025Y-3.7 42 | X8.025Y-3.8 43 | X8.025Y-3.9 44 | T3 45 | X7.375Y-3.875 46 | X7.775Y-3.875 47 | T0 48 | M30 49 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/fp-lib-table: -------------------------------------------------------------------------------- 1 | (fp_lib_table 2 | (lib (name firethings-kicad-libs)(type KiCad)(uri ${KIPRJMOD}/../firethings-kicad-libs)(options "")(descr "")) 3 | ) 4 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/front-3d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FirebaseExtended/firebase-arduino/c2b39a3afd55af27e0c39318b89bab71148517b2/contrib/hardware/firethings/ft1.3/front-3d.png -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/raw-cache.lib: -------------------------------------------------------------------------------- 1 | EESchema-LIBRARY Version 2.3 2 | #encoding utf-8 3 | # 4 | # +3V3 5 | # 6 | DEF +3V3 #PWR 0 0 Y Y 1 F P 7 | F0 "#PWR" 0 -150 50 H I C CNN 8 | F1 "+3V3" 0 140 50 H V C CNN 9 | F2 "" 0 0 50 H V C CNN 10 | F3 "" 0 0 50 H V C CNN 11 | ALIAS +3.3V 12 | DRAW 13 | P 2 0 1 0 -30 50 0 100 N 14 | P 2 0 1 0 0 0 0 100 N 15 | P 2 0 1 0 0 100 30 50 N 16 | X +3V3 1 0 0 0 U 50 50 1 1 W N 17 | ENDDRAW 18 | ENDDEF 19 | # 20 | # +5V 21 | # 22 | DEF +5V #PWR 0 0 Y Y 1 F P 23 | F0 "#PWR" 0 -150 50 H I C CNN 24 | F1 "+5V" 0 140 50 H V C CNN 25 | F2 "" 0 0 50 H V C CNN 26 | F3 "" 0 0 50 H V C CNN 27 | DRAW 28 | P 2 0 1 0 -30 50 0 100 N 29 | P 2 0 1 0 0 0 0 100 N 30 | P 2 0 1 0 0 100 30 50 N 31 | X +5V 1 0 0 0 U 50 50 1 1 W N 32 | ENDDRAW 33 | ENDDEF 34 | # 35 | # AP131-15 36 | # 37 | DEF AP131-15 U 0 40 Y Y 1 F N 38 | F0 "U" -200 250 50 H V L CNN 39 | F1 "AP131-15" 350 250 50 H V R CNN 40 | F2 "TO_SOT_Packages_SMD:SOT-23-5" 0 -400 50 H I C CNN 41 | F3 "" 0 0 50 H V C CNN 42 | ALIAS AP131-18 AP131-20 AP131-25 AP131-28 AP131-29 AP131-30 AP131-33 AP131-35 43 | $FPLIST 44 | SOT-23* 45 | $ENDFPLIST 46 | DRAW 47 | S -200 200 200 -200 0 1 10 f 48 | X IN 1 -300 100 100 R 50 50 1 1 W 49 | X GND 2 0 -300 100 U 50 50 1 1 W 50 | X EN 3 -300 0 100 R 50 50 1 1 I 51 | X BP 4 300 0 100 L 50 50 1 1 I 52 | X OUT 5 300 100 100 L 50 50 1 1 w 53 | ENDDRAW 54 | ENDDEF 55 | # 56 | # C 57 | # 58 | DEF C C 0 10 N Y 1 F N 59 | F0 "C" 25 100 50 H V L CNN 60 | F1 "C" 25 -100 50 H V L CNN 61 | F2 "" 38 -150 50 H V C CNN 62 | F3 "" 0 0 50 H V C CNN 63 | $FPLIST 64 | C? 65 | C_????_* 66 | C_???? 67 | SMD*_c 68 | Capacitor* 69 | $ENDFPLIST 70 | DRAW 71 | P 2 0 1 20 -80 -30 80 -30 N 72 | P 2 0 1 20 -80 30 80 30 N 73 | X ~ 1 0 150 110 D 40 40 1 1 P 74 | X ~ 2 0 -150 110 U 40 40 1 1 P 75 | ENDDRAW 76 | ENDDEF 77 | # 78 | # ESP-12 79 | # 80 | DEF ESP-12 U 0 40 Y Y 1 F N 81 | F0 "U" 0 -100 50 H V C CNN 82 | F1 "ESP-12" 0 100 50 H V C CNN 83 | F2 "" 0 0 50 H I C CNN 84 | F3 "" 0 0 50 H I C CNN 85 | ALIAS ESP-07v2 86 | $FPLIST 87 | ESP-07* 88 | ESP-12* 89 | $ENDFPLIST 90 | DRAW 91 | S -600 -600 600 600 1 0 0 N 92 | X REST 1 -900 300 300 R 50 50 1 1 I 93 | X ADC 2 -900 200 300 R 50 50 1 1 P 94 | X CH_PD 3 -900 100 300 R 50 50 1 1 I 95 | X GPIO16 4 -900 0 300 R 50 50 1 1 B 96 | X GPIO14 5 -900 -100 300 R 50 50 1 1 B 97 | X GPIO12 6 -900 -200 300 R 50 50 1 1 B 98 | X GPIO13 7 -900 -300 300 R 50 50 1 1 B 99 | X VCC 8 0 900 300 D 50 50 1 1 W 100 | X GND 9 0 -900 300 U 50 50 1 1 W 101 | X GPIO15 10 900 -300 300 L 50 50 1 1 B 102 | X GPIO2 11 900 -200 300 L 50 50 1 1 B 103 | X GPIO0 12 900 -100 300 L 50 50 1 1 B 104 | X GPIO4 13 900 0 300 L 50 50 1 1 B 105 | X GPIO5 14 900 100 300 L 50 50 1 1 B 106 | X RXD 15 900 200 300 L 50 50 1 1 I 107 | X TXD 16 900 300 300 L 50 50 1 1 O 108 | ENDDRAW 109 | ENDDEF 110 | # 111 | # Firethings_Mini 112 | # 113 | DEF Firethings_Mini U 0 40 Y Y 1 F N 114 | F0 "U" 0 500 60 H V C CNN 115 | F1 "Firethings_Mini" 0 -500 60 H V C CNN 116 | F2 "" 550 -700 60 H V C CNN 117 | F3 "" 550 -700 60 H V C CNN 118 | DRAW 119 | S -300 450 300 -550 0 1 0 N 120 | X 5V 1 150 650 200 D 50 50 1 1 W 121 | X GND 2 0 -750 200 U 50 50 1 1 W 122 | X IO2 3 -500 150 200 R 50 50 1 1 B 123 | X IO0 4 -500 50 200 R 50 50 1 1 B 124 | X IO4 5 -500 -50 200 R 50 50 1 1 B 125 | X IO5 6 -500 -150 200 R 50 50 1 1 B 126 | X RXD 7 -500 -250 200 R 50 50 1 1 B 127 | X TXD 8 -500 -350 200 R 50 50 1 1 B 128 | X Rst 9 500 -350 200 L 50 50 1 1 B 129 | X A0 10 500 -250 200 L 50 50 1 1 B 130 | X IO16 11 500 -150 200 L 50 50 1 1 B 131 | X IO14 12 500 -50 200 L 50 50 1 1 B 132 | X IO12 13 500 50 200 L 50 50 1 1 B 133 | X IO13 14 500 150 200 L 50 50 1 1 B 134 | X IO15 15 500 250 200 L 50 50 1 1 B 135 | X 3.3V 16 -150 650 200 D 50 50 1 1 w 136 | ENDDRAW 137 | ENDDEF 138 | # 139 | # GND 140 | # 141 | DEF GND #PWR 0 0 Y Y 1 F P 142 | F0 "#PWR" 0 -250 50 H I C CNN 143 | F1 "GND" 0 -150 50 H V C CNN 144 | F2 "" 0 0 50 H V C CNN 145 | F3 "" 0 0 50 H V C CNN 146 | DRAW 147 | P 6 0 1 0 0 0 0 -50 50 -50 0 -100 -50 -50 0 -50 N 148 | X GND 1 0 0 0 D 50 50 1 1 W N 149 | ENDDRAW 150 | ENDDEF 151 | # 152 | # LED 153 | # 154 | DEF LED D 0 40 Y N 1 F N 155 | F0 "D" 0 100 50 H V C CNN 156 | F1 "LED" 0 -100 50 H V C CNN 157 | F2 "" 0 0 50 H V C CNN 158 | F3 "" 0 0 50 H V C CNN 159 | $FPLIST 160 | LED-* 161 | LED_* 162 | $ENDFPLIST 163 | DRAW 164 | P 2 0 1 0 -50 50 -50 -50 N 165 | P 3 0 1 0 -80 -25 -125 -65 -120 -40 N 166 | P 3 0 1 0 -65 -40 -110 -80 -105 -55 N 167 | P 3 0 1 0 50 50 -50 0 50 -50 F 168 | X K 1 -200 0 150 R 40 40 1 1 P 169 | X A 2 200 0 150 L 40 40 1 1 P 170 | ENDDRAW 171 | ENDDEF 172 | # 173 | # R 174 | # 175 | DEF R R 0 0 N Y 1 F N 176 | F0 "R" 80 0 50 V V C CNN 177 | F1 "R" 0 0 50 V V C CNN 178 | F2 "" -70 0 50 V V C CNN 179 | F3 "" 0 0 50 H V C CNN 180 | $FPLIST 181 | R_* 182 | Resistor_* 183 | $ENDFPLIST 184 | DRAW 185 | S -40 -100 40 100 0 1 10 N 186 | X ~ 1 0 150 50 D 50 50 1 1 P 187 | X ~ 2 0 -150 50 U 50 50 1 1 P 188 | ENDDRAW 189 | ENDDEF 190 | # 191 | # SPST 192 | # 193 | DEF SPST SW 0 0 N Y 1 F N 194 | F0 "SW" 0 100 50 H V C CNN 195 | F1 "SPST" 0 -100 50 H V C CNN 196 | F2 "" 0 0 50 H V C CNN 197 | F3 "" 0 0 50 H V C CNN 198 | DRAW 199 | C -150 0 50 0 0 0 N 200 | C 150 0 50 0 0 0 N 201 | P 2 0 0 0 -100 0 100 100 N 202 | X 1 1 -500 0 300 R 50 50 1 1 I 203 | X 2 2 500 0 300 L 50 50 1 1 I 204 | ENDDRAW 205 | ENDDEF 206 | # 207 | #End Library 208 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/raw-gerbers1.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FirebaseExtended/firebase-arduino/c2b39a3afd55af27e0c39318b89bab71148517b2/contrib/hardware/firethings/ft1.3/raw-gerbers1.3.zip -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/raw-schematic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FirebaseExtended/firebase-arduino/c2b39a3afd55af27e0c39318b89bab71148517b2/contrib/hardware/firethings/ft1.3/raw-schematic.pdf -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/raw.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FirebaseExtended/firebase-arduino/c2b39a3afd55af27e0c39318b89bab71148517b2/contrib/hardware/firethings/ft1.3/raw.bin -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/raw.csv: -------------------------------------------------------------------------------- 1 | "Id";"Designator";"Package";"Quantity";"Designation";"Supplier and ref"; 2 | 1;"U2";"firethings_mini";1;"Firethings_Mini";;; 3 | 2;"R1,R2,R3,R4,R5";"R_1206_HandSoldering";5;"10K";;; 4 | 3;"G***";"firebase-logo";1;"LOGO";;; 5 | 4;"U1";"ESP-12-SMD";1;"ESP-12";;; 6 | 5;"U3";"LED_WS2812B-PLCC4";1;"INFO";;; 7 | 6;"SW1";"SW_SPST_EVQP7A";1;"RESET";;; 8 | 7;"SW2";"SW_SPST_EVQP7A";1;"CTRL";;; 9 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/raw.pro: -------------------------------------------------------------------------------- 1 | update=Wed 24 Aug 2016 01:22:17 PM PDT 2 | version=1 3 | last_client=kicad 4 | [pcbnew] 5 | version=1 6 | LastNetListRead= 7 | UseCmpFile=1 8 | PadDrill=0.600000000000 9 | PadDrillOvalY=0.600000000000 10 | PadSizeH=1.500000000000 11 | PadSizeV=1.500000000000 12 | PcbTextSizeV=1.500000000000 13 | PcbTextSizeH=1.500000000000 14 | PcbTextThickness=0.300000000000 15 | ModuleTextSizeV=1.000000000000 16 | ModuleTextSizeH=1.000000000000 17 | ModuleTextSizeThickness=0.150000000000 18 | SolderMaskClearance=0.000000000000 19 | SolderMaskMinWidth=0.000000000000 20 | DrawSegmentWidth=0.200000000000 21 | BoardOutlineThickness=0.100000000000 22 | ModuleOutlineThickness=0.150000000000 23 | [cvpcb] 24 | version=1 25 | NetIExt=net 26 | [general] 27 | version=1 28 | [eeschema] 29 | version=1 30 | LibDir= 31 | [eeschema/libraries] 32 | LibName1=../firethings-kicad-libs/esp-12 33 | LibName2=../firethings-kicad-libs/firethings-mini 34 | -------------------------------------------------------------------------------- /contrib/hardware/firethings/ft1.3/raw.rules: -------------------------------------------------------------------------------- 1 | 2 | (rules PCB raw 3 | (snap_angle 4 | fortyfive_degree 5 | ) 6 | (autoroute_settings 7 | (fanout off) 8 | (autoroute on) 9 | (postroute on) 10 | (vias on) 11 | (via_costs 50) 12 | (plane_via_costs 5) 13 | (start_ripup_costs 100) 14 | (start_pass_no 1473) 15 | (layer_rule F.Cu 16 | (active on) 17 | (preferred_direction horizontal) 18 | (preferred_direction_trace_costs 1.0) 19 | (against_preferred_direction_trace_costs 2.2) 20 | ) 21 | (layer_rule B.Cu 22 | (active on) 23 | (preferred_direction vertical) 24 | (preferred_direction_trace_costs 1.0) 25 | (against_preferred_direction_trace_costs 1.8) 26 | ) 27 | ) 28 | (rule 29 | (width 250.0) 30 | (clear 200.2) 31 | (clear 125.0 (type smd_to_turn_gap)) 32 | (clear 50.0 (type smd_smd)) 33 | ) 34 | (padstack "Via[0-1]_800:400_um" 35 | (shape 36 | (circle F.Cu 800.0 0.0 0.0) 37 | ) 38 | (shape 39 | (circle B.Cu 800.0 0.0 0.0) 40 | ) 41 | (attach off) 42 | ) 43 | (via 44 | "Via[0-1]_800:400_um" "Via[0-1]_800:400_um" default 45 | ) 46 | (via 47 | "Via[0-1]_800:400_um-kicad_default" "Via[0-1]_800:400_um" "kicad_default" 48 | ) 49 | (via_rule 50 | default "Via[0-1]_800:400_um" 51 | ) 52 | (via_rule 53 | "kicad_default" "Via[0-1]_800:400_um-kicad_default" 54 | ) 55 | (class default 56 | (clearance_class default) 57 | (via_rule default) 58 | (rule 59 | (width 250.0) 60 | ) 61 | (circuit 62 | (use_layer F.Cu B.Cu) 63 | ) 64 | ) 65 | (class "kicad_default" 66 | /RST GND /EN /RX /TX /FLASH/0/D3 /SS/15/D8 /MISO/12/D6 67 | /MOSI/13/D7 /SCL/5/D1 /SDA/4/D2 /2/D4 /SCK/14/D5 /16/D0 /ADC/A0 +3V3 68 | "Net-(D1-Pad2)" "Net-(D2-Pad2)" +5V "Net-(U3-Pad4)" 69 | (clearance_class "kicad_default") 70 | (via_rule kicad_default) 71 | (rule 72 | (width 250.0) 73 | ) 74 | (circuit 75 | (use_layer F.Cu B.Cu) 76 | ) 77 | ) 78 | ) -------------------------------------------------------------------------------- /contrib/src/SerialTransceiver.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "modem/SerialTransceiver.h" 4 | #include "modem/db/DatabaseProtocol.h" 5 | 6 | // Bring them into the base namespace for easier use in arduino ide. 7 | using firebase::modem::SerialTransceiver; 8 | using firebase::modem::DatabaseProtocol; 9 | -------------------------------------------------------------------------------- /contrib/src/Thing.h: -------------------------------------------------------------------------------- 1 | #include "thing/FireThing.h" 2 | #include "thing/Transcriber.h" 3 | #include "thing/Portal.h" 4 | #include "thing/WiFiManager.h" 5 | -------------------------------------------------------------------------------- /contrib/src/modem/SerialProtocol.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEM_SERIAL_PROTOCOL_H 2 | #define MODEM_SERIAL_PROTOCOL_H 3 | 4 | #include 5 | #include 6 | 7 | namespace firebase { 8 | namespace modem { 9 | 10 | class InputStream; 11 | class OutputStream; 12 | 13 | /* 14 | * Define generic baseclass for all serial protocols that wish to share 15 | * the common commandspace. 16 | */ 17 | class SerialProtocol { 18 | public: 19 | virtual ~SerialProtocol() = default; 20 | 21 | /* 22 | * Returns all commands this protocol supports, commands are single words. 23 | * Returned vector MUST be sorted. 24 | */ 25 | virtual const std::vector& commands() const = 0; 26 | 27 | /* 28 | * Execute command, takes over the serial line until execution is done. 29 | */ 30 | virtual void Execute(const String& command, InputStream* in, OutputStream* out) = 0; 31 | 32 | }; 33 | 34 | } // modem 35 | } // firebase 36 | 37 | #endif // MODEM_SERIAL_PROTOCOL_H 38 | -------------------------------------------------------------------------------- /contrib/src/modem/SerialTransceiver.cpp: -------------------------------------------------------------------------------- 1 | #include "SerialTransceiver.h" 2 | 3 | #include 4 | 5 | namespace firebase { 6 | namespace modem { 7 | 8 | void SerialTransceiver::begin(Stream* serial) { 9 | in_.reset(new ArduinoInputStream(serial)); 10 | out_.reset(new ArduinoOutputStream(serial)); 11 | } 12 | 13 | void SerialTransceiver::RegisterProtocol(std::unique_ptr protocol) { 14 | protocols_.push_back(std::move(protocol)); 15 | } 16 | 17 | void SerialTransceiver::loop() { 18 | String command_name = in_->readStringUntil(' '); 19 | 20 | if (command_name.length() == 0 // Generally means a timeout has occured. 21 | || command_name == "\n") { 22 | return; 23 | } 24 | 25 | bool command_found = false; 26 | for (auto& protocol : protocols_) { 27 | const std::vector& commands = protocol->commands(); 28 | if (std::binary_search(commands.begin(), commands.end(), command_name)) { 29 | protocol->Execute(command_name, in_.get(), out_.get()); 30 | command_found = true; 31 | break; 32 | } 33 | } 34 | 35 | if (!command_found) { 36 | in_->drain(); 37 | out_->println(String("-FAIL Invalid command '") + command_name + "'." ); 38 | return; 39 | } 40 | } 41 | 42 | 43 | } // modem 44 | } // firebase 45 | -------------------------------------------------------------------------------- /contrib/src/modem/SerialTransceiver.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEM_SERIAL_TRANSCIEVER_H 2 | #define MODEM_SERIAL_TRANSCIEVER_H 3 | 4 | #include 5 | #include 6 | 7 | #include "modem/SerialProtocol.h" 8 | #include "modem/input-stream.h" 9 | #include "modem/output-stream.h" 10 | 11 | namespace firebase { 12 | namespace modem { 13 | 14 | class SerialTransceiver { 15 | public: 16 | void RegisterProtocol(std::unique_ptr protocol); 17 | // Also takes ownership as above but more arduino friendly. 18 | void RegisterProtocol(SerialProtocol* protocol) { 19 | RegisterProtocol(std::unique_ptr(protocol)); 20 | } 21 | 22 | void begin(Stream* serial); 23 | void loop(); 24 | 25 | private: 26 | std::unique_ptr in_; 27 | std::unique_ptr out_; 28 | std::vector> protocols_; 29 | }; 30 | 31 | } // modem 32 | } // firebase 33 | 34 | #endif // MODEM_SERIAL_TRANSCIEVER_H 35 | -------------------------------------------------------------------------------- /contrib/src/modem/command.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEM_COMMAND_H 2 | #define MODEM_COMMAND_H 3 | 4 | #include "FirebaseArduino.h" 5 | #include "modem/output-stream.h" 6 | #include "modem/input-stream.h" 7 | 8 | namespace firebase { 9 | namespace modem { 10 | 11 | class Command { 12 | public: 13 | Command(FirebaseArduino* fbase) : fbase_(fbase) {} 14 | 15 | // Execute command, reading any additional data needed from stream. 16 | // Return false if execution failed. 17 | virtual bool execute(const String& command, 18 | InputStream* in, OutputStream* out) = 0; 19 | protected: 20 | FirebaseArduino& fbase() { 21 | return *fbase_; 22 | } 23 | 24 | private: 25 | FirebaseArduino* fbase_; 26 | }; 27 | 28 | } // modem 29 | } // firebase 30 | 31 | #endif //MODEM_COMMAND_H 32 | -------------------------------------------------------------------------------- /contrib/src/modem/db/DatabaseProtocol.cpp: -------------------------------------------------------------------------------- 1 | #include "modem/db/DatabaseProtocol.h" 2 | 3 | namespace firebase { 4 | namespace modem { 5 | namespace { 6 | const std::vector kCommands { 7 | "BEGIN_DB", 8 | "GET", 9 | "SET", 10 | "PUSH", 11 | "REMOVE", 12 | "BEGIN_STREAM" 13 | }; 14 | } 15 | 16 | const std::vector& DatabaseProtocol::commands() const { 17 | return kCommands; 18 | } 19 | 20 | void DatabaseProtocol::Execute(const String& command_name, InputStream* in, 21 | OutputStream* out) { 22 | if (command_name == "BEGIN_DB") { 23 | BeginCommand command; 24 | if (command.execute(command_name, in, out)) { 25 | fbase_ = std::move(command.firebase()); 26 | } 27 | return; 28 | } else if (!fbase_) { 29 | in->drain(); 30 | out->println("-FAIL Must call BEGIN_DB before anything else."); 31 | return; 32 | } 33 | 34 | std::unique_ptr command = CreateCommand(command_name, fbase_.get()); 35 | if (!command) { 36 | in->drain(); 37 | out->println(String("-FAIL unhandled command '") + command_name + "'." ); 38 | return; 39 | } 40 | 41 | command->execute(command_name, in, out); 42 | } 43 | 44 | std::unique_ptr DatabaseProtocol::CreateCommand(const String& text, 45 | FirebaseArduino* fbase) { 46 | std::unique_ptr command; 47 | if (text == "GET") { 48 | command.reset(new GetCommand(fbase)); 49 | } else if (text == "SET") { 50 | command.reset(new SetCommand(fbase)); 51 | } else if (text == "PUSH") { 52 | command.reset(new PushCommand(fbase)); 53 | } else if (text == "REMOVE") { 54 | command.reset(new RemoveCommand(fbase)); 55 | } else if (text == "BEGIN_STREAM") { 56 | command.reset(new StreamCommand(fbase)); 57 | } 58 | return command; 59 | } 60 | } // modem 61 | } // firebase 62 | -------------------------------------------------------------------------------- /contrib/src/modem/db/DatabaseProtocol.h: -------------------------------------------------------------------------------- 1 | #ifndef MDOEM_DB_DATABASE_PROTOCOL_H 2 | #define MODEM_DB_DATABASE_PROTOCOL_H 3 | 4 | #include "modem/SerialProtocol.h" 5 | #include "modem/db/commands.h" 6 | #include "Firebase.h" 7 | 8 | namespace firebase { 9 | namespace modem { 10 | 11 | class DatabaseProtocol : public SerialProtocol { 12 | public: 13 | const std::vector& commands() const override; 14 | void Execute(const String& command, InputStream* in, OutputStream* out) override; 15 | private: 16 | std::unique_ptr CreateCommand(const String& text, FirebaseArduino* fbase); 17 | 18 | std::unique_ptr fbase_; 19 | }; 20 | 21 | 22 | } // modem 23 | } // firebase 24 | 25 | 26 | #endif // MODEM_DB_DATABASE_PROTOCOL_H 27 | -------------------------------------------------------------------------------- /contrib/src/modem/db/begin-command.cpp: -------------------------------------------------------------------------------- 1 | #include "modem/db/commands.h" 2 | 3 | namespace firebase { 4 | namespace modem { 5 | 6 | bool BeginCommand::execute(const String& command, 7 | InputStream* in, OutputStream* out) { 8 | if (in == nullptr || out == nullptr) { 9 | return false; 10 | } 11 | 12 | if (command != "BEGIN_DB") { 13 | return false; 14 | } 15 | 16 | String host; 17 | String auth; 18 | 19 | String data(in->readLine()); 20 | 21 | int space_index = data.indexOf(' '); 22 | if (space_index == -1) { 23 | // host only. 24 | host = data; 25 | } else { 26 | // host and auth. 27 | host = data.substring(0, space_index); 28 | auth = data.substring(space_index + 1); 29 | } 30 | 31 | if (host.length() == 0) { 32 | out->println("-FAIL Missing host"); 33 | return false; 34 | } 35 | 36 | new_firebase_.reset(new FirebaseArduino()); 37 | new_firebase_.get()->begin(host.c_str(), auth.c_str()); 38 | 39 | out->println("+OK"); 40 | return true; 41 | } 42 | 43 | std::unique_ptr BeginCommand::firebase() { 44 | return std::move(new_firebase_); 45 | } 46 | 47 | } // modem 48 | } // firebase 49 | -------------------------------------------------------------------------------- /contrib/src/modem/db/commands.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEM_DB_COMMANDS_H 2 | #define MODEM_DB_COMMANDS_H 3 | 4 | #include "FirebaseArduino.h" 5 | #include "modem/command.h" 6 | #include "modem/output-stream.h" 7 | #include "modem/input-stream.h" 8 | 9 | namespace firebase { 10 | namespace modem { 11 | 12 | class GetCommand : public Command { 13 | public: 14 | GetCommand(FirebaseArduino* fbase) : Command(fbase) {} 15 | 16 | bool execute(const String& command, InputStream* in, OutputStream* out); 17 | }; 18 | 19 | class SetCommand : public Command { 20 | public: 21 | SetCommand(FirebaseArduino* fbase) : Command(fbase) {} 22 | 23 | bool execute(const String& command, InputStream* in, OutputStream* out); 24 | }; 25 | 26 | class RemoveCommand : public Command { 27 | public: 28 | RemoveCommand(FirebaseArduino* fbase) : Command(fbase) {} 29 | 30 | bool execute(const String& command, InputStream* in, OutputStream* out); 31 | }; 32 | 33 | class PushCommand : public Command { 34 | public: 35 | PushCommand(FirebaseArduino* fbase) : Command(fbase) {} 36 | 37 | bool execute(const String& command, InputStream* in, OutputStream* out); 38 | }; 39 | 40 | class BeginCommand : public Command { 41 | public: 42 | BeginCommand() : Command(nullptr) {} 43 | 44 | bool execute(const String& command, InputStream* in, OutputStream* out); 45 | 46 | // This can only be called once. 47 | std::unique_ptr firebase(); 48 | 49 | private: 50 | std::unique_ptr new_firebase_; 51 | }; 52 | 53 | class StreamCommand : public Command { 54 | public: 55 | StreamCommand(FirebaseArduino* fbase) : Command(fbase) {} 56 | 57 | bool execute(const String& command, InputStream* in, OutputStream* out); 58 | }; 59 | 60 | } // modem 61 | } // firebase 62 | 63 | #endif //MODEM_DB_COMMANDS_H 64 | -------------------------------------------------------------------------------- /contrib/src/modem/db/get-command.cpp: -------------------------------------------------------------------------------- 1 | #include "modem/db/commands.h" 2 | 3 | namespace firebase { 4 | namespace modem { 5 | 6 | bool GetCommand::execute(const String& command, 7 | InputStream* in, OutputStream* out) { 8 | if (in == nullptr || out == nullptr) { 9 | return false; 10 | } 11 | 12 | if (command != "GET") { 13 | return false; 14 | } 15 | 16 | String path = in->readLine(); 17 | String value = fbase().getString(path); 18 | if (fbase().error().length() != 0) { 19 | out->print("-FAIL "); 20 | out->println(fbase().error().c_str()); 21 | return false; 22 | } 23 | 24 | // TODO implement json parsing to pull and process value. 25 | out->print("+"); 26 | out->println(value); 27 | return true; 28 | } 29 | 30 | } // modem 31 | } // firebase 32 | -------------------------------------------------------------------------------- /contrib/src/modem/db/push-command.cpp: -------------------------------------------------------------------------------- 1 | #include "modem/db/commands.h" 2 | #include "modem/json_util.h" 3 | 4 | namespace firebase { 5 | namespace modem { 6 | 7 | bool PushCommand::execute(const String& command, 8 | InputStream* in, OutputStream* out) { 9 | if (in == nullptr || out == nullptr) { 10 | return false; 11 | } 12 | 13 | if (command != "PUSH") { 14 | return false; 15 | } 16 | 17 | String path = in->readStringUntil(' '); 18 | String data = in->readLine(); 19 | 20 | fbase().pushString(path, data); 21 | 22 | if (fbase().error().length() != 0) { 23 | out->print("-FAIL "); 24 | out->println(fbase().error().c_str()); 25 | return false; 26 | } else { 27 | out->println("+OK"); 28 | return true; 29 | } 30 | } 31 | 32 | } // modem 33 | } // firebase 34 | -------------------------------------------------------------------------------- /contrib/src/modem/db/remove-command.cpp: -------------------------------------------------------------------------------- 1 | #include "modem/db/commands.h" 2 | 3 | namespace firebase { 4 | namespace modem { 5 | 6 | bool RemoveCommand::execute(const String& command, 7 | InputStream* in, OutputStream* out) { 8 | if (in == nullptr || out == nullptr) { 9 | return false; 10 | } 11 | 12 | if (command != "REMOVE") { 13 | return false; 14 | } 15 | 16 | String path = in->readLine(); 17 | fbase().remove(path); 18 | 19 | if (fbase().error().length() != 0) { 20 | out->print("-FAIL "); 21 | out->println(fbase().error().c_str()); 22 | return false; 23 | } 24 | 25 | out->println("+OK"); 26 | return true; 27 | } 28 | 29 | } // modem 30 | } // firebase 31 | -------------------------------------------------------------------------------- /contrib/src/modem/db/set-command.cpp: -------------------------------------------------------------------------------- 1 | #include "modem/db/commands.h" 2 | #include "modem/json_util.h" 3 | 4 | namespace firebase { 5 | namespace modem { 6 | 7 | bool SetCommand::execute(const String& command, 8 | InputStream* in, OutputStream* out) { 9 | if (in == nullptr || out == nullptr) { 10 | return false; 11 | } 12 | 13 | if (command != "SET") { 14 | return false; 15 | } 16 | 17 | String path = in->readStringUntil(' '); 18 | String data = in->readLine(); 19 | 20 | fbase().setString(path, data); 21 | 22 | if (fbase().error().length() != 0) { 23 | out->print("-FAIL "); 24 | out->println(fbase().error().c_str()); 25 | return false; 26 | } else { 27 | out->println("+OK"); 28 | return true; 29 | } 30 | } 31 | 32 | } // modem 33 | } // firebase 34 | -------------------------------------------------------------------------------- /contrib/src/modem/db/stream-command.cpp: -------------------------------------------------------------------------------- 1 | #include "modem/db/commands.h" 2 | 3 | namespace firebase { 4 | namespace modem { 5 | 6 | bool StreamCommand::execute(const String& command, 7 | InputStream* in, OutputStream* out) { 8 | if (in == nullptr || out == nullptr) { 9 | return false; 10 | } 11 | 12 | if (command != "BEGIN_STREAM") { 13 | return false; 14 | } 15 | 16 | String path = in->readLine().c_str(); 17 | fbase().stream(path); 18 | 19 | if (fbase().error().length() != 0) { 20 | out->print("-FAIL "); 21 | out->println(fbase().error().c_str()); 22 | return false; 23 | } 24 | bool running = true; 25 | DynamicJsonBuffer buffer; 26 | while(running) { 27 | if (fbase().available()) { 28 | FirebaseObject event = fbase().readEvent(); 29 | out->print("+"); 30 | out->print(event.getString("type").c_str()); 31 | out->print(" "); 32 | String data = event.getString("data"); 33 | out->println(event.getString("path")); 34 | out->println(data.length()); 35 | out->println(data); 36 | } else if (in->available()) { 37 | String command = in->readLine(); 38 | if (command == "END_STREAM") { 39 | out->println("+OK"); 40 | running = false; 41 | } else { 42 | out->println("-FAIL Cannot call any command but END_STREAM."); 43 | } 44 | } 45 | } 46 | 47 | return true; 48 | } 49 | 50 | } // modem 51 | } // firebase 52 | -------------------------------------------------------------------------------- /contrib/src/modem/design.md: -------------------------------------------------------------------------------- 1 | Overview: 2 | 3 | ![Design diagram](diagram.png) 4 | 5 | We create a SerialTransceiver object that will manage the serial connection. It will read the first word on a line to determine which command is being called and construct the appropriate Command subclass to handle the interaction. Commands will be short lived objects with no state between calls, they will own the serial connection until they hand it back and are responsible for handling all necessary input and leaving the input line in a clean state for the next command. 6 | 7 | We will aim to keep the Transceiver/Command interaction generic enough to enable creating additional Protocol Transceivers in the future. 8 | 9 | The Transceiver object will also own the Firebase object and present it to each command during construction. The Firebase object is our link to the firebase backend. 10 | 11 | -------------------------------------------------------------------------------- /contrib/src/modem/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FirebaseExtended/firebase-arduino/c2b39a3afd55af27e0c39318b89bab71148517b2/contrib/src/modem/diagram.png -------------------------------------------------------------------------------- /contrib/src/modem/input-stream.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEM_INPUT_STREAM_H 2 | #define MODEM_INPUT_STREAM_H 3 | 4 | #include 5 | 6 | namespace firebase { 7 | namespace modem { 8 | 9 | class InputStream { 10 | public: 11 | virtual String readLine() = 0; 12 | // This call consumes the terminator. 13 | virtual String readStringUntil(const char terminator) = 0; 14 | virtual void drain() = 0; 15 | virtual bool available() = 0; 16 | }; 17 | 18 | class ArduinoInputStream : public InputStream { 19 | public: 20 | ArduinoInputStream(Stream* stream) : stream_(stream) {} 21 | String readLine() { 22 | String out = stream_->readStringUntil('\n'); 23 | if (out[out.length()-1] == '\r') { 24 | out.remove(out.length()-1); 25 | } 26 | return out; 27 | } 28 | 29 | String readStringUntil(const char terminator) { 30 | return stream_->readStringUntil(terminator); 31 | } 32 | 33 | void drain() { 34 | while(stream_->available()) { 35 | stream_->read(); 36 | } 37 | } 38 | 39 | bool available() { 40 | return stream_->available(); 41 | } 42 | 43 | private: 44 | Stream* stream_; 45 | }; 46 | 47 | } // modem 48 | } // firebase 49 | 50 | #endif // MODEM_INPUT_STREAM_H 51 | 52 | -------------------------------------------------------------------------------- /contrib/src/modem/json_util.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEM_JSON_UTIL_H 2 | #define MODEM_JSON_UTIL_H 3 | 4 | namespace firebase { 5 | namespace modem { 6 | namespace { 7 | std::string ReplaceAll(std::string str, const std::string& from, const std::string& to) { 8 | size_t start_pos = 0; 9 | while((start_pos = str.find(from, start_pos)) != std::string::npos) { 10 | str.replace(start_pos, from.length(), to); 11 | start_pos += to.length(); // Handles case where 'to' is a substring of 'from' 12 | } 13 | return str; 14 | } 15 | } 16 | 17 | // TODO(edcoyne): We should use a json library to escape. 18 | inline std::string EncodeForJson(std::string input) { 19 | input = ReplaceAll(input, "\\", "\\\\"); 20 | input = ReplaceAll(input, "\"", "\\\""); 21 | return "\"" + input + "\""; 22 | } 23 | 24 | } // modem 25 | } // firebase 26 | 27 | #endif // MODEM_JSON_UTIL_H 28 | -------------------------------------------------------------------------------- /contrib/src/modem/output-stream.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEM_OUTPUT_STREAM_H 2 | #define MODEM_OUTPUT_STREAM_H 3 | 4 | #include 5 | #include 6 | 7 | namespace firebase { 8 | namespace modem { 9 | 10 | class OutputStream { 11 | public: 12 | virtual int println(const String& string) = 0; 13 | virtual int println(const int value) = 0; 14 | virtual int print(const String& string) = 0; 15 | }; 16 | 17 | class ArduinoOutputStream : public OutputStream { 18 | public: 19 | ArduinoOutputStream(Stream* stream) : stream_(stream) {} 20 | 21 | int println(const String& string) override { 22 | return stream_->println(string.c_str()); 23 | } 24 | 25 | int println(const int value) override { 26 | return stream_->println(value); 27 | } 28 | 29 | int print(const String& string) override { 30 | return stream_->print(string.c_str()); 31 | } 32 | private: 33 | Stream* stream_; 34 | }; 35 | 36 | } // modem 37 | } // firebase 38 | 39 | #endif // MODEM_OUTPUT_STREAM 40 | -------------------------------------------------------------------------------- /contrib/src/thing/Config.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "thing/Config.h" 3 | #include 4 | 5 | namespace thing { 6 | 7 | ConfigJsonSerializer::ConfigJsonSerializer(const Config& config) { 8 | JsonObject& root = buffer_.createObject(); 9 | root_ = &root; 10 | root["host"] = config.host.c_str(); 11 | root["auth"] = config.auth.c_str(); 12 | root["path"] = config.path.c_str(); 13 | root["wifi_ssid"] = config.wifi_ssid.c_str(); 14 | root["wifi_key"] = config.wifi_key.c_str(); 15 | root["analog_activation"] = config.analog_activation_threshold; 16 | root["wifi_connect_attempts"] = config.wifi_connect_attempts; 17 | 18 | JsonObject& pins_root = root.createNestedObject("pins"); 19 | pins_root["digital_in"] = config.pins.digital_in; 20 | pins_root["digital_out"] = config.pins.digital_out; 21 | pins_root["analog_in"] = config.pins.analog_in; 22 | pins_root["analog_out"] = config.pins.analog_out; 23 | pins_root["config_mode_button"] = config.pins.config_mode_button; 24 | } 25 | 26 | ConfigJsonSerializer::ConfigJsonSerializer(char* serialized_config) { 27 | root_ = &(buffer_.parseObject(serialized_config)); 28 | } 29 | 30 | int ConfigJsonSerializer::content_length() const { 31 | return root_->measureLength(); 32 | } 33 | 34 | void ConfigJsonSerializer::SerializeTo(Stream* output) { 35 | // TODO: We "should" be able to have the root_ print directly to the stream 36 | // however it currently closes the connection half way through. Fixing this 37 | // would save ~250B of memory during serialization. 38 | String buffer; 39 | root_->printTo(buffer); 40 | output->print(buffer); 41 | } 42 | 43 | void ConfigJsonSerializer::DeserializeTo(Config* config) { 44 | config->host = root()["host"].asString(); 45 | config->auth = root()["auth"].asString(); 46 | config->path = root()["path"].asString(); 47 | config->wifi_ssid = root()["wifi_ssid"].asString(); 48 | config->wifi_key = root()["wifi_key"].asString(); 49 | config->analog_activation_threshold = root()["activation_threshold"]; 50 | config->wifi_connect_attempts = root()["wifi_connect_attempts"]; 51 | 52 | config->pins.digital_in = root()["pins"]["digital_in"]; 53 | config->pins.digital_out = root()["pins"]["digital_out"]; 54 | config->pins.analog_in = root()["pins"]["analog_in"]; 55 | config->pins.analog_out = root()["pins"]["analog_out"]; 56 | config->pins.config_mode_button = root()["pins"]["config_mode_button"]; 57 | } 58 | 59 | }; 60 | 61 | -------------------------------------------------------------------------------- /contrib/src/thing/Config.h: -------------------------------------------------------------------------------- 1 | #ifndef THING_CONFIG_H 2 | #define THING_CONFIG_H 3 | 4 | #include "Arduino.h" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace thing { 10 | 11 | struct Pins { 12 | int digital_in; 13 | int digital_out; 14 | int analog_in; 15 | int analog_out; 16 | int config_mode_button; 17 | }; 18 | 19 | struct Config { 20 | std::string host; 21 | std::string auth; 22 | std::string path; 23 | 24 | std::string wifi_ssid; 25 | std::string wifi_key; 26 | 27 | // If the change is analog value is less than this amount we don't send an 28 | // update. 29 | float analog_activation_threshold; 30 | int wifi_connect_attempts; 31 | 32 | Pins pins; 33 | }; 34 | 35 | class ConfigJsonSerializer { 36 | public: 37 | ConfigJsonSerializer(const Config& config); 38 | 39 | // We need a mutable char array here, otherwise a copy will be made. 40 | ConfigJsonSerializer(char* config); 41 | 42 | int content_length() const; 43 | void SerializeTo(Stream* output); 44 | void DeserializeTo(Config* config); 45 | 46 | private: 47 | JsonObject& root() {return *root_;} 48 | 49 | DynamicJsonBuffer buffer_; 50 | JsonObject* root_; 51 | }; 52 | 53 | } // namespace thing 54 | 55 | #endif // THING_CONFIG_H 56 | -------------------------------------------------------------------------------- /contrib/src/thing/FireThing.cpp: -------------------------------------------------------------------------------- 1 | #include "thing/FireThing.h" 2 | #include "Arduino.h" 3 | #include "FS.h" 4 | 5 | namespace thing { 6 | namespace { 7 | 8 | Config kDefaultConfig = { 9 | "", // firebase host 10 | "", // firebase auth 11 | "/fthing", // path in firebase 12 | "", // wifi ssid 13 | "", // wifi key 14 | 0.1, // analog activation threshold 15 | 2, // wifi connect attempts 16 | { 17 | D1, // digital in 18 | BUILTIN_LED, // digital out 19 | A0, // analog in 20 | D1, // analog out 21 | D0, // config mode button 22 | } 23 | }; 24 | 25 | const char kStorageFilename[] = "fthing.cfg"; 26 | 27 | } // namespace 28 | 29 | FireThing::FireThing() : debug_([](const char*) {}) {} 30 | 31 | bool FireThing::Setup() { 32 | Config config; 33 | if (!ReadConfigFromStorage(&config)) { 34 | debug_("Failed to read config from storage."); 35 | return false; 36 | } 37 | SetPinModes(config); 38 | if (digitalRead(config.pins.config_mode_button) == HIGH || !ConnectToWiFi(config)) { 39 | wifi_.StartAP(); 40 | } 41 | 42 | portal_.NotifyOnUpdate([this](const Config& config) { 43 | if (!WriteConfigToStorage(config)) { 44 | debug_("Failed to write config to storage."); 45 | } 46 | SetPinModes(config); 47 | transcriber_.UpdateConfig(config); 48 | ConnectToWiFi(config); 49 | }); 50 | portal_.Start(config); 51 | } 52 | 53 | void FireThing::Loop() { 54 | wifi_.Loop(); 55 | portal_.Loop(); 56 | transcriber_.Loop(); 57 | } 58 | 59 | bool FireThing::DeleteStoredConfig() { 60 | if (!SPIFFS.begin()) { 61 | debug_("Failed to mount FS."); 62 | return false; 63 | } 64 | bool success = SPIFFS.remove(kStorageFilename); 65 | SPIFFS.end(); 66 | return success; 67 | } 68 | 69 | bool FireThing::ConnectToWiFi(const Config& config) { 70 | debug_("Connecting to wifi:"); 71 | debug_(config.wifi_ssid.c_str()); 72 | // TODO we should probably not print the key to serial. 73 | debug_(config.wifi_key.c_str()); 74 | if (wifi_.Connect(config.wifi_ssid, config.wifi_key)) { 75 | debug_("Connected"); 76 | return true; 77 | } 78 | debug_("Failed to Connect."); 79 | return false; 80 | } 81 | 82 | void FireThing::SetPinModes(const Config& config) { 83 | pinMode(config.pins.digital_in, INPUT); 84 | pinMode(config.pins.digital_out, OUTPUT); 85 | pinMode(config.pins.analog_in, INPUT); 86 | pinMode(config.pins.analog_out, OUTPUT); 87 | 88 | pinMode(config.pins.config_mode_button, INPUT); 89 | } 90 | 91 | bool FireThing::ReadConfigFromStorage(Config* config) { 92 | if (!SPIFFS.begin()) { 93 | debug_("Failed to mount FS."); 94 | return false; 95 | } 96 | 97 | if (!SPIFFS.exists(kStorageFilename)) { 98 | debug_("Config not found, using default."); 99 | *config = kDefaultConfig; 100 | } else { 101 | File cfg = SPIFFS.open(kStorageFilename, "r"); 102 | if (!cfg) { 103 | debug_("Failed to open config for read"); 104 | SPIFFS.end(); 105 | return false; 106 | } 107 | char buffer[cfg.size()]; 108 | cfg.readBytes(buffer, cfg.size()); 109 | ConfigJsonSerializer serializer(buffer); 110 | serializer.DeserializeTo(config); 111 | debug_("Config read from disk."); 112 | } 113 | 114 | SPIFFS.end(); 115 | return true; 116 | } 117 | 118 | bool FireThing::WriteConfigToStorage(const Config& config) { 119 | if (!SPIFFS.begin()) { 120 | debug_("Failed to mount FS."); 121 | return false; 122 | } 123 | 124 | File cfg = SPIFFS.open(kStorageFilename, "w"); 125 | if (!cfg) { 126 | debug_("Failed to open config for write"); 127 | SPIFFS.end(); 128 | return false; 129 | } 130 | ConfigJsonSerializer serializer(config); 131 | serializer.SerializeTo(&cfg); 132 | 133 | SPIFFS.end(); 134 | return true; 135 | } 136 | 137 | void FireThing::SetDebugHandler(std::function debug) { 138 | debug_ = debug; 139 | wifi_.SetDebugHandler(debug); 140 | portal_.SetDebugHandler(debug); 141 | transcriber_.SetDebugHandler(debug); 142 | } 143 | 144 | } // namespace thing 145 | -------------------------------------------------------------------------------- /contrib/src/thing/FireThing.h: -------------------------------------------------------------------------------- 1 | #ifndef THING_FIRETHING_H 2 | #define THING_FIRETHING_H 3 | 4 | #include "thing/Config.h" 5 | #include "thing/WiFiManager.h" 6 | #include "thing/Transcriber.h" 7 | #include "thing/Portal.h" 8 | 9 | namespace thing { 10 | 11 | // Operates the device as a FireThing which manages a connection 12 | // between several pins and a firebase database. The configuration 13 | // will be read from and persisted too flash. 14 | class FireThing { 15 | public: 16 | FireThing(); 17 | bool Setup(); 18 | void Loop(); 19 | 20 | void SetDebugHandler(std::function debug); 21 | 22 | // Called to delete the currently stored config from the filesystem. 23 | bool DeleteStoredConfig(); 24 | 25 | private: 26 | bool ReadConfigFromStorage(Config* config); 27 | bool WriteConfigToStorage(const Config& config); 28 | 29 | bool ConnectToWiFi(const Config& config); 30 | void SetPinModes(const Config& config); 31 | 32 | WiFiManager wifi_; 33 | Portal portal_; 34 | Transcriber transcriber_; 35 | std::function debug_; 36 | }; 37 | 38 | } // namespace thing 39 | 40 | 41 | #endif // THING_FIRETHING_H 42 | -------------------------------------------------------------------------------- /contrib/src/thing/Portal.cpp: -------------------------------------------------------------------------------- 1 | #include "thing/Portal.h" 2 | #include 3 | 4 | namespace thing { 5 | 6 | Portal::Portal() 7 | : callback_([](const Config&){}), 8 | debug_([](const char*){}) {} 9 | 10 | void Portal::SetDebugHandler(std::function handler) { 11 | debug_ = std::move(handler); 12 | } 13 | 14 | void Portal::Start(const Config& config) { 15 | config_ = config; 16 | server_.on("/", [&] () { 17 | static const PROGMEM char page[] = R"( 18 | 19 | 90 | 91 | 92 |
Host:
93 |
Auth:
94 |
Path:
95 |
Wifi SSID:
96 | 97 |
98 |
Wifi Key:
99 |
100 |
Loading....
101 | 102 | 103 | 104 | )"; 105 | static const PROGMEM char type[] = "text/html"; 106 | 107 | server_.send_P(200, type, page); 108 | debug_("served root page."); 109 | }); 110 | 111 | server_.on("/config", [&] () { 112 | if (server_.method() == HTTP_GET) { 113 | auto client = server_.client(); 114 | 115 | ConfigJsonSerializer serializer(config_); 116 | server_.setContentLength(serializer.content_length()); 117 | server_.send(200, "application/json"); 118 | serializer.SerializeTo(&client); 119 | 120 | debug_("config retrieved"); 121 | } else if (server_.method() == HTTP_POST) { 122 | DynamicJsonBuffer jsonBuffer; 123 | if (!server_.hasArg("config")) { 124 | server_.send(500, "text/plain", "Missing config.\r\n"); 125 | debug_("Config updated called without param."); 126 | return; 127 | } 128 | 129 | char* buffer; 130 | { // Scoped to free String memory. 131 | String config = server_.arg("config"); 132 | buffer = (char*)malloc(config.length()+1); 133 | memcpy(buffer, config.c_str(), config.length()+1); 134 | } 135 | { // Scoped because serializer is invalid after free(). 136 | ConfigJsonSerializer serializer(buffer); 137 | serializer.DeserializeTo(&config_); 138 | free(buffer); 139 | } 140 | 141 | callback_(config_); 142 | server_.send(200, "text/plain", ""); 143 | debug_("config updated."); 144 | } 145 | }); 146 | 147 | server_.on("/wifi/scan", [&] () { 148 | int net_count = WiFi.scanNetworks(); 149 | DynamicJsonBuffer json_buffer; 150 | JsonArray& data = json_buffer.createArray(); 151 | for (int i=0; i < net_count; i++) { 152 | JsonObject& entry = data.createNestedObject(); 153 | entry["ssid"] = WiFi.SSID(i); 154 | entry["rssi"] = WiFi.RSSI(i); 155 | } 156 | // Free station info from memory. 157 | WiFi.scanDelete(); 158 | 159 | String buffer; 160 | data.printTo(buffer); 161 | server_.send(200, "application/json", buffer); 162 | debug_("served networks."); 163 | }); 164 | 165 | server_.begin(); 166 | debug_("Portal started."); 167 | } 168 | 169 | void Portal::Loop() { 170 | server_.handleClient(); 171 | } 172 | 173 | void Portal::NotifyOnUpdate(std::function callback) { 174 | callback_ = callback; 175 | } 176 | 177 | }; 178 | -------------------------------------------------------------------------------- /contrib/src/thing/Portal.h: -------------------------------------------------------------------------------- 1 | #ifndef THING_PORTAL_H 2 | #define THING_PORTAL_H 3 | 4 | #include "ESP8266WebServer.h" 5 | #include "thing/Config.h" 6 | 7 | namespace thing { 8 | 9 | class Portal { 10 | public: 11 | Portal(); 12 | 13 | void Start(const Config& config); 14 | void Loop(); 15 | void NotifyOnUpdate(std::function cb); 16 | 17 | void SetDebugHandler(std::function handler); 18 | 19 | private: 20 | Config config_; 21 | ESP8266WebServer server_; 22 | std::function callback_; 23 | std::function debug_; 24 | 25 | }; 26 | 27 | } // namespace thing 28 | 29 | #endif // THING_PORTAL_H 30 | -------------------------------------------------------------------------------- /contrib/src/thing/Transcriber.cpp: -------------------------------------------------------------------------------- 1 | #include "thing/Transcriber.h" 2 | #include 3 | 4 | namespace thing { 5 | namespace { 6 | const char* kSubPathDigitalOut = "/digital_out"; 7 | const char* kSubPathDigitalIn = "/digital_in"; 8 | const char* kSubPathAnalogOut = "/analog_out"; 9 | const char* kSubPathAnalogIn = "/analog_in"; 10 | } // namespace 11 | 12 | 13 | Transcriber::Transcriber() : debug_([](const char*) {}) {} 14 | 15 | void Transcriber::Setup(const Config& config) { 16 | Init(config); 17 | } 18 | 19 | void Transcriber::UpdateConfig(const Config& config) { 20 | Init(config); 21 | } 22 | 23 | void Transcriber::Init(const Config& config) { 24 | path_ = config.path; 25 | analog_activation_threshold_ = config.analog_activation_threshold; 26 | pin_digital_out_ = config.pins.digital_out; 27 | pin_digital_in_ = config.pins.digital_in; 28 | pin_analog_out_ = config.pins.analog_out; 29 | pin_analog_in_ = config.pins.analog_in; 30 | 31 | fbase_.reset(new Firebase(config.host, config.auth)); 32 | } 33 | 34 | void Transcriber::SetValue(const std::string& path, const std::string& value) { 35 | stream_.reset(nullptr); 36 | fbase_->set(path, value); 37 | stream_ = fbase_->streamPtr(path_); 38 | } 39 | 40 | void Transcriber::Loop() { 41 | if (WiFi.status() != WL_CONNECTED) { 42 | connected_ = false; 43 | return; 44 | } 45 | 46 | // If first time connecting start stream. 47 | if (!connected_) { 48 | debug_("Transcriber connected."); 49 | stream_ = fbase_->streamPtr(path_); 50 | connected_ = true; 51 | } 52 | 53 | // Read incoming data 54 | if (stream_->available()) { 55 | std::string event_str; 56 | if (stream_->read(event_str) == FirebaseStream::PUT) { 57 | FirebaseObject update(event_str.c_str()); 58 | if (update.success()) { 59 | if (update.getString("path") == "/") { 60 | ProcessInitialUpdate(update); 61 | } else { 62 | ProcessIncrementalUpdate(update); 63 | } 64 | } 65 | } 66 | } 67 | 68 | // Send values to cloud 69 | int new_digital_in = digitalRead(pin_digital_in_); 70 | if (new_digital_in != digital_in_) { 71 | SetValue(path_ + kSubPathDigitalIn, String(new_digital_in).c_str()); 72 | digital_in_ = new_digital_in; 73 | } 74 | 75 | float new_analog_in = analogRead(pin_analog_in_); 76 | if (abs(new_analog_in - analog_in_) > analog_activation_threshold_) { 77 | SetValue(path_ + kSubPathAnalogIn, String(new_analog_in).c_str()); 78 | analog_in_ = new_analog_in; 79 | } 80 | } 81 | 82 | void Transcriber::ProcessInitialUpdate(const FirebaseObject& update) { 83 | int digital_out = update.getInt((std::string("data") + kSubPathDigitalOut).c_str()); 84 | if (!update.failed()) { 85 | digitalWrite(pin_digital_out_, digital_out); 86 | } 87 | 88 | float analog_out = update.getFloat((std::string("data") + kSubPathAnalogOut).c_str()); 89 | if (!update.failed()) { 90 | analogWrite(pin_analog_out_, analog_out); 91 | } 92 | } 93 | 94 | void Transcriber::ProcessIncrementalUpdate(const FirebaseObject& update) { 95 | if (update.getString("path").equals(kSubPathDigitalOut)) { 96 | int digital_out = update.getInt("data"); 97 | if (!update.failed()) { 98 | digitalWrite(pin_digital_out_, update.getInt("data")); 99 | } 100 | } 101 | 102 | if (update.getString("path").equals(kSubPathAnalogOut)) { 103 | float analog_out = update.getFloat("data"); 104 | if (!update.failed()) { 105 | analogWrite(pin_analog_out_, analog_out); 106 | } 107 | } 108 | } 109 | 110 | void Transcriber::SetDebugHandler(std::function debug) { 111 | debug_ = debug; 112 | } 113 | 114 | } // thing 115 | -------------------------------------------------------------------------------- /contrib/src/thing/Transcriber.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2016 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #ifndef transcriber_h 18 | #define transcriber_h 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "Firebase.h" 25 | #include "FirebaseObject.h" 26 | #include "thing/Config.h" 27 | 28 | namespace thing { 29 | 30 | class Transcriber { 31 | public: 32 | Transcriber(); 33 | void Setup(const Config& config); 34 | void UpdateConfig(const Config& config); 35 | void Loop(); 36 | 37 | void SetDebugHandler(std::function handler); 38 | 39 | private: 40 | void Init(const Config& config); 41 | 42 | void ProcessInitialUpdate(const FirebaseObject& update); 43 | void ProcessIncrementalUpdate(const FirebaseObject& update); 44 | 45 | // Wrapper around Firebase::Set that stops the stream before setting, 46 | // Currently we have memory issues if we try to have two simultanious 47 | // SSL connections. 48 | void SetValue(const std::string& path, const std::string& value); 49 | 50 | std::unique_ptr fbase_; 51 | std::unique_ptr stream_; 52 | 53 | int digital_in_ = 0; 54 | float analog_activation_threshold_ = 0.0f; 55 | float analog_in_ = 0.0f; 56 | 57 | int pin_digital_out_; 58 | int pin_digital_in_; 59 | int pin_analog_out_; 60 | int pin_analog_in_; 61 | 62 | std::string path_; 63 | 64 | bool connected_ = false; 65 | std::function debug_; 66 | }; 67 | 68 | }; // thing 69 | 70 | 71 | #endif // transcriber_h 72 | -------------------------------------------------------------------------------- /contrib/src/thing/WiFiManager.cpp: -------------------------------------------------------------------------------- 1 | #include "thing/WiFiManager.h" 2 | 3 | #include 4 | #include 5 | 6 | 7 | namespace thing { 8 | namespace { 9 | 10 | const short kDnsPort = 53; 11 | 12 | } // namespace 13 | 14 | WiFiManager::WiFiManager() : debug_([](const char*){}) {} 15 | 16 | bool WiFiManager::StartAP() { 17 | // Use arduino string, casting an int to std::string with arduino C++ support 18 | // isn't easy. 19 | String ssid("FireThing-"); 20 | ssid += ESP.getChipId(); 21 | 22 | WiFi.mode(WIFI_AP_STA); 23 | if (!WiFi.softAP(ssid.c_str())) { 24 | return false; 25 | } 26 | 27 | debug_((String("WiFi AP : ") + ssid).c_str()); 28 | debug_((String("Wifi AP IP : ") + WiFi.softAPIP().toString()).c_str()); 29 | 30 | dns_.reset(new DNSServer()); 31 | dns_->start(kDnsPort, "*", WiFi.softAPIP()); 32 | dns_->setTTL(30); 33 | 34 | ap_up_ = true; 35 | return true; 36 | } 37 | 38 | bool WiFiManager::StopAP() { 39 | if (!WiFi.softAPdisconnect()) { 40 | return false; 41 | } 42 | dns_->stop(); 43 | dns_.reset(nullptr); 44 | 45 | ap_up_ = false; 46 | return true; 47 | } 48 | 49 | void WiFiManager::Loop() { 50 | if (dns_) { 51 | dns_->processNextRequest(); 52 | } 53 | } 54 | 55 | bool WiFiManager::Connect(const std::string& ssid, const std::string& auth) { 56 | auto status = WiFi.begin(ssid.c_str(), auth.c_str()); 57 | 58 | return status != WL_CONNECT_FAILED; 59 | } 60 | 61 | bool WiFiManager::connected() const { 62 | return WiFi.status() == WL_CONNECTED; 63 | } 64 | 65 | void WiFiManager::SetDebugHandler(std::function handler) { 66 | debug_ = std::move(handler); 67 | } 68 | 69 | }; 70 | -------------------------------------------------------------------------------- /contrib/src/thing/WiFiManager.h: -------------------------------------------------------------------------------- 1 | #ifndef THING_WIFI_MANAGER_H 2 | #define THING_WIFI_MANAGER_H 3 | 4 | #include 5 | #include 6 | 7 | namespace thing { 8 | 9 | class WiFiManager { 10 | public: 11 | WiFiManager(); 12 | 13 | bool StartAP(); 14 | bool StopAP(); 15 | bool Connect(const std::string& ssid, const std::string& auth); 16 | 17 | void Loop(); 18 | 19 | bool connected() const; 20 | bool ap_up() const { return ap_up_; } 21 | 22 | void SetDebugHandler(std::function handler); 23 | private: 24 | bool ap_up_ = false; 25 | std::unique_ptr dns_; 26 | std::function debug_; 27 | }; 28 | 29 | }; 30 | 31 | #endif // THING_WIFI_MANAGER_H 32 | -------------------------------------------------------------------------------- /contrib/test/FirebaseArduino_test.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2016 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #include "FirebaseObject.h" 18 | #include "gtest/gtest.h" 19 | 20 | 21 | TEST(FirebaseObjectTest, GetBool) { 22 | FirebaseObject obj("true"); 23 | EXPECT_EQ(true, obj.getBool()); 24 | EXPECT_TRUE(obj.success()); 25 | EXPECT_FALSE(obj.failed()); 26 | EXPECT_EQ(obj.error(), ""); 27 | } 28 | 29 | TEST(FirebaseObjectTest, GetInt) { 30 | { 31 | FirebaseObject obj("42"); 32 | EXPECT_EQ(42, obj.getInt()); 33 | EXPECT_TRUE(obj.success()); 34 | EXPECT_FALSE(obj.failed()); 35 | EXPECT_EQ(obj.error(), ""); 36 | } 37 | { 38 | FirebaseObject obj("42.0"); 39 | EXPECT_EQ(42, obj.getInt()); 40 | EXPECT_TRUE(obj.success()); 41 | EXPECT_FALSE(obj.failed()); 42 | EXPECT_EQ(obj.error(), ""); 43 | } 44 | } 45 | 46 | TEST(FirebaseObjectTest, GetFloat) { 47 | { 48 | FirebaseObject obj("43.1"); 49 | EXPECT_FLOAT_EQ(43.1, obj.getFloat()); 50 | EXPECT_TRUE(obj.success()); 51 | EXPECT_FALSE(obj.failed()); 52 | EXPECT_EQ(obj.error(), ""); 53 | } 54 | { 55 | FirebaseObject obj("43"); 56 | EXPECT_FLOAT_EQ(43, obj.getFloat()); 57 | EXPECT_TRUE(obj.success()); 58 | EXPECT_FALSE(obj.failed()); 59 | EXPECT_EQ(obj.error(), ""); 60 | } 61 | } 62 | 63 | TEST(FirebaseObjectTest, GetString) { 64 | FirebaseObject obj("\"foo\""); 65 | EXPECT_EQ("foo", obj.getString()); 66 | EXPECT_TRUE(obj.success()); 67 | EXPECT_FALSE(obj.failed()); 68 | EXPECT_EQ(obj.error(), ""); 69 | } 70 | 71 | TEST(FirebaseObjectTest, GetObject) { 72 | { 73 | FirebaseObject obj("{\"foo\":\"bar\"}"); 74 | EXPECT_EQ(obj.getString("/foo"), "bar"); 75 | EXPECT_EQ(obj.getString("foo"), "bar"); 76 | } 77 | { 78 | FirebaseObject obj("{\"foo\": {\"bar\": \"hop\"}}"); 79 | EXPECT_EQ(obj.getString("/foo/bar"), "hop"); 80 | } 81 | } 82 | 83 | TEST(FirebaseObjectTest, GetIntFailure) { 84 | FirebaseObject obj("{\"foo\":\"bar\"}"); 85 | EXPECT_EQ(obj.getInt(), 0); 86 | EXPECT_FALSE(obj.success()); 87 | EXPECT_TRUE(obj.failed()); 88 | EXPECT_EQ(obj.error(), "failed to convert to number"); 89 | } 90 | 91 | TEST(FirebaseObjectTest, GetFloatFailure) { 92 | FirebaseObject obj("{\"foo\":\"bar\"}"); 93 | EXPECT_EQ(obj.getFloat(), 0); 94 | EXPECT_FALSE(obj.success()); 95 | EXPECT_TRUE(obj.failed()); 96 | EXPECT_EQ(obj.error(), "failed to convert to number"); 97 | } 98 | 99 | TEST(FirebaseObjectTest, GetBoolFailure) { 100 | FirebaseObject obj("{\"foo\":\"bar\"}"); 101 | EXPECT_EQ(obj.getBool(), 0); 102 | EXPECT_FALSE(obj.success()); 103 | EXPECT_TRUE(obj.failed()); 104 | EXPECT_EQ(obj.error(), "failed to convert to bool"); 105 | } 106 | 107 | TEST(FirebaseObjectTest, GetStringFailure) { 108 | FirebaseObject obj("{\"foo\":\"bar\"}"); 109 | EXPECT_EQ(obj.getString(), ""); 110 | EXPECT_FALSE(obj.success()); 111 | EXPECT_TRUE(obj.failed()); 112 | EXPECT_EQ(obj.error(), "failed to convert to string"); 113 | } 114 | 115 | TEST(FirebaseObjectTest, GetTwice) { 116 | { 117 | FirebaseObject obj("{\"foo\":\"bar\"}"); 118 | EXPECT_EQ(obj.getString("hop"), ""); 119 | EXPECT_FALSE(obj.success()); 120 | EXPECT_TRUE(obj.failed()); 121 | EXPECT_EQ(obj.error(), "failed to convert to string"); 122 | 123 | EXPECT_EQ(obj.getString("foo"), "bar"); 124 | EXPECT_TRUE(obj.success()); 125 | EXPECT_FALSE(obj.failed()); 126 | EXPECT_EQ(obj.error(), ""); 127 | } 128 | { 129 | FirebaseObject obj("{\"foo\": 42}"); 130 | EXPECT_EQ(obj.getInt("hop"), 0); 131 | EXPECT_FALSE(obj.success()); 132 | EXPECT_TRUE(obj.failed()); 133 | EXPECT_EQ(obj.error(), "failed to convert to number"); 134 | 135 | EXPECT_EQ(obj.getInt("foo"), 42); 136 | EXPECT_TRUE(obj.success()); 137 | EXPECT_FALSE(obj.failed()); 138 | EXPECT_EQ(obj.error(), ""); 139 | } 140 | { 141 | FirebaseObject obj("{\"foo\": true}"); 142 | EXPECT_EQ(obj.getBool("hop"), 0); 143 | EXPECT_FALSE(obj.success()); 144 | EXPECT_TRUE(obj.failed()); 145 | EXPECT_EQ(obj.error(), "failed to convert to bool"); 146 | 147 | EXPECT_EQ(obj.getBool("foo"), true); 148 | EXPECT_TRUE(obj.success()); 149 | EXPECT_FALSE(obj.failed()); 150 | EXPECT_EQ(obj.error(), ""); 151 | } 152 | { 153 | FirebaseObject obj("{\"foo\": 43.1}"); 154 | EXPECT_FLOAT_EQ(obj.getFloat("hop"), 0); 155 | EXPECT_FALSE(obj.success()); 156 | EXPECT_TRUE(obj.failed()); 157 | EXPECT_EQ(obj.error(), "failed to convert to number"); 158 | 159 | EXPECT_FLOAT_EQ(obj.getFloat("foo"), 43.1); 160 | EXPECT_TRUE(obj.success()); 161 | EXPECT_FALSE(obj.failed()); 162 | EXPECT_EQ(obj.error(), ""); 163 | } 164 | } 165 | 166 | 167 | 168 | int main(int argc, char **argv) { 169 | ::testing::InitGoogleTest(&argc, argv); 170 | return RUN_ALL_TESTS(); 171 | } 172 | -------------------------------------------------------------------------------- /contrib/test/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016 Google Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | FIREBASE_DIR=../.. 18 | GTEST_DIR=googletest/googletest 19 | ARDUINOJSON_DIR=${ARDUINO_HOME}/libraries/ArduinoJson 20 | 21 | FIREBASE_SRCS=${FIREBASE_DIR}/src/FirebaseObject.cpp 22 | GTEST_SRCS=${GTEST_DIR}/src/gtest-all.cpp 23 | 24 | SRCS=FirebaseArduino_test.cpp\ 25 | ${FIREBASE_SRCS}\ 26 | ${GTEST_SRCS} 27 | 28 | OBJS=${SRCS:.cpp=.o} 29 | 30 | CXXFLAGS=-I. -I${FIREBASE_DIR}/src -I${ARDUINOJSON_DIR}/src -Igoogletest/googletest/include -Igoogletest/googletest -std=c++11 -g 31 | LDFLAGS=-lpthread 32 | 33 | all: check 34 | 35 | firebase-test: ${OBJS} 36 | ${CXX} -o $@ ${OBJS} ${LDFLAGS} 37 | 38 | check: firebase-test 39 | ./firebase-test 40 | 41 | clean: 42 | rm -f ${OBJS} firebase-test 43 | -------------------------------------------------------------------------------- /contrib/test/WString.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef std::string String; 4 | -------------------------------------------------------------------------------- /contrib/test/dummies/ESP8266HTTPClient.h: -------------------------------------------------------------------------------- 1 | // Need a placeholder for complilation for now. 2 | class HTTPClient {}; 3 | -------------------------------------------------------------------------------- /contrib/test/dummies/FirebaseHttpClient_dummy.cpp: -------------------------------------------------------------------------------- 1 | #ifdef __GNUC__ 2 | # define UNUSED_ARG(x) UNUSED_ ## x __attribute__((__unused__)) 3 | #else 4 | # define UNUSED_ARG(x) UNUSED_ ## x 5 | #endif 6 | 7 | #include "FirebaseHttpClient.h" 8 | 9 | class FirebaseHttpClientDummy : public FirebaseHttpClient { 10 | public: 11 | void setReuseConnection(bool UNUSED_ARG(reuse)) override { 12 | } 13 | 14 | void begin(const std::string& UNUSED_ARG(url)) override { 15 | } 16 | 17 | void begin(const std::string& UNUSED_ARG(host), const std::string& UNUSED_ARG(path)) override { 18 | } 19 | 20 | void end() override { 21 | } 22 | 23 | void addHeader(const std::string& UNUSED_ARG(name), const std::string& UNUSED_ARG(value)) override { 24 | } 25 | 26 | bool connected() override { 27 | return true; 28 | } 29 | 30 | void collectHeaders(const char* UNUSED_ARG(header_keys[]), const int UNUSED_ARG(count)) override { 31 | } 32 | 33 | std::string header(const std::string& UNUSED_ARG(name)) override { 34 | return ""; 35 | } 36 | 37 | int sendRequest(const std::string& UNUSED_ARG(method), const std::string& UNUSED_ARG(data)) override { 38 | return 0; 39 | } 40 | 41 | std::string getString() override { 42 | return ""; 43 | } 44 | 45 | Stream* getStreamPtr() override { 46 | return nullptr; 47 | } 48 | 49 | std::string errorToString(int UNUSED_ARG(error_code)) override { 50 | return std::string(); 51 | } 52 | }; 53 | 54 | FirebaseHttpClient* FirebaseHttpClient::create() { 55 | return new FirebaseHttpClientDummy(); 56 | } 57 | 58 | -------------------------------------------------------------------------------- /contrib/test/dummies/Stream.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_DUMMIES_STREAM_H 2 | #define TEST_DUMMIES_STREAM_H 3 | 4 | #include "Arduino.h" 5 | 6 | class Stream { 7 | public: 8 | virtual int available() { 9 | return 0; 10 | } 11 | 12 | virtual String readStringUntil(const char term __attribute__((unused))) { 13 | return String(); 14 | } 15 | 16 | virtual int println(const String&) { 17 | return 0; 18 | } 19 | 20 | virtual int println(const char*) { 21 | return 0; 22 | } 23 | 24 | virtual int println(int) { 25 | return 0; 26 | } 27 | 28 | virtual int print(const char*) { 29 | return 0; 30 | } 31 | 32 | virtual char peek() { 33 | return '\0'; 34 | } 35 | 36 | virtual char read() { 37 | return '\0'; 38 | } 39 | }; 40 | 41 | #endif // TEST_DUMMIES_STREAM_H 42 | -------------------------------------------------------------------------------- /contrib/test/dummies/WString.h: -------------------------------------------------------------------------------- 1 | // Arduino.h includes our String overrides. 2 | #include 3 | -------------------------------------------------------------------------------- /contrib/test/mock-firebase.h: -------------------------------------------------------------------------------- 1 | #ifndef TEST_MOCK_FIREBASE_H 2 | #define TEST_MOCK_FIREBASE_H 3 | 4 | #include 5 | #include "gtest/gtest.h" 6 | #include "FirebaseArduino.h" 7 | 8 | namespace firebase { 9 | namespace modem { 10 | 11 | class MockFirebase : public FirebaseArduino { 12 | public: 13 | MOCK_METHOD0(error, const String &()); 14 | MOCK_METHOD1(getString, String (const String& path)); 15 | MOCK_METHOD2(pushString, String (const String& path, const String& data)); 16 | MOCK_METHOD1(remove, void(const String& path)); 17 | MOCK_METHOD2(setString, void(const String& path, const String& data)); 18 | MOCK_METHOD0(available, bool ()); 19 | MOCK_METHOD0(readEvent, FirebaseObject ()); 20 | MOCK_METHOD2(begin, void (const String& host, const String& auth)); 21 | MOCK_METHOD1(stream, void (const String& path)); 22 | }; 23 | 24 | } // modem 25 | } // firebase 26 | #endif // TEST_MOCK_FIREBASE_H 27 | -------------------------------------------------------------------------------- /contrib/test/modem/Makefile: -------------------------------------------------------------------------------- 1 | # A sample Makefile for building both Google Mock and Google Test and 2 | # using them in user tests. This file is self-contained, so you don't 3 | # need to use the Makefile in Google Test's source tree. Please tweak 4 | # it to suit your environment and project. You may want to move it to 5 | # your project's root directory. 6 | # 7 | # SYNOPSIS: 8 | # 9 | # make [all] - makes everything. 10 | # make TARGET - makes the given target. 11 | # make clean - removes all files generated by make. 12 | 13 | # Please tweak the following variable definitions as needed by your 14 | # project, except GMOCK_HEADERS and GTEST_HEADERS, which you can use 15 | # in your own targets but shouldn't modify. 16 | 17 | # Points to the root of Google Test, relative to where this file is. 18 | # Remember to tweak this if you move this file, or if you want to use 19 | # a copy of Google Test at a different location. 20 | GTEST_DIR = ../googletest/googletest/ 21 | 22 | # Points to the root of Google Mock, relative to where this file is. 23 | # Remember to tweak this if you move this file. 24 | GMOCK_DIR = ../googletest/googlemock/ 25 | 26 | # Points to the root of Arduino mock, relative to where this file is. 27 | # Remember to tweak this if you move this file. 28 | ARDUINO_MOCK_DIR = ../arduino-mock/ 29 | 30 | # Where to find user code. 31 | TEST_DIR = . 32 | 33 | FIREBASE_ROOT = ../../.. 34 | PROJECT_ROOT = ../.. 35 | SRC_ROOT = $(PROJECT_ROOT)/src 36 | FIREBASE_SRC_ROOT = $(FIREBASE_ROOT)/src 37 | ARDUINOJSON_DIR=$(ARDUINO_HOME)/libraries/ArduinoJson 38 | 39 | # Flags passed to the preprocessor. 40 | # Set Google Test and Google Mock's header directories as system 41 | # directories, such that the compiler doesn't generate warnings in 42 | # these headers. 43 | CPPFLAGS += -isystem $(GTEST_DIR)/include -isystem $(GMOCK_DIR)/include \ 44 | -I$(ARDUINO_MOCK_DIR)/include/arduino-mock/ \ 45 | -I$(ARDUINO_MOCK_DIR)/include/ \ 46 | -I$(PROJECT_ROOT)/test/dummies \ 47 | -I$(PROJECT_ROOT)/src \ 48 | -I$(FIREBASE_ROOT)/src \ 49 | -I$(ARDUINOJSON_DIR)/src \ 50 | -I$(PROJECT_ROOT) 51 | 52 | # Flags passed to the C++ compiler. 53 | CXXFLAGS += -g -Wall -Wextra -pthread -std=c++11 54 | 55 | # All tests produced by this Makefile. Remember to add new tests you 56 | # created to the list. 57 | TESTS = get-command_test set-command_test remove-command_test \ 58 | push-command_test begin-command_test \ 59 | serial-transceiver_test stream-command_test 60 | 61 | # All Google Test headers. Usually you shouldn't change this 62 | # definition. 63 | GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ 64 | $(GTEST_DIR)/include/gtest/internal/*.h 65 | 66 | # All Google Mock headers. Note that all Google Test headers are 67 | # included here too, as they are #included by Google Mock headers. 68 | # Usually you shouldn't change this definition. 69 | GMOCK_HEADERS = $(GMOCK_DIR)/include/gmock/*.h \ 70 | $(GMOCK_DIR)/include/gmock/internal/*.h \ 71 | $(GTEST_HEADERS) 72 | 73 | # Arduino Mock headers. 74 | # Usually you shouldn't change this definition. 75 | ARDUINO_MOCK_HEADERS = $(ARDUINO_MOCK_DIR)/include/arduino-mock/*.h 76 | 77 | # House-keeping build targets. 78 | 79 | all : $(TESTS) 80 | 81 | test : $(TESTS) 82 | for t in $(TESTS); do ./$$t; done; 83 | 84 | clean : 85 | rm -f $(TESTS) gmock.a gmock_main.a arduino_mock_all.a *.o 86 | 87 | # Builds gmock.a and gmock_main.a. These libraries contain both 88 | # Google Mock and Google Test. A test should link with either gmock.a 89 | # or gmock_main.a, depending on whether it defines its own main() 90 | # function. It's fine if your test only uses features from Google 91 | # Test (and not Google Mock). 92 | 93 | # Usually you shouldn't tweak such internal variables, indicated by a 94 | # trailing _. 95 | GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS) 96 | GMOCK_SRCS_ = $(GMOCK_DIR)/src/*.cc $(GMOCK_HEADERS) 97 | ARDUINO_MOCK_SRCS_ = $(ARDUINO_MOCK_DIR)/src/*.cc $(ARDUINO_MOCK_HEADERS) 98 | 99 | # For simplicity and to avoid depending on implementation details of 100 | # Google Mock and Google Test, the dependencies specified below are 101 | # conservative and not optimized. This is fine as Google Mock and 102 | # Google Test compile fast and for ordinary users their source rarely 103 | # changes. 104 | gtest-all.o : $(GTEST_SRCS_) 105 | $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \ 106 | -c $(GTEST_DIR)/src/gtest-all.cc 107 | 108 | gmock-all.o : $(GMOCK_SRCS_) 109 | $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \ 110 | -c $(GMOCK_DIR)/src/gmock-all.cc 111 | 112 | gmock_main.o : $(GMOCK_SRCS_) 113 | $(CXX) $(CPPFLAGS) -I$(GTEST_DIR) -I$(GMOCK_DIR) $(CXXFLAGS) \ 114 | -c $(GMOCK_DIR)/src/gmock_main.cc 115 | 116 | gmock.a : gmock-all.o gtest-all.o 117 | $(AR) $(ARFLAGS) $@ $^ 118 | 119 | gmock_main.a : gmock-all.o gtest-all.o gmock_main.o 120 | $(AR) $(ARFLAGS) $@ $^ 121 | 122 | 123 | # Builds Arduino mocks. 124 | ArduinoMockAll.o : $(ARDUINO_MOCK_SRCS_) 125 | $(CXX) $(CPPFLAGS) -I$(ARDUINO_MOCK_DIR) $(CXXFLAGS) -c \ 126 | $(ARDUINO_MOCK_DIR)/src/ArduinoMockAll.cc 127 | 128 | arduino_mock_all.a : ArduinoMockAll.o 129 | $(AR) $(ARFLAGS) $@ $^ 130 | 131 | # Builds shared objects. 132 | 133 | FirebaseArduino.o : $(FIREBASE_SRC_ROOT)/FirebaseArduino.cpp 134 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FIREBASE_SRC_ROOT)/FirebaseArduino.cpp 135 | 136 | FirebaseObject.o : $(FIREBASE_SRC_ROOT)/FirebaseObject.cpp 137 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FIREBASE_SRC_ROOT)/FirebaseObject.cpp 138 | 139 | Firebase.o : $(FIREBASE_SRC_ROOT)/Firebase.cpp 140 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(FIREBASE_SRC_ROOT)/Firebase.cpp 141 | 142 | FirebaseHttpClient_dummy.o : $(PROJECT_ROOT)/test/dummies/FirebaseHttpClient_dummy.cpp 143 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(PROJECT_ROOT)/test/dummies/FirebaseHttpClient_dummy.cpp 144 | 145 | # Builds tests. 146 | 147 | get-command.o : $(SRC_ROOT)/modem/db/get-command.cpp 148 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_ROOT)/modem/db/get-command.cpp 149 | 150 | get-command_test.o : $(TEST_DIR)/get-command_test.cpp $(GMOCK_HEADERS) 151 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TEST_DIR)/get-command_test.cpp 152 | 153 | get-command_test : get-command_test.o FirebaseArduino.o Firebase.o FirebaseObject.o FirebaseHttpClient_dummy.o get-command.o gmock_main.a \ 154 | arduino_mock_all.a 155 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ 156 | 157 | 158 | set-command.o : $(SRC_ROOT)/modem/db/set-command.cpp 159 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_ROOT)/modem/db/set-command.cpp 160 | 161 | set-command_test.o : $(TEST_DIR)/set-command_test.cpp $(GMOCK_HEADERS) 162 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TEST_DIR)/set-command_test.cpp 163 | 164 | set-command_test : set-command.o set-command_test.o FirebaseArduino.o Firebase.o FirebaseObject.o FirebaseHttpClient_dummy.o gmock_main.a \ 165 | arduino_mock_all.a 166 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ 167 | 168 | 169 | remove-command.o : $(SRC_ROOT)/modem/db/remove-command.cpp 170 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_ROOT)/modem/db/remove-command.cpp 171 | 172 | remove-command_test.o : $(TEST_DIR)/remove-command_test.cpp $(GMOCK_HEADERS) 173 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TEST_DIR)/remove-command_test.cpp 174 | 175 | remove-command_test : remove-command.o remove-command_test.o FirebaseArduino.o Firebase.o FirebaseObject.o FirebaseHttpClient_dummy.o gmock_main.a \ 176 | arduino_mock_all.a 177 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ 178 | 179 | 180 | push-command.o : $(SRC_ROOT)/modem/db/push-command.cpp 181 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_ROOT)/modem/db/push-command.cpp 182 | 183 | push-command_test.o : $(TEST_DIR)/push-command_test.cpp $(GMOCK_HEADERS) 184 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TEST_DIR)/push-command_test.cpp 185 | 186 | push-command_test : push-command.o push-command_test.o FirebaseArduino.o Firebase.o FirebaseObject.o FirebaseHttpClient_dummy.o gmock_main.a \ 187 | arduino_mock_all.a 188 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ 189 | 190 | 191 | begin-command.o : $(SRC_ROOT)/modem/db/begin-command.cpp 192 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_ROOT)/modem/db/begin-command.cpp 193 | 194 | begin-command_test.o : $(TEST_DIR)/begin-command_test.cpp $(GMOCK_HEADERS) 195 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TEST_DIR)/begin-command_test.cpp 196 | 197 | begin-command_test : begin-command.o begin-command_test.o FirebaseArduino.o Firebase.o FirebaseObject.o FirebaseHttpClient_dummy.o gmock_main.a \ 198 | arduino_mock_all.a 199 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ 200 | 201 | 202 | stream-command.o : $(SRC_ROOT)/modem/db/stream-command.cpp 203 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_ROOT)/modem/db/stream-command.cpp 204 | 205 | stream-command_test.o : $(TEST_DIR)/stream-command_test.cpp $(GMOCK_HEADERS) 206 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TEST_DIR)/stream-command_test.cpp 207 | 208 | stream-command_test : stream-command.o stream-command_test.o FirebaseArduino.o Firebase.o FirebaseObject.o FirebaseHttpClient_dummy.o gmock_main.a \ 209 | arduino_mock_all.a 210 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ 211 | 212 | 213 | SerialTransceiver.o : $(SRC_ROOT)/modem/SerialTransceiver.cpp 214 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(SRC_ROOT)/modem/SerialTransceiver.cpp 215 | 216 | serial-transceiver_test.o : $(TEST_DIR)/serial-transceiver_test.cpp $(GMOCK_HEADERS) 217 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(TEST_DIR)/serial-transceiver_test.cpp 218 | 219 | serial-transceiver_test : SerialTransceiver.o serial-transceiver_test.o gmock_main.a arduino_mock_all.a 220 | $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@ 221 | 222 | -------------------------------------------------------------------------------- /contrib/test/modem/WString.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef std::string String; 4 | -------------------------------------------------------------------------------- /contrib/test/modem/begin-command_test.cpp: -------------------------------------------------------------------------------- 1 | #include "FirebaseArduino.h" 2 | #include "gtest/gtest.h" 3 | #include "modem/db/commands.h" 4 | #include "test/modem/mock-input-stream.h" 5 | #include "test/modem/mock-output-stream.h" 6 | #include "test/mock-firebase.h" 7 | 8 | namespace firebase { 9 | namespace modem { 10 | 11 | using ::testing::Return; 12 | using ::testing::ByMove; 13 | using ::testing::ReturnRef; 14 | using ::testing::StartsWith; 15 | using ::testing::Matcher; 16 | using ::testing::_; 17 | 18 | class BeginCommandTest : public ::testing::Test { 19 | protected: 20 | void FeedCommand(const String& host, const String& auth = "") { 21 | String command_fragment(host); 22 | if (!auth.empty()) { 23 | command_fragment += String(" ") + auth; 24 | } 25 | 26 | EXPECT_CALL(in_, readLine()) 27 | .WillOnce(Return(command_fragment)); 28 | } 29 | 30 | void ExpectOutput(const String& output) { 31 | EXPECT_CALL(out_, println(output)) 32 | .WillOnce(Return(3)); 33 | } 34 | 35 | void ExpectOutputStartsWith(const String& output) { 36 | // We have to be explicit here due to the polymorphic nature of println(). 37 | const Matcher matcher = StartsWith(output); 38 | EXPECT_CALL(out_, println(matcher)) 39 | .WillOnce(Return(3)); 40 | } 41 | 42 | MockInputStream in_; 43 | MockOutputStream out_; 44 | }; 45 | 46 | TEST_F(BeginCommandTest, hostOnly) { 47 | const String host("http://test.firebase.com"); 48 | 49 | FeedCommand(host); 50 | ExpectOutput("+OK"); 51 | 52 | BeginCommand command; 53 | ASSERT_TRUE(command.execute("BEGIN_DB", &in_, &out_)); 54 | 55 | std::unique_ptr firebase(command.firebase()); 56 | } 57 | 58 | TEST_F(BeginCommandTest, hostAndAuth) { 59 | const String host("http://test.firebase.com"); 60 | const String auth("afasdfsadfasdssfadsfsd"); 61 | 62 | FeedCommand(host, auth); 63 | ExpectOutput("+OK"); 64 | 65 | BeginCommand command; 66 | ASSERT_TRUE(command.execute("BEGIN_DB", &in_, &out_)); 67 | 68 | std::unique_ptr firebase(command.firebase()); 69 | } 70 | 71 | TEST_F(BeginCommandTest, neitherHostNorAuth) { 72 | FeedCommand(""); 73 | ExpectOutputStartsWith("-FAIL"); 74 | 75 | BeginCommand command; 76 | ASSERT_FALSE(command.execute("BEGIN_DB", &in_, &out_)); 77 | 78 | std::unique_ptr firebase(command.firebase()); 79 | EXPECT_FALSE(firebase); 80 | } 81 | } // modem 82 | } // firebase 83 | -------------------------------------------------------------------------------- /contrib/test/modem/get-command_test.cpp: -------------------------------------------------------------------------------- 1 | #include "FirebaseArduino.h" 2 | #include "gtest/gtest.h" 3 | #include "modem/db/commands.h" 4 | #include "test/modem/mock-input-stream.h" 5 | #include "test/modem/mock-output-stream.h" 6 | #include "test/mock-firebase.h" 7 | 8 | namespace firebase { 9 | namespace modem { 10 | 11 | using ::testing::Return; 12 | using ::testing::ByMove; 13 | using ::testing::ReturnRef; 14 | using ::testing::_; 15 | 16 | class GetCommandTest : public ::testing::Test { 17 | protected: 18 | void SetUp() override { 19 | } 20 | 21 | void FeedCommand(const String& path) { 22 | const String command_fragment(String(" ") + path); 23 | EXPECT_CALL(in_, readLine()) 24 | .WillOnce(Return(command_fragment)); 25 | } 26 | 27 | bool RunCommand(const FirebaseError& error) { 28 | GetCommand getCmd(&fbase_); 29 | return getCmd.execute("GET", &in_, &out_); 30 | } 31 | 32 | MockInputStream in_; 33 | MockOutputStream out_; 34 | MockFirebase fbase_; 35 | }; 36 | 37 | TEST_F(GetCommandTest, gets) { 38 | const String path("/test/path"); 39 | const String command_fragment(" /test/path"); 40 | FeedCommand(path); 41 | 42 | const String value("Test value"); 43 | EXPECT_CALL(fbase_, getString(command_fragment)).WillOnce(Return("Test value")); 44 | 45 | const String no_error = ""; 46 | EXPECT_CALL(fbase_, error()).WillOnce(ReturnRef(no_error)); 47 | 48 | EXPECT_CALL(out_, print(String("+"))) 49 | .WillOnce(Return(1)); 50 | 51 | EXPECT_CALL(out_, println(value)) 52 | .WillOnce(Return(1)); 53 | 54 | ASSERT_TRUE(RunCommand(FirebaseError())); 55 | } 56 | 57 | TEST_F(GetCommandTest, handlesError) { 58 | FirebaseError error(-200, "Test Error."); 59 | const String command_fragment(" /test/path"); 60 | const String path("/test/path"); 61 | FeedCommand(path); 62 | 63 | const String error_value = "Test Error."; 64 | EXPECT_CALL(fbase_, error()).WillRepeatedly(ReturnRef(error_value)); 65 | 66 | EXPECT_CALL(fbase_, getString(command_fragment)).WillOnce(Return("")); 67 | 68 | EXPECT_CALL(out_, print(String("-FAIL "))) 69 | .WillOnce(Return(1)); 70 | 71 | EXPECT_CALL(out_, println(error_value)) 72 | .WillOnce(Return(1)); 73 | ASSERT_FALSE(RunCommand(error)); 74 | 75 | } 76 | 77 | } // modem 78 | } // firebase 79 | -------------------------------------------------------------------------------- /contrib/test/modem/mock-input-stream.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEM_TEST_MOCK_INPUT_STREAM_H 2 | #define MODEM_TEST_MOCK_INPUT_STREAM_H 3 | 4 | #include "gtest/gtest.h" 5 | #include "modem/input-stream.h" 6 | 7 | namespace firebase { 8 | namespace modem { 9 | 10 | class MockInputStream : public InputStream { 11 | public: 12 | MOCK_METHOD0(readLine, String ()); 13 | MOCK_METHOD1(readStringUntil, String (const char)); 14 | MOCK_METHOD0(drain, void ()); 15 | MOCK_METHOD0(available, bool ()); 16 | }; 17 | 18 | } // modem 19 | } // firebase 20 | 21 | #endif //MODEM_TEST_MOCK_INPUT_STREAM_H 22 | -------------------------------------------------------------------------------- /contrib/test/modem/mock-output-stream.h: -------------------------------------------------------------------------------- 1 | #ifndef MODEM_TEST_MOCK_OUTPUT_STREAM_H 2 | #define MODEM_TEST_MOCK_OUTPUT_STREAM_H 3 | 4 | #include "gtest/gtest.h" 5 | #include "modem/output-stream.h" 6 | 7 | namespace firebase { 8 | namespace modem { 9 | 10 | class MockOutputStream : public OutputStream { 11 | public: 12 | MOCK_METHOD1(println, int (const String&)); 13 | MOCK_METHOD1(println, int (const int)); 14 | MOCK_METHOD1(print, int (const String&)); 15 | }; 16 | 17 | } // modem 18 | } // firebase 19 | 20 | #endif //MODEM_TEST_MOCK_OUTPUT_STREAM_H 21 | 22 | -------------------------------------------------------------------------------- /contrib/test/modem/push-command_test.cpp: -------------------------------------------------------------------------------- 1 | #include "FirebaseArduino.h" 2 | #include "gtest/gtest.h" 3 | #include "modem/db/commands.h" 4 | #include "modem/json_util.h" 5 | #include "test/modem/mock-input-stream.h" 6 | #include "test/modem/mock-output-stream.h" 7 | #include "test/mock-firebase.h" 8 | 9 | namespace firebase { 10 | namespace modem { 11 | 12 | using ::testing::Return; 13 | using ::testing::ByMove; 14 | using ::testing::ReturnRef; 15 | using ::testing::_; 16 | 17 | class PushCommandTest : public ::testing::Test { 18 | protected: 19 | void SetUp() override { 20 | } 21 | 22 | void FeedCommand(const String& path, const String& data) { 23 | const String data_fragment(data); 24 | EXPECT_CALL(in_, readStringUntil(' ')) 25 | .WillOnce(Return(path)); 26 | EXPECT_CALL(in_, readLine()) 27 | .WillOnce(Return(data_fragment)); 28 | } 29 | 30 | void ExpectOutput(const String& output) { 31 | EXPECT_CALL(out_, println(output)) 32 | .WillOnce(Return(output.length())); 33 | } 34 | 35 | void ExpectErrorOutput(const String& error_message) { 36 | EXPECT_CALL(out_, print(String("-FAIL "))) 37 | .WillOnce(Return(5)); 38 | EXPECT_CALL(out_, println(error_message)) 39 | .WillOnce(Return(error_message.length())); 40 | } 41 | 42 | bool RunCommand() { 43 | PushCommand pushCmd(&fbase_); 44 | return pushCmd.execute("PUSH", &in_, &out_); 45 | } 46 | 47 | MockInputStream in_; 48 | MockOutputStream out_; 49 | MockFirebase fbase_; 50 | }; 51 | 52 | TEST_F(PushCommandTest, sendsData) { 53 | const String path("/test/path"); 54 | const String data("This is a test payload."); 55 | 56 | FeedCommand(path, data); 57 | const String no_error = ""; 58 | EXPECT_CALL(fbase_, error()).WillOnce(ReturnRef(no_error)); 59 | 60 | ExpectOutput("+OK"); 61 | 62 | ASSERT_TRUE(RunCommand()); 63 | } 64 | 65 | TEST_F(PushCommandTest, HandlesError) { 66 | const String path("/test/path"); 67 | const String data("This is a test payload."); 68 | 69 | FeedCommand(path, data); 70 | const String error = "Test Error."; 71 | EXPECT_CALL(fbase_, error()).WillRepeatedly(ReturnRef(error)); 72 | 73 | ExpectErrorOutput(error); 74 | 75 | ASSERT_FALSE(RunCommand()); 76 | } 77 | 78 | } // modem 79 | } // firebase 80 | -------------------------------------------------------------------------------- /contrib/test/modem/remove-command_test.cpp: -------------------------------------------------------------------------------- 1 | #include "gtest/gtest.h" 2 | #include "test/modem/mock-output-stream.h" 3 | #include "test/modem/mock-input-stream.h" 4 | #include "test/mock-firebase.h" 5 | #include "FirebaseArduino.h" 6 | #include "modem/db/commands.h" 7 | 8 | namespace firebase { 9 | namespace modem { 10 | 11 | using ::testing::Return; 12 | using ::testing::ByMove; 13 | using ::testing::ReturnRef; 14 | using ::testing::_; 15 | 16 | class RemoveCommandTest : public ::testing::Test { 17 | protected: 18 | void SetUp() override { 19 | } 20 | 21 | void FeedCommand(const String& path) { 22 | const String command_fragment(String(" ") + path); 23 | EXPECT_CALL(in_, readLine()) 24 | .WillOnce(Return(command_fragment)); 25 | } 26 | 27 | bool RunCommand() { 28 | RemoveCommand command(&fbase_); 29 | return command.execute("REMOVE", &in_, &out_); 30 | } 31 | 32 | MockInputStream in_; 33 | MockOutputStream out_; 34 | MockFirebase fbase_; 35 | }; 36 | 37 | TEST_F(RemoveCommandTest, success) { 38 | const String path("/test/path"); 39 | FeedCommand(path); 40 | 41 | const String no_error = ""; 42 | EXPECT_CALL(fbase_, error()).WillOnce(ReturnRef(no_error)); 43 | 44 | EXPECT_CALL(out_, println(String("+OK"))) 45 | .WillOnce(Return(3)); 46 | 47 | ASSERT_TRUE(RunCommand()); 48 | } 49 | 50 | TEST_F(RemoveCommandTest, handlesError) { 51 | const String path("/test/path"); 52 | FeedCommand(path); 53 | 54 | EXPECT_CALL(out_, print(String("-FAIL "))) 55 | .WillOnce(Return(1)); 56 | 57 | const String error = "Test Error."; 58 | EXPECT_CALL(fbase_, error()).WillRepeatedly(ReturnRef(error)); 59 | 60 | EXPECT_CALL(out_, println(String(error.c_str()))) 61 | .WillOnce(Return(1)); 62 | ASSERT_FALSE(RunCommand()); 63 | } 64 | 65 | } // modem 66 | } // firebase 67 | -------------------------------------------------------------------------------- /contrib/test/modem/serial-transceiver_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "FirebaseArduino.h" 4 | #include "gtest/gtest.h" 5 | #include "modem/SerialTransceiver.h" 6 | 7 | namespace firebase { 8 | namespace modem { 9 | 10 | using ::testing::Return; 11 | using ::testing::ReturnRef; 12 | using ::testing::_; 13 | 14 | class MockSerialProtocol : public SerialProtocol { 15 | public: 16 | MOCK_CONST_METHOD0(commands, const std::vector&()); 17 | MOCK_METHOD3(Execute, void(const String&, InputStream*, OutputStream*)); 18 | }; 19 | 20 | class MockStream : public Stream { 21 | public: 22 | MOCK_METHOD1(readStringUntil, String(char)); 23 | }; 24 | 25 | class SerialTranscieverTest : public ::testing::Test { 26 | }; 27 | 28 | TEST_F(SerialTranscieverTest, delegatesCommand) { 29 | const String good_command = "GOOD"; 30 | const std::vector commands{good_command}; 31 | 32 | MockStream serial; 33 | EXPECT_CALL(serial, readStringUntil(' ')) 34 | .WillOnce(Return(good_command)); 35 | 36 | MockSerialProtocol* protocol = new MockSerialProtocol(); 37 | EXPECT_CALL(*protocol, commands()) 38 | .WillOnce(ReturnRef(commands)); 39 | EXPECT_CALL(*protocol, Execute(good_command, _, _)); 40 | 41 | SerialTransceiver transceiver; 42 | transceiver.RegisterProtocol(std::unique_ptr(protocol)); 43 | transceiver.begin(static_cast(&serial)); 44 | transceiver.loop(); 45 | } 46 | 47 | TEST_F(SerialTranscieverTest, doesNotDelegateInvalidCommand) { 48 | const String good_command = "GOOD"; 49 | const String bad_command = "BAD"; 50 | const std::vector commands{good_command}; 51 | 52 | MockStream serial; 53 | EXPECT_CALL(serial, readStringUntil(' ')) 54 | .WillOnce(Return(bad_command)); 55 | 56 | MockSerialProtocol* protocol = new MockSerialProtocol(); 57 | EXPECT_CALL(*protocol, commands()) 58 | .WillOnce(ReturnRef(commands)); 59 | EXPECT_CALL(*protocol, Execute(bad_command, _, _)) 60 | .Times(0); 61 | 62 | SerialTransceiver transceiver; 63 | transceiver.RegisterProtocol(std::unique_ptr(protocol)); 64 | transceiver.begin(static_cast(&serial)); 65 | transceiver.loop(); 66 | } 67 | 68 | 69 | } // namespace modem 70 | } // namespace firebase 71 | -------------------------------------------------------------------------------- /contrib/test/modem/set-command_test.cpp: -------------------------------------------------------------------------------- 1 | #include "FirebaseArduino.h" 2 | #include "gtest/gtest.h" 3 | #include "modem/db/commands.h" 4 | #include "modem/json_util.h" 5 | #include "test/modem/mock-input-stream.h" 6 | #include "test/modem/mock-output-stream.h" 7 | #include "test/mock-firebase.h" 8 | 9 | namespace firebase { 10 | namespace modem { 11 | 12 | using ::testing::Return; 13 | using ::testing::ByMove; 14 | using ::testing::ReturnRef; 15 | using ::testing::_; 16 | 17 | class SetCommandTest : public ::testing::Test { 18 | protected: 19 | void SetUp() override { 20 | } 21 | 22 | void FeedCommand(const String& path, const String& data) { 23 | const String data_fragment(data); 24 | EXPECT_CALL(in_, readStringUntil(' ')) 25 | .WillOnce(Return(path)); 26 | EXPECT_CALL(in_, readLine()) 27 | .WillOnce(Return(data_fragment)); 28 | } 29 | 30 | void ExpectOutput(const String& output) { 31 | EXPECT_CALL(out_, println(output)) 32 | .WillOnce(Return(3)); 33 | } 34 | 35 | void ExpectErrorOutput(const String& error_message) { 36 | EXPECT_CALL(out_, print(String("-FAIL "))) 37 | .WillOnce(Return(5)); 38 | EXPECT_CALL(out_, println(error_message)) 39 | .WillOnce(Return(error_message.length())); 40 | } 41 | 42 | bool RunCommand() { 43 | SetCommand setCmd(&fbase_); 44 | return setCmd.execute("SET", &in_, &out_); 45 | } 46 | 47 | MockInputStream in_; 48 | MockOutputStream out_; 49 | MockFirebase fbase_; 50 | }; 51 | 52 | TEST_F(SetCommandTest, sendsData) { 53 | const String path("/test/path"); 54 | const String data("This is a test payload."); 55 | const String no_error = ""; 56 | EXPECT_CALL(fbase_, error()).WillOnce(ReturnRef(no_error)); 57 | 58 | FeedCommand(path, data); 59 | ExpectOutput("+OK"); 60 | 61 | ASSERT_TRUE(RunCommand()); 62 | } 63 | 64 | TEST_F(SetCommandTest, HandlesError) { 65 | const String path("/test/path"); 66 | const String data("This is a test payload."); 67 | const String error = "TestError"; 68 | EXPECT_CALL(fbase_, error()).WillRepeatedly(ReturnRef(error)); 69 | 70 | FeedCommand(path, data); 71 | ExpectErrorOutput(error); 72 | 73 | ASSERT_FALSE(RunCommand()); 74 | } 75 | } // modem 76 | } // firebase 77 | -------------------------------------------------------------------------------- /contrib/test/modem/stream-command_test.cpp: -------------------------------------------------------------------------------- 1 | #include "FirebaseArduino.h" 2 | #include "gtest/gtest.h" 3 | #include "modem/db/commands.h" 4 | #include "test/modem/mock-input-stream.h" 5 | #include "test/modem/mock-output-stream.h" 6 | #include "test/mock-firebase.h" 7 | 8 | namespace firebase { 9 | namespace modem { 10 | 11 | using ::testing::Return; 12 | using ::testing::Invoke; 13 | using ::testing::ByMove; 14 | using ::testing::ReturnRef; 15 | using ::testing::_; 16 | 17 | class StreamCommandTest : public ::testing::Test { 18 | protected: 19 | void SetUp() override { 20 | } 21 | 22 | bool RunCommand() { 23 | StreamCommand cmd(&fbase_); 24 | return cmd.execute("BEGIN_STREAM", &in_, &out_); 25 | } 26 | 27 | MockInputStream in_; 28 | MockOutputStream out_; 29 | MockFirebase fbase_; 30 | }; 31 | 32 | TEST_F(StreamCommandTest, streams) { 33 | const String path("/test/path"); 34 | 35 | const String no_error = ""; 36 | EXPECT_CALL(fbase_, error()).WillRepeatedly(ReturnRef(no_error)); 37 | 38 | const String data = "TestValue"; 39 | const String value(String("{\"path\":\"/test/path\",\"data\":\"") + data + "\",\"type\":\"PUT\"}"); 40 | 41 | const FirebaseObject fo = FirebaseObject(value.c_str()); 42 | EXPECT_CALL(fbase_, readEvent()).WillRepeatedly(Return(fo)); 43 | 44 | EXPECT_CALL(in_, available()) 45 | .WillRepeatedly(Return(true)); 46 | 47 | EXPECT_CALL(in_, readLine()) 48 | .WillOnce(Return(path)) 49 | .WillOnce(Return("END_STREAM")); 50 | 51 | EXPECT_CALL(fbase_, available()) 52 | .WillOnce(Return(true)) 53 | .WillRepeatedly(Return(false)); 54 | EXPECT_CALL(fbase_, stream(path)); 55 | 56 | EXPECT_CALL(out_, print(String("+"))) 57 | .WillOnce(Return(1)); 58 | EXPECT_CALL(out_, print(String("PUT"))) 59 | .WillOnce(Return(1)); 60 | EXPECT_CALL(out_, print(String(" "))) 61 | .WillOnce(Return(1)); 62 | EXPECT_CALL(out_, println(path)) 63 | .WillOnce(Return(1)); 64 | 65 | EXPECT_CALL(out_, println(data.length())) 66 | .WillOnce(Return(1)); 67 | EXPECT_CALL(out_, println(data)) 68 | .WillOnce(Return(1)); 69 | 70 | EXPECT_CALL(out_, println(String("+OK"))) 71 | .WillOnce(Return(1)); 72 | 73 | ASSERT_TRUE(RunCommand()); 74 | } 75 | 76 | TEST_F(StreamCommandTest, handlesError) { 77 | const String error("Test Error."); 78 | const String path("/test/path"); 79 | EXPECT_CALL(in_, readLine()) 80 | .WillOnce(Return(path)); 81 | 82 | EXPECT_CALL(fbase_, error()).WillRepeatedly(ReturnRef(error)); 83 | 84 | EXPECT_CALL(out_, print(String("-FAIL "))) 85 | .WillOnce(Return(1)); 86 | 87 | EXPECT_CALL(out_, println(String(error.c_str()))) 88 | .WillOnce(Return(1)); 89 | ASSERT_FALSE(RunCommand()); 90 | } 91 | 92 | } // modem 93 | } // firebase 94 | -------------------------------------------------------------------------------- /contrib/test/travis/check_all_examples_use_standard_init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | FBASE_SNIPPET=contrib/test/travis/firebase_init.cc.snip 3 | FBASE_NOAUTH_SNIPPET=contrib/test/travis/no_firebase_init.cc.snip 4 | FBASE_NOCONFIG_SNIPPET=contrib/test/travis/no_config_init.cc.snip 5 | for example in `find examples/ contrib/examples/ -name *.ino`; 6 | do 7 | echo $example; 8 | (xxd -p $example | tr -d '\n' | grep -q `xxd -p $FBASE_SNIPPET | tr -d '\n'`) || 9 | (xxd -p $example | tr -d '\n' | grep -q `xxd -p $FBASE_NOAUTH_SNIPPET | tr -d '\n'`) || 10 | (xxd -p $example | tr -d '\n' | grep -q `xxd -p $FBASE_NOCONFIG_SNIPPET | tr -d '\n'`) || 11 | if [ $? -ne 0 ]; 12 | then 13 | echo $example does not contain standard defined in contrib/test/travis/*_init.cc.snip. 14 | exit 1; 15 | fi; 16 | done; 17 | -------------------------------------------------------------------------------- /contrib/test/travis/firebase_init.cc.snip: -------------------------------------------------------------------------------- 1 | // Set these to run example. 2 | #define FIREBASE_HOST "example.firebaseio.com" 3 | #define FIREBASE_AUTH "token_or_secret" 4 | #define WIFI_SSID "SSID" 5 | #define WIFI_PASSWORD "PASSWORD" 6 | -------------------------------------------------------------------------------- /contrib/test/travis/no_config_init.cc.snip: -------------------------------------------------------------------------------- 1 | // No config variables. 2 | -------------------------------------------------------------------------------- /contrib/test/travis/no_firebase_init.cc.snip: -------------------------------------------------------------------------------- 1 | // Set these to run example. 2 | #define WIFI_SSID "SSID" 3 | #define WIFI_PASSWORD "PASSWORD" 4 | -------------------------------------------------------------------------------- /docs/read_the_docs/Doxyfile: -------------------------------------------------------------------------------- 1 | DOXYFILE_ENCODING = UTF-8 2 | PROJECT_NAME = firebase-arduino 3 | PROJECT_NUMBER = 4 | PROJECT_BRIEF = 5 | PROJECT_LOGO = 6 | OUTPUT_DIRECTORY = . 7 | CREATE_SUBDIRS = NO 8 | ALLOW_UNICODE_NAMES = NO 9 | OUTPUT_LANGUAGE = English 10 | BRIEF_MEMBER_DESC = YES 11 | REPEAT_BRIEF = YES 12 | ABBREVIATE_BRIEF = "The $name class" "The $name widget" "The $name file" is provides specifies contains represents a an the 13 | ALWAYS_DETAILED_SEC = NO 14 | INLINE_INHERITED_MEMB = NO 15 | FULL_PATH_NAMES = YES 16 | SHORT_NAMES = NO 17 | JAVADOC_AUTOBRIEF = YES 18 | QT_AUTOBRIEF = NO 19 | MULTILINE_CPP_IS_BRIEF = NO 20 | INHERIT_DOCS = YES 21 | SEPARATE_MEMBER_PAGES = NO 22 | TAB_SIZE = 4 23 | OPTIMIZE_OUTPUT_FOR_C = NO 24 | OPTIMIZE_OUTPUT_JAVA = NO 25 | OPTIMIZE_FOR_FORTRAN = NO 26 | OPTIMIZE_OUTPUT_VHDL = NO 27 | MARKDOWN_SUPPORT = YES 28 | AUTOLINK_SUPPORT = YES 29 | BUILTIN_STL_SUPPORT = NO 30 | CPP_CLI_SUPPORT = NO 31 | SIP_SUPPORT = NO 32 | IDL_PROPERTY_SUPPORT = YES 33 | DISTRIBUTE_GROUP_DOC = NO 34 | SUBGROUPING = YES 35 | INLINE_GROUPED_CLASSES = NO 36 | INLINE_SIMPLE_STRUCTS = NO 37 | TYPEDEF_HIDES_STRUCT = NO 38 | LOOKUP_CACHE_SIZE = 0 39 | EXTRACT_ALL = NO 40 | EXTRACT_PRIVATE = NO 41 | EXTRACT_STATIC = NO 42 | EXTRACT_LOCAL_CLASSES = YES 43 | EXTRACT_LOCAL_METHODS = NO 44 | EXTRACT_ANON_NSPACES = NO 45 | HIDE_UNDOC_MEMBERS = NO 46 | HIDE_UNDOC_CLASSES = NO 47 | HIDE_FRIEND_COMPOUNDS = NO 48 | HIDE_IN_BODY_DOCS = NO 49 | INTERNAL_DOCS = NO 50 | CASE_SENSE_NAMES = NO 51 | HIDE_SCOPE_NAMES = NO 52 | HIDE_COMPOUND_REFERENCE= NO 53 | SHOW_INCLUDE_FILES = YES 54 | SHOW_GROUPED_MEMB_INC = NO 55 | FORCE_LOCAL_INCLUDES = NO 56 | INLINE_INFO = YES 57 | SORT_MEMBER_DOCS = YES 58 | SORT_BRIEF_DOCS = NO 59 | SORT_MEMBERS_CTORS_1ST = NO 60 | SORT_GROUP_NAMES = NO 61 | SORT_BY_SCOPE_NAME = NO 62 | STRICT_PROTO_MATCHING = NO 63 | GENERATE_TODOLIST = YES 64 | GENERATE_TESTLIST = YES 65 | GENERATE_BUGLIST = YES 66 | GENERATE_DEPRECATEDLIST= YES 67 | MAX_INITIALIZER_LINES = 30 68 | SHOW_USED_FILES = YES 69 | SHOW_FILES = YES 70 | SHOW_NAMESPACES = YES 71 | QUIET = NO 72 | WARNINGS = YES 73 | WARN_IF_UNDOCUMENTED = YES 74 | WARN_IF_DOC_ERROR = YES 75 | WARN_NO_PARAMDOC = NO 76 | WARN_FORMAT = "$file:$line: $text" 77 | INPUT = ../../src 78 | INPUT_ENCODING = UTF-8 79 | FILE_PATTERNS = *.c *.cc *.cxx *.cpp *.h *.hxx *.hpp *.h++ 80 | RECURSIVE = YES 81 | EXCLUDE_SYMLINKS = NO 82 | EXAMPLE_PATTERNS = * 83 | EXAMPLE_RECURSIVE = NO 84 | FILTER_SOURCE_FILES = NO 85 | SOURCE_BROWSER = NO 86 | INLINE_SOURCES = NO 87 | STRIP_CODE_COMMENTS = YES 88 | REFERENCED_BY_RELATION = NO 89 | REFERENCES_RELATION = NO 90 | REFERENCES_LINK_SOURCE = YES 91 | SOURCE_TOOLTIPS = YES 92 | USE_HTAGS = NO 93 | VERBATIM_HEADERS = YES 94 | CLANG_ASSISTED_PARSING = NO 95 | ALPHABETICAL_INDEX = YES 96 | COLS_IN_ALPHA_INDEX = 5 97 | GENERATE_HTML = NO 98 | HTML_OUTPUT = html 99 | HTML_FILE_EXTENSION = .html 100 | HTML_COLORSTYLE_HUE = 220 101 | HTML_COLORSTYLE_SAT = 100 102 | HTML_COLORSTYLE_GAMMA = 80 103 | HTML_TIMESTAMP = YES 104 | HTML_DYNAMIC_SECTIONS = NO 105 | HTML_INDEX_NUM_ENTRIES = 100 106 | GENERATE_DOCSET = NO 107 | DOCSET_FEEDNAME = "Doxygen generated docs" 108 | DOCSET_BUNDLE_ID = org.doxygen.firebase-arduino 109 | DOCSET_PUBLISHER_ID = org.doxygen.Publisher 110 | DOCSET_PUBLISHER_NAME = Publisher 111 | GENERATE_HTMLHELP = NO 112 | GENERATE_CHI = NO 113 | BINARY_TOC = NO 114 | TOC_EXPAND = NO 115 | GENERATE_QHP = NO 116 | QHP_NAMESPACE = org.doxygen.firebase-arduino 117 | QHP_VIRTUAL_FOLDER = doc 118 | GENERATE_ECLIPSEHELP = NO 119 | ECLIPSE_DOC_ID = org.doxygen.firebase-arduino 120 | DISABLE_INDEX = NO 121 | GENERATE_TREEVIEW = NO 122 | ENUM_VALUES_PER_LINE = 4 123 | TREEVIEW_WIDTH = 250 124 | EXT_LINKS_IN_WINDOW = NO 125 | FORMULA_FONTSIZE = 10 126 | FORMULA_TRANSPARENT = YES 127 | USE_MATHJAX = NO 128 | MATHJAX_FORMAT = HTML-CSS 129 | MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest 130 | SEARCHENGINE = YES 131 | SERVER_BASED_SEARCH = NO 132 | EXTERNAL_SEARCH = NO 133 | SEARCHDATA_FILE = searchdata.xml 134 | GENERATE_LATEX = NO 135 | LATEX_OUTPUT = latex 136 | LATEX_CMD_NAME = latex 137 | MAKEINDEX_CMD_NAME = makeindex 138 | COMPACT_LATEX = NO 139 | PAPER_TYPE = a4 140 | PDF_HYPERLINKS = YES 141 | USE_PDFLATEX = YES 142 | LATEX_BATCHMODE = NO 143 | LATEX_HIDE_INDICES = NO 144 | LATEX_SOURCE_CODE = NO 145 | LATEX_BIB_STYLE = plain 146 | GENERATE_RTF = NO 147 | RTF_OUTPUT = rtf 148 | COMPACT_RTF = NO 149 | RTF_HYPERLINKS = NO 150 | RTF_SOURCE_CODE = NO 151 | GENERATE_MAN = NO 152 | MAN_OUTPUT = man 153 | MAN_EXTENSION = .3 154 | MAN_LINKS = NO 155 | GENERATE_XML = YES 156 | XML_OUTPUT = xml 157 | XML_PROGRAMLISTING = YES 158 | GENERATE_DOCBOOK = NO 159 | DOCBOOK_OUTPUT = docbook 160 | DOCBOOK_PROGRAMLISTING = NO 161 | GENERATE_AUTOGEN_DEF = NO 162 | GENERATE_PERLMOD = NO 163 | PERLMOD_LATEX = NO 164 | PERLMOD_PRETTY = YES 165 | ENABLE_PREPROCESSING = YES 166 | MACRO_EXPANSION = NO 167 | EXPAND_ONLY_PREDEF = NO 168 | SEARCH_INCLUDES = YES 169 | SKIP_FUNCTION_MACROS = YES 170 | ALLEXTERNALS = NO 171 | EXTERNAL_GROUPS = YES 172 | EXTERNAL_PAGES = YES 173 | PERL_PATH = /usr/bin/perl 174 | CLASS_DIAGRAMS = NO 175 | HIDE_UNDOC_RELATIONS = YES 176 | HAVE_DOT = NO 177 | DOT_NUM_THREADS = 0 178 | DOT_FONTNAME = Helvetica 179 | DOT_FONTSIZE = 10 180 | CLASS_GRAPH = YES 181 | COLLABORATION_GRAPH = YES 182 | GROUP_GRAPHS = YES 183 | UML_LOOK = NO 184 | UML_LIMIT_NUM_FIELDS = 10 185 | TEMPLATE_RELATIONS = NO 186 | INCLUDE_GRAPH = YES 187 | INCLUDED_BY_GRAPH = YES 188 | CALL_GRAPH = NO 189 | CALLER_GRAPH = NO 190 | GRAPHICAL_HIERARCHY = YES 191 | DIRECTORY_GRAPH = YES 192 | DOT_IMAGE_FORMAT = png 193 | INTERACTIVE_SVG = NO 194 | DOT_GRAPH_MAX_NODES = 50 195 | MAX_DOT_GRAPH_DEPTH = 0 196 | DOT_TRANSPARENT = NO 197 | DOT_MULTI_TARGETS = NO 198 | GENERATE_LEGEND = YES 199 | DOT_CLEANUP = YES 200 | -------------------------------------------------------------------------------- /docs/read_the_docs/conf.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import shlex 4 | import subprocess 5 | read_the_docs_build = os.environ.get('READTHEDOCS', None) == 'True' 6 | if read_the_docs_build: 7 | subprocess.call('doxygen', shell=True) 8 | extensions = ['breathe'] 9 | breathe_projects = { 'firebase-arduino': 'xml' } 10 | breathe_default_project = "firebase-arduino" 11 | templates_path = ['_templates'] 12 | source_suffix = '.rst' 13 | master_doc = 'index' 14 | project = u'firebase-arduino' 15 | copyright = u'2015, firebase-arduino' 16 | author = u'firebase-arduino' 17 | version = '1.0' 18 | release = '1.0' 19 | language = None 20 | exclude_patterns = ['_build'] 21 | pygments_style = 'sphinx' 22 | todo_include_todos = False 23 | html_static_path = ['_static'] 24 | htmlhelp_basename = 'firebase-arduinodoc' 25 | latex_elements = { 26 | } 27 | latex_documents = [ 28 | (master_doc, 'firebase-arduino.tex', u'firebase-arduino Documentation', 29 | u'firebase-arduino', 'manual'), 30 | ] 31 | -------------------------------------------------------------------------------- /docs/read_the_docs/index.rst: -------------------------------------------------------------------------------- 1 | .. toctree:: 2 | :maxdepth: 2 3 | .. include:: ../../README.rst 4 | :end-before: ---- 5 | Class Documentation 6 | =================== 7 | .. doxygenclass:: FirebaseArduino 8 | :project: firebase-arduino 9 | :members: 10 | .. doxygenclass:: FirebaseObject 11 | :project: firebase-arduino 12 | :members: 13 | ---- 14 | This documentation was built using ArduinoDocs_. 15 | .. _ArduinoDocs: http://arduinodocs.readthedocs.org 16 | -------------------------------------------------------------------------------- /docs/read_the_docs/requirements.txt: -------------------------------------------------------------------------------- 1 | breathe 2 | -------------------------------------------------------------------------------- /examples/FirebaseCloudMessaging_Send_ESP8266/FirebaseCloudMessaging_Send_ESP8266.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2015 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // FirebaseCloudMessaging_Send_ESP8266 is a sample that shows sending 18 | // messages to firebase. 19 | 20 | #include 21 | 22 | #include 23 | 24 | // Set these to run example. 25 | #define WIFI_SSID "SSID" 26 | #define WIFI_PASSWORD "PASSWORD" 27 | 28 | #define SERVER_KEY "key_from_dashboard" 29 | #define CLIENT_REGISTRATION_ID "key_from_client_after_registration" 30 | 31 | void setup() { 32 | Serial.begin(9600); 33 | 34 | // connect to wifi. 35 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 36 | Serial.print("connecting"); 37 | while (WiFi.status() != WL_CONNECTED) { 38 | Serial.print("."); 39 | delay(500); 40 | } 41 | Serial.println(); 42 | Serial.print("connected: "); 43 | Serial.println(WiFi.localIP()); 44 | 45 | FirebaseCloudMessaging fcm(SERVER_KEY); 46 | FirebaseCloudMessage message = 47 | FirebaseCloudMessage::SimpleNotification("Hello World!", "What's happening?"); 48 | FirebaseError error = fcm.SendMessageToUser(CLIENT_REGISTRATION_ID, message); 49 | if (error) { 50 | Serial.print("Error:"); 51 | Serial.print(error.code()); 52 | Serial.print(" :: "); 53 | Serial.println(error.message().c_str()); 54 | } else { 55 | Serial.println("Sent OK!"); 56 | } 57 | } 58 | 59 | void loop() { 60 | } 61 | 62 | -------------------------------------------------------------------------------- /examples/FirebaseDemo_ESP8266/FirebaseDemo_ESP8266.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2015 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // FirebaseDemo_ESP8266 is a sample that demo the different functions 18 | // of the FirebaseArduino API. 19 | 20 | #include 21 | #include 22 | 23 | // Set these to run example. 24 | #define FIREBASE_HOST "example.firebaseio.com" 25 | #define FIREBASE_AUTH "token_or_secret" 26 | #define WIFI_SSID "SSID" 27 | #define WIFI_PASSWORD "PASSWORD" 28 | 29 | void setup() { 30 | Serial.begin(9600); 31 | 32 | // connect to wifi. 33 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 34 | Serial.print("connecting"); 35 | while (WiFi.status() != WL_CONNECTED) { 36 | Serial.print("."); 37 | delay(500); 38 | } 39 | Serial.println(); 40 | Serial.print("connected: "); 41 | Serial.println(WiFi.localIP()); 42 | 43 | Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); 44 | } 45 | 46 | int n = 0; 47 | 48 | void loop() { 49 | // set value 50 | Firebase.setFloat("number", 42.0); 51 | // handle error 52 | if (Firebase.failed()) { 53 | Serial.print("setting /number failed:"); 54 | Serial.println(Firebase.error()); 55 | return; 56 | } 57 | delay(1000); 58 | 59 | // update value 60 | Firebase.setFloat("number", 43.0); 61 | // handle error 62 | if (Firebase.failed()) { 63 | Serial.print("setting /number failed:"); 64 | Serial.println(Firebase.error()); 65 | return; 66 | } 67 | delay(1000); 68 | 69 | // get value 70 | Serial.print("number: "); 71 | Serial.println(Firebase.getFloat("number")); 72 | delay(1000); 73 | 74 | // remove value 75 | Firebase.remove("number"); 76 | delay(1000); 77 | 78 | // set string value 79 | Firebase.setString("message", "hello world"); 80 | // handle error 81 | if (Firebase.failed()) { 82 | Serial.print("setting /message failed:"); 83 | Serial.println(Firebase.error()); 84 | return; 85 | } 86 | delay(1000); 87 | 88 | // set bool value 89 | Firebase.setBool("truth", false); 90 | // handle error 91 | if (Firebase.failed()) { 92 | Serial.print("setting /truth failed:"); 93 | Serial.println(Firebase.error()); 94 | return; 95 | } 96 | delay(1000); 97 | 98 | // append a new value to /logs 99 | String name = Firebase.pushInt("logs", n++); 100 | // handle error 101 | if (Firebase.failed()) { 102 | Serial.print("pushing /logs failed:"); 103 | Serial.println(Firebase.error()); 104 | return; 105 | } 106 | Serial.print("pushed: /logs/"); 107 | Serial.println(name); 108 | delay(1000); 109 | } 110 | -------------------------------------------------------------------------------- /examples/FirebaseDemo_ESP8266/README.md: -------------------------------------------------------------------------------- 1 | # FirebaseDemo 2 | 3 | FirebaseDemo is a sample that shows basic usage of the `FirebaseArduino` API. 4 | 5 | ## Software setup 6 | 7 | 1. Install [Arduino 1.6.9](https://www.arduino.cc/en/Main/Software) 8 | 1. Install [Arduino ESP8266 core](https://github.com/esp8266/Arduino#installing-with-boards-manager) 9 | 1. Download [FirebaseArduino library](https://github.com/googlesamples/firebase-arduino/archive/master.zip) 10 | 1. Start Arduino 11 | 1. Click `Sketch > Include Library > Add .ZIP Library...` 12 | 1. Choose `firebase-arduino-master.zip` downloaded in step `3.` 13 | 14 | ## Configuration 15 | 16 | 1. Start Arduino 17 | 1. Open `File > Examples > FirebaseArduino > FirebaseRoom_ESP8266` 18 | 1. In `FirebaseRoom_ESP8266`: Replace `WIFI_SSID` and `WIFI_PASSWORD` with WiFi credentials 19 | 1. Go to https://firebase.google.com/console/ and create a new Firebase Project 20 | 1. Go to `Database` 21 | 1. Copy the `Database hostname` (Database URL without `https://` and trailing `/`) 22 | 1. In `FirebaseRoom_ESP8266`: replace `FIREBASE_HOST` with the `Database Hostname` 23 | 1. Go to `⚙ > Project Settings > Database > Database secrets` 24 | 1. Click `Firebase Secrets > Show` 25 | 1. Copy the `Database Secret` 26 | 1. In `FirebaseRoom_ESP8266`: Replace `FIREBASE_AUTH` with `Database Secret` 27 | 1. Select the board `Board > ESP8266 Modules > NodeMCU 1.0` 28 | 1. Select the serial port `Port > /dev/tty...` 29 | 1. Select the upload speed `Upload Speed > 115200` 30 | 1. Click `Sketch > Upload` 31 | 32 | ## Play 33 | 34 | 1. Go to the Firebase console `Data` section 35 | 1. Watch the data being modified as the sketch runs 36 | -------------------------------------------------------------------------------- /examples/FirebaseNeoPixel_ESP8266/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | -------------------------------------------------------------------------------- /examples/FirebaseNeoPixel_ESP8266/FirebaseNeoPixel_ESP8266.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2016 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // FirebaseNeoPixel is a sample that demonstrates how 18 | // to set pixel data from Firebase. 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | // Set these to run example. 25 | #define FIREBASE_HOST "example.firebaseio.com" 26 | #define FIREBASE_AUTH "token_or_secret" 27 | #define WIFI_SSID "SSID" 28 | #define WIFI_PASSWORD "PASSWORD" 29 | 30 | const int pixelPin = 13; 31 | Adafruit_NeoPixel strip = Adafruit_NeoPixel(32, pixelPin, NEO_GRB + NEO_KHZ800); 32 | 33 | void setup() { 34 | Serial.begin(9600); 35 | 36 | strip.begin(); 37 | strip.setBrightness(25); // 0 ... 255 38 | strip.show(); // Initialize all pixels to 'off' 39 | 40 | // connect to wifi. 41 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 42 | Serial.print("connecting"); 43 | while (WiFi.status() != WL_CONNECTED) { 44 | Serial.print("."); 45 | delay(500); 46 | } 47 | Serial.println(); 48 | Serial.print("connected: "); 49 | Serial.println(WiFi.localIP()); 50 | 51 | Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); 52 | } 53 | 54 | 55 | void loop() { 56 | // Get all entries. 57 | // TODO: Replace with streaming 58 | FirebaseObject pixels = Firebase.get("/rgbdata"); 59 | if (Firebase.failed()) { 60 | Serial.println("Firebase get failed"); 61 | Serial.println(Firebase.error()); 62 | return; 63 | } 64 | 65 | for (int i = 0; i < strip.numPixels(); i++) { 66 | int pixel = pixels.getInt(String("pixel") + i); 67 | strip.setPixelColor(i, pixel); 68 | } 69 | strip.show(); 70 | delay(200); 71 | } 72 | -------------------------------------------------------------------------------- /examples/FirebaseNeoPixel_ESP8266/README.md: -------------------------------------------------------------------------------- 1 | # FirebaseNeoPixel 2 | 3 | FirebaseNeoPixel is a sample that shows how to set pixel data from a Firebase web app. 4 | 5 | ## Hardware setup 6 | 7 | 1. Get a [Feather Huzzah](https://www.adafruit.com/product/2821) 8 | 1. Get a [FeatherWing NeoPixel](https://www.adafruit.com/product/2945) 9 | 1. Cut the default jumper and [solder](https://learn.adafruit.com/adafruit-neopixel-featherwing/pinouts) the one forfor `pin13` 10 | 1. Solder female headers on the `Feather Huzzah` 11 | 1. Solder mail headers on the `FeatherWing NeoPixel` 12 | 1. Stack the `FeatherWing NeoPixel` on top of the `Feather Huzzah` 13 | 14 | ## Software setup 15 | 16 | 1. Install [Arduino 1.6.9](https://www.arduino.cc/en/Main/Software) 17 | 1. Install [Arduino ESP8266 core](https://github.com/esp8266/Arduino#installing-with-boards-manager) 18 | 1. Download [FirebaseArduino library](https://github.com/googlesamples/firebase-arduino/archive/master.zip) 19 | 1. Start Arduino 20 | 1. Click `Sketch > Include Library > Add .ZIP Library...` 21 | 1. Choose `firebase-arduino-master.zip` downloaded in step `3.` 22 | 1. Install the following libraries using `Sketch > Include Library > Manage Libraries...`: 23 | - [Adafruit_NeoPixel](https://github.com/adafruit/Adafruit_NeoPixel) 24 | 25 | ## Configuration 26 | 27 | 1. Start Arduino 28 | 1. Open `File > Examples > FirebaseArduino > FirebaseNeoPixel_ESP8266` 29 | 1. In `FirebaseNeoPixel_ESP8266`: Replace `WIFI_SSID` and `WIFI_PASSWORD` with WiFi credentials 30 | 1. Go to https://firebase.google.com/console/ and create a new Firebase Project 31 | 1. Go to `Database` 32 | 1. Copy the `Database hostname` (Database URL without `https://` and trailing `/`) 33 | 1. In `FirebaseNeoPixel_ESP8266`: replace `FIREBASE_HOST` with the `Database Hostname` 34 | 1. Go to `⚙ > Project Settings > Database > Database secrets` 35 | 1. Click `Firebase Secrets > Show` 36 | 1. Copy the `Database Secret` 37 | 1. In `FirebaseNeoPixel_ESP8266`: Replace `FIREBASE_AUTH` with `Database Secret` 38 | 1. Select the board `Board > ESP8266 Modules > NodeMCU 1.0` 39 | 1. Select the serial port `Port > /dev/tty...` 40 | 1. Select the upload speed `Upload Speed > 115200` 41 | 1. Click `Sketch > Upload` 42 | 1. Open `public/index.html` with a text editor 43 | 1. Replace `example.firebaseio.com` with the `Firebase Hostname` used for configuring the Arduino project. 44 | 1. Replace `example.firebaseapp.com` with the `Firebase Domain` from hosting tab of the Firebase Console. 45 | 1. Replace `secret_or_token` with the `Firebase Secret` used to configure the Arduino project. 46 | 1. Deploy the `public` directory to Firebase hosting 47 | ``` 48 | npm install -g firebase-tools bower 49 | (cd public && bower install) 50 | firebase login 51 | firebase init 52 | firebase deploy 53 | ``` 54 | 55 | ## Play 56 | 57 | 1. Go to the firebase hosting URL: `example.firebaseapp.com`. 58 | 1. Initialize the pixel data by copying / pasting example pixel data from the page and clicking **Update**. 59 | 1. Use the color picker and paint the NeoPixel table. 60 | 1. Watch the NeoPixel being updated to the matching color. 61 | -------------------------------------------------------------------------------- /examples/FirebaseNeoPixel_ESP8266/public/.gitignore: -------------------------------------------------------------------------------- 1 | bower_components/ 2 | node_modules/ 3 | -------------------------------------------------------------------------------- /examples/FirebaseNeoPixel_ESP8266/public/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web", 3 | "homepage": "https://github.com/gguuss/firebase-arduino", 4 | "authors": [ 5 | "Gus Class " 6 | ], 7 | "description": "", 8 | "main": "", 9 | "moduleType": [], 10 | "license": "MIT", 11 | "private": true, 12 | "ignore": [ 13 | "**/.*", 14 | "node_modules", 15 | "bower_components", 16 | "test", 17 | "tests" 18 | ], 19 | "dependencies": { 20 | "polymer": "^1.2.0", 21 | "polymer-color-picker": "^1.0.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/FirebaseRoom_ESP8266/FirebaseRoom_ESP8266.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2015 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // FirebaseRoom_ESP8266 is a sample that demo using multiple sensors 18 | // and actuactor with the FirebaseArduino library. 19 | 20 | #include 21 | #include 22 | 23 | // Set these to run example. 24 | #define FIREBASE_HOST "example.firebaseio.com" 25 | #define FIREBASE_AUTH "token_or_secret" 26 | #define WIFI_SSID "SSID" 27 | #define WIFI_PASSWORD "PASSWORD" 28 | 29 | const int grovePowerPin = 15; 30 | const int vibratorPin = 5; 31 | const int lightSensorPin = A0; 32 | const int ledPin = 12; 33 | const int buttonPin = 14; 34 | const int fanPin = 13; 35 | 36 | void setup() { 37 | Serial.begin(9600); 38 | 39 | pinMode(grovePowerPin, OUTPUT); 40 | digitalWrite(grovePowerPin, HIGH); 41 | 42 | pinMode(vibratorPin, OUTPUT); 43 | pinMode(lightSensorPin, INPUT); 44 | pinMode(ledPin, OUTPUT); 45 | pinMode(buttonPin, INPUT); 46 | pinMode(fanPin, OUTPUT); 47 | 48 | // connect to wifi. 49 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 50 | Serial.print("connecting"); 51 | while (WiFi.status() != WL_CONNECTED) { 52 | Serial.print("."); 53 | delay(500); 54 | } 55 | Serial.println(); 56 | Serial.print("connected: "); 57 | Serial.println(WiFi.localIP()); 58 | 59 | Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH); 60 | Firebase.set("pushbutton", 0); 61 | Firebase.set("sunlight", 0); 62 | Firebase.set("redlight", 0); 63 | Firebase.set("cooldown", 0); 64 | Firebase.set("brrr", 0); 65 | } 66 | 67 | int button = 0; 68 | float light = 0.0; 69 | 70 | void loop() { 71 | digitalWrite(ledPin, Firebase.getInt("redlight")); 72 | digitalWrite(fanPin, Firebase.getInt("cooldown")); 73 | digitalWrite(vibratorPin, Firebase.getInt("brrr")); 74 | int newButton = digitalRead(buttonPin); 75 | if (newButton != button) { 76 | button = newButton; 77 | Firebase.setInt("pushbutton", button); 78 | } 79 | float newLight = analogRead(lightSensorPin); 80 | if (abs(newLight - light) > 100) { 81 | light = newLight; 82 | Firebase.setFloat("sunlight", light); 83 | } 84 | delay(200); 85 | } 86 | -------------------------------------------------------------------------------- /examples/FirebaseRoom_ESP8266/README.md: -------------------------------------------------------------------------------- 1 | # FirebaseRoom 2 | 3 | FirebaseRoom is a sample that shows basic usage of FirebaseArduino to push 4 | sensor data to Firebase, and trigger actuators from Firebase. 5 | 6 | ## Software setup 7 | 8 | 1. Install [Arduino 1.6.9](https://www.arduino.cc/en/Main/Software) 9 | 1. Install [Arduino ESP8266 core](https://github.com/esp8266/Arduino#installing-with-boards-manager) 10 | 1. Install [Silicon Labs VCP driver](https://www.silabs.com/products/mcu/Pages/USBtoUARTBridgeVCPDrivers.aspx) (for MacOSX and Windows) 11 | 1. Download [FirebaseArduino library](https://github.com/googlesamples/firebase-arduino/archive/master.zip) 12 | 1. Start Arduino 13 | 1. Click `Sketch > Include Library > Add .ZIP Library...` 14 | 1. Choose `firebase-arduino-master.zip` downloaded in step `3.` 15 | 16 | ## Hardware setup 17 | 18 | 1. Get a [Wio Link](http://www.seeedstudio.com/depot/Wio-Link-p-2604.html) board 19 | 1. Connect: 20 | - a [Grove - Vibration Motor](http://www.seeedstudio.com/wiki/Grove_-_Vibration_Motor) on `pin 5` 21 | - a [Grove - Light Sensor](http://www.seeedstudio.com/wiki/Grove_-_Light_Sensor) on `pin A0` 22 | - a [Grove - Red LED](http://www.seeedstudio.com/wiki/Grove_-_Red_LED) on `pin 12` 23 | - a [Grove - Button](http://www.seeedstudio.com/wiki/Grove_-_Button) on `pin 14` 24 | - a [Grove - Mini Fan](http://www.seeedstudio.com/wiki/Grove_-_Mini_Fan) on `pin 13` 25 | 26 | ## Configuration 27 | 28 | 1. Start Arduino 29 | 1. Open `File > Examples > FirebaseArduino > FirebaseRoom_ESP8266` 30 | 1. In `FirebaseRoom_ESP8266`: Replace `WIFI_SSID` and `WIFI_PASSWORD` with WiFi credentials 31 | 1. Go to https://firebase.google.com/console/ and create a new Firebase Project 32 | 1. Go to `Database` 33 | 1. Copy the `Database hostname` (Database URL without `https://` and trailing `/`) 34 | 1. In `FirebaseRoom_ESP8266`: replace `FIREBASE_HOST` with the `Database Hostname` 35 | 1. Go to `⚙ > Project Settings > Database > Database secrets` 36 | 1. Click `Firebase Secrets > Show` 37 | 1. Copy the `Database Secret` 38 | 1. In `FirebaseRoom_ESP8266`: Replace `FIREBASE_AUTH` with `Database Secret` 39 | 1. Select the board `Board > ESP8266 Modules > NodeMCU 1.0` 40 | 1. Select the serial port `Port > /dev/tty...` 41 | 1. Select the upload speed `Upload Speed > 115200` 42 | 1. Click `Sketch > Upload` 43 | 44 | ## Play 45 | 46 | 1. Go to the Firebase console `Data` section 47 | 1. Set `redlight` to `1` then `0` 48 | 1. Watch the Red LED turn on and off in the room 49 | 1. Same for `cooldown` and `brrr` 50 | 1. Press the push button in the room 51 | 1. Watch the `pushbutton` value change in the Firebase console 52 | 1. Put one hand on the light sensor 53 | 1. Watch the `sunlight` value change in the Firebase console 54 | 55 | ## Homeworks 56 | 57 | - Build a [Firebase web app](https://www.firebase.com/docs/web/) that interacts with the room. 58 | - Add Grove modules to modules interactions. 59 | - Connect other Grove modules to the room and submit new [PRs](https://github.com/googlesamples/firebase-arduino/pulls) 60 | - Reduce the number of Firebase API calls using `FirebaseObject` or `FirebaseStream`. 61 | - Watch or star the [GitHub repo](https://github.com/googlesamples/firebase-arduino) 62 | - Give [feedback](https://gitter.im/googlesamples/firebase-arduino) 63 | - Report [bugs](https://github.com/googlesamples/firebase-arduino/issues/new) 64 | - [Fork](https://github.com/googlesamples/firebase-arduino#fork-destination-box) and [contribute](https://github.com/googlesamples/firebase-arduino/blob/master/CONTRIBUTING.md) 65 | -------------------------------------------------------------------------------- /examples/FirebaseStream_ESP8266/FirebaseStream_ESP8266.ino: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2015 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // FirebaseStream_ESP8266 is a sample that stream bitcoin price from a 18 | // public Firebase and optionally display them on a OLED i2c screen. 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | // Set these to run example. 26 | #define WIFI_SSID "SSID" 27 | #define WIFI_PASSWORD "PASSWORD" 28 | 29 | #define OLED_RESET 3 30 | Adafruit_SSD1306 display(OLED_RESET); 31 | 32 | void setup() { 33 | Serial.begin(9600); 34 | 35 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32) 36 | display.display(); 37 | 38 | // connect to wifi. 39 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 40 | Serial.print("connecting"); 41 | while (WiFi.status() != WL_CONNECTED) { 42 | Serial.print("."); 43 | delay(500); 44 | } 45 | Serial.println(); 46 | Serial.print("connected: "); 47 | Serial.println(WiFi.localIP()); 48 | 49 | Firebase.begin("publicdata-cryptocurrency.firebaseio.com"); 50 | Firebase.stream("/bitcoin/last"); 51 | } 52 | 53 | 54 | void loop() { 55 | if (Firebase.failed()) { 56 | Serial.println("streaming error"); 57 | Serial.println(Firebase.error()); 58 | } 59 | 60 | if (Firebase.available()) { 61 | FirebaseObject event = Firebase.readEvent(); 62 | String eventType = event.getString("type"); 63 | eventType.toLowerCase(); 64 | 65 | Serial.print("event: "); 66 | Serial.println(eventType); 67 | if (eventType == "put") { 68 | Serial.print("data: "); 69 | Serial.println(event.getString("data")); 70 | String path = event.getString("path"); 71 | String data = event.getString("data"); 72 | 73 | display.clearDisplay(); 74 | display.setTextSize(2); 75 | display.setTextColor(WHITE); 76 | display.setCursor(0,0); 77 | display.println(path.c_str()+1); 78 | display.println(data); 79 | display.display(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /examples/FirebaseStream_ESP8266/README.md: -------------------------------------------------------------------------------- 1 | # FirebaseStream 2 | 3 | FirebaseStream is a sample that shows basic usage of the `FirebaseArduino` 4 | streaming API. 5 | 6 | It displays the current bitcoin price on a OLED screen as it gets updated on 7 | https://publicdata-cryptocurrency.firebaseio.com. 8 | 9 | ## Hardware setup 10 | 11 | 1. Get a [Feather Huzzah](https://www.adafruit.com/product/2821) 12 | 1. Get a [FeatherWing OLED](https://www.adafruit.com/products/2900) 13 | 1. Solder female headers on the `Feather Huzzah` 14 | 1. Solder mail headers on the `FeatherWing OLED` 15 | 1. Stack the `FeatherWing OLED` on top of the `Feather Huzzah` 16 | 17 | ## Software setup 18 | 19 | 1. Install [Arduino 1.6.9](https://www.arduino.cc/en/Main/Software) 20 | 1. Install [Arduino ESP8266 core](https://github.com/esp8266/Arduino#installing-with-boards-manager) 21 | 1. Download [FirebaseArduino library](https://github.com/googlesamples/firebase-arduino/archive/master.zip) 22 | 1. Start Arduino 23 | 1. Click `Sketch > Include Library > Add .ZIP Library...` 24 | 1. Choose `firebase-arduino-master.zip` downloaded in step `3.` 25 | 1. Install the following libraries using `Sketch > Include Library > Manage Libraries...`: 26 | - [Adafruit_GFX](https://github.com/adafruit/Adafruit-GFX-Library) 27 | - [Adafruit_SSD1306](https://github.com/adafruit/Adafruit_SSD1306) 28 | 29 | ## Configuration 30 | 31 | 1. Start Arduino 32 | 1. Open `File > Examples > FirebaseArduino > FirebaseRoom_ESP8266` 33 | 1. In `FirebaseRoom_ESP8266`: Replace `WIFI_SSID` and `WIFI_PASSWORD` with WiFi credentials 34 | 1. Go to https://firebase.google.com/console/ and create a new Firebase Project 35 | 1. Go to `Database` 36 | 1. Copy the `Database hostname` (Database URL without `https://` and trailing `/`) 37 | 1. In `FirebaseRoom_ESP8266`: replace `FIREBASE_HOST` with the `Database Hostname` 38 | 1. Go to `⚙ > Project Settings > Database > Database secrets` 39 | 1. Click `Firebase Secrets > Show` 40 | 1. Copy the `Database Secret` 41 | 1. In `FirebaseRoom_ESP8266`: Replace `FIREBASE_AUTH` with `Database Secret` 42 | 1. Select the board `Board > ESP8266 Modules > NodeMCU 1.0` 43 | 1. Select the serial port `Port > /dev/tty...` 44 | 1. Select the upload speed `Upload Speed > 115200` 45 | 1. Click `Sketch > Upload` 46 | 47 | ## Play 48 | 49 | 1. Watch the screen be updated with the current bitcoin price. 50 | 1. Watch the data being modified as the sketch run 51 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=FirebaseArduino 2 | version=0.1 3 | author= 4 | maintainer= 5 | sentence=Library for communicating with Firebase. 6 | paragraph=This library simplifies the process of communicating with Firebase. It hides the complexity of authentication and json parsing. 7 | category=Communication 8 | url=https://github.com/googlesamples/firebase-arduino 9 | architectures=esp8266 10 | -------------------------------------------------------------------------------- /src/Firebase.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2015 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | #include "Firebase.h" 17 | 18 | using std::unique_ptr; 19 | using std::shared_ptr; 20 | 21 | namespace { 22 | std::string makeFirebaseURL(const std::string& path, const std::string& auth) { 23 | std::string url; 24 | if (path[0] != '/') { 25 | url = "/"; 26 | } 27 | url += path + ".json"; 28 | if (auth.length() > 0) { 29 | url += "?auth=" + auth; 30 | } 31 | return url; 32 | } 33 | 34 | } // namespace 35 | 36 | Firebase::Firebase(const std::string& host, const std::string& auth) : host_(host), auth_(auth) { 37 | http_.reset(FirebaseHttpClient::create()); 38 | http_->setReuseConnection(true); 39 | } 40 | 41 | const std::string& Firebase::auth() const { 42 | return auth_; 43 | } 44 | 45 | void FirebaseCall::analyzeError(char* method, int status, const std::string& path_with_auth) { 46 | if (status != 200) { 47 | error_ = FirebaseError(status, 48 | std::string(method) + " " + path_with_auth + 49 | ": " + http_->errorToString(status)); 50 | } else { 51 | error_ = FirebaseError(); 52 | } 53 | } 54 | 55 | FirebaseCall::~FirebaseCall() { 56 | http_->end(); 57 | } 58 | 59 | const JsonObject& FirebaseCall::json() { 60 | //TODO(edcoyne): This is not efficient, we should do something smarter with 61 | //the buffers. kotl: Is this still valid? 62 | if (buffer_.get() == NULL) { 63 | buffer_.reset(new StaticJsonBuffer()); 64 | } 65 | return buffer_.get()->parseObject(response().c_str()); 66 | } 67 | 68 | // FirebaseRequest 69 | int FirebaseRequest::sendRequest( 70 | const std::string& host, const std::string& auth, 71 | char* method, const std::string& path, const std::string& data) { 72 | std::string path_with_auth = makeFirebaseURL(path, auth); 73 | http_->setReuseConnection(true); 74 | http_->begin(host, path_with_auth); 75 | int status = http_->sendRequest(method, data); 76 | analyzeError(method, status, path_with_auth); 77 | response_ = http_->getString(); 78 | } 79 | 80 | // FirebaseStream 81 | void FirebaseStream::startStreaming(const std::string& host, const std::string& auth, const std::string& path) { 82 | std::string path_with_auth = makeFirebaseURL(path, auth); 83 | http_->setReuseConnection(true); 84 | http_->begin(host, path_with_auth); 85 | 86 | http_->addHeader("Accept", "text/event-stream"); 87 | const char* headers[] = {"Location"}; 88 | http_->collectHeaders(headers, 1); 89 | 90 | int status = http_->sendRequest("GET", ""); 91 | analyzeError("STREAM", status, path_with_auth); 92 | 93 | while (status == HttpStatus::TEMPORARY_REDIRECT) { 94 | std::string location = http_->header("Location"); 95 | http_->setReuseConnection(false); 96 | http_->end(); 97 | http_->setReuseConnection(true); 98 | http_->begin(location); 99 | status = http_->sendRequest("GET", std::string()); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Firebase.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2015 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // firebase-arduino is an Arduino client for Firebase. 18 | // It is currently limited to the ESP8266 board family. 19 | 20 | #ifndef firebase_h 21 | #define firebase_h 22 | 23 | #include "WString.h" 24 | #include 25 | #include 26 | #include 27 | 28 | #include "FirebaseHttpClient.h" 29 | #include "FirebaseError.h" 30 | #include "FirebaseObject.h" 31 | 32 | // Firebase REST API client. 33 | class Firebase { 34 | public: 35 | Firebase(const std::string& host, const std::string& auth = ""); 36 | 37 | const std::string& auth() const; 38 | 39 | // Fetch json encoded `value` at `path`. 40 | void get(const std::string& path); 41 | 42 | // Set json encoded `value` at `path`. 43 | void set(const std::string& path, const std::string& json); 44 | 45 | // Add new json encoded `value` to list at `path`. 46 | void push(const std::string& path, const std::string& json); 47 | 48 | // Delete value at `path`. 49 | void remove(const std::string& path); 50 | 51 | // Start a stream of events that affect value at `path`. 52 | void stream(const std::string& path); 53 | 54 | protected: 55 | // Used for testing. 56 | Firebase() {} 57 | 58 | private: 59 | std::shared_ptr http_; 60 | std::string host_; 61 | std::string auth_; 62 | }; 63 | 64 | 65 | class FirebaseCall { 66 | public: 67 | FirebaseCall(const std::shared_ptr http = NULL) : http_(http) {} 68 | virtual ~FirebaseCall(); 69 | 70 | const FirebaseError& error() const { 71 | return error_; 72 | } 73 | 74 | void analyzeError(char* method, int status, const std::string & path_with_auth); 75 | 76 | const std::string& response() const { 77 | return response_; 78 | } 79 | 80 | const JsonObject& json(); 81 | 82 | protected: 83 | const std::shared_ptr http_; 84 | FirebaseError error_; 85 | std::string response_; 86 | std::shared_ptr> buffer_; 87 | }; 88 | 89 | class FirebaseRequest : public FirebaseCall { 90 | public: 91 | FirebaseRequest(const std::shared_ptr http = NULL) : FirebaseCall(http) { } 92 | virtual ~FirebaseRequest() {} 93 | int sendRequest(const std::string& host, const std::string& auth, 94 | char* method, const std::string& path, const std::string& data = ""); 95 | }; 96 | 97 | class FirebaseStream : public FirebaseCall { 98 | public: 99 | FirebaseStream(const std::shared_ptr http = NULL) : FirebaseCall(http) { } 100 | virtual ~FirebaseStream() {} 101 | 102 | void startStreaming(const std::string& host, const std::string& auth, const std::string& path); 103 | }; 104 | 105 | #endif // firebase_h 106 | -------------------------------------------------------------------------------- /src/FirebaseArduino.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2016 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #include "FirebaseArduino.h" 18 | 19 | // This is needed to compile std::string on esp8266. 20 | template class std::basic_string; 21 | 22 | void FirebaseArduino::begin(const String& host, const String& auth) { 23 | host_ = host.c_str(); 24 | auth_ = auth.c_str(); 25 | } 26 | 27 | void FirebaseArduino::initStream() { 28 | if (stream_http_.get() == nullptr) { 29 | stream_http_.reset(FirebaseHttpClient::create()); 30 | stream_http_->setReuseConnection(true); 31 | stream_.reset(new FirebaseStream(stream_http_)); 32 | } 33 | } 34 | 35 | void FirebaseArduino::initRequest() { 36 | if (req_http_.get() == nullptr) { 37 | req_http_.reset(FirebaseHttpClient::create()); 38 | req_http_->setReuseConnection(true); 39 | req_.reset(new FirebaseRequest(req_http_)); 40 | } 41 | } 42 | 43 | String FirebaseArduino::pushInt(const String& path, int value) { 44 | return push(path, value); 45 | } 46 | 47 | String FirebaseArduino::pushFloat(const String& path, float value) { 48 | return push(path, value); 49 | } 50 | 51 | String FirebaseArduino::pushBool(const String& path, bool value) { 52 | return push(path, value); 53 | } 54 | 55 | String FirebaseArduino::pushString(const String& path, const String& value) { 56 | JsonVariant json(value.c_str()); 57 | return push(path, json); 58 | } 59 | 60 | String FirebaseArduino::push(const String& path, const JsonVariant& value) { 61 | int size = value.measureLength()+1; 62 | char * buf = new char[size]; 63 | value.printTo(buf, size); 64 | initRequest(); 65 | int status = req_.get()->sendRequest(host_, auth_, "POST", path.c_str(), buf); 66 | error_ = req_.get()->error(); 67 | const char* name = req_.get()->json()["name"].as(); 68 | delete buf; 69 | return name; 70 | } 71 | 72 | void FirebaseArduino::setInt(const String& path, int value) { 73 | set(path, value); 74 | } 75 | 76 | void FirebaseArduino::setFloat(const String& path, float value) { 77 | set(path, value); 78 | } 79 | 80 | void FirebaseArduino::setBool(const String& path, bool value) { 81 | set(path, value); 82 | } 83 | 84 | void FirebaseArduino::setString(const String& path, const String& value) { 85 | JsonVariant json(value.c_str()); 86 | set(path, json); 87 | } 88 | 89 | void FirebaseArduino::set(const String& path, const JsonVariant& value) { 90 | int size = value.measureLength()+1; 91 | char* buf= new char[size]; 92 | value.printTo(buf, size); 93 | initRequest(); 94 | req_.get()->sendRequest(host_, auth_, "PUT", path.c_str(), buf); 95 | error_ = req_.get()->error(); 96 | delete buf; 97 | } 98 | 99 | void FirebaseArduino::getRequest(const String& path) { 100 | initRequest(); 101 | req_.get()->sendRequest(host_, auth_, "GET", path.c_str()); 102 | error_ = req_.get()->error(); 103 | } 104 | 105 | FirebaseObject FirebaseArduino::get(const String& path) { 106 | getRequest(path); 107 | if (failed()) { 108 | return FirebaseObject{""}; 109 | } 110 | return FirebaseObject(req_.get()->response().c_str()); 111 | } 112 | 113 | int FirebaseArduino::getInt(const String& path) { 114 | getRequest(path); 115 | if (failed()) { 116 | return 0; 117 | } 118 | return FirebaseObject(req_.get()->response().c_str()).getInt(); 119 | } 120 | 121 | 122 | float FirebaseArduino::getFloat(const String& path) { 123 | getRequest(path); 124 | if (failed()) { 125 | return 0.0f; 126 | } 127 | return FirebaseObject(req_.get()->response().c_str()).getFloat(); 128 | } 129 | 130 | String FirebaseArduino::getString(const String& path) { 131 | getRequest(path); 132 | if (failed()) { 133 | return ""; 134 | } 135 | return FirebaseObject(req_.get()->response().c_str()).getString(); 136 | } 137 | 138 | bool FirebaseArduino::getBool(const String& path) { 139 | getRequest(path); 140 | if (failed()) { 141 | return ""; 142 | } 143 | return FirebaseObject(req_.get()->response().c_str()).getBool(); 144 | } 145 | void FirebaseArduino::remove(const String& path) { 146 | initRequest(); 147 | req_.get()->sendRequest(host_, auth_, "DELETE", path.c_str()); 148 | error_ = req_.get()->error(); 149 | } 150 | 151 | void FirebaseArduino::stream(const String& path) { 152 | initStream(); 153 | stream_.get()->startStreaming(host_, auth_, path.c_str()); 154 | error_ = stream_.get()->error(); 155 | } 156 | 157 | bool FirebaseArduino::available() { 158 | if (stream_http_.get() == nullptr) { 159 | error_ = FirebaseError(FIREBASE_ERROR_CODES::STREAM_NOT_INITIALIZED, "HTTP stream is not initialized"); 160 | return 0; 161 | } 162 | if (!stream_http_.get()->connected()) { 163 | error_ = FirebaseError(FIREBASE_ERROR_CODES::HTTP_CONNECTION_LOST, "Connection Lost"); 164 | return 0; 165 | } 166 | auto client = stream_http_.get()->getStreamPtr(); 167 | return (client == nullptr) ? false : client->available(); 168 | } 169 | 170 | FirebaseObject FirebaseArduino::readEvent() { 171 | if (stream_http_.get() == nullptr) { 172 | return FirebaseObject(""); 173 | } 174 | auto client = stream_http_.get()->getStreamPtr(); 175 | if (client == nullptr) { 176 | return FirebaseObject(""); 177 | } 178 | String type = client->readStringUntil('\n').substring(7);; 179 | String event = client->readStringUntil('\n').substring(6); 180 | client->readStringUntil('\n'); // consume separator 181 | FirebaseObject obj = FirebaseObject(event.c_str()); 182 | 183 | // required to have a copy of the string but use a char[] format which is 184 | // the only supported format for JsonObject#set (it does not like the std::string of the test env) 185 | char *cstr = new char[type.length() + 1]; 186 | strncpy(cstr, type.c_str(), type.length() + 1); 187 | obj.getJsonVariant().as().set("type", cstr); 188 | delete[] cstr; 189 | return obj; 190 | } 191 | 192 | bool FirebaseArduino::success() { 193 | return error_.code() == 0; 194 | } 195 | 196 | bool FirebaseArduino::failed() { 197 | return error_.code() != 0; 198 | } 199 | 200 | const String& FirebaseArduino::error() { 201 | return error_.message().c_str(); 202 | } 203 | 204 | FirebaseArduino Firebase; 205 | -------------------------------------------------------------------------------- /src/FirebaseArduino.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2016 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #ifndef FIREBASE_ARDUINO_H 18 | #define FIREBASE_ARDUINO_H 19 | 20 | #include 21 | 22 | #include "Firebase.h" 23 | #include "FirebaseObject.h" 24 | 25 | /** 26 | * Main class for Arduino clients to interact with Firebase. 27 | * This implementation is designed to follow Arduino best practices and favor 28 | * simplicity over all else. 29 | * For more complicated usecases and more control see the Firebase class in 30 | * Firebase.h. 31 | */ 32 | class FirebaseArduino { 33 | public: 34 | /** 35 | * Must be called first. This initialize the client with the given 36 | * firebase host and credentials. 37 | * \param host Your firebase db host, usually X.firebaseio.com. 38 | * \param auth Optional credentials for the db, a secret or token. 39 | */ 40 | virtual void begin(const String& host, const String& auth = ""); 41 | 42 | /** 43 | * Appends the integer value to the node at path. 44 | * Equivalent to the REST API's POST. 45 | * You should check success() after calling. 46 | * \param path The path of the parent node. 47 | * \param value Integer value that you wish to append to the node. 48 | * \return The unique key of the new child node. 49 | */ 50 | String pushInt(const String& path, int value); 51 | 52 | /** 53 | * Appends the float value to the node at path. 54 | * Equivalent to the REST API's POST. 55 | * You should check success() after calling. 56 | * \param path The path of the parent node. 57 | * \param value Float value that you wish to append to the node. 58 | * \return The unique key of the new child node. 59 | */ 60 | String pushFloat(const String& path, float value); 61 | 62 | /** 63 | * Appends the bool value to the node at path. 64 | * Equivalent to the REST API's POST. 65 | * You should check success() after calling. 66 | * \param path The path of the parent node. 67 | * \param value Bool value that you wish to append to the node. 68 | * \return The unique key of the new child node. 69 | */ 70 | String pushBool(const String& path, bool value); 71 | 72 | /** 73 | * Appends the String value to the node at path. 74 | * Equivalent to the REST API's POST. 75 | * You should check success() after calling. 76 | * \param path The path of the parent node. 77 | * \param value String value that you wish to append to the node. 78 | * \return The unique key of the new child node. 79 | */ 80 | virtual String pushString(const String& path, const String& value); 81 | 82 | /** 83 | * Appends the JSON data to the node at path. 84 | * Equivalent to the REST API's POST. 85 | * You should check success() after calling. 86 | * \param path The path of the parent node. 87 | * \param value JSON data that you wish to append to the node. 88 | * \return The unique key of the new child node. 89 | */ 90 | String push(const String& path, const JsonVariant& value); 91 | 92 | /** 93 | * Writes the integer value to the node located at path equivalent to the 94 | * REST API's PUT. 95 | * You should check success() after calling. 96 | * \param path The path inside of your db to the node you wish to update. 97 | * \param value Integer value that you wish to write. 98 | */ 99 | void setInt(const String& path, int value); 100 | 101 | /** 102 | * Writes the float value to the node located at path equivalent to the 103 | * REST API's PUT. 104 | * You should check success() after calling. 105 | * \param path The path inside of your db to the node you wish to update. 106 | * \param value Float value that you wish to write. 107 | */ 108 | void setFloat(const String& path, float value); 109 | 110 | /** 111 | * Writes the bool value to the node located at path equivalent to the 112 | * REST API's PUT. 113 | * You should check success() after calling. 114 | * \param path The path inside of your db to the node you wish to update. 115 | * \param value Bool value that you wish to write. 116 | */ 117 | void setBool(const String& path, bool value); 118 | 119 | /** 120 | * Writes the String value to the node located at path equivalent to the 121 | * REST API's PUT. 122 | * You should check success() after calling. 123 | * \param path The path inside of your db to the node you wish to update. 124 | * \param value String value that you wish to write. 125 | */ 126 | virtual void setString(const String& path, const String& value); 127 | 128 | /** 129 | * Writes the JSON data to the node located at path. 130 | * Equivalent to the REST API's PUT. 131 | * You should check success() after calling. 132 | * \param path The path inside of your db to the node you wish to update. 133 | * \param value JSON data that you wish to write. 134 | */ 135 | void set(const String& path, const JsonVariant& value); 136 | 137 | 138 | /** 139 | * Gets the integer value located at path. 140 | * You should check success() after calling. 141 | * \param path The path to the node you wish to retrieve. 142 | * \return The integer value located at that path. Will only be populated if success() is true. 143 | */ 144 | int getInt(const String& path); 145 | 146 | /** 147 | * Gets the float value located at path. 148 | * You should check success() after calling. 149 | * \param path The path to the node you wish to retrieve. 150 | * \return The float value located at that path. Will only be populated if success() is true. 151 | */ 152 | float getFloat(const String& path); 153 | 154 | /** 155 | * Gets the string value located at path. 156 | * You should check success() after calling. 157 | * \param path The path to the node you wish to retrieve. 158 | * \return The string value located at that path. Will only be populated if success() is true. 159 | */ 160 | virtual String getString(const String& path); 161 | 162 | /** 163 | * Gets the boolean value located at path. 164 | * You should check success() after calling. 165 | * \param path The path to the node you wish to retrieve. 166 | * \return The boolean value located at that path. Will only be populated if success() is true. 167 | */ 168 | bool getBool(const String& path); 169 | 170 | /** 171 | * Gets the json object value located at path. 172 | * You should check success() after calling. 173 | * \param path The path to the node you wish to retrieve. 174 | * \return a FirebaseObject value located at that path. Will only be populated if success() is true. 175 | */ 176 | FirebaseObject get(const String& path); 177 | 178 | /** 179 | * Remove the node, and possibly entire tree, located at path. 180 | * You should check success() after calling. 181 | * \param path The path to the node you wish to remove, 182 | * including all of its children. 183 | */ 184 | virtual void remove(const String& path); 185 | 186 | /** 187 | * Starts streaming any changes made to the node located at path, including 188 | * any of its children. 189 | * You should check success() after calling. 190 | * This changes the state of this object. Once this is called you may start 191 | * monitoring available() and calling readEvent() to get new events. 192 | * \param path The path inside of your db to the node you wish to monitor. 193 | */ 194 | virtual void stream(const String& path); 195 | 196 | /** 197 | * Checks if there are new events available. This is only meaningful once 198 | * stream() has been called. 199 | * \return If a new event is ready. 200 | */ 201 | virtual bool available(); 202 | 203 | /** 204 | * Reads the next event in a stream. This is only meaningful once stream() has 205 | * been called. 206 | * \return FirebaseObject will have ["type"] that describes the event type, ["path"] 207 | * that describes the effected path and ["data"] that was updated. 208 | */ 209 | virtual FirebaseObject readEvent(); 210 | 211 | /** 212 | * \return Whether the last command was successful. 213 | */ 214 | bool success(); 215 | 216 | /** 217 | * \return Whether the last command failed. 218 | */ 219 | bool failed(); 220 | 221 | /** 222 | * \return Error message from last command if failed() is true. 223 | */ 224 | virtual const String& error(); 225 | private: 226 | std::string host_; 227 | std::string auth_; 228 | FirebaseError error_; 229 | std::shared_ptr req_http_; 230 | std::shared_ptr req_; 231 | std::shared_ptr stream_http_; 232 | std::shared_ptr stream_; 233 | 234 | void initStream(); 235 | void initRequest(); 236 | void getRequest(const String& path); 237 | }; 238 | 239 | extern FirebaseArduino Firebase; 240 | 241 | #endif // FIREBASE_ARDUINO_H 242 | -------------------------------------------------------------------------------- /src/FirebaseCloudMessaging.cpp: -------------------------------------------------------------------------------- 1 | #include "FirebaseCloudMessaging.h" 2 | 3 | FirebaseCloudMessage FirebaseCloudMessage::SimpleNotification( 4 | const std::string& title, const std::string& body) { 5 | FirebaseCloudMessage message; 6 | message.notification.title = title; 7 | message.notification.body = body; 8 | return message; 9 | } 10 | 11 | FirebaseCloudMessaging::FirebaseCloudMessaging(const std::string& server_key) { 12 | auth_header_ = "key="; 13 | auth_header_ += server_key; 14 | } 15 | 16 | const FirebaseError FirebaseCloudMessaging::SendMessageToUser( 17 | const std::string& registration_id, 18 | const FirebaseCloudMessage& message) { 19 | DynamicJsonBuffer buffer; 20 | JsonObject& root = buffer.createObject(); 21 | root["to"] = registration_id.c_str(); 22 | 23 | AddToJson(message, root); 24 | 25 | char payload[root.measureLength() + 1]; 26 | root.printTo(payload, sizeof(payload)); 27 | return SendPayload(payload); 28 | } 29 | 30 | const FirebaseError FirebaseCloudMessaging::SendMessageToUsers( 31 | const std::vector& registration_ids, 32 | const FirebaseCloudMessage& message) { 33 | DynamicJsonBuffer buffer; 34 | JsonObject& root = buffer.createObject(); 35 | JsonArray& ids = root.createNestedArray("registration_ids"); 36 | for (const std::string& id : registration_ids) { 37 | ids.add(id.c_str()); 38 | } 39 | 40 | AddToJson(message, root); 41 | 42 | char payload[root.measureLength() + 1]; 43 | root.printTo(payload, sizeof(payload)); 44 | return SendPayload(payload); 45 | } 46 | 47 | 48 | const FirebaseError FirebaseCloudMessaging::SendMessageToTopic( 49 | const std::string& topic, const FirebaseCloudMessage& message) { 50 | std::string to("/topics/"); 51 | to += topic; 52 | 53 | DynamicJsonBuffer buffer; 54 | JsonObject& root = buffer.createObject(); 55 | root["to"] = to.c_str(); 56 | 57 | AddToJson(message, root); 58 | 59 | char payload[root.measureLength() + 1]; 60 | root.printTo(payload, sizeof(payload)); 61 | return SendPayload(payload); 62 | } 63 | 64 | const FirebaseError FirebaseCloudMessaging::SendPayload( 65 | const char* payload) { 66 | std::shared_ptr client(FirebaseHttpClient::create()); 67 | client->begin("http://fcm.googleapis.com/fcm/send"); 68 | client->addHeader("Authorization", auth_header_.c_str()); 69 | client->addHeader("Content-Type", "application/json"); 70 | 71 | int status = client->sendRequest("POST", payload); 72 | if (status != 200) { 73 | return FirebaseError(status, client->errorToString(status)); 74 | } else { 75 | return FirebaseError::OK(); 76 | } 77 | } 78 | 79 | const void FirebaseCloudMessaging::AddToJson( 80 | const FirebaseCloudMessage& message, JsonObject& json) const { 81 | if (!message.collapse_key.empty()) { 82 | json["collapse_key"] = message.collapse_key.c_str(); 83 | } 84 | 85 | json["priority"] = message.high_priority ? "high" : "normal"; 86 | json["delay_while_idle"] = message.delay_while_idle; 87 | if (message.time_to_live > 0 && message.time_to_live < 2419200) { 88 | json["time_to_live"] = message.time_to_live; 89 | } 90 | 91 | if (!message.data.empty()) { 92 | JsonObject& data = json.createNestedObject("data"); 93 | for (const auto& datum : message.data) { 94 | data[datum.first.c_str()] = datum.second.c_str(); 95 | } 96 | } 97 | 98 | if (!message.notification.title.empty() || !message.notification.body.empty()) { 99 | JsonObject& notification = json.createNestedObject("notification"); 100 | if (!message.notification.title.empty()) { 101 | notification["title"] = message.notification.title.c_str(); 102 | } 103 | if (!message.notification.body.empty()) { 104 | notification["body"] = message.notification.body.c_str(); 105 | } 106 | } 107 | } 108 | 109 | -------------------------------------------------------------------------------- /src/FirebaseCloudMessaging.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2016 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | // firebase-arduino is an Arduino client for Firebase. 18 | // It is currently limited to the ESP8266 board family. 19 | 20 | #ifndef firebase_cloud_messaging_h 21 | #define firebase_cloud_messaging_h 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "FirebaseHttpClient.h" 28 | #include "FirebaseError.h" 29 | #include 30 | 31 | // Defines the actual message to the client, for more detail on 32 | // options and settings see: 33 | // https://firebase.google.com/docs/cloud-messaging/http-server-ref 34 | struct FirebaseCloudMessage { 35 | // If you set a collapse_key then when the server receives a 36 | // message, if it already has messages waiting for the client 37 | // with the same collapse_key it will discard them and deliver 38 | // this instead. 39 | std::string collapse_key; 40 | 41 | // If true the user's device will wake to receive the message. 42 | bool high_priority = false; 43 | 44 | // If true message will not be delivered until device is active. 45 | bool delay_while_idle = false; 46 | 47 | // Optional, The message will expire after this many seconds. 48 | // Valid values are 0 to 2,419,200, defaults to max value (4 weeks). 49 | int time_to_live = -1; 50 | 51 | // Optional, defines the notification to be displayed to the user. 52 | struct Notification { 53 | std::string title; 54 | std::string body; 55 | }; 56 | Notification notification; 57 | 58 | // Optional, defines data to be delivered to client application. 59 | std::vector> data; 60 | 61 | static FirebaseCloudMessage SimpleNotification(const std::string& title, const std::string& body); 62 | }; 63 | 64 | // Firebase REST API client. 65 | class FirebaseCloudMessaging { 66 | public: 67 | FirebaseCloudMessaging(const std::string& server_key); 68 | const FirebaseError SendMessageToUser(const std::string& registration_id, 69 | const FirebaseCloudMessage& message); 70 | const FirebaseError SendMessageToUsers(const std::vector& registration_ids, 71 | const FirebaseCloudMessage& message); 72 | 73 | // TODO: The protocol supports sending a message to multiple topics but it is 74 | // not implemented here. 75 | const FirebaseError SendMessageToTopic(const std::string& topic, 76 | const FirebaseCloudMessage& message); 77 | 78 | private: 79 | // Make the actual call to the backend. 80 | const FirebaseError SendPayload(const char* payload); 81 | 82 | const void AddToJson(const FirebaseCloudMessage& message, JsonObject& json) const; 83 | 84 | std::string auth_header_; 85 | }; 86 | #endif // firebase_cloud_messaging_h 87 | -------------------------------------------------------------------------------- /src/FirebaseError.h: -------------------------------------------------------------------------------- 1 | #ifndef firebase_error_h 2 | #define firebase_error_h 3 | 4 | 5 | // These error codes are used in addition to regular HTTP error codes. 6 | // Same error space is shared between HTTP errors and these values. 7 | enum FIREBASE_ERROR_CODES { 8 | HTTP_CONNECTION_LOST = -5, 9 | STREAM_NOT_INITIALIZED = -6 10 | }; 11 | 12 | class FirebaseError { 13 | public: 14 | // Make it explicit that the empty constructor mean no error. 15 | static FirebaseError OK() { 16 | return FirebaseError(); 17 | } 18 | 19 | FirebaseError() {} 20 | FirebaseError(int code, const std::string& message) : code_(code), message_(message) { 21 | } 22 | 23 | operator bool() const { return code_ != 0; } 24 | int code() const { return code_; } 25 | const std::string& message() const { return message_; } 26 | 27 | private: 28 | int code_ = 0; 29 | std::string message_ = ""; 30 | }; 31 | 32 | #endif //firebase_error_h 33 | -------------------------------------------------------------------------------- /src/FirebaseHttpClient.h: -------------------------------------------------------------------------------- 1 | #ifndef FIREBASE_HTTP_CLIENT_H 2 | #define FIREBASE_HTTP_CLIENT_H 3 | 4 | #include 5 | 6 | #include "Arduino.h" 7 | #include "Stream.h" 8 | 9 | struct HttpStatus { 10 | static const int TEMPORARY_REDIRECT = 307; 11 | }; 12 | 13 | class FirebaseHttpClient { 14 | public: 15 | static FirebaseHttpClient* create(); 16 | 17 | virtual void setReuseConnection(bool reuse) = 0; 18 | virtual void begin(const std::string& url) = 0; 19 | virtual void begin(const std::string& host, const std::string& path) = 0; 20 | 21 | virtual void end() = 0; 22 | 23 | virtual void addHeader(const std::string& name, const std::string& value) = 0; 24 | virtual void collectHeaders(const char* header_keys[], 25 | const int header_key_count) = 0; 26 | virtual std::string header(const std::string& name) = 0; 27 | 28 | virtual int sendRequest(const std::string& method, const std::string& data) = 0; 29 | 30 | virtual std::string getString() = 0; 31 | 32 | virtual Stream* getStreamPtr() = 0; 33 | 34 | virtual std::string errorToString(int error_code) = 0; 35 | 36 | virtual bool connected() = 0; 37 | 38 | protected: 39 | static const uint16_t kFirebasePort = 443; 40 | }; 41 | 42 | static const char kFirebaseFingerprint[] = 43 | "03:D6:42:23:03:D1:0C:06:73:F7:E2:BD:29:47:13:C3:22:71:37:1B"; // 2020-02 44 | 45 | #endif // FIREBASE_HTTP_CLIENT_H 46 | -------------------------------------------------------------------------------- /src/FirebaseHttpClient_Esp8266.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "FirebaseHttpClient.h" 3 | 4 | #include 5 | 6 | // The ordering of these includes matters greatly. 7 | #include 8 | #include 9 | #include 10 | 11 | // Detect whether stable version of HTTP library is installed instead of 12 | // master branch and patch in missing status and methods. 13 | #ifndef HTTP_CODE_TEMPORARY_REDIRECT 14 | #define HTTP_CODE_TEMPORARY_REDIRECT 307 15 | #define USE_ESP_ARDUINO_CORE_2_0_0 16 | #endif 17 | 18 | // Firebase now returns `Connection: close` after REST streaming redirection. 19 | // 20 | // Override the built-in ESP8266HTTPClient to *not* close the 21 | // connection if forceReuse it set to `true`. 22 | class ForceReuseHTTPClient : public HTTPClient { 23 | public: 24 | void end() { 25 | if (_forceReuse) { 26 | _canReuse = true; 27 | } 28 | HTTPClient::end(); 29 | } 30 | void forceReuse(bool forceReuse) { 31 | _forceReuse = forceReuse; 32 | } 33 | protected: 34 | bool _forceReuse = false; 35 | }; 36 | 37 | class FirebaseHttpClientEsp8266 : public FirebaseHttpClient { 38 | public: 39 | FirebaseHttpClientEsp8266() {} 40 | 41 | void setReuseConnection(bool reuse) override { 42 | http_.setReuse(reuse); 43 | http_.forceReuse(reuse); 44 | } 45 | 46 | void begin(const std::string& url) override { 47 | http_.begin(url.c_str(), kFirebaseFingerprint); 48 | } 49 | 50 | void begin(const std::string& host, const std::string& path) override { 51 | http_.begin(host.c_str(), kFirebasePort, path.c_str(), kFirebaseFingerprint); 52 | } 53 | 54 | void end() override { 55 | http_.end(); 56 | } 57 | 58 | void addHeader(const std::string& name, const std::string& value) override { 59 | http_.addHeader(name.c_str(), value.c_str()); 60 | } 61 | 62 | void collectHeaders(const char* header_keys[], const int count) override { 63 | http_.collectHeaders(header_keys, count); 64 | } 65 | 66 | std::string header(const std::string& name) override { 67 | return http_.header(name.c_str()).c_str(); 68 | } 69 | 70 | int sendRequest(const std::string& method, const std::string& data) override { 71 | return http_.sendRequest(method.c_str(), (uint8_t*)data.c_str(), data.length()); 72 | } 73 | 74 | std::string getString() override { 75 | return http_.getString().c_str(); 76 | } 77 | 78 | Stream* getStreamPtr() override { 79 | return http_.getStreamPtr(); 80 | } 81 | 82 | std::string errorToString(int error_code) override { 83 | return HTTPClient::errorToString(error_code).c_str(); 84 | } 85 | 86 | bool connected() override { 87 | return http_.connected(); 88 | } 89 | 90 | private: 91 | ForceReuseHTTPClient http_; 92 | }; 93 | 94 | FirebaseHttpClient* FirebaseHttpClient::create() { 95 | return new FirebaseHttpClientEsp8266(); 96 | } 97 | 98 | -------------------------------------------------------------------------------- /src/FirebaseObject.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2016 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #include "FirebaseObject.h" 18 | 19 | // We need to make a copy of data here, even though it may be large. 20 | // It will need to be long lived. 21 | FirebaseObject::FirebaseObject(const char* data) : data_{data} { 22 | buffer_.reset(new StaticJsonBuffer); 23 | json_ = buffer_.get()->parse(&data_[0]); 24 | // TODO(proppy): find a way to check decoding error, tricky because 25 | // ArduinoJson doesn't surface error for variant parsing. 26 | // See: https://github.com/bblanchon/ArduinoJson/issues/279 27 | } 28 | 29 | bool FirebaseObject::getBool(const String& path) const { 30 | JsonVariant variant = getJsonVariant(path); 31 | if (!variant.is()) { 32 | error_ = "failed to convert to bool"; 33 | return 0; 34 | } 35 | error_ = ""; 36 | return static_cast(variant); 37 | } 38 | 39 | int FirebaseObject::getInt(const String& path) const { 40 | JsonVariant variant = getJsonVariant(path); 41 | if (!variant.is() && !variant.is()) { 42 | error_ = "failed to convert to number"; 43 | return 0; 44 | } 45 | error_ = ""; 46 | return static_cast(variant); 47 | } 48 | 49 | float FirebaseObject::getFloat(const String& path) const { 50 | JsonVariant variant = getJsonVariant(path); 51 | if (!variant.is() && !variant.is()) { 52 | error_ = "failed to convert to number"; 53 | return 0; 54 | } 55 | error_ = ""; 56 | return static_cast(variant); 57 | } 58 | 59 | String FirebaseObject::getString(const String& path) const { 60 | JsonVariant variant = getJsonVariant(path); 61 | if (!variant.is() || isNullString(path)) { 62 | error_ = "failed to convert to string"; 63 | return ""; 64 | } 65 | error_ = ""; 66 | return static_cast(variant); 67 | } 68 | 69 | bool FirebaseObject::isNullString(const String& path) const { 70 | JsonVariant variant = getJsonVariant(path); 71 | return variant.is() && variant.asString() == NULL; 72 | } 73 | 74 | JsonVariant FirebaseObject::getJsonVariant(const String& path) const { 75 | String key(path); 76 | char* start = &key[0]; 77 | char* end = start + key.length(); 78 | // skip first `/`. 79 | if (*start == '/') { 80 | start++; 81 | } 82 | JsonVariant json = json_; 83 | while (start < end) { 84 | // TODO(proppy) split in a separate function. 85 | char* p = start; 86 | // advance to next `/`. 87 | while (*p && (*p != '/')) p++; 88 | // make `start` a C string. 89 | *p = 0; 90 | // return json variant at `start`. 91 | json = json.asObject().get(start); 92 | // advance to next path element. 93 | start = p + 1; 94 | } 95 | return json; 96 | } 97 | 98 | bool FirebaseObject::failed() const { 99 | return error_.length() > 0; 100 | } 101 | 102 | bool FirebaseObject::success() const { 103 | return error_.length() == 0; 104 | } 105 | 106 | const String& FirebaseObject::error() const { 107 | return error_; 108 | } 109 | -------------------------------------------------------------------------------- /src/FirebaseObject.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright 2015 Google Inc. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | #ifndef FIREBASE_OBJECT_H 18 | #define FIREBASE_OBJECT_H 19 | 20 | 21 | #include "WString.h" 22 | #include 23 | 24 | #include 25 | 26 | 27 | #ifndef FIREBASE_JSONBUFFER_SIZE 28 | #define FIREBASE_JSONBUFFER_SIZE JSON_OBJECT_SIZE(32) 29 | #endif // FIREBASE_JSONBUFFER_SIZE 30 | 31 | 32 | 33 | /** 34 | * Represents value stored in firebase, may be a singular value (leaf node) or 35 | * a tree structure. 36 | */ 37 | class FirebaseObject { 38 | public: 39 | /** 40 | * Construct from json. 41 | * \param data JSON formatted string. 42 | */ 43 | FirebaseObject(const char* data); 44 | 45 | /** 46 | * Return the value as a boolean. 47 | * \param optional path in the JSON object. 48 | * \return result as a bool. 49 | */ 50 | bool getBool(const String& path = "") const; 51 | 52 | /** 53 | * Returns true if specified path is NULL string. 54 | * Useful to detect tree deletions. 55 | * \param optional path in the JSON object. 56 | * \return result as a bool. 57 | */ 58 | bool isNullString(const String& path = "") const; 59 | 60 | /** 61 | * Return the value as an int. 62 | * \param optional path in the JSON object. 63 | * \return result as an integer. 64 | */ 65 | int getInt(const String& path = "") const; 66 | 67 | /** 68 | * Return the value as a float. 69 | * \param optional path in the JSON object. 70 | * \return result as a float. 71 | */ 72 | float getFloat(const String& path = "") const; 73 | 74 | /** 75 | * Return the value as a String. 76 | * \param optional path in the JSON object. 77 | * \return result as a String. 78 | */ 79 | String getString(const String& path = "") const; 80 | 81 | /** 82 | * Return the value as a JsonVariant. 83 | * \param optional path in the JSON object. 84 | * \return result as a JsonVariant. 85 | */ 86 | JsonVariant getJsonVariant(const String& path = "") const; 87 | 88 | 89 | /** 90 | * 91 | * \return Whether there was an error decoding or accessing the JSON object. 92 | */ 93 | bool success() const; 94 | 95 | /** 96 | * 97 | * \return Whether there was an error decoding or accessing the JSON object. 98 | */ 99 | bool failed() const; 100 | 101 | /** 102 | * 103 | * \return Error message if failed() is true. 104 | */ 105 | const String& error() const; 106 | 107 | private: 108 | String data_; 109 | std::shared_ptr> buffer_; 110 | JsonVariant json_; 111 | mutable String error_; 112 | }; 113 | 114 | #endif // FIREBASE_OBJECT_H 115 | -------------------------------------------------------------------------------- /src/throw_out_of_range.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //TODO(edcoyne): remove this when it is present upstream. 4 | // Currently this is needed to use std::string on Arduino. 5 | namespace std{ 6 | void __attribute__((weak)) __throw_out_of_range(const char* str) { 7 | panic(); 8 | } 9 | } 10 | --------------------------------------------------------------------------------