├── .editorconfig ├── .gitignore ├── .jshintrc ├── .travis.yml ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── api_examples.md ├── build.rs ├── build.sh ├── clippy.toml ├── components ├── core │ ├── Cargo.toml │ └── src │ │ ├── config_store.rs │ │ ├── lib.rs │ │ ├── managed_process.rs │ │ ├── profile_service.rs │ │ ├── traits.rs │ │ ├── upnp.rs │ │ └── utils.rs ├── openzwave-adapter │ ├── Cargo.toml │ └── src │ │ ├── id_map.rs │ │ ├── lib.rs │ │ └── watchers.rs ├── taxonomy │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ ├── src │ │ ├── adapter.rs │ │ ├── adapter_utils.rs │ │ ├── api.rs │ │ ├── backend.rs │ │ ├── channel.rs │ │ ├── fake_adapter.rs │ │ ├── io.rs │ │ ├── lib.rs │ │ ├── lock.rs │ │ ├── manager.rs │ │ ├── parse.rs │ │ ├── selector.rs │ │ ├── services.rs │ │ ├── tag_storage.rs │ │ ├── transact.rs │ │ ├── util.rs │ │ └── values.rs │ ├── tests │ │ └── test_manager.rs │ └── tools │ │ └── execute-unit-tests-with-coverage ├── thinkerbell │ ├── .gitignore │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ ├── examples │ │ ├── events.json │ │ ├── ruleset.json │ │ └── simulator.rs │ ├── src │ │ ├── ast.rs │ │ ├── compile.rs │ │ ├── fake_env.rs │ │ ├── lib.rs │ │ ├── manager.rs │ │ ├── run.rs │ │ └── util.rs │ └── tests │ │ ├── test_manager.rs │ │ ├── test_parse.rs │ │ └── test_rules.rs └── tls │ ├── Cargo.toml │ ├── certificate_manager.rs │ ├── certificate_record.rs │ ├── dns_client.rs │ ├── letsencrypt.rs │ ├── lib.rs │ ├── scripts │ └── letsencrypt.sh │ ├── ssl_context.rs │ ├── test_fixtures │ ├── cert.pem │ ├── chain.pem │ └── privkey.pem │ └── utils.rs ├── docs └── user-manual.md ├── package.json ├── run.sh ├── src ├── adapters │ ├── clock │ │ └── mod.rs │ ├── console │ │ └── mod.rs │ ├── ip_camera │ │ ├── api.rs │ │ ├── mod.rs │ │ └── upnp_listener.rs │ ├── mod.rs │ ├── philips_hue │ │ ├── discovery.rs │ │ ├── http.rs │ │ ├── hub.rs │ │ ├── hub_api.rs │ │ ├── lights.rs │ │ ├── mod.rs │ │ └── structs.rs │ ├── thinkerbell │ │ └── mod.rs │ ├── tts │ │ ├── engine.rs │ │ ├── espeak.rs │ │ └── mod.rs │ └── webpush │ │ ├── crypto.rs │ │ ├── db.rs │ │ └── mod.rs ├── bin │ ├── dnschallenge.rs │ └── foxbox.rs ├── controller.rs ├── http_server.rs ├── lib.rs ├── registration.rs ├── static_router.rs ├── stubs │ └── controller.rs ├── taxonomy_router.rs ├── tunnel_controller.rs └── ws_server.rs ├── static ├── main │ ├── css │ │ └── main.css │ ├── favicon.ico │ ├── index.html │ └── js │ │ ├── console.js │ │ ├── main.js │ │ ├── session.js │ │ └── users.js ├── setup │ ├── favicon.ico │ ├── index.html │ └── js │ │ └── setup.js └── shared │ ├── bower_components │ └── fetch │ │ ├── .bower.json │ │ ├── LICENSE │ │ ├── bower.json │ │ └── fetch.js │ ├── css │ ├── FiraSans │ │ ├── FiraSans-Bold.woff │ │ ├── FiraSans-BoldItalic.woff │ │ ├── FiraSans-Italic.woff │ │ ├── FiraSans-Light.woff │ │ ├── FiraSans-LightItalic.woff │ │ ├── FiraSans-Regular.woff │ │ └── font.css │ └── common.css │ └── js │ ├── url_search_params.js │ └── utils.js ├── test ├── integration │ ├── .jshintrc │ ├── lib │ │ ├── colville.jpg │ │ ├── config │ │ │ ├── foxbox.js │ │ │ └── header.js │ │ ├── foxbox_process_manager.js │ │ ├── html │ │ │ └── philips_initial.html │ │ ├── ipcamera_server.js │ │ ├── json │ │ │ └── bridge_status.json │ │ ├── make_suite.js │ │ ├── nupnp_PhilipsHue.js │ │ ├── philipsHue_server.js │ │ ├── upnp │ │ │ ├── upnp_ipcamera.js │ │ │ └── upnpserver_base.js │ │ └── webpush_server.js │ └── test │ │ ├── ip_camera_test.js │ │ ├── no_travis │ │ └── pagekite_ping_test.js │ │ ├── philips_authentication_test.js │ │ ├── philips_color_test.js │ │ ├── philips_light_test.js │ │ ├── recipe_test.js │ │ └── webpush_test.js ├── ip-camera │ ├── README.md │ └── image │ │ └── jpeg.cgi └── selenium │ ├── .jshintrc │ ├── app_test.js │ ├── lib │ ├── foxbox_process_manager.js │ ├── make_suite.js │ ├── passwords.json │ ├── setup_webapp.js │ └── view │ │ ├── accessor.js │ │ ├── alert.js │ │ ├── app_main │ │ ├── accessor.js │ │ └── view.js │ │ ├── services │ │ ├── accessor.js │ │ └── view.js │ │ ├── set_up │ │ ├── accessor.js │ │ └── view.js │ │ ├── sign_in │ │ ├── accessor.js │ │ └── view.js │ │ ├── signed_in │ │ ├── accessor.js │ │ └── view.js │ │ ├── signed_out │ │ ├── accessor.js │ │ └── view.js │ │ ├── successful_page │ │ ├── accessor.js │ │ └── view.js │ │ └── view.js │ └── sessions_ui_test.js └── tools ├── docker ├── README.md ├── armhf │ ├── Dockerfile │ ├── armhf-linker │ ├── cargoarmhf │ ├── gcc_triple │ ├── rust_target │ └── sources.list ├── build.sh ├── check_args.sh ├── docker.sh ├── package.sh └── support │ ├── launch.sh │ └── open-zwave │ └── config │ ├── 2gig │ ├── ct100.xml │ ├── ct101.xml │ └── ct30.xml │ ├── BeNext │ ├── 1poleswitch.xml │ ├── 2poleswitch.xml │ ├── AlarmSound.xml │ ├── BuiltinDimmer.xml │ ├── DoorSensor.xml │ ├── EnergySwitch.xml │ ├── HeatingControl.xml │ ├── Molite.xml │ ├── PluginDimmer.xml │ ├── SceneController.xml │ └── TagReader.xml │ ├── act │ ├── lfm20.xml │ ├── zdm230.xml │ ├── zdw103.xml │ ├── zdw232.xml │ ├── zir010.xml │ ├── zrp110.xml │ └── zrw103.xml │ ├── aeotec │ ├── alms.xml │ ├── doorbell_gen5.xml │ ├── doorwindow.xml │ ├── drycontactsensor.xml │ ├── dsd31.xml │ ├── dws6.xml │ ├── hdss_gen5.xml │ ├── hem.xml │ ├── hemg2.xml │ ├── keyfob.xml │ ├── keyfob2.xml │ ├── ledbulb.xml │ ├── minimote.xml │ ├── msesv2.xml │ ├── multisensor6.xml │ ├── multisensor_gen5.xml │ ├── panicbtn.xml │ ├── recessed_doorsensor.xml │ ├── recessed_doorsensor_gen5.xml │ ├── sd6.xml │ ├── ses.xml │ ├── ses2.xml │ ├── ss6.xml │ ├── watersensor.xml │ └── zstickgen5.xml │ ├── assa_abloy │ └── RealLivingCapTouch.xml │ ├── cooper │ ├── RF9505-T.xml │ └── RF9540-N.xml │ ├── danfoss │ ├── living.xml │ └── z.xml │ ├── device_classes.xml │ ├── device_classes.xsd │ ├── device_configuration.xsd │ ├── dlink │ ├── dch-z110.xml │ ├── dch-z120.xml │ └── dch-z510.xml │ ├── dragontech │ └── wd-100.xml │ ├── duwi │ ├── ZWES1000.xml │ └── ZWESJ300.xml │ ├── enerwave │ ├── zw15s.xml │ ├── zw20r.xml │ ├── zw500d.xml │ └── zwn-sc7.xml │ ├── eurotronic │ ├── eur_cometz.xml │ └── eur_stellaz.xml │ ├── everspring │ ├── ad146.xml │ ├── ad147.xml │ ├── an145.xml │ ├── an158.xml │ ├── an179.xml │ ├── an180.xml │ ├── hsp02.xml │ ├── se812.xml │ ├── sf812.xml │ ├── sm103.xml │ ├── sp103.xml │ ├── sp814.xml │ ├── st812.xml │ ├── st814.xml │ ├── st815.xml │ └── tse03.xml │ ├── everspringct │ └── hsm02.xml │ ├── evolve │ ├── lrm-as.xml │ ├── lsm-15.xml │ └── ltm-5.xml │ ├── fibaro │ ├── fgbs001.xml │ ├── fgd211.xml │ ├── fgd212.xml │ ├── fgfs101.xml │ ├── fgk001.xml │ ├── fgms.xml │ ├── fgr221.xml │ ├── fgrgbwm441.xml │ ├── fgrm222.xml │ ├── fgs211.xml │ ├── fgs212.xml │ ├── fgs221.xml │ ├── fgs222.xml │ ├── fgsd002.xml │ ├── fgss101.xml │ └── fgwpe.xml │ ├── fortrezz │ └── mimolite.xml │ ├── frostdale │ └── fdn2nxx.xml │ ├── ge │ ├── dimmer.xml │ ├── dimmer_module.xml │ └── relay.xml │ ├── greenwave │ ├── powernode1.xml │ └── powernode6.xml │ ├── homeseer │ ├── ezmotionplus.xml │ ├── hsm100.xml │ ├── hsm200.xml │ └── ztroller.xml │ ├── honeywell │ └── th8320zw1000.xml │ ├── horstmann │ ├── hrt4zw.xml │ └── scsc17.xml │ ├── intermatic │ └── ca8900.xml │ ├── iris │ └── rangeextender.xml │ ├── leviton │ ├── rzi10.xml │ ├── vrcpg.xml │ ├── vrf01.xml │ ├── vri06.xml │ └── vri10.xml │ ├── linear │ ├── PD300Z-2.xml │ └── WD500Z-1.xml │ ├── manufacturer_specific.xml │ ├── manufacturer_specific.xsd │ ├── mcohome │ ├── mhs311.xml │ ├── mhs312.xml │ ├── mhs314.xml │ ├── mhs411.xml │ ├── mhs412.xml │ └── mhs513.xml │ ├── merten │ ├── 507801.xml │ └── 50x5xx.xml │ ├── nodon │ ├── asp3100SmartPlug.xml │ ├── crc3100OctanRemote.xml │ └── cws3101wallswitch.xml │ ├── northq │ └── nq92021.xml │ ├── options.xml │ ├── options.xsd │ ├── philio │ ├── pan04.xml │ ├── pan08.xml │ ├── psm02.xml │ ├── pst02-1c.xml │ ├── pst02-b.xml │ └── pst02.xml │ ├── polycontrol │ ├── doorlock.xml │ ├── keypad.xml │ └── polylock.xml │ ├── popp │ ├── 123580.xml │ ├── 123601.xml │ ├── 123658.xml │ ├── POP009303.xml │ └── POPE009105.xml │ ├── qees │ └── reto-plugin-switch.xml │ ├── qubino │ ├── ZMNHAA2.xml │ ├── ZMNHAD1.xml │ ├── ZMNHBA2.xml │ ├── ZMNHBD1.xml │ ├── ZMNHBD2.xml │ ├── ZMNHCA2.xml │ ├── ZMNHCD.xml │ ├── ZMNHCD1.xml │ ├── ZMNHDA2.xml │ ├── ZMNHDD1.xml │ ├── ZMNHIA2.xml │ ├── ZMNHID1.xml │ ├── ZMNHJA2.xml │ ├── ZMNHJD1.xml │ ├── ZMNHLD1.xml │ ├── ZMNHND1.xml │ ├── ZMNHOD1.xml │ ├── ZMNHSD1.xml │ └── ZMNHUD1.xml │ ├── rcs │ ├── em52-zw.xml │ ├── pm12-zw.xml │ ├── therm0005.xml │ ├── therm0007.xml │ └── therm0009.xml │ ├── remotec │ ├── zfm-80.xml │ ├── zurc.xml │ └── zxt-120.xml │ ├── schlage │ └── BE469NXCEN.xml │ ├── schlagelink │ ├── itemp.xml │ └── minikeypad.xml │ ├── sensative │ └── strips-mazw.xml │ ├── swiid │ ├── swiidinter.xml │ └── swiidplug.xml │ ├── thermofloor │ └── multireg.xml │ ├── trane │ ├── TZEMT400AB32MAA.xml │ └── TZEMT400BB32MAA.xml │ ├── vision │ ├── zd2102.xml │ ├── zm1601eu.xml │ ├── zm1602eu.xml │ ├── zp3102.xml │ └── zs5101eu.xml │ ├── vitrum │ └── vitrumBS.xml │ ├── waynedalton │ └── WDTC-20.xml │ ├── wenzhou │ ├── sm103.xml │ ├── tsp01.xml │ ├── tz65d.xml │ ├── tz66d.xml │ ├── tz67.xml │ ├── tz68.xml │ └── tz88.xml │ ├── widom │ ├── UBS104.xml │ └── UME304C_S.xml │ ├── zipato │ ├── MiniKeypad.xml │ └── RGBBulb.xml │ ├── zwave.me │ ├── ZME_05431.xml │ ├── ZME_05461.xml │ ├── ZME_06433.xml │ ├── ZME_06436.xml │ ├── ZME_064381.xml │ ├── ZME_064435.xml │ ├── ZME_KFOB-S.xml │ ├── ZME_WALLC-S.xml │ ├── ZME_WCD2.xml │ ├── iTemp.xml │ └── kfob.xml │ ├── zwcfg.xsd │ └── zwscene.xsd ├── execute-all-rust-tests.sh ├── execute-selenium-tests.sh ├── execute-unit-tests-with-coverage.sh ├── pre-commit ├── scripts ├── huedemo.sh ├── ipcam.py ├── make-root-ca-and-certs.sh └── svc.py ├── travis-linux-arm_cross_compile.sh ├── travis-linux-cargo_update.sh ├── travis-linux-common.sh ├── travis-linux.sh └── travis-osx.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.js] 15 | indent_size = 2 16 | 17 | [*.json] 18 | indent_size = 2 19 | 20 | [*.html] 21 | indent_size = 2 22 | 23 | [*.yml] 24 | indent_size = 2 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled files 2 | *.o 3 | *.so 4 | *.rlib 5 | *.dll 6 | 7 | # Executables 8 | *.exe 9 | 10 | # Generated by Cargo 11 | /target/ 12 | components/*/target 13 | components/*/Cargo.lock 14 | .cargo 15 | 16 | # Generated by IPCameraAdapter 17 | /snapshots/ 18 | 19 | # Used in selenium tests 20 | node_modules 21 | 22 | # Database files 23 | *.sqlite 24 | 25 | # Folders created by various IDEs 26 | .vscode 27 | .idea 28 | 29 | # vim swap files 30 | .*.sw? 31 | 32 | # Shared copied assets 33 | /static/main/shared 34 | /static/setup/shared 35 | 36 | # Foxbox config 37 | foxbox.conf 38 | 39 | # Generated certs 40 | certs 41 | *.pkcs12 42 | 43 | # Builds in tools/docker 44 | builds 45 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "camelcase": false, 3 | "curly": true, 4 | "forin": false, 5 | "latedef": "nofunc", 6 | "newcap": false, 7 | "noarg": true, 8 | "nonew": true, 9 | "quotmark": "single", 10 | "undef": true, 11 | "unused": "vars", 12 | "strict": true, 13 | "trailing": true, 14 | "maxlen": 80, 15 | 16 | "eqnull": true, 17 | "esnext": true, 18 | "expr": true, 19 | "globalstrict": true, 20 | 21 | "maxerr": 1000, 22 | "regexdash": true, 23 | "laxcomma": true, 24 | "proto": true, 25 | 26 | "browser": true, 27 | "devel": true, 28 | "nonstandard": true, 29 | "worker": true, 30 | 31 | "-W078": true 32 | } 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | os: 4 | # Disabling OS X because of link failures with sqlite. 5 | # - osx 6 | - linux 7 | 8 | dist: trusty 9 | 10 | language: rust 11 | rust: 12 | # Make sure to also update the nightly version for the arm_cross_compile branch of the matrix. 13 | - nightly-2017-01-12 14 | - nightly 15 | 16 | matrix: 17 | fast_finish: true 18 | allow_failures: 19 | - rust: nightly 20 | include: 21 | - os: linux 22 | rust: nightly-2017-01-12 23 | env: BUILD_ENV=-arm_cross_compile 24 | - os: linux 25 | rust: nightly 26 | env: BUILD_ENV=-cargo_update 27 | 28 | addons: 29 | firefox: latest 30 | apt: 31 | packages: 32 | - libupnp-dev 33 | - libespeak-dev 34 | - libudev-dev 35 | # pagekite 36 | - libev-dev 37 | # kcov 38 | - libcurl4-openssl-dev 39 | - libelf-dev 40 | - libdw-dev 41 | 42 | before_install: source $TRAVIS_BUILD_DIR/tools/travis-$TRAVIS_OS_NAME$BUILD_ENV.sh 43 | install: install_dependencies 44 | 45 | before_script: set_up_tests 46 | script: 47 | - build 48 | - lint 49 | - run_tests 50 | -------------------------------------------------------------------------------- /api_examples.md: -------------------------------------------------------------------------------- 1 | # API Usage Examples 2 | 3 | All the requests have to be authenticated unless you compiled Foxbox with 4 | authentication disabled. 5 | 6 | ## To change light status: 7 | 8 | `PUT` to `api/v1/channels/set` : 9 | 10 | ```json 11 | { "select": { 12 | "id": "channel:power.1.001788fffe251236.philips_hue@link.mozilla.org", 13 | "feature": "light/is-on" 14 | }, 15 | "value": "Off" 16 | } 17 | ``` 18 | 19 | ## To retrieve light status: 20 | 21 | `PUT` to `api/v1/channels/get` : 22 | 23 | ```json 24 | { 25 | "id": "channel:power.1.001788fffe251236.philips_hue@link.mozilla.org", 26 | "feature": "light/is-on" 27 | } 28 | ``` 29 | 30 | ## To say something: 31 | 32 | `PUT` to `api/v1/channels/set` : 33 | 34 | ```json 35 | { 36 | "select": { 37 | "id": "setter:talk@link.mozilla.org", 38 | "feature": "speak/sentence" 39 | }, 40 | "value": "Hello FoxBox" 41 | } 42 | ``` -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | use std::env; 6 | use std::fs; 7 | use std::path::Path; 8 | extern crate pkg_config; 9 | 10 | fn update_local_git_hook() { 11 | let p = env::current_dir().unwrap(); 12 | let origin_path = Path::new(&p).join("./tools/pre-commit"); 13 | let dest_path = Path::new(&p).join(".git/hooks/pre-commit"); 14 | 15 | fs::copy(&origin_path, &dest_path).unwrap(); 16 | } 17 | 18 | fn cp_r(origin: &Path, dest: &Path) { 19 | let dir = fs::read_dir(origin).unwrap(); 20 | for file in dir { 21 | let file = file.unwrap(); 22 | let origin_buf = origin.join(file.file_name()); 23 | let origin = origin_buf.as_path(); 24 | let dest_buf = dest.join(file.file_name()); 25 | let dest = dest_buf.as_path(); 26 | 27 | if file.file_type().unwrap().is_dir() { 28 | let dest_str = dest.to_str().unwrap(); 29 | if let Err(_) = fs::metadata(&dest_str) { 30 | fs::create_dir(dest_str).unwrap(); 31 | } 32 | cp_r(origin, dest); 33 | } else { 34 | fs::copy(origin, dest).unwrap(); 35 | } 36 | } 37 | } 38 | 39 | fn copy_shared_static_files() { 40 | let current = env::current_dir().unwrap(); 41 | let shared = Path::new(¤t).join("./static/shared"); 42 | for dest in vec!["./static/setup/shared", "./static/main/shared"] { 43 | let dest = Path::new(¤t).join(dest); 44 | let dest_str = dest.to_str().unwrap(); 45 | if let Err(_) = fs::metadata(&dest_str) { 46 | fs::create_dir(dest_str).unwrap(); 47 | } 48 | cp_r(&shared, &dest); 49 | } 50 | } 51 | 52 | fn link_external_libs() { 53 | pkg_config::probe_library("libupnp").unwrap(); 54 | } 55 | 56 | fn main() { 57 | update_local_git_hook(); 58 | link_external_libs(); 59 | copy_shared_static_files(); 60 | } 61 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Update this when doing a rustup. 4 | EXPECTED_HASH="2782e8f8fcefdce77c5e0dd0846c15c4c5103d84" 5 | EXPECTED_DATE="2017-01-12" 6 | 7 | CURRENT_HASH=`rustc --version -v|grep commit-hash|cut -f 2 -d ' '` 8 | 9 | install_rustc() { 10 | echo "Checking for rustup" 11 | RUSTUP=`which rustup` 12 | if [[ "$RUSTUP" == "" ]]; then 13 | echo "Installing rustup" 14 | curl https://sh.rustup.rs -sSf | sh 15 | RUSTUP=`which rustup` 16 | fi 17 | $RUSTUP install nightly-$EXPECTED_DATE 18 | $RUSTUP override set nightly-$EXPECTED_DATE 19 | } 20 | 21 | prompt_rust_install() { 22 | while true; do 23 | read -p "Do you wish to install the correct Rustc version? [y/n] " yn 24 | case $yn in 25 | [Yy]* ) install_rustc; break;; 26 | [Nn]* ) exit;; 27 | * ) echo "Please answer yes or no.";; 28 | esac 29 | done 30 | } 31 | 32 | if [ "$CURRENT_HASH" != "$EXPECTED_HASH" ]; then 33 | echo "You need Rustc nightly from $EXPECTED_DATE to build." 34 | echo "Found $CURRENT_HASH but expected $EXPECTED_HASH" 35 | prompt_rust_install 36 | fi 37 | 38 | echo "Building..." 39 | set -e -x 40 | cargo build 41 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | doc-valid-idents = ["DLink", "UPnP"] 2 | too-many-arguments-threshold = 8 3 | 4 | -------------------------------------------------------------------------------- /components/core/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foxbox_core" 3 | version = "0.1.0" 4 | authors = ["The Project Link Developers"] 5 | 6 | [lib] 7 | name = "foxbox_core" 8 | path = "src/lib.rs" 9 | 10 | [dependencies.iron] 11 | version = "0.4" 12 | default-features = true 13 | features = ["ssl"] 14 | 15 | [dependencies] 16 | clippy = "0.0" 17 | foxbox_users = { git = "https://github.com/fxbox/users.git", rev = "66add38dcf96e4c56e80fb3f0f35084647567837" } 18 | hyper = "0.9" 19 | libc = "0.2.7" 20 | log = "0.3" 21 | serde_json = "0.8" 22 | tls = { path = "../tls/" } 23 | ws = { version = "0.5", features = ["ssl"] } 24 | xml-rs = "0.3.0" 25 | 26 | [dev-dependencies] 27 | stainless = "0.1.4" 28 | tempdir = "0.3.4" 29 | uuid = { version = "0.3", features = ["v4"] } 30 | -------------------------------------------------------------------------------- /components/core/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | #![feature(plugin)] 6 | 7 | #![plugin(clippy)] 8 | #![deny(clippy)] 9 | 10 | #![cfg_attr(test, feature(const_fn))] // Dependency of stainless 11 | #![cfg_attr(test, plugin(stainless))] // Test runner 12 | 13 | extern crate core; 14 | extern crate foxbox_users; 15 | extern crate hyper; 16 | extern crate libc; 17 | 18 | #[macro_use] 19 | extern crate log; 20 | extern crate serde_json; 21 | 22 | extern crate tls; 23 | 24 | #[cfg(test)] 25 | extern crate uuid; 26 | #[cfg(test)] 27 | extern crate tempdir; 28 | 29 | extern crate ws; 30 | extern crate xml; 31 | 32 | // Needs to come first to let other modules use exported macros. 33 | #[macro_use] 34 | pub mod utils; 35 | 36 | pub mod config_store; 37 | pub mod managed_process; 38 | pub mod profile_service; 39 | pub mod traits; 40 | pub mod upnp; 41 | -------------------------------------------------------------------------------- /components/core/src/traits.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | use config_store::ConfigService; 6 | use foxbox_users::UsersManager; 7 | use profile_service::ProfileService; 8 | use serde_json; 9 | use std::io; 10 | use std::net::SocketAddr; 11 | use std::sync::atomic::AtomicBool; 12 | use std::sync::Arc; 13 | use std::vec::IntoIter; 14 | use tls::{CertificateRecord, CertificateManager}; 15 | use upnp::UpnpManager; 16 | use ws; 17 | 18 | pub trait Controller: Send + Sync + Clone + 'static { 19 | fn run(&mut self, shutdown_flag: &AtomicBool); 20 | fn adapter_started(&self, adapter: String); 21 | fn adapter_notification(&self, notification: serde_json::value::Value); 22 | fn http_as_addrs(&self) -> Result, io::Error>; 23 | fn ws_as_addrs(&self) -> Result, io::Error>; 24 | 25 | fn get_tls_enabled(&self) -> bool; 26 | fn get_certificate_manager(&self) -> CertificateManager; 27 | fn get_box_certificate(&self) -> io::Result; 28 | fn get_hostname(&self) -> String; 29 | fn get_domain(&self) -> String; 30 | 31 | fn add_websocket(&mut self, socket: ws::Sender); 32 | fn remove_websocket(&mut self, socket: ws::Sender); 33 | fn broadcast_to_websockets(&self, data: serde_json::value::Value); 34 | 35 | fn get_config(&self) -> Arc; 36 | fn get_upnp_manager(&self) -> Arc; 37 | fn get_users_manager(&self) -> Arc; 38 | fn get_profile(&self) -> &ProfileService; 39 | } 40 | -------------------------------------------------------------------------------- /components/openzwave-adapter/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "openzwave-adapter" 3 | version = "0.1.0" 4 | authors = ["Julien Wajsberg "] 5 | 6 | [dependencies] 7 | openzwave-stateful = { git = "https://github.com/fxbox/openzwave-stateful-rust" } 8 | foxbox_taxonomy = { path = "../taxonomy/" } 9 | transformable_channels = "^0.1" 10 | log = "^0.3" 11 | -------------------------------------------------------------------------------- /components/openzwave-adapter/src/id_map.rs: -------------------------------------------------------------------------------- 1 | use taxonomy::util::Id as TaxoId; 2 | 3 | use std::sync::{Arc, RwLock}; 4 | 5 | #[derive(Debug, Clone)] 6 | pub struct IdMap { 7 | map: Arc, Type)>>>, 8 | } 9 | 10 | impl IdMap 11 | where Type: Eq + Clone, 12 | Kind: Clone 13 | { 14 | pub fn new() -> Self { 15 | IdMap { map: Arc::new(RwLock::new(Vec::new())) } 16 | } 17 | 18 | pub fn push(&mut self, id: TaxoId, ozw_object: Type) { 19 | let mut guard = self.map.write().unwrap(); // we have bigger problems if we're poisoned 20 | guard.push((id, ozw_object)); 21 | } 22 | 23 | pub fn find_taxo_id_from_ozw(&self, needle: &Type) -> Option> { 24 | let guard = self.map.read().unwrap(); // we have bigger problems if we're poisoned 25 | let find_result = guard.iter().find(|&&(_, ref item)| item == needle); 26 | find_result.map(|&(ref id, _)| id.clone()) 27 | } 28 | 29 | pub fn find_ozw_from_taxo_id(&self, needle: &TaxoId) -> Option { 30 | let guard = self.map.read().unwrap(); // we have bigger problems if we're poisoned 31 | let find_result = guard.iter().find(|&&(ref id, _)| id == needle); 32 | find_result.map(|&(_, ref ozw_object)| ozw_object.clone()) 33 | } 34 | 35 | pub fn remove_by_ozw(&mut self, needle: &Type) -> Option> { 36 | let mut guard = self.map.write().unwrap(); // we have bigger problems if we're poisoned 37 | guard.iter().position(|&(_, ref item)| item == needle).map(|index| guard.remove(index).0) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /components/taxonomy/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foxbox_taxonomy" 3 | version = "0.2.0" 4 | authors = ["David Rajchenbach-Teller "] 5 | 6 | [dependencies] 7 | chrono = "0.2.19" 8 | clippy = "0.0" 9 | lazy_static = "^0.2" 10 | libc = "0.2.9" 11 | log = "0.3" 12 | mopa = "0.2.2" 13 | odds = "0.2.*" 14 | rusqlite = "0.7" 15 | serde = "0.8" 16 | serde_json = "0.8" 17 | serde_derive = "0.8" 18 | string_cache = "^0.2" 19 | sublock = "^0.1" 20 | transformable_channels = "^0.1" 21 | 22 | [dev-dependencies] 23 | assert_matches = "1.0.0" 24 | -------------------------------------------------------------------------------- /components/taxonomy/README.md: -------------------------------------------------------------------------------- 1 | # FoxBox Taxonomy 2 | 3 | [![Build Status](https://api.travis-ci.org/fxbox/taxonomy.svg?branch=master)](https://travis-ci.org/fxbox/taxonomy) 4 | [![Coverage Status](https://coveralls.io/repos/github/fxbox/taxonomy/badge.svg?branch=master)](https://coveralls.io/github/fxbox/taxonomy?branch=master) 5 | [![Clippy Linting Result](http://clippy.bashy.io/github/fxbox/taxonomy/master/badge.svg)](http://clippy.bashy.io/github/fxbox/taxonomy/master/log) 6 | 7 | Specifications-as-code for the high-level API to manipulate devices in 8 | the FoxBox project. 9 | -------------------------------------------------------------------------------- /components/taxonomy/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate defines the high-level API for accessing Connected Devices. 2 | #![feature(custom_derive, plugin, stmt_expr_attributes)] 3 | #![plugin(clippy)] 4 | // To prevent clippy being noisy with derive(...) 5 | #![allow(used_underscore_binding)] 6 | #![allow(let_unit_value)] // For some reason, clippy decides to display this warning, without any hint as to *where* it applies. 7 | 8 | #[macro_use] 9 | extern crate lazy_static; 10 | 11 | extern crate chrono; 12 | extern crate libc; 13 | #[macro_use] 14 | extern crate log; 15 | #[macro_use] 16 | extern crate mopa; 17 | extern crate odds; 18 | extern crate rusqlite; 19 | extern crate serde; 20 | #[macro_use] 21 | extern crate serde_derive; 22 | extern crate serde_json; 23 | extern crate string_cache; 24 | extern crate sublock; 25 | extern crate transformable_channels; 26 | 27 | /// Metadata on devices. 28 | pub mod services; 29 | 30 | /// Metadata on channels. 31 | /// 32 | /// This module also offers definitions for standardized channels. 33 | pub mod channel; 34 | 35 | /// Public-facing API 36 | pub mod api; 37 | 38 | /// Tools for parsing from JSON. 39 | pub mod parse; 40 | 41 | /// Selecting one or more devices. Exposed through the API. 42 | pub mod selector; 43 | 44 | /// Values that may be sent to/received from devices 45 | pub mod values; 46 | 47 | /// Various utilities 48 | pub mod util; 49 | 50 | /// The back-end thread, in charge of the heavy lifting of managing adapters. 51 | mod backend; 52 | 53 | /// The manager provides an API for (un)registering adapters, services, channels, and 54 | /// uses these to implements the taxonomy API. 55 | pub mod manager; 56 | 57 | /// The API for defining Adapters. 58 | pub mod adapter; 59 | 60 | /// Utilities for writing Adapters. 61 | pub mod adapter_utils; 62 | 63 | /// Utility module for inserting values in maps and keeping the insertion reversible in case of 64 | /// any error. 65 | pub mod transact; 66 | 67 | /// Implementation of the database storing tags. 68 | pub mod tag_storage; 69 | 70 | /// Implementation of a fake adapter, controlled entirely programmatically. Designed to be used 71 | /// as a component of tests. 72 | pub mod fake_adapter; 73 | 74 | /// Serialization and deserialization. 75 | pub mod io; 76 | -------------------------------------------------------------------------------- /components/taxonomy/tools/execute-unit-tests-with-coverage: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Warning: kcov is a Linux only tool 4 | 5 | set -ex 6 | 7 | CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 8 | 9 | PROJECT_HOME="$CURRENT_PATH/.." 10 | PROJECT_NAME=$(sed --quiet 's/^name *= *"\(.*\)"$/\1/p' $PROJECT_HOME/Cargo.toml) 11 | PROJECT_BINARY_LOCATION="$PROJECT_HOME/target/debug" 12 | 13 | KCOV_VERSION="30" 14 | KCOV_TEMP="$PROJECT_HOME/target/kcov" 15 | KCOV_COMPILE_HOME="$KCOV_TEMP/kcov-$KCOV_VERSION" 16 | KCOV_BINARY="$KCOV_TEMP/kcov" 17 | 18 | 19 | get_prebuilt() { 20 | local ubuntu_version="$1" 21 | curl --location --output "$KCOV_BINARY" \ 22 | "https://github.com/JohanLorenzo/kcov/releases/download/v$KCOV_VERSION/kcov_$ubuntu_version" 23 | chmod +x "$KCOV_BINARY" 24 | } 25 | 26 | get_and_compile_kcov_locally() { 27 | curl --location --output "$KCOV_TEMP/kcov.tar.gz" \ 28 | "https://github.com/SimonKagstrom/kcov/archive/v$KCOV_VERSION.tar.gz" 29 | tar xvf "$KCOV_TEMP/kcov.tar.gz" --directory="$KCOV_TEMP" 30 | cd "$KCOV_COMPILE_HOME" 31 | cmake . 32 | make 33 | cp "src/kcov" "$KCOV_BINARY" 34 | cd - 35 | } 36 | 37 | get_kcov() { 38 | mkdir -p "$KCOV_TEMP" 39 | 40 | local ubuntu_version=$(lsb_release --codename --short) 41 | if [[ "$ubuntu_version" == 'precise' || "$ubuntu_version" == 'trusty' ]] ; then 42 | get_prebuilt "$ubuntu_version" 43 | else 44 | get_and_compile_kcov_locally 45 | fi 46 | } 47 | 48 | compile_project_with_dead_code() { 49 | RUSTFLAGS="-C link-dead-code" cargo test --no-run 50 | } 51 | 52 | run_tests_and_coverage() { 53 | PROJECT_UNIT_TEST_BINARY=$(find "$PROJECT_BINARY_LOCATION" -maxdepth 1 -executable -name "$PROJECT_NAME"-\*) 54 | 55 | RUST_BACKTRACE=1 "$KCOV_BINARY" \ 56 | --exclude-path="${CARGO_HOME:=~/.cargo},\ 57 | $PROJECT_HOME/src/stubs,\ 58 | $PROJECT_HOME/target" \ 59 | --coveralls-id="${TRAVIS_JOB_ID:=no-job-id}" \ 60 | "$PROJECT_HOME/target/coverage-report/" \ 61 | "$PROJECT_UNIT_TEST_BINARY" 62 | } 63 | 64 | 65 | if ! [ -f "$KCOV_BINARY" ] ; then 66 | get_kcov 67 | fi 68 | 69 | compile_project_with_dead_code 70 | run_tests_and_coverage 71 | -------------------------------------------------------------------------------- /components/thinkerbell/.gitignore: -------------------------------------------------------------------------------- 1 | test_script_database.sqlite 2 | -------------------------------------------------------------------------------- /components/thinkerbell/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "foxbox_thinkerbell" 3 | version = "0.1.2" 4 | authors = ["David Rajchenbach-Teller "] 5 | 6 | [dependencies] 7 | log = "0.3" 8 | serde = "0.8" 9 | serde_json = "0.8" 10 | serde_derive = "0.8" 11 | chrono = "0.2.19" 12 | foxbox_taxonomy = { path = "../taxonomy/" } 13 | rusqlite = "0.7" 14 | transformable_channels = "*" 15 | 16 | [dev-dependencies] 17 | docopt = "0.6.78" 18 | -------------------------------------------------------------------------------- /components/thinkerbell/README.md: -------------------------------------------------------------------------------- 1 | # ThinkerBell: A scripting engine for the world of IoT 2 | 3 | [![Build Status](https://api.travis-ci.org/fxbox/thinkerbell.svg?branch=master)](https://travis-ci.org/fxbox/thinkerbell) 4 | [![Coverage Status](https://coveralls.io/repos/github/fxbox/thinkerbell/badge.svg?branch=master)](https://coveralls.io/github/fxbox/thinkerbell?branch=master) 5 | 6 | ThinkerBell is two things: 7 | - an engine designed to let users assemble scripts to automate their devices, without any knowledge of programming; 8 | - an engine designed to be embedded in a scripting language, to let developers assemble more sophisticated scripts to automate devices. 9 | 10 | The scripts offered by ThinkerBell are designed to be executed on the FoxBox (i.e. a local server). Some of the scripts need to interact with a client-side application, executed on an interactive smart device (i.e. smartphone, smarttv, tablet, computer). 11 | 12 | ThinkerBell is written in Rust, as part of the FoxBox architecture. 13 | 14 | 15 | # User stories 16 | 17 | User stories are filed [as issues](https://github.com/fxbox/thinkerbell/issues?q=is%3Aopen+is%3Aissue+label%3AStory). 18 | 19 | ## See also 20 | 21 | * [More applications of sensors ](http://www.libelium.com/top_50_iot_sensor_applications_ranking/) 22 | * [More applications](https://temboo.com/iot-applications) 23 | * [And on Wikipedia](https://en.wikipedia.org/wiki/Internet_of_Things#Applications) 24 | -------------------------------------------------------------------------------- /components/thinkerbell/examples/events.json: -------------------------------------------------------------------------------- 1 | [{ "AddAdapters": ["Simulator"] }, 2 | { "AddServices": [{ 3 | "adapter": "Simulator", 4 | "tags": [], 5 | "id": "Simulator service", 6 | "getters": {}, 7 | "setters": {} 8 | }]}, { 9 | "AddGetters": [{ 10 | "mechanism": { 11 | "kind": { 12 | "CurrentTimeOfDay": [] 13 | } 14 | }, 15 | "adapter": "Simulator", 16 | "tags": [], 17 | "id": "Clock #1", 18 | "service": "Simulator service" 19 | }] 20 | }, { 21 | "AddSetters": [{ 22 | "adapter": "Simulator", 23 | "tags": [], 24 | "id": "Ready #1", 25 | "service": "Simulator service", 26 | "mechanism": { 27 | "kind": { 28 | "Ready": [] 29 | } 30 | } 31 | }] 32 | }, { 33 | "InjectGetterValues": [["Clock #1", {"Duration": 1}]] 34 | }, { 35 | "InjectGetterValues": [["Clock #1", {"Duration": 2}]] 36 | }, { 37 | "InjectGetterValues": [["Clock #1", {"Duration": 3}]] 38 | }, { 39 | "InjectGetterValues": [["Clock #1", {"Duration": 4}]] 40 | }, { 41 | "InjectGetterValues": [["Clock #1", {"Duration": 5}]] 42 | }, { 43 | "InjectGetterValues": [["Clock #1", {"Duration": 6}]] 44 | }, { 45 | "InjectGetterValues": [["Clock #1", {"Duration": 7}]] 46 | }, { 47 | "InjectGetterValues": [["Clock #1", {"Duration": 8}]] 48 | }, { 49 | "InjectGetterValues": [["Clock #1", {"Duration": 9}]] 50 | }] -------------------------------------------------------------------------------- /components/thinkerbell/examples/ruleset.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Example ruleset", 3 | "rules": [ 4 | { 5 | "conditions": [ 6 | { 7 | "source": [ 8 | { 9 | "feature": "clock/time-of-day-s" 10 | } 11 | ], 12 | "feature": "clock/time-of-day-s", 13 | "when": { 14 | "Duration": 5 15 | } 16 | }, 17 | { 18 | "source": [ 19 | { 20 | "feature": "clock/time-of-day-s" 21 | } 22 | ], 23 | "feature": "clock/time-of-day-s", 24 | "when": { 25 | "Duration": 2 26 | } 27 | } 28 | ], 29 | "execute": [ 30 | { 31 | "destination": [ 32 | { 33 | "feature": "Ready" 34 | } 35 | ], 36 | "value": { 37 | "Unit": [] 38 | }, 39 | "feature": "Ready" 40 | } 41 | ] 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /components/thinkerbell/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(custom_derive)] 2 | //! This create defines mechanisms for executing simple scripts on the 3 | //! server. 4 | //! 5 | //! By design, these scripts have limited capabilities. Each script 6 | //! takes the form of a set of rules: "when any of the input services 7 | //! of foo matches some condition, send some value to all of the onput 8 | //! services of bar". 9 | //! 10 | //! See module `ast` for more details on the grammar of scripts. 11 | 12 | extern crate foxbox_taxonomy; 13 | 14 | extern crate transformable_channels; 15 | 16 | extern crate chrono; 17 | 18 | #[macro_use] 19 | extern crate log; 20 | extern crate rusqlite; 21 | extern crate serde; 22 | #[macro_use] 23 | extern crate serde_derive; 24 | extern crate serde_json; 25 | 26 | 27 | /// Definition of the AST. 28 | pub mod ast; 29 | 30 | /// Compiling an AST into something runnable. 31 | pub mod compile; 32 | 33 | /// Actually executing code. 34 | pub mod run; 35 | 36 | /// Miscellaneous internal utilities. 37 | pub mod util; 38 | 39 | /// An implementation of Thinkerbell's Execution Environment on top of fake devices. 40 | /// Useful mainly for writing tests. 41 | pub mod fake_env; 42 | 43 | /// ScriptManager manages storing and executing scripts. 44 | pub mod manager; 45 | -------------------------------------------------------------------------------- /components/thinkerbell/src/util.rs: -------------------------------------------------------------------------------- 1 | //! Utility functions 2 | 3 | /// Utility function. A variant of `map` that stops in case of error. 4 | pub fn map(vec: Vec, cb: F) -> Result, E> 5 | where F: Fn(T) -> Result 6 | { 7 | let mut result = Vec::with_capacity(vec.len()); 8 | for val in vec { 9 | result.push(try!(cb(val))); 10 | } 11 | Ok(result) 12 | } 13 | -------------------------------------------------------------------------------- /components/thinkerbell/tests/test_parse.rs: -------------------------------------------------------------------------------- 1 | extern crate foxbox_thinkerbell; 2 | extern crate foxbox_taxonomy; 3 | extern crate serde_json; 4 | 5 | use foxbox_taxonomy::parse::*; 6 | use foxbox_thinkerbell::ast::*; 7 | 8 | #[test] 9 | fn test_parse_bad_field() { 10 | let src = "{ 11 | \"name\": \"foo\", 12 | \"requirements\": [], 13 | \"allocations\": [], 14 | \"rules\": [] 15 | }"; 16 | 17 | Script::from_str(src).unwrap(); 18 | } 19 | 20 | #[test] 21 | fn test_parse_empty() { 22 | let src = "{ \"name\": \"foo\", \"rules\": []}"; 23 | let script = Script::from_str(src).unwrap(); 24 | assert_eq!(script.rules.len(), 0); 25 | } 26 | 27 | #[test] 28 | fn test_parse_simple_rule() { 29 | let src = 30 | "{ 31 | \"name\": \"foo\", 32 | \"rules\": [ 33 | { 34 | \"execute\": [], 35 | \"conditions\": [ 36 | ] 37 | } 38 | ] 39 | }"; 40 | Script::from_str(src).unwrap(); 41 | } 42 | 43 | -------------------------------------------------------------------------------- /components/tls/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "tls" 3 | version = "0.1.0" 4 | authors = ["The Project Link Developers"] 5 | publish = false 6 | 7 | [lib] 8 | name = "tls" 9 | path = "lib.rs" 10 | 11 | [dependencies.iron] 12 | version = "0.4" 13 | default-features = true 14 | features = ["ssl"] 15 | 16 | [dependencies] 17 | clippy = "0.0" 18 | hyper = "0.9" 19 | log = "0.3" 20 | mktemp = "0.3" 21 | openssl = "0.7.6" 22 | openssl-sys = "0.7.6" 23 | serde = "0.8" 24 | serde_json = "0.8" 25 | serde_derive = "0.8" 26 | -------------------------------------------------------------------------------- /components/tls/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | #![feature(plugin)] 6 | #![plugin(serde_derive)] 7 | 8 | #![plugin(clippy)] 9 | #![deny(clippy)] 10 | 11 | 12 | #[macro_use] 13 | extern crate hyper; 14 | extern crate iron; 15 | #[macro_use] 16 | extern crate log; 17 | extern crate mktemp; 18 | extern crate openssl; 19 | extern crate openssl_sys; 20 | extern crate serde; 21 | extern crate serde_json; 22 | 23 | macro_rules! checklock ( 24 | ($e: expr) => { 25 | match $e { 26 | Ok(guard) => guard, 27 | Err(poisoned) => poisoned.into_inner(), 28 | } 29 | } 30 | ); 31 | 32 | macro_rules! current_dir { 33 | () => { 34 | { 35 | use std::path::PathBuf; 36 | let mut this_file = PathBuf::from(file!()); 37 | this_file.pop(); 38 | this_file.to_str().unwrap().to_owned() 39 | } 40 | }; 41 | } 42 | 43 | mod certificate_manager; 44 | mod certificate_record; 45 | mod dns_client; 46 | mod letsencrypt; 47 | mod ssl_context; 48 | mod utils; 49 | 50 | pub use certificate_manager::*; 51 | pub use certificate_record::*; 52 | pub use dns_client::*; 53 | pub use letsencrypt::*; 54 | pub use ssl_context::*; 55 | 56 | #[derive(Clone, Eq, PartialEq)] 57 | pub enum TlsOption { 58 | Enabled, 59 | Disabled, 60 | } 61 | -------------------------------------------------------------------------------- /components/tls/test_fixtures/cert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDYDCCAkgCCQDYYy2gwD5CXTANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJV 3 | UzENMAsGA1UECBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xIzAhBgNVBAoTGkFDTUUg 4 | U2lnbmluZyBBdXRob3JpdHkgSW5jMRQwEgYDVQQDEwtleGFtcGxlLmNvbTAgFw0x 5 | NjAzMDkxNDAxMDZaGA80NzU0MDIwNDE0MDEwNlowezELMAkGA1UEBhMCVVMxDTAL 6 | BgNVBAgTBFV0YWgxDjAMBgNVBAcTBVByb3ZvMRYwFAYDVQQKEw1BQ01FIFRlY2gg 7 | SW5jMTUwMwYDVQQDEyxiMjg4MDQ0ZjkwNzcxZjI0NTA3YzNjN2QyMmRmNDRiMi5z 8 | ZWxmLXNpZ25lZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOg6X0kQ 9 | fWCoH7Dr2lspEZlEwp1FgxreFSAbJcodfOebtG3i/hJACAzpHWDSEujk6aBo25NH 10 | bztW8Wa2tbrwi1yLExFjehXCevsa7O409WnS54XGDVMiu4aXIgG0B7W0RvfwNMB4 11 | ZniV4P475QOzy8+a3I5yLuqpMrvQTAObf6jvm+HoPkMtP2wRCb9GKqkTuRJLsX1D 12 | vhtZEHiVWwOgBbY93tYeNlFTqfWpEzeOm1GrSXcW1rcmaMzGj2xvGzbJ4hLJ0IKD 13 | Sx/PpubMCwFGEN22rbOJ52mMd/oBBvvP6rPm/tFUiLurbcOM4PT7ViFK+CVPJ4BB 14 | 0rL8k71rJQYInyECAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAdpxEEJDpq2tz5Z1S 15 | kdqsq2SEEt+0m6ObkiNfrQfGnK/FzTUNl4P63m6XIyoAhdGuxoWUa7RF24fyHOW9 16 | Oro9O+/K4ENlufWOWPxy6I85w8Z4Kv7ZafBwSNBRLaKVMaaNQDh33MShBIWtDpHe 17 | cZNXE2NKEKDWc+t4TErCJ2WAIqPZRjlBKMFkm7EvYAuke9sNN1YnkTdZMzn77ArP 18 | qsS4FNx2fdyrzgXDUiGRqInIUDl0XXW+Any1VnlcDW2VjByXuy4RirDzF+3XS3JD 19 | lii7pQ3DXxQNObZaNKoFHqtfI2h7C3wwAYNdoZ3jZe51Xg4MVSPeVte+4CZCTO2I 20 | LRO3Ew== 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /components/tls/test_fixtures/chain.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIEIDCCAwigAwIBAgIJAOjPWpwsfzRlMA0GCSqGSIb3DQEBBQUAMGcxCzAJBgNV 3 | BAYTAlVTMQ0wCwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMa 4 | QUNNRSBTaWduaW5nIEF1dGhvcml0eSBJbmMxFDASBgNVBAMTC2V4YW1wbGUuY29t 5 | MCAXDTE2MDMwOTE0MDEwNloYDzQ3NTQwMjA0MTQwMTA2WjBnMQswCQYDVQQGEwJV 6 | UzENMAsGA1UECBMEVXRhaDEOMAwGA1UEBxMFUHJvdm8xIzAhBgNVBAoTGkFDTUUg 7 | U2lnbmluZyBBdXRob3JpdHkgSW5jMRQwEgYDVQQDEwtleGFtcGxlLmNvbTCCASIw 8 | DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPKRAxKY8MOJqqKdMIyYHd1paCLb 9 | DS9VoKDwtWmt9OJHF3yM2jHHlI1BBbh7RznHGnXyDu5DM/gZx92CmJpqoZns3AyC 10 | np/HJgD5FVylbkaw7xS+T5xYJYglehmjKZLArBgrguhjZI/tTaNm7TKNeGMaA23+ 11 | 60hzQStsfwo16EeesY0df7JzAUsx6X0tyScLZz5tdGMlM35WoH65pNTmeGaGzTe3 12 | 9FX9m9zi2/zRcmefyP+zTNCaxLACBco1YsN6dDvmPaLYEbU0bC9g/tad2Kvho+f2 13 | MwVtk2daKH8petbbnfiC5znUF4M38+tmkaODSNcsBhs/epvJGCN4mVY5tAECAwEA 14 | AaOBzDCByTAdBgNVHQ4EFgQUGQfomfchFez2VWRNzKXqX19LjwMwgZkGA1UdIwSB 15 | kTCBjoAUGQfomfchFez2VWRNzKXqX19LjwOha6RpMGcxCzAJBgNVBAYTAlVTMQ0w 16 | CwYDVQQIEwRVdGFoMQ4wDAYDVQQHEwVQcm92bzEjMCEGA1UEChMaQUNNRSBTaWdu 17 | aW5nIEF1dGhvcml0eSBJbmMxFDASBgNVBAMTC2V4YW1wbGUuY29tggkA6M9anCx/ 18 | NGUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAqCv2n2Pzdb4kekXQ 19 | SxFYsk9W2FbMHX1vG4Ko8DbfKciWkEKnzUfVdX4IKTEEm/avt0HJKdAjgV7W0qzG 20 | gPTvTiuqA0kSQiSv2x30lPv+cm6CKRYqJYBOYBd5spYy8LJCCNdhofGZxqaBi2go 21 | 3vPkjy9eV1CtBC+k74EGr3Qr5pM10jNs/lJPdcRYwxRMpz1Ycma0o/oF+I8as5HI 22 | 1R1uL4MqQxhOXr2QSjXJNaHsaiw0Jk2wxZFPZ1itCqdCO3TgwRur4RwG8+3WAESc 23 | kdqxAXwawOOWOMvRuzHkv48E6Vq57SnufUwdQGMRK9JOxOvSn+zekJ0jrFXhuEnx 24 | oC9nrg== 25 | -----END CERTIFICATE----- 26 | -------------------------------------------------------------------------------- /components/tls/test_fixtures/privkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEA6DpfSRB9YKgfsOvaWykRmUTCnUWDGt4VIBslyh1855u0beL+ 3 | EkAIDOkdYNIS6OTpoGjbk0dvO1bxZra1uvCLXIsTEWN6FcJ6+xrs7jT1adLnhcYN 4 | UyK7hpciAbQHtbRG9/A0wHhmeJXg/jvlA7PLz5rcjnIu6qkyu9BMA5t/qO+b4eg+ 5 | Qy0/bBEJv0YqqRO5EkuxfUO+G1kQeJVbA6AFtj3e1h42UVOp9akTN46bUatJdxbW 6 | tyZozMaPbG8bNsniEsnQgoNLH8+m5swLAUYQ3bats4nnaYx3+gEG+8/qs+b+0VSI 7 | u6ttw4zg9PtWIUr4JU8ngEHSsvyTvWslBgifIQIDAQABAoIBAEwaXQGPstbLId+T 8 | 2zIGqmrE+tYZYpaacufbna23rigkgaOFQOfwLfM1Ldh9346M/fcAhfyk61HR8zhK 9 | 5hFGJRWFyhDnvamF21GRCFYj6szsPc08Ez/MYRIBUzalreUhGCTGhjMRAdvAmkQW 10 | kr183WzCfkb8Kl3iZurfnxmLivFsPKPJweNZUuo9EJoVsMkbTR6zCet1yzug4Pra 11 | /4jgX/jOSgn2/7VeC6TEreNsiGtihYh5EkqoRC3ojTriYysKPhTjWK6UHpPGrENy 12 | x7Z9Gdmf1HNnSAFoXCjFie6pdAQNNyk2SgN5LIOrfNO/w+P/PR0T0WX+flCOJPTH 13 | pBbpXtUCgYEA9fo0+wP0oyBLbShSyAIQGcgLgeNR1rwFH0oy2QHFnxOMJt9KrqWg 14 | bKWAj+nWPJ8u6WP9/vP4c/muAFLndFrJalCFgGUgGhf456xFY7JWZxZ2Z2m+i9gG 15 | i0uOvGpVnRQPYcScv4qP0lf7LJHV6Bsasq6QRheQxUhYFehvGJaPyP8CgYEA8bC+ 16 | 3UvXcx5YmILl9BBGtzaCf/tnb5wd/4MJ+bHZV4TnWOnJIMBcJ2IOzl9wl1c6pqCm 17 | Bdv3RUTNKkDt3OLsG4KxnzoXsKsWpe76bY3WvCls/xnSFmPas+sJvCYi0PY70fHA 18 | CBtjSuFlSSqgsiwOVaWmi/Jdomys44s99E2md98CgYBO4duFuEIG4j9uFSVfANJb 19 | Aj02fUjsfUWDQE9IKnpOxn0GpksT8QeecADnpgzPShlIPYnh7il6P9LeRbf2J3s6 20 | PfJiN4vw8kkfOq7SBwoQazKzfUTfIfsPRr7Si6NDCYDZUK0X+/6dbRuesnIPyklo 21 | jfS0lbAWpFmjRPQDxZz8zwKBgG6iqbxDa2yXB5dI1FrU2Iolubc8Li05GcJNCdPz 22 | Rbp6bCyXWCpV49ljWcO+jJu6om6EO3uTJa3fwMsGzdu/RLWTLhvlS9LjfoqWyqw7 23 | sYCQtgRQnYsCSqrxfJNUIbvl+5wvPeh4IQu2AddsXAMzh5xNJ+AIIjSn6rx+kO20 24 | Xe+hAoGAV1hqmPVVI9uzd4m9RNK+GL3U0xDBRuQ04stG40hi9Huizg7S2uo3gJAy 25 | NGFkqe/BhyD+x72ar6jWLR7cE8Do3obWeKToTIAjVPDc5R8pNimNlkAEQswSuZB0 26 | ENLRgzys5j0VjeqKwHp3SC9fkDS7majHtoxuRKwG5dqtRAAL4lg= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /docs/user-manual.md: -------------------------------------------------------------------------------- 1 | # Setting up your FoxBox 2 | 3 | * Connect your FoxBox to your internet router, using the ethernet cable provided. 4 | * Browse to [http://foxbox.local/](http://foxbox.local/). 5 | * Follow the instructions there. 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foxbox", 3 | "version": "1.0.0", 4 | "description": "The FoxBox daemon", 5 | "engines": { 6 | "node": ">=4.0.0" 7 | }, 8 | "scripts": { 9 | "test-selenium": "./tools/execute-selenium-tests.sh", 10 | "test-integration": "npm run clean && ./node_modules/.bin/mocha test/integration/test/*.js && ./node_modules/.bin/mocha test/integration/test/no_travis/*.js", 11 | "test-integration-travis": "npm run clean && ./node_modules/.bin/mocha test/integration/test/*.js", 12 | "clean": "npm run clean_db && npm run clean_picture", 13 | "clean_db": "rm -rf ~/.local/share/foxbox", 14 | "clean_picture": "rm -rf ~/.local/share/foxbox/snapshots" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/fxbox/foxbox.git" 19 | }, 20 | "author": "The FoxLink Team", 21 | "license": "MPL-2.0", 22 | "bugs": { 23 | "url": "https://github.com/fxbox/foxbox/issues" 24 | }, 25 | "homepage": "https://github.com/fxbox/foxbox", 26 | "devDependencies": { 27 | "body-parser": "^1.15.0", 28 | "callsite": "^1.0.0", 29 | "chai": "^3.5.0", 30 | "chakram": "^1.2.2", 31 | "config-js": "^1.1.9", 32 | "express": "^4.13.4", 33 | "find": "^0.2.4", 34 | "http_ece": "^0.5.0", 35 | "iso-date": "^1.0.0", 36 | "jshint": "2.9.1", 37 | "media-typer": "^0.3.0", 38 | "mocha": "2.4.5", 39 | "node-ssdp": "^2.7.0", 40 | "path": "^0.12.7", 41 | "raw-body": "^2.1.6", 42 | "selenium-webdriver": "https://github.com/JohanLorenzo/selenium/releases/download/2.54.0-dev/selenium-webdriver-2.54.0-dev.tgz", 43 | "should": "^8.2.2", 44 | "socket.io": "^1.4.5", 45 | "supertest": "^1.2.0", 46 | "urlsafe-base64": "^1.0.0" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | PATH=target/debug:"$PATH" cargo run --bin foxbox "$@" 4 | -------------------------------------------------------------------------------- /src/adapters/tts/engine.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | /// Simple trait to abstract the TTS engine implementation. 6 | pub trait TtsEngine: Send + Sync { 7 | fn init(&self) -> bool; 8 | fn shutdown(&self); 9 | fn say(&self, text: &str); 10 | } 11 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | // Needed to derive `Serialize` on ServiceProperties 6 | #![feature(custom_derive, plugin)] 7 | 8 | // Make linter fail for every warning 9 | #![plugin(clippy)] 10 | 11 | #![deny(clippy)] 12 | 13 | // Needed for many #[derive(...)] macros 14 | #![allow(used_underscore_binding)] 15 | 16 | #![cfg_attr(test, feature(const_fn))] // Dependency of stainless 17 | #![cfg_attr(test, plugin(stainless))] // Test runner 18 | 19 | #![feature(associated_consts)] 20 | 21 | extern crate chrono; 22 | extern crate core; 23 | #[macro_use] 24 | extern crate foxbox_core; 25 | #[macro_use] 26 | extern crate foxbox_taxonomy; 27 | #[cfg(feature = "thinkerbell")] 28 | extern crate foxbox_thinkerbell; 29 | extern crate foxbox_users; 30 | #[macro_use] 31 | extern crate hyper; 32 | #[macro_use] 33 | extern crate iron; 34 | extern crate iron_cors; 35 | #[cfg(test)] 36 | extern crate iron_test; 37 | #[macro_use] 38 | extern crate lazy_static; 39 | extern crate libc; 40 | #[macro_use] 41 | extern crate log; 42 | extern crate mio; 43 | extern crate mount; 44 | extern crate openssl; 45 | extern crate openssl_sys; 46 | extern crate pagekite; 47 | extern crate rand; 48 | extern crate router; 49 | extern crate rusqlite; 50 | extern crate rustc_serialize; 51 | extern crate serde; 52 | #[macro_use] 53 | extern crate serde_derive; 54 | extern crate serde_json; 55 | extern crate staticfile; 56 | extern crate tls; 57 | extern crate time; 58 | extern crate timer; 59 | extern crate transformable_channels; 60 | extern crate unicase; 61 | extern crate url; 62 | extern crate ws; 63 | 64 | // adapters 65 | #[cfg(feature = "zwave")] 66 | extern crate openzwave_adapter as openzwave; 67 | 68 | #[cfg(test)] 69 | extern crate regex; 70 | #[cfg(test)] 71 | extern crate tempdir; 72 | #[cfg(test)] 73 | extern crate uuid; 74 | 75 | #[cfg(test)] 76 | mod stubs { 77 | #![allow(dead_code)] 78 | #![allow(unused_variables)] 79 | #![allow(boxed_local)] 80 | pub mod controller; 81 | } 82 | 83 | mod adapters; 84 | pub mod controller; 85 | mod http_server; 86 | pub mod registration; 87 | mod static_router; 88 | mod taxonomy_router; 89 | pub mod tunnel_controller; 90 | mod ws_server; 91 | -------------------------------------------------------------------------------- /src/static_router.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public 2 | // License, v. 2.0. If a copy of the MPL was not distributed with this 3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 | 5 | use foxbox_users::{UsersManager, UsersDb, ReadFilter}; 6 | use iron::middleware::Handler; 7 | use iron::prelude::*; 8 | use iron::status; 9 | use router::Router; 10 | use staticfile::Static; 11 | use std::path::Path; 12 | use std::sync::Arc; 13 | 14 | fn handler(req: &mut Request, db: &UsersDb) -> IronResult { 15 | let handler = match db.read(ReadFilter::IsAdmin(true)) { 16 | Ok(users) => { 17 | if users.is_empty() { 18 | Static::new(Path::new("static/setup")) 19 | } else { 20 | Static::new(Path::new("static/main")) 21 | } 22 | } 23 | Err(_) => { 24 | return Ok(Response::with(status::InternalServerError)); 25 | } 26 | }; 27 | Handler::handle(&handler, req) 28 | } 29 | 30 | pub fn create(manager: Arc) -> Router { 31 | let mut router = Router::new(); 32 | let usersmanager = manager.clone(); 33 | router.any("", 34 | move |req: &mut Request| -> IronResult { 35 | handler(req, &usersmanager.get_db()) 36 | }, 37 | "_empty_"); 38 | let usersmanager = manager.clone(); 39 | router.any("*", 40 | move |req: &mut Request| -> IronResult { 41 | handler(req, &usersmanager.get_db()) 42 | }, 43 | "_any_"); 44 | router 45 | } 46 | -------------------------------------------------------------------------------- /static/main/css/main.css: -------------------------------------------------------------------------------- 1 | input#console-toggle, 2 | input#users-toggle { 3 | display: none; 4 | visibility: hidden; 5 | } 6 | 7 | label#for-console-toggle, 8 | label#for-users-toggle { 9 | display: block; 10 | padding: 0.5em; 11 | text-align: center; 12 | border-bottom: 1px solid #CCC; 13 | color: #666; 14 | } 15 | 16 | label#for-console-toggle::before, 17 | label#for-users-toggle::before { 18 | content: "+"; 19 | display: inline-block; 20 | width: 20px; 21 | height: 20px; 22 | margin-right: 3px; 23 | } 24 | 25 | #console-toggle:checked ~ #console, 26 | #users-toggle:checked ~ #users { 27 | height: 100%; 28 | } 29 | 30 | #console-toggle:checked ~ label#for-console-toggle::before, 31 | #users-toggle:checked ~ label#for-users-toggle::before { 32 | content: "-"; 33 | } 34 | 35 | #console, 36 | #users { 37 | height: 0px; 38 | overflow: hidden; 39 | } 40 | 41 | #user { 42 | font-size: 1.4rem; 43 | } 44 | 45 | /* Table styling*/ 46 | table { 47 | width: 100%; 48 | border-collapse: collapse; 49 | font-size: 1.4rem; 50 | } 51 | 52 | th { 53 | background: #333; 54 | color: white; 55 | } 56 | 57 | td, th { 58 | padding: 6px; 59 | border-bottom: 1px solid #ccc; 60 | text-align: left; 61 | } 62 | 63 | @media 64 | only screen and (max-width: 760px), 65 | (min-device-width: 768px) and (max-device-width: 1024px) { 66 | 67 | /* Force table to not be like tables anymore */ 68 | table, thead, tbody, th, td, tr { 69 | display: block; 70 | } 71 | 72 | /* Hide table headers (but not display: none;, for accessibility) */ 73 | thead tr { 74 | position: absolute; 75 | top: -9999px; 76 | left: -9999px; 77 | } 78 | 79 | td { 80 | /* Behave like a "row" */ 81 | border: none; 82 | position: relative; 83 | text-align: center; 84 | } 85 | 86 | td:before { 87 | /* Now like a table header */ 88 | position: absolute; 89 | /* Top/left values mimic padding */ 90 | top: 6px; 91 | left: 6px; 92 | width: 45%; 93 | padding-right: 10px; 94 | white-space: nowrap; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /static/main/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/static/main/favicon.ico -------------------------------------------------------------------------------- /static/setup/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/static/setup/favicon.ico -------------------------------------------------------------------------------- /static/setup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | FoxBox 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 41 |
42 | 43 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /static/shared/bower_components/fetch/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fetch", 3 | "main": "fetch.js", 4 | "devDependencies": { 5 | "es6-promise": "1.0.0" 6 | }, 7 | "ignore": [ 8 | ".*", 9 | "*.md", 10 | "examples/", 11 | "Makefile", 12 | "package.json", 13 | "script/", 14 | "test/" 15 | ], 16 | "homepage": "https://github.com/github/fetch", 17 | "version": "0.11.0", 18 | "_release": "0.11.0", 19 | "_resolution": { 20 | "type": "version", 21 | "tag": "v0.11.0", 22 | "commit": "989a1e8132e9adb4c4e973875ad043ff7219fc5a" 23 | }, 24 | "_source": "https://github.com/github/fetch.git", 25 | "_target": "^0.11.0", 26 | "_originalSource": "fetch", 27 | "_direct": true 28 | } -------------------------------------------------------------------------------- /static/shared/bower_components/fetch/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2016 GitHub, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /static/shared/bower_components/fetch/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fetch", 3 | "main": "fetch.js", 4 | "devDependencies": { 5 | "es6-promise": "1.0.0" 6 | }, 7 | "ignore": [ 8 | ".*", 9 | "*.md", 10 | "examples/", 11 | "Makefile", 12 | "package.json", 13 | "script/", 14 | "test/" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /static/shared/css/FiraSans/FiraSans-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/static/shared/css/FiraSans/FiraSans-Bold.woff -------------------------------------------------------------------------------- /static/shared/css/FiraSans/FiraSans-BoldItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/static/shared/css/FiraSans/FiraSans-BoldItalic.woff -------------------------------------------------------------------------------- /static/shared/css/FiraSans/FiraSans-Italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/static/shared/css/FiraSans/FiraSans-Italic.woff -------------------------------------------------------------------------------- /static/shared/css/FiraSans/FiraSans-Light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/static/shared/css/FiraSans/FiraSans-Light.woff -------------------------------------------------------------------------------- /static/shared/css/FiraSans/FiraSans-LightItalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/static/shared/css/FiraSans/FiraSans-LightItalic.woff -------------------------------------------------------------------------------- /static/shared/css/FiraSans/FiraSans-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/static/shared/css/FiraSans/FiraSans-Regular.woff -------------------------------------------------------------------------------- /static/shared/css/FiraSans/font.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Fira Sans'; 3 | font-style: normal; 4 | font-weight: 300; 5 | src: local('Fira Sans Light'), local('Fira-Sans-Light'), url('FiraSans-Light.woff') format('woff'); 6 | } 7 | 8 | @font-face { 9 | font-family: 'Fira Sans'; 10 | font-style: italic; 11 | font-weight: 300; 12 | src: local('Fira Sans Light Italic'), local('Fira-Sans-Light-Italic'), url('FiraSans-LightItalic.woff') format('woff'); 13 | } 14 | 15 | @font-face { 16 | font-family: 'Fira Sans'; 17 | font-style: normal; 18 | font-weight: 400; 19 | src: local('Fira Sans Regular'), local('Fira-Sans-Regular'), url('FiraSans-Regular.woff') format('woff'); 20 | } 21 | 22 | @font-face { 23 | font-family: 'Fira Sans'; 24 | font-style: normal; 25 | font-weight: 700; 26 | src: local('Fira Sans Bold'), local('Fira-Sans-Bold'), url('FiraSans-Bold.woff') format('woff'); 27 | } 28 | 29 | @font-face { 30 | font-family: 'Fira Sans'; 31 | font-style: italic; 32 | font-weight: 400; 33 | src: local('Fira Sans Italic'), local('Fira-Sans-Italic'), url('FiraSans-Italic.woff') format('woff'); 34 | } 35 | 36 | @font-face { 37 | font-family: 'Fira Sans'; 38 | font-style: italic; 39 | font-weight: 700; 40 | src: local('Fira Sans Bold Italic'), local('Fira-Sans-BoldItalic'), url('FiraSans-BoldItalic.woff') format('woff'); 41 | } 42 | -------------------------------------------------------------------------------- /static/shared/js/utils.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | /* export getElementName */ 6 | 7 | 'use strict'; 8 | 9 | function getElementName(str) { 10 | str = str.toLowerCase().replace('#', ''); 11 | return str.replace(/-([a-z])/g, function(g) { 12 | return g[1].toUpperCase(); 13 | }); 14 | } 15 | 16 | function validateEmail(email) { 17 | var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 18 | return re.test(email); 19 | } 20 | -------------------------------------------------------------------------------- /test/integration/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../.jshintrc", 3 | "predef": [ 4 | "require" 5 | ], 6 | "mocha": true, 7 | "node": true 8 | } -------------------------------------------------------------------------------- /test/integration/lib/colville.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/test/integration/lib/colville.jpg -------------------------------------------------------------------------------- /test/integration/lib/config/foxbox.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | 5 | nupnp_server : { 6 | param : 'philips_hue;nupnp_url', 7 | id :'111788fffe230b96', 8 | url : 'http://localhost', 9 | port: '8002' 10 | }, 11 | 12 | credential : { 13 | 'email': 'a@b.com', 14 | 'name': 'admin', 15 | 'password': '87654321' 16 | }, 17 | 18 | pagekite : { 19 | 'r' : 'https://knilxof.org:4443', 20 | 't' : 'knilxof.org:443', 21 | 's' : 'foxbox', 22 | }, 23 | 24 | foxbox : { 25 | url : 'http://localhost:3000' 26 | }, 27 | 28 | ipCamera : { 29 | ip: 'localhost', 30 | port: '8111', 31 | udn: 'ae67e622-7a66-465e-bab0-aaaaaaaaaaaa', 32 | description: 'descriptionurl', 33 | usn: 'urn:cellvision:service:Null:1' 34 | }, 35 | 36 | webpush : { 37 | ip: 'http://localhost', 38 | port: '8112', 39 | endpoint: '/endpoint' 40 | }, 41 | 42 | philips_hue : { 43 | url: 'localhost', 44 | port: 8001 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /test/integration/lib/config/header.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | 5 | 'Content-Type' : 'application/json' 6 | }; -------------------------------------------------------------------------------- /test/integration/lib/nupnp_PhilipsHue.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var express = require ('express'); 3 | 4 | var philips_nupnp_page = (function() { 5 | var _app = express(); 6 | var instance; 7 | 8 | function start(hue_id,hue_ipaddress,port) { 9 | 10 | _app.get('/', function (req, res) { 11 | res.send([{'id':hue_id,'internalipaddress':hue_ipaddress}]); 12 | }); 13 | 14 | return new Promise(resolve => { 15 | instance = _app.listen(port, function () { 16 | console.log('Philips nupnp app listening on port ' + port); 17 | resolve(); 18 | }); 19 | }); 20 | } 21 | 22 | function stop() { 23 | return new Promise(resolve => { 24 | instance.close(function(){ 25 | console.log('nupnp server closed'); 26 | resolve(); // it's like if you called `callback()` 27 | }); 28 | }); 29 | } 30 | 31 | return {start,stop}; 32 | })(); 33 | 34 | module.exports = philips_nupnp_page; -------------------------------------------------------------------------------- /test/integration/lib/upnp/upnp_ipcamera.js: -------------------------------------------------------------------------------- 1 | /* global module */ 2 | 'use strict'; 3 | var upnpServer = require('./upnpserver_base.js'); 4 | 5 | class ipCamera extends upnpServer { 6 | 7 | constructor(ipValue,portValue,udnValue,usnValue,descriptionValue) { 8 | var cameraLocation = 'http://' + ipValue + ':' + portValue; 9 | var ipCamera_config = 10 | { 11 | location:cameraLocation, 12 | udn:udnValue, 13 | description:descriptionValue 14 | }; 15 | 16 | super(ipCamera_config); 17 | this._server.addUSN(usnValue); 18 | } 19 | 20 | startServer (something) { 21 | super.startServer(something); 22 | } 23 | } 24 | module.exports = ipCamera; -------------------------------------------------------------------------------- /test/integration/lib/upnp/upnpserver_base.js: -------------------------------------------------------------------------------- 1 | /* global module */ 2 | 'use strict'; 3 | 4 | const Server = require('node-ssdp').Server; 5 | 6 | class upnpServer { 7 | constructor(parameters) { 8 | this.parameters = parameters; 9 | this._server = new Server(parameters); 10 | } 11 | 12 | createServer() { 13 | console.log('Defining callbacks'); 14 | this._server.on('advertise-alive', function (headers) { 15 | // Expire old devices from your cache. 16 | // Register advertising device somewhere 17 | // (as designated in http headers heads) 18 | console.log('Advertising'); 19 | console.log(headers); 20 | }); 21 | 22 | this._server.on('advertise-bye', function (headers) { 23 | // Remove specified device from cache. 24 | console.log('Saying Bye'); 25 | console.log(headers); 26 | }); 27 | } 28 | 29 | startServer(something) { 30 | console.log('Start server: ' + something); 31 | this._server.start(); 32 | } 33 | 34 | stopServer(something) { 35 | this._server.stop(); 36 | console.log('Stop server: ' + something); 37 | } 38 | } 39 | 40 | module.exports = upnpServer; 41 | -------------------------------------------------------------------------------- /test/integration/test/no_travis/pagekite_ping_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const chakram = require('chakram'), expect = chakram.expect; 4 | const Config = require('config-js'); 5 | 6 | var config = new Config('./test/integration/lib/config/foxbox.js'); 7 | var Prepper = require('../../lib/make_suite.js'); 8 | 9 | Prepper.makeSuite('Verify validity of pagekite ping endpoint', function(){ 10 | var local_url; 11 | var credential = config.get('credential'); 12 | var pingUrl = config.get('pagekite.r') + '/ping'; 13 | 14 | before(Prepper.turnOnAllSimulators); 15 | before(Prepper.turnOnFoxbox); 16 | 17 | it('get address from pagekite ping endpoint', function() { 18 | var pick; 19 | var timestamp = 0; 20 | 21 | return chakram.get(pingUrl,{'json': true}) 22 | .then(function(pingResp){ 23 | for (var match in pingResp.body) { 24 | // may be multiple entries. in that case, pick latest 25 | if (parseInt(pingResp.body[match].timestamp) > 26 | parseInt(timestamp)) { 27 | timestamp = pingResp.body[match].timestamp; 28 | pick = match; 29 | } 30 | } 31 | 32 | expect(pingResp).to.have.status(200); 33 | expect(pingResp.body[pick].timestamp).to.match(/\d+/); 34 | expect(pingResp.body[pick].public_ip).to.match(/\d+.\d+.\d+.\d+/); 35 | // Since tls is disabled, there is no tunnel address 36 | expect(pingResp.body[pick].tunnel_origin).equals(undefined); 37 | }); 38 | }); 39 | 40 | describe('Initiate the remote connection',function(){ 41 | before('fetch the url', function() { 42 | return chakram.get(pingUrl,{'json': true}) 43 | .then(function(pingResp){ 44 | var entry = Prepper.foxboxManager.getLatestIPFromPingSrv(pingResp.body); 45 | var originList = JSON.parse(pingResp.body[entry].message); 46 | 47 | local_url = originList.local_origin; 48 | }); 49 | }); 50 | 51 | it('create account via local_origin',function(){ 52 | return chakram.post(local_url + '/users/v1/setup', credential) 53 | .then(function(setupResp) { 54 | expect(setupResp).to.have.status(201); 55 | }); 56 | }); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /test/integration/test/philips_authentication_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const chakram = require('chakram'), expect = chakram.expect; 4 | 5 | var Prepper = require('../lib/make_suite.js'); 6 | 7 | Prepper.makeSuite('Test Hue Authentication', function () { 8 | 9 | var getterPayload = [{ 'feature': 'light/is-on' }]; 10 | var lights; 11 | 12 | before(Prepper.turnOnAllSimulators); 13 | before(Prepper.turnOnFoxbox); 14 | before(Prepper.foxboxManager.foxboxLogin); 15 | 16 | it('Send light query without authentication', function () { 17 | 18 | // collect all getters for the lightbulbs 19 | return chakram.put(Prepper.foxboxManager.getterURL, getterPayload) 20 | .then(function (listResponse) { 21 | lights = Object.keys(listResponse.body); 22 | expect(lights.length).equals(0); 23 | expect(listResponse).to.have.status(200); 24 | }); 25 | }); 26 | 27 | describe('Authenticate with Philips Hue', function () { 28 | before(Prepper.philipshue_server.pressButton); 29 | 30 | it('Send light query after authentication', function () { 31 | 32 | // collect all getters for the lightbulbs 33 | return chakram.put(Prepper.foxboxManager.getterURL, getterPayload) 34 | .then(function (listResponse) { 35 | lights = Object.keys(listResponse.body); 36 | expect(lights.length).equals(3); 37 | expect(listResponse).to.have.status(200); 38 | }); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /test/ip-camera/README.md: -------------------------------------------------------------------------------- 1 | The image directory contains a small JPEG image 2 | which is used as part of the ip-camera adapter tests. 3 | -------------------------------------------------------------------------------- /test/ip-camera/image/jpeg.cgi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fxbox/foxbox/ca7a3b1a08d160253e002be01bd5686ae8df7c7f/test/ip-camera/image/jpeg.cgi -------------------------------------------------------------------------------- /test/selenium/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../.jshintrc", 3 | "predef": [ 4 | "require" 5 | ], 6 | "mocha": true, 7 | "node": true 8 | } 9 | -------------------------------------------------------------------------------- /test/selenium/app_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const SuiteBuilder = require('./lib/make_suite'); 4 | const HOST_URL = 'http://fxbox.github.io/app'; 5 | 6 | var suiteBuilder = new SuiteBuilder('Github.io webapp', HOST_URL); 7 | 8 | suiteBuilder.build((app) => { 9 | 10 | describe('open the web app', function() { 11 | 12 | var webAppMainPage; 13 | 14 | beforeEach(function() { 15 | webAppMainPage = app.appMainView; 16 | }); 17 | 18 | it('should log in from web app', function() { 19 | return webAppMainPage.connectToFoxBox().then((setUpView) => { 20 | setUpView.successSignUpFromApp(); 21 | }); 22 | }); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /test/selenium/lib/foxbox_process_manager.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const find = require('find'); 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | const spawn = require('child_process').spawn; 7 | const format = require('util').format; 8 | 9 | const PROFILE_PATH = path.join(process.env.HOME, '.local/share/foxbox-tests/'); 10 | const WAIT_TIME_IN_MS = { 11 | startUp: 2500, 12 | shutdown: 500 13 | }; 14 | 15 | 16 | function FoxboxManager() { 17 | this._foxboxInstance = null; 18 | } 19 | 20 | FoxboxManager.PORT = 3331; 21 | FoxboxManager.HOST_URL = format('http://localhost:%d/', FoxboxManager.PORT); 22 | 23 | FoxboxManager.prototype = { 24 | start() { 25 | return new Promise(resolve => { 26 | this._foxboxInstance = spawn('cargo', [ 27 | 'run', '--bin', 'foxbox', '--', 28 | '--disable-tls', 29 | '--port', FoxboxManager.PORT, 30 | '--profile', PROFILE_PATH, 31 | ], { stdio: 'inherit' }); 32 | 33 | setTimeout(resolve, WAIT_TIME_IN_MS.startUp); 34 | }); 35 | }, 36 | 37 | kill() { 38 | return new Promise(resolve => { 39 | this._foxboxInstance.kill('SIGINT'); 40 | 41 | setTimeout(resolve, WAIT_TIME_IN_MS.shutdown); 42 | }); 43 | }, 44 | 45 | cleanData() { 46 | return this._deleteAllProfileButCertificates(); 47 | }, 48 | 49 | /* Keeping certificates allows foxbox to have the same public domain name. 50 | * As a consequence, tests don't fail because many foxboxes are detected on 51 | * github.io. 52 | */ 53 | _deleteAllProfileButCertificates() { 54 | return new Promise(resolve => { 55 | find.file(/^((?!\.pem).)*$/, PROFILE_PATH, files => { 56 | var promises = files.map(file => new Promise(res => { 57 | fs.unlink(file, res); 58 | })); 59 | 60 | Promise.all(promises).then(resolve); 61 | }); 62 | }); 63 | } 64 | }; 65 | 66 | module.exports = FoxboxManager; 67 | -------------------------------------------------------------------------------- /test/selenium/lib/make_suite.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const FoxboxProcessManager = require('./foxbox_process_manager'); 4 | const App = require('./setup_webapp'); 5 | 6 | function Suite(description, hostUrl) { 7 | hostUrl = hostUrl || FoxboxProcessManager.HOST_URL; 8 | this.app = new App(hostUrl); 9 | 10 | this.description = description; 11 | this.foxboxProcessManager = new FoxboxProcessManager(); 12 | } 13 | 14 | Suite.prototype = { 15 | build(subSuite) { 16 | var self = this; 17 | 18 | describe(this.description, function() { 19 | this.timeout(30000); 20 | 21 | before(function() { 22 | return self.foxboxProcessManager.start() 23 | .then(() => self.app.init()); 24 | }); 25 | 26 | subSuite(self.app); 27 | 28 | after(function() { 29 | return self.app.stop() 30 | .then(() => self.foxboxProcessManager.kill()) 31 | .then(() => self.foxboxProcessManager.cleanData()); 32 | }); 33 | }); 34 | }, 35 | 36 | browserCleanUp() { 37 | return this.app.clear() 38 | // init() should run even if clear() failed. This is useful at the initial 39 | // start up, when there is nothing to clear 40 | .then(() => this.app.init(), 41 | () => this.app.init()); 42 | }, 43 | 44 | restartFromScratch() { 45 | return this.app.clear() 46 | .then(() => this.foxboxProcessManager.kill()) 47 | .then(() => this.foxboxProcessManager.cleanData()) 48 | .then(() => this.foxboxProcessManager.start()) 49 | .then(() => this.app.init()); 50 | } 51 | }; 52 | 53 | 54 | module.exports = Suite; 55 | -------------------------------------------------------------------------------- /test/selenium/lib/passwords.json: -------------------------------------------------------------------------------- 1 | { 2 | "valid": 12345678, 3 | "invalids": [{ 4 | "value": "", 5 | "reason": "empty" 6 | }, { 7 | "value": 1234567, 8 | "reason": "short" 9 | }] 10 | } 11 | -------------------------------------------------------------------------------- /test/selenium/lib/setup_webapp.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const webdriver = require('selenium-webdriver'); 4 | const SetUpView = require('./view/set_up/view.js'); 5 | const SignInPageView = require('./view/sign_in/view.js'); 6 | const MainView = require('./view/app_main/view.js'); 7 | var firefoxCapabilities = require('selenium-webdriver/lib/capabilities') 8 | .Capabilities.firefox(); 9 | 10 | firefoxCapabilities.set('marionette', true); 11 | const driverBuilder = new webdriver.Builder() 12 | .withCapabilities(firefoxCapabilities); 13 | 14 | 15 | function SetUpWebapp(url) { 16 | this.url = url; 17 | this.driver = driverBuilder.build(); 18 | } 19 | 20 | SetUpWebapp.prototype = { 21 | init() { 22 | return this.driver.get(this.url) 23 | .then(() => this.defaultView); 24 | }, 25 | 26 | clear() { 27 | // Session data is not stored in cookies, but in local storage 28 | return this._clearLocalStorage() 29 | .then(() => this.init()); 30 | }, 31 | 32 | _clearLocalStorage() { 33 | return this.driver.executeScript('localStorage.clear();'); 34 | }, 35 | 36 | stop() { 37 | return this.driver.quit() 38 | .then(() => { this.driver = null; }); 39 | }, 40 | 41 | get defaultView() { 42 | return this.setUpView; 43 | }, 44 | 45 | get signInPage() { 46 | return new SignInPageView(this.driver); 47 | }, 48 | 49 | get setUpView() { 50 | return new SetUpView(this.driver); 51 | }, 52 | 53 | get appMainView() { 54 | return new MainView(this.driver); 55 | } 56 | }; 57 | 58 | module.exports = SetUpWebapp; 59 | -------------------------------------------------------------------------------- /test/selenium/lib/view/accessor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const webdriver = require('selenium-webdriver'); 4 | const By = webdriver.By; 5 | const until = webdriver.until; 6 | 7 | function Accessor(driver) { 8 | this.driver = driver; 9 | } 10 | 11 | Accessor.prototype = { 12 | /** 13 | * Waits until the element is present *and* displayed. 14 | * @param {string | By} locator - Either the css selector (if string) or a 15 | * "Webdriver By" object. 16 | * @return WebElement 17 | */ 18 | waitForElement(locator) { 19 | locator = typeof locator === 'string' ? By.css(locator) : locator; 20 | 21 | var element = this.driver.wait(until.elementLocated(locator)); 22 | return this.driver.wait(until.elementIsVisible(element)); 23 | } 24 | 25 | }; 26 | 27 | module.exports = Accessor; 28 | -------------------------------------------------------------------------------- /test/selenium/lib/view/alert.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const until = require('selenium-webdriver').until; 4 | 5 | 6 | function AlertWrapper(driver) { 7 | this.driver = driver; 8 | } 9 | 10 | AlertWrapper.prototype = { 11 | 12 | get message() { 13 | return this._waitForAlert().then(alert => alert.getText()); 14 | }, 15 | 16 | accept() { 17 | return this._waitForAlert().then(alert => alert.accept()); 18 | }, 19 | 20 | _waitForAlert() { 21 | return this.driver.wait(until.alertIsPresent()); 22 | }, 23 | }; 24 | 25 | module.exports = AlertWrapper; 26 | -------------------------------------------------------------------------------- /test/selenium/lib/view/app_main/accessor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Accessor = require('../accessor'); 4 | 5 | 6 | function MainAccessor() { 7 | Accessor.apply(this, arguments); 8 | } 9 | 10 | MainAccessor.prototype = Object.assign({ 11 | 12 | get connectToFoxBoxButton() { 13 | return this.waitForElement('.user-login__login-button'); 14 | } 15 | 16 | }, Accessor.prototype); 17 | 18 | module.exports = MainAccessor; 19 | -------------------------------------------------------------------------------- /test/selenium/lib/view/app_main/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const View = require('../view'); 4 | 5 | 6 | function MainView() { 7 | View.apply(this, arguments); 8 | 9 | this.accessor.connectToFoxBoxButton; 10 | } 11 | 12 | MainView.prototype = Object.assign({ 13 | 14 | connectToFoxBox: function() { 15 | return this.accessor.connectToFoxBoxButton.click() 16 | .then(() => this.instanciateNextView('set_up')); 17 | } 18 | 19 | }, View.prototype); 20 | 21 | module.exports = MainView; 22 | -------------------------------------------------------------------------------- /test/selenium/lib/view/services/accessor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Accessor = require('../accessor'); 4 | 5 | 6 | function ServicesAccessor() { 7 | Accessor.apply(this, arguments); 8 | } 9 | 10 | ServicesAccessor.prototype = Object.assign({ 11 | 12 | get logOutButton() { 13 | return this.waitForElement('.user-logout-button'); 14 | }, 15 | 16 | }, Accessor.prototype); 17 | 18 | module.exports = ServicesAccessor; 19 | -------------------------------------------------------------------------------- /test/selenium/lib/view/services/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const View = require('../view'); 4 | 5 | 6 | function ServicesView() { 7 | View.apply(this, arguments); 8 | 9 | this.accessor.logOutButton; // Wait until it appears 10 | } 11 | 12 | module.exports = ServicesView; 13 | -------------------------------------------------------------------------------- /test/selenium/lib/view/set_up/accessor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Accessor = require('../accessor'); 4 | 5 | 6 | function SetUpAccessor() { 7 | Accessor.apply(this, arguments); 8 | } 9 | 10 | SetUpAccessor.prototype = Object.assign({ 11 | get emailField() { 12 | return this.waitForElement('#signup-email'); 13 | }, 14 | 15 | get passwordField() { 16 | // This makes sure password field is not plain text 17 | return this.waitForElement('#signup-pwd1[type="password"]'); 18 | }, 19 | 20 | get confirmPasswordField() { 21 | return this.waitForElement('#signup-pwd2[type="password"]'); 22 | }, 23 | 24 | get submitButton() { 25 | return this.waitForElement('#signup-button'); 26 | }, 27 | 28 | }, Accessor.prototype); 29 | 30 | module.exports = SetUpAccessor; 31 | -------------------------------------------------------------------------------- /test/selenium/lib/view/set_up/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const View = require('../view'); 4 | const PASSWORDS = require('../../passwords.json'); 5 | const Alert = require('../alert.js'); 6 | 7 | 8 | function SetUpView() { 9 | View.apply(this, arguments); 10 | } 11 | 12 | SetUpView.prototype = Object.assign({ 13 | 14 | successLogin(email, password) { 15 | return this._submitPassword(email, password) 16 | .then(() => this.instanciateNextView('successful_page')); 17 | }, 18 | 19 | successSignUpFromApp(email, password) { 20 | return this._submitPassword(email, password) 21 | .then(() => this.instanciateNextView('services')); 22 | }, 23 | 24 | failureLogin(email, password, confirmPassword) { 25 | return this._submitPassword(email, password, confirmPassword) 26 | .then(() => this.alert.message); 27 | }, 28 | 29 | _submitPassword(email, password, confirmPassword) { 30 | password = password !== undefined ? password : PASSWORDS.valid; 31 | confirmPassword = confirmPassword !== undefined ? 32 | confirmPassword : password; 33 | 34 | return this.accessor.emailField.sendKeys(email) 35 | .then(() => this.accessor.passwordField.sendKeys(password)) 36 | .then(() => this.accessor.confirmPasswordField.sendKeys(confirmPassword)) 37 | .then(() => this.accessor.submitButton.click()); 38 | }, 39 | 40 | get alert() { 41 | return new Alert(this.driver); 42 | }, 43 | 44 | acceptAlert() { 45 | return this.alert.accept(); 46 | }, 47 | 48 | }, View.prototype); 49 | 50 | module.exports = SetUpView; 51 | -------------------------------------------------------------------------------- /test/selenium/lib/view/sign_in/accessor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Accessor = require('../accessor'); 4 | 5 | 6 | function SignInAccessor() { 7 | Accessor.apply(this, arguments); 8 | } 9 | 10 | SignInAccessor.prototype = Object.assign({ 11 | get emailField() { 12 | return this.waitForElement('#signin-email'); 13 | }, 14 | 15 | get passwordField() { 16 | // Make sure this field is not plain text 17 | return this.waitForElement('#signin-pwd[type="password"]'); 18 | }, 19 | 20 | get submitButton() { 21 | return this.waitForElement('#signin-button'); 22 | } 23 | 24 | }, Accessor.prototype); 25 | 26 | module.exports = SignInAccessor; 27 | -------------------------------------------------------------------------------- /test/selenium/lib/view/sign_in/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const View = require('../view'); 4 | const PASSWORDS = require('../../passwords.json'); 5 | const Alert = require('../alert.js'); 6 | 7 | 8 | function SignInView() { 9 | View.apply(this, arguments); 10 | } 11 | 12 | SignInView.prototype = Object.assign({ 13 | successLogin(email, password) { 14 | password = password !== undefined ? password : PASSWORDS.valid; 15 | return this._submitPassword(email, password) 16 | .then(() => this.instanciateNextView('signed_in')); 17 | }, 18 | 19 | failureLogin(email, password) { 20 | return this._submitPassword(email, password) 21 | .then(() => new Alert(this.driver).message); 22 | }, 23 | 24 | _submitPassword(email, password) { 25 | return this.accessor.emailField.sendKeys(email) 26 | .then(() => this.accessor.passwordField.sendKeys(password)) 27 | .then(() => this.accessor.submitButton.click()); 28 | }, 29 | 30 | }, View.prototype); 31 | 32 | module.exports = SignInView; 33 | -------------------------------------------------------------------------------- /test/selenium/lib/view/signed_in/accessor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Accessor = require('../accessor'); 4 | 5 | 6 | function SignedInPageAccessor() { 7 | Accessor.apply(this, arguments); 8 | } 9 | 10 | SignedInPageAccessor.prototype = Object.assign({ 11 | get signOutButton() { 12 | return this.waitForElement('#signout-button'); 13 | } 14 | }, Accessor.prototype); 15 | 16 | module.exports = SignedInPageAccessor; 17 | -------------------------------------------------------------------------------- /test/selenium/lib/view/signed_in/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const View = require('../view.js'); 4 | 5 | 6 | function SignedInPageView() { 7 | View.apply(this, arguments); 8 | 9 | this.accessor.signOutButton; // Wait until button is displayed 10 | } 11 | 12 | SignedInPageView.prototype = Object.assign({ 13 | signOut() { 14 | return this.accessor.signOutButton.click() 15 | .then(() => this.instanciateNextView('signed_out')); 16 | } 17 | }, View.prototype); 18 | 19 | module.exports = SignedInPageView; 20 | -------------------------------------------------------------------------------- /test/selenium/lib/view/signed_out/accessor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Accessor = require('../accessor'); 4 | 5 | 6 | function SignedOutAccessor() { 7 | Accessor.apply(this, arguments); 8 | } 9 | 10 | SignedOutAccessor.prototype = Object.assign({ 11 | get root() { 12 | return this.waitForElement('#signin'); 13 | } 14 | }, Accessor.prototype); 15 | 16 | module.exports = SignedOutAccessor; 17 | -------------------------------------------------------------------------------- /test/selenium/lib/view/signed_out/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const View = require('../view.js'); 4 | 5 | function SignedOutPageView() { 6 | View.apply(this, arguments); 7 | 8 | this.accessor.root; 9 | } 10 | 11 | module.exports = SignedOutPageView; 12 | -------------------------------------------------------------------------------- /test/selenium/lib/view/successful_page/accessor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Accessor = require('../accessor'); 4 | 5 | 6 | function SuccessfulPageAccessor() { 7 | Accessor.apply(this, arguments); 8 | } 9 | 10 | SuccessfulPageAccessor.prototype = Object.assign({ 11 | get successMessageElement() { 12 | return this.waitForElement('#thank-you'); 13 | } 14 | }, Accessor.prototype); 15 | 16 | module.exports = SuccessfulPageAccessor; 17 | -------------------------------------------------------------------------------- /test/selenium/lib/view/successful_page/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const View = require('../view'); 4 | 5 | 6 | function SuccessfulPageView() { 7 | View.apply(this, arguments); 8 | 9 | this.accessor.successMessageElement; // Wait until message is displayed 10 | } 11 | 12 | SuccessfulPageView.prototype = Object.assign({ 13 | get loginMessage() { 14 | return this.accessor.successMessageElement.getText(); 15 | }, 16 | 17 | goToSignedIn() { 18 | return this.driver.navigate().to('http://localhost:3331') 19 | .then(() => this.instanciateNextView('signed_in')); 20 | } 21 | }, View.prototype); 22 | 23 | module.exports = SuccessfulPageView; 24 | -------------------------------------------------------------------------------- /test/selenium/lib/view/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const stack = require('callsite'); 4 | const path = require('path'); 5 | 6 | function View(driver) { 7 | this.driver = driver; 8 | 9 | // Here we fetch `accessor.js` located in the same directory than 10 | // the child view 11 | var lastCallerInStackStace = stack()[1]; // 0 actually points to this line 12 | var childViewDirectory = path.dirname(lastCallerInStackStace.getFileName()); 13 | const ChildAccessor = require(childViewDirectory + '/accessor.js'); 14 | this.accessor = new ChildAccessor(this.driver); 15 | } 16 | 17 | View.prototype = { 18 | instanciateNextView(viewFolderName) { 19 | const NextView = require('./' + viewFolderName + '/view.js'); 20 | return new NextView(this.driver); 21 | } 22 | }; 23 | 24 | module.exports = View; 25 | -------------------------------------------------------------------------------- /tools/docker/README.md: -------------------------------------------------------------------------------- 1 | Cross-compiling FoxBox 2 | ====================== 3 | 4 | # Adding a new target 5 | 6 | Each target lives in its own directory (see `rpi2` for instance), where the 7 | scripts expect to find the following: 8 | - A `Dockerfile` to create the docker image. This image must provide all the 9 | tools needed to cross-compile for the target. 10 | - A `gcc_triple` file containing the gcc triple definition for this target. 11 | - A `rust_target` file containing the Rust target definition. 12 | 13 | # Usage 14 | 15 | Three scripts are provided to manage builds: 16 | 17 | ## Creating Docker images 18 | Use `./docker.sh TARGET_NAME` to create a local Docker image name `foxbox-TARGET`. 19 | 20 | ## Building 21 | Run `./build.sh TARGET_NAME` to build a release version. 22 | 23 | ## Packaging 24 | Run `./package.sh TARGET_NAME` to create a package in `builds/TARGET_NAME/foxbox-TARGET_NAME-DATE.tar.bz2`. -------------------------------------------------------------------------------- /tools/docker/armhf/armhf-linker: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | arm-linux-gnueabihf-gcc "$@" 3 | -------------------------------------------------------------------------------- /tools/docker/armhf/cargoarmhf: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cargo "$@" --target=armv7-unknown-linux-gnueabihf -------------------------------------------------------------------------------- /tools/docker/armhf/gcc_triple: -------------------------------------------------------------------------------- 1 | arm-linux-gnueabihf 2 | -------------------------------------------------------------------------------- /tools/docker/armhf/rust_target: -------------------------------------------------------------------------------- 1 | armv7-unknown-linux-gnueabihf 2 | -------------------------------------------------------------------------------- /tools/docker/armhf/sources.list: -------------------------------------------------------------------------------- 1 | deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ trusty main 2 | deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ trusty-updates main 3 | deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ trusty universe 4 | deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ trusty-updates universe 5 | deb [arch=armhf,arm64] http://ports.ubuntu.com/ trusty main 6 | deb [arch=armhf,arm64] http://ports.ubuntu.com/ trusty-updates main 7 | deb [arch=armhf,arm64] http://ports.ubuntu.com/ trusty universe 8 | deb [arch=armhf,arm64] http://ports.ubuntu.com/ trusty-updates universe 9 | -------------------------------------------------------------------------------- /tools/docker/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . ./check_args.sh 4 | 5 | set -x 6 | 7 | docker run --name foxbox_${TARGET}_builder -v `pwd`/../..:/home/user/dev/source -v $HOME/.cargo:/home/user/.cargo foxbox-${TARGET} cargo${TARGET} build --release 8 | docker rm foxbox_${TARGET}_builder 9 | -------------------------------------------------------------------------------- /tools/docker/check_args.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | die () { 4 | # TODO: dynamically get the list of available targets. 5 | echo "Usage: |$0 TARGET| where TARGET can be: rpi2" 6 | exit 1 7 | } 8 | 9 | [ "$#" -eq 1 ] || die 10 | 11 | export TARGET=$1 -------------------------------------------------------------------------------- /tools/docker/docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . ./check_args.sh 4 | 5 | set -x -e 6 | 7 | docker build -t foxbox-${TARGET} ${TARGET} 8 | -------------------------------------------------------------------------------- /tools/docker/package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | . ./check_args.sh 4 | 5 | set -x -e 6 | 7 | DEST_DIR=builds/${TARGET}/dist 8 | RUST_TARGET=`cat ${TARGET}/rust_target` 9 | GCC_TRIPLE=`cat ${TARGET}/gcc_triple` 10 | 11 | function copy_and_strip() { 12 | cp ../../target/${RUST_TARGET}/release/$1 ${DEST_DIR} 13 | docker run --name foxbox_${TARGET}_strip -v `pwd`:/home/user/dev/source foxbox-${TARGET} ${GCC_TRIPLE}-strip ${DEST_DIR}/$1 14 | docker rm foxbox_${TARGET}_strip 15 | } 16 | 17 | mkdir -p ${DEST_DIR}/lib 18 | mkdir -p ${DEST_DIR}/open-zwave/config 19 | 20 | # Copy stripped executables. 21 | copy_and_strip dnschallenge 22 | copy_and_strip foxbox 23 | 24 | # Package the libpagekite dynamic library. 25 | cp `find ../../target/${RUST_TARGET}/release/ -name libpagekite.so.1` ${DEST_DIR}/lib 26 | 27 | # Copy open-zwave configuration files. 28 | # TODO: don't rely on a prebuilt copy in support/ 29 | cp -R support/open-zwave/config ${DEST_DIR} 30 | 31 | cp support/launch.sh ${DEST_DIR} 32 | cp -R ../../static ${DEST_DIR} 33 | 34 | tar -cjf builds/${TARGET}/foxbox-${TARGET}-`date +%Y-%m-%d`.tar.bz2 -C ${DEST_DIR} . 35 | 36 | rm -rf ${DEST_DIR} -------------------------------------------------------------------------------- /tools/docker/support/launch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export LD_LIBRARY_PATH=`pwd`/lib:$LD_LIBRARY_PATH 4 | export PATH=`pwd`:$PATH 5 | 6 | set -x -e 7 | 8 | ./foxbox -s foxbox -t knilxof.org:443 $@ -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/2gig/ct100.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/2gig/ct101.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/2gig/ct30.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/BeNext/1poleswitch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Set all configuration values to default values (factory settings). 9 | 10 | 11 | 12 | The mode in which a different Z-Wave message is sent. 13 | 14 | 15 | 16 | The time that a user has to activate the double button pressed scene, if time is passed then the single pressed button scene is notified. (value * 10 ms) 17 | 18 | 19 | 20 | A signed integer to determine the offset of the temperature. 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/BeNext/2poleswitch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Set all configuration values to default values (factory settings). 9 | 10 | 11 | 12 | The mode in which a different Z-Wave message is sent. 13 | 14 | 15 | 16 | The time that a user has to activate the double button pressed scene, if time is passed then the single pressed button scene is notified. (value * 10 ms) 17 | 18 | 19 | 20 | A signed integer to determine the offset of the temperature. 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/BeNext/EnergySwitch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Set all configuration values to default values (factory settings). 8 | 9 | 10 | The state in what the switch is when power is supplied. 11 | 12 | 13 | 14 | 15 | When the relay is switched it can't be switched again until the configured time has passed. 16 | 17 | 18 | Show the led state compared to the relay state. 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/BeNext/Molite.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Set all configuration values to default values (factory settings). 8 | 9 | 10 | The time used in mode 2 to turn the sensor off. This Time will start running as soon as detection is seen. 11 | 12 | 13 | The switch off time will start running as soon as mode timeout is done. Motion sensor is turned on and when movement is detected again the mode timeout (cfg param 1) will start running all over again. When switch off time is done a basic off message is sent to the associated node. 14 | 15 | 16 | Sensitivity value between 0 and 127 (values above 127 will be reported as the set value but will be handled in SW as 127). 17 | 18 | 19 | The mode that is entered after detection. If mode is 0 or higher then 3, that value will be reported after a get but will be handled in SW as mode 2. 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/BeNext/SceneController.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Set all configuration values to default values (factory settings). 10 | 11 | 12 | 13 | The time that a user has to activate the double button pressed scene, if time is passed then the single pressed button scene is notified. 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/act/lfm20.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/act/zrp110.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/act/zrw103.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dimmers controlled by this switch will start dimming from their current level. 7 | 8 | 9 | 10 | 11 | In night-light mode the LED on the switch will turn ON when the switch is turned OFF. 12 | 13 | 14 | 15 | 16 | Change the top of the switch to OFF and the bottom of the switch to ON. 17 | 18 | 19 | 20 | 21 | The ZRW103 will flicker its LED when it is transmitting to any of its 4 groups. This flickering can be set to not flicker at all, to flicker the entire time it is transmitting, or to flicker for only 1 second when it begins transmitting. 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/aeotec/keyfob2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Enable selective Group Mode or Scene Mode when the Key Fob is in Use mode 14 | 15 | 16 | 17 | 18 | 19 | Reset configuration set up to default setting 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/aeotec/panicbtn.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Enable selective Group Mode or Scene Mode when the Panic Button is in Use mode 14 | 15 | 16 | 17 | 18 | 19 | Reset configuration set up to default setting 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/aeotec/watersensor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Toggle the sensor binary report value when the Water Sensor is Triggered 9 | 10 | 11 | 12 | 13 | Enable wake up 10 minutes when the power is switched on. 14 | 15 | 16 | 17 | 18 | Toggle the basic set value when the Water Sensor is Triggered 19 | 20 | 21 | 22 | 23 | To set which command will be sent to the associated nodes when the Water Sensor is triggered. 24 | Bitsets: 25 | 1 -> Battery 26 | 4 -> Sensor Binary 27 | 8 -> Basic Set 28 | 12 -> Alarm 29 | Default setting: 0x100 (Basic Set) 30 | OZW Ideal Setting: 0x1011 (Battery, Sensor Binary Report, Alarm) 31 | 32 | 33 | 34 | 35 | Reset to factory defaults. 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/aeotec/zstickgen5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | When the USB power supply, the LED indicator light configuration 8 | 9 | 10 | 11 | 12 | 1~10, other= ignore. 13 | A total of 10 levels, level 1 as the weak output power, and so on, 10 for most output power level 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Lock/ unlock all configuration parameters 35 | 36 | 37 | 38 | 39 | Reset to the default configuration 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/assa_abloy/RealLivingCapTouch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/danfoss/living.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/danfoss/z.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/dlink/dch-z510.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Bit 0: Reserved 10 | Bit 1: Reserved 11 | Bit 2: Reserved 12 | Bit 3: Reserved 13 | Bit 4: Notification type (0: Using Notification Report, 1: Using sensor Binary Report). 14 | Bit 5: Reserved 15 | Bit 6: Reserved 16 | Bit 7: Reserved 17 | 18 | 19 | 20 | 21 | Disable the alarm function. 22 | 0: Enable Alarm, 1:Disable Alarm, 23 | Caution: After the power up, this configuration always be 0. 24 | 25 | 26 | 27 | 28 | 29 | 30 | Play alarm sound duration. 31 | 1 tick is 30 second. Default is 3 minutes, maximum is 63.5 minutes. 32 | 0: means never auto stop 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/dragontech/wd-100.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | The orientation of the ON/OFF on the rocker switch can be inverted by changing the configuration item from 0 to 1 8 | 9 | 10 | 11 | 12 | indicates the number of levels the lighting will change when the timer runs out 13 | 14 | 15 | 16 | 17 | indicates the time duration of each level. The resolution is 10 miliseconds. for example, a default value of 3 means the timer runs out every 30 milliseconds. 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/duwi/ZWES1000.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/duwi/ZWESJ300.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Continuous operation. 0x01-0x7F: 1-127 seconds in 1-second steps. 0x80-0xFE: 130-1390 seconds (0xFE) in 10 second-steps. 0xFF: 120 seconds (default; 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/enerwave/zw15s.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Set to 1 for LED to be in sync with switch. 8 | 9 | 10 | 11 | 12 | Set to 1 for "up" to turn the load off. 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/enerwave/zw20r.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Set to 1 for LED to be in sync with switch. 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/enerwave/zw500d.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Set to 1 for LED to be in sync with switch. 8 | 9 | 10 | 11 | 12 | Set to 1 for "up" to turn the load off. 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/enerwave/zwn-sc7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/eurotronic/eur_cometz.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/eurotronic/eur_stellaz.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/ad146.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 0 is off. 1 to 99 sets output level at specified value. 9 | 255 sets output level at last memorized level 10 | 11 | 12 | 13 | 14 | Delaying time to report to Group 1 15 | 16 | 17 | 18 | 19 | Remember the last status: 0 (do not remember) | 1 (remember) 20 | 21 | 22 | 23 | 24 | 0: Single Pole Double Throw (1: Toggle switch) 25 | 26 | 27 | 28 | 29 | Output mode setting: 0 (dimming) | 1 (on/off) 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/ad147.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 is off. 1 to 99 sets output level at specified value. 10 | 255 sets output level at last memorized level 11 | 12 | 13 | 14 | 15 | Delaying time to report to Group 1 16 | 17 | 18 | 19 | 20 | Remember the last status: 0 (do not remember) | 1 (remember) 21 | 22 | 23 | 24 | 25 | Output mode setting: 0 (dimming) | 1 (on/off) 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/an145.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/an158.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | This is the time the switching status needs to remain 10 | unchanged after a change to cause the device to send out a status 11 | message. 0 is Disabled. 12 | 13 | 14 | 15 | 16 | Enable or Disable Send Basic Command to Group 2 when the local 17 | button press changes the switching state. 18 | 19 | 20 | 21 | 22 | The device will report its meter value within the interval 23 | set. Set to 0 will disable the autoreporting function. 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/an179.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Basic Set Command value 7 | 8 | 9 | 10 | The delaying time to report to Group 1 11 | 12 | 13 | 14 | 15 | Remember the last status on plug 16 | 17 | 18 | 19 | 20 | 21 | 22 | 0: Single Pole Double Throw (1: Toggle switch) 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/an180.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Basic Set Command value 7 | 8 | 9 | 10 | The delaying time to report to Group 1 11 | 12 | 13 | 14 | 15 | Remember the last status on plug 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/hsp02.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | When Basic Set Command is sent where contains a value, the receiver will take it for consideration; for instance, if a lamp module is received the Basic Set Command of which value is decisive as to how bright of dim level of lamp modeule shall be. 8 | 9 | 10 | 11 | 12 | The Detecting function can be Disabled of Enabled. 13 | 14 | 15 | 16 | 17 | 1 Means lowest sensitivity and 10 means highest. 18 | 19 | 20 | 21 | 22 | Adjust the interval of being re-triggered afer the detector has been triggered in seconds. 23 | 24 | 25 | 26 | 27 | Sets minimum Lux Level of ambient illumination neccesary for Motion Detector to trigger. 28 | 29 | 30 | 31 | 32 | The duration determines how long before the module sends an Off after being triggered. 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/se812.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/sf812.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/sm103.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Defines the level in the event sent when the sensor is triggered. Default is 99 (full brightness for a Z-Wave dimmer). 100-127 will set device on to the last value it was when turned off. 8 | 9 | 10 | 11 | 12 | On Time sets the number of seconds the sensor stays alerted before the off event is sent. 13 | 14 | 15 | 16 | 17 | Enable/Disable power saving mode. 0 enables. 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/sp103.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Phase Level of ON Command 9 | The Configuration parameter that can be used to adjust the phase level of ON command is transmitted is Configuration Parameter # 1. 10 | This parameter can be configured with the value of 0 through 127. 11 | Value 0: Set Device OFF(0x00) 12 | Value 1-99: Set Device On (1-99) 13 | Value 100-127: Set Device On to the last phase (0xFF) 14 | Note: 0xFF means the device will be on to the last phase before the device was turned off. 15 | Information reproduced from: http://www.techstyleuk.co.uk/index_files/sp103_manual.pdf 16 | 17 | 18 | 19 | 20 | Enabling/Disabling Power Saving Function (for testing) 21 | When no movement has been detected for 10 seconds, the SP103 will enter the power saving mode. 22 | It can be disabled or enabled power saving function by setting Configuration Parameter # 3. 23 | This parameter can be configured with the value of 0 through 127, where 0 means power saving being enabled and others mean power saving being disabled. 24 | PS : As long as the batteries have been refitted, the Detector will enable the power saving function automatically. 25 | Information reproduced from: http://www.techstyleuk.co.uk/index_files/sp103_manual.pdf 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/sp814.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | When Basic Set Command is sent where contains a value, the receiver will take it for consideration; for instance, if a lamp module is received the Basic Set Command of which value is decisive as to how bright of dim level of lamp modeule shall be. 8 | 9 | 10 | 11 | 12 | The Detecting function can be Disabled of Enabled. 13 | 14 | 15 | 16 | 17 | 1 Means lowest sensitivity and 10 means highest. 18 | 19 | 20 | 21 | 22 | Adjust the interval of being re-triggered afer the detector has been triggered in seconds. 23 | 24 | 25 | 26 | 27 | Sets minimum Lux Level of ambient illumination neccesary for Motion Detector to trigger. 28 | 29 | 30 | 31 | 32 | The duration determines how long before the module sends an Off after being triggered. 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/st812.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Defines the level in the Basic Set event sent to group 2 when the sensor is triggered. Default is 99 (full brightness for a Z-Wave dimmer). 0 disables. 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/st815.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Defines the level in the Basic Set event sent to group 2 when the sensor is triggered. Default is 99 (full brightness for a Z-Wave dimmer). 0 disables. 8 | 9 | 10 | 11 | 12 | Lux level to trigger when a ON command is sent out. 0 will clear the value. 13 | 14 | 15 | 16 | 17 | Lux level to trigger when an OFF command is sent out. 0 will clear the value. 18 | 19 | 20 | 21 | 22 | Set Lux timer trigger to send an OFF command. 0 will clear the value. 23 | 24 | 25 | 26 | 27 | Sets the auto report time interval. 0 disables. 28 | 29 | 30 | 31 | 32 | Sets the auto report Lux interval. 0 disabled. 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/everspring/tse03.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/evolve/lrm-as.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | By default, the LED on the LRM-AS will turn OFF when the load attached is turned ON. To make the LED turn ON when the load attached is turned ON, set parameter to a value of 0. 10 | 11 | 12 | To change the top of the switch to OFF and the bottom of the switch to ON, set parameter to 1. 13 | 14 | 15 | Set this parameter to 0 to disable load sense. Set this parameter to 1 to enable load sense 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/evolve/lsm-15.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | By default, the LED on the LSM-15 will turn OFF when the load attached is turned ON. To make the LED turn ON when the load attached is turned ON, set parameter to a value of 0. 10 | 11 | 12 | To change the top of the switch to OFF and the bottom of the switch to ON, set parameter to 1. 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/evolve/ltm-5.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dimmers controlled by this switch will start dimming from their current level. 7 | 8 | 9 | 10 | 11 | In night-light mode the LED on the switch will turn ON when the switch is turned OFF. 12 | 13 | 14 | 15 | 16 | Change the top of the switch to OFF and the bottom of the switch to ON. 17 | 18 | 19 | 20 | 21 | This dimmer will start dimming from its current level. 22 | 23 | 24 | 25 | 26 | Flicker LED while transmitting. 27 | 28 | 29 | 30 | 31 | 32 | How often to poll to keep synchronized with group. 33 | 34 | 35 | Poll only the first node in Group 1. 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/frostdale/fdn2nxx.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/ge/relay.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | In night-light mode the LED on the switch will turn ON when the switch is turned OFF. 7 | 8 | 9 | 10 | 11 | Change the top of the switch to OFF and the bottom of the switch to ON. Note: If you invert the switches and also install the product upside down, remember the load will now be controlled by the right, not the left switch. 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/greenwave/powernode1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | After how many minutes the GreenWave device should start flashing if the controller didn't communicate with this device 8 | 9 | 10 | 11 | The room color (Corner wheel color) on the GreenWave device 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/greenwave/powernode6.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | After how many minutes the GreenWave device should start flashing if the controller didn't communicate with this device 8 | 9 | 10 | 11 | The room color (Corner wheel color) on the GreenWave device 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/homeseer/ztroller.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/honeywell/th8320zw1000.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/horstmann/hrt4zw.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 0-127 = Disabled. 20 | 128-255 = Enabled. 21 | 22 | 23 | 24 | 25 | 0-127 = Celsius. 26 | 128-255 = Fahrenheit. 27 | 28 | 29 | 30 | 31 | Delta T in steps of 0.1 degree. 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/horstmann/scsc17.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/intermatic/ca8900.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/iris/rangeextender.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/leviton/rzi10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/leviton/vrcpg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/leviton/vrf01.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/leviton/vri06.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/leviton/vri10.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/linear/PD300Z-2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Turn on the module when the attached load is connected. 7 | 8 | 9 | This dimmer will always start dimming from its current level, ignoring any commanded start level. 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/linear/WD500Z-1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | In night-light mode the LED on the switch will turn ON when the switch is turned OFF, instead of folliwng the state of the load. 7 | 8 | 9 | 10 | 11 | Change the top of the switch to OFF and the bottom of the switch to ON. 12 | 13 | 14 | This dimmer will always start dimming from its current level, ignoring any commanded start level. 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/manufacturer_specific.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/mcohome/mhs311.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Switch state saved or not when power down 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/mcohome/mhs312.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Switch state saved or not when power down 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/mcohome/mhs314.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Switch state saved or not when power down 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/mcohome/mhs411.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Switch state saved or not when power down 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/mcohome/mhs412.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Switch state saved or not when power down 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/mcohome/mhs513.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Switch state saved or not when power down 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/merten/507801.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | To configure the time (value * 0.1 sec) the motor waits before switching direction. 9 | 10 | 11 | 12 | To configure input 1 of the raising time calculation (256 * Input 1 + Input 2) * 0.1 sec 13 | 14 | 15 | 16 | To configure input 1 of the raising time calculation (256 * Input 1 + Input 2) * 0.1 sec 17 | 18 | 19 | 20 | To configure input 1 of the lowering time calculation (256 * Input 1 + Input 2) * 0.1 sec 21 | 22 | 23 | 24 | To configure input 1 of the lowering time calculation (256 * Input 1 + Input 2) * 0.1 sec 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/options.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/options.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/philio/pan08.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Watt Meter Report Period. Unit: 5 seconds. 9 | 10 | 11 | 12 | kWH Meter Report Period. Unit: 10 minutes. 13 | 14 | 15 | 16 | Threshold of Watt for Load Caution. Unit: 1 watt 17 | 18 | 19 | 20 | Threshold of kWH for Load Caution. Unit: 1 kWH 21 | 22 | 23 | 24 | External switch type: 1-> One Push button, 2->Two Push button 25 | 26 | 27 | 28 | Level report mode: 1-> Report destination level in 5s, 2-> Report 10 percent level while running 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/polycontrol/keypad.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/polycontrol/polylock.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 0=The motor goes clockwise when unlatched; 1= The motor goes counterclockwise when unlatched 12 | 13 | 14 | Motor/relay run time LOCK in sec 1-15 15 | 16 | 17 | Motor/relay run time UNLOCK in sec 1-15 18 | 19 | 20 | Value 0-15/0=fastest 15=slowest 21 | 22 | 23 | How the motor will turn according to torque and speed 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/popp/123658.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | If the setting is configured for 1 hour(set value=720), the device will report its instant power consumption every 1 hour to Z_Wave controller. Unit: 5 secs, Min: 1, Max: 32767, Default: 720 10 | 11 | 12 | 13 | If the setting is configured for 1 hour(set value=6), the device will report its Accumulated power consumption (KW/h) every hour to Z_Wave controller. Unit: 10 min, Min: 1, Max: 32767, Default: 6 14 | 15 | 16 | 17 | This is a warning when the wattage of load over the present threshold value, if the load wattage exceeds the setting value the device will send a warning alarm command to the controller. Min: 10, Max: 3000, Default: 3000 18 | 19 | 20 | 21 | 0 for Switch Off, 1 for Last Switch State (Default), 2 for Switch On 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/qees/reto-plugin-switch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/rcs/em52-zw.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/rcs/pm12-zw.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/rcs/therm0005.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/rcs/therm0007.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/rcs/therm0009.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/remotec/zfm-80.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Set external switch type. 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Set timeout period. 15 | 16 | 17 | Configure Node ID number for Z-Wave command source. 18 | 19 | 20 | Set relay output status if timeout period has been reached. 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/remotec/zurc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/schlagelink/itemp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Attention: This will delete all your configuration, but the device will remain in the network. Handle with care. 9 | 10 | 11 | 12 | 13 | 14 | Configure what the external contact sends when trigger 15 | 16 | 17 | 18 | 19 | 20 | Defines if the sensor is in normal wakeup-mode or always on. This function shall be used only for testing since it draining the battery very fast. 21 | 22 | 23 | 24 | 25 | 26 | Offset to the temperature. This parameter can be used to calibrate the temperature sensor function if needed. Note. As factory default the temperature sensor function is calibrated. 0 = 0K (default), not 0 = Temperature Offset in K 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/schlagelink/minikeypad.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Set all configuration values to default values (factory settings) if set to 0xff. 10 | 11 | 12 | 13 | To configure the time the beep is automatically turned off in seconds. 0 means disabled. 255 is endless 14 | 15 | 16 | 17 | To configure the timeout to wait for a WAKEUP_NO_MORE_INFORMATION before the error beep is automatically sound. The error beeps are fixed 8 beeps shortly after each other. 0 means disabled 18 | 19 | 20 | 21 | To configure the number of beeps per second. Every beep is fixed about 10ms. 22 | 23 | 24 | 25 | To configure the operating mode. If any mode other then 3, that value will be reported after a get but will be handled in SW as mode 1. 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/sensative/strips-mazw.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Define the notification type. 9 | 10 | 11 | 12 | 13 | 14 | Specify if LED should indicate special event. 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/swiid/swiidinter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Activate/Deactive ALL ON/OFF 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/swiid/swiidplug.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Activate/Deactive ALL ON/OFF 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/vision/zd2102.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | External Switch Status 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/vision/zm1601eu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Defines the reaction of the siren: [0] Strobe and Siren, [1] Siren, [2] Strobe (Default setting: 0) 8 | 9 | 10 | Defines the auto time out of the alarm indication: [0] 30 seconds, [1] 60 seconds, [2] 120 seconds, [3] Continuous (Default setting: 0) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/vision/zm1602eu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Defines the reaction of the siren: [0] Strobe and Siren, [1] Siren, [2] Strobe (Default setting: 0) 8 | 9 | 10 | Defines the auto time out of the alarm indication: [0] 30 seconds, [1] 60 seconds, [2] 120 seconds, [3] Continuous (Default setting: 0) 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/vision/zs5101eu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/vitrum/vitrumBS.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/waynedalton/WDTC-20.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/wenzhou/sm103.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Defines the level in the event sent when the sensor is triggered. Default is 99 (full brightness for a Z-Wave dimmer). 100-127 will set device on to the last value it was when turned off. 8 | 9 | 10 | 11 | 12 | On Time sets the number of seconds the sensor stays alerted before the off event is sent. 13 | 14 | 15 | 16 | 17 | Enable/Disable power saving mode. 0 enables. 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/wenzhou/tz67.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Defines the behavior of the blue LED. Default: 0 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/wenzhou/tz68.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 -> night light - LED ON when the load attached is turned OFF (default). 10 | 1 -> on indicator - LED ON when the load attached is turned ON. 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/wenzhou/tz88.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | If the setting is configured for 1 hour (value=720), the TZ88 will report its instant power consumption every 1 hour. 8 | 9 | 10 | If the setting is configured for 1 hour (value=6), the TZ88 will report its accumulated power consumption (kWh) every 1 hour. 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/zipato/MiniKeypad.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Set all configuration values to default values (factory settings). 10 | 11 | 12 | 14 | To configure the time the beep is automatically turned off in seconds. 15 | 16 | 17 | 18 | 19 | 20 | To configure the timeout to wait for a WAKEUP_NO_MORE_INFORMATION before the error beep is automatically sound. The error beeps are fixed 8 beeps shortly after each other. 21 | 22 | 23 | 24 | To configure the number of beeps per second. Every beep is fixed about 10ms. 25 | 26 | 27 | 28 | To configure the operating mode. If any mode other then 3, that value will be reported after a get but will be handled in SW as mode 1. 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/zipato/RGBBulb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Color Temperature 8 | 9 | 10 | 11 | 12 | Shock sensor : 0=Maximum sensitivity ; 32=minimum sensitivity 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/zwave.me/iTemp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /tools/docker/support/open-zwave/config/zwscene.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tools/execute-all-rust-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This runs unit tests as well as tests living under $crate/tests 4 | 5 | set -ex 6 | CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 7 | PROJECT_PATH="$CURRENT_PATH/.." 8 | COMPONENTS_CRATES="$(find "$PROJECT_PATH/components/" -mindepth 1 -maxdepth 1 -type d)" 9 | CRATES="$PROJECT_PATH $COMPONENTS_CRATES" 10 | 11 | for crate in $CRATES; do 12 | cd $crate 13 | echo "Running tests for crate at $crate" 14 | cargo test 15 | cd - 16 | done 17 | -------------------------------------------------------------------------------- /tools/execute-selenium-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | PROJECT_HOME="$CURRENT_PATH/.." 7 | 8 | GECKO_DRIVER_BINARY_NAME='wires' # wires is the previous project name of geckodriver 9 | GECKO_DRIVER_VERSION='0.7.1' 10 | GECKO_DRIVER_FOLDER="$PROJECT_HOME/target" 11 | GECKO_DRIVER_BINARY="$GECKO_DRIVER_FOLDER/$GECKO_DRIVER_BINARY_NAME" 12 | 13 | # GeckoDriver must be in the path, so Selenium client can locate it 14 | export PATH="$PATH:$GECKO_DRIVER_FOLDER" 15 | 16 | 17 | _build_project() { 18 | pushd "${PROJECT_HOME}" 19 | cargo build 20 | } 21 | 22 | 23 | _install_firefox_driver() { 24 | local KERNEL_NAME="$(uname -s)" 25 | local os='' 26 | 27 | if [[ $KERNEL_NAME == "Darwin" ]]; then 28 | os='OSX' 29 | elif [[ $KERNEL_NAME == "Linux" ]]; then 30 | os='linux64' # Warning: No 32 bits binary is available 31 | else 32 | echo 'Error: Unsupported OS' 33 | exit 1 34 | fi 35 | 36 | curl --location --output "$GECKO_DRIVER_BINARY.gz" \ 37 | "https://github.com/mozilla/geckodriver/releases/download/v$GECKO_DRIVER_VERSION/$GECKO_DRIVER_BINARY_NAME-$GECKO_DRIVER_VERSION-$os.gz" 38 | 39 | gunzip "$GECKO_DRIVER_BINARY.gz" 40 | chmod +x "$GECKO_DRIVER_BINARY" 41 | } 42 | 43 | _run_tests() { 44 | "${PROJECT_HOME}/node_modules/.bin/mocha" "${PROJECT_HOME}/test/selenium/sessions_ui_test.js" 45 | } 46 | 47 | 48 | _build_project 49 | if ! [ -f "$GECKO_DRIVER_BINARY" ] ; then 50 | _install_firefox_driver 51 | fi 52 | _run_tests 53 | -------------------------------------------------------------------------------- /tools/execute-unit-tests-with-coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Warning: kcov is a Linux only tool 4 | 5 | set -ex 6 | 7 | CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 8 | 9 | PROJECT_HOME="$CURRENT_PATH/.." 10 | PROJECT_NAME=$(sed --quiet 's/^name *= *"\(.*\)"$/\1/p' $PROJECT_HOME/Cargo.toml) 11 | PROJECT_BINARY_LOCATION="$PROJECT_HOME/target/debug" 12 | 13 | KCOV_VERSION="30" 14 | KCOV_TEMP="$PROJECT_HOME/target/kcov" 15 | KCOV_COMPILE_HOME="$KCOV_TEMP/kcov-$KCOV_VERSION" 16 | KCOV_BINARY="$KCOV_TEMP/kcov" 17 | 18 | get_prebuilt() { 19 | local ubuntu_version="$1" 20 | curl --location --output "$KCOV_BINARY" \ 21 | "https://github.com/JohanLorenzo/kcov/releases/download/v$KCOV_VERSION/kcov_$ubuntu_version" 22 | chmod +x "$KCOV_BINARY" 23 | } 24 | 25 | get_and_compile_kcov_locally() { 26 | curl --location --output "$KCOV_TEMP/kcov.tar.gz" \ 27 | "https://github.com/SimonKagstrom/kcov/archive/v$KCOV_VERSION.tar.gz" 28 | tar xvf "$KCOV_TEMP/kcov.tar.gz" --directory="$KCOV_TEMP" 29 | cd "$KCOV_COMPILE_HOME" 30 | cmake . 31 | make 32 | cp "src/kcov" "$KCOV_BINARY" 33 | cd - 34 | } 35 | 36 | get_kcov() { 37 | mkdir -p "$KCOV_TEMP" 38 | 39 | local ubuntu_version=$(lsb_release --codename --short) 40 | if [[ "$ubuntu_version" == 'precise' || "$ubuntu_version" == 'trusty' ]] ; then 41 | get_prebuilt "$ubuntu_version" 42 | else 43 | get_and_compile_kcov_locally 44 | fi 45 | } 46 | 47 | compile_foxbox_with_dead_code() { 48 | RUSTFLAGS="-C link-dead-code" cargo test --no-run 49 | } 50 | 51 | run_tests_and_coverage() { 52 | PROJECT_UNIT_TEST_BINARY=$(find "$PROJECT_BINARY_LOCATION" -maxdepth 1 -executable -name "$PROJECT_NAME"-\*) 53 | PAGEKITE_LIB=$(dirname $(find "$PROJECT_BINARY_LOCATION" -name libpagekite.so)) 54 | # TODO: Add components and figure out why its not counted as part of the report 55 | LD_LIBRARY_PATH="$PAGEKITE_LIB" RUST_BACKTRACE=1 "$KCOV_BINARY" \ 56 | --include-path="$PROJECT_HOME/src" \ 57 | --exclude-path="$PROJECT_HOME/src/stubs" \ 58 | --coveralls-id="${TRAVIS_JOB_ID:=no-job-id}" \ 59 | "$PROJECT_HOME/target/coverage-report/" \ 60 | "$PROJECT_UNIT_TEST_BINARY" 61 | } 62 | 63 | 64 | if ! [ -f "$KCOV_BINARY" ] ; then 65 | get_kcov 66 | fi 67 | 68 | compile_foxbox_with_dead_code 69 | run_tests_and_coverage 70 | -------------------------------------------------------------------------------- /tools/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | CARGO_EXECUTABLE="cargo" 4 | CARGO_COMMAND="build" 5 | 6 | hash cargo > /dev/null 2>&1 7 | if [ $? -eq 1 ]; 8 | then 9 | echo >&2 "You should install cargo to lint your patch" 10 | echo >&2 "https://crates.io/install" 11 | exit 0 12 | fi 13 | 14 | rs_changed_files=`git diff --staged --name-only --diff-filter=ACMRT | grep '\.rs$'` 15 | if [ -n "$rs_changed_files" ] 16 | then 17 | 18 | echo "clippy check:" 19 | 20 | $CARGO_EXECUTABLE $CARGO_COMMAND 21 | cargot_result=$? 22 | 23 | if [ $cargot_result -ne 0 ] ; then 24 | echo "There were errors while linting the files, please see above." 25 | exit 1 26 | fi 27 | 28 | fi 29 | -------------------------------------------------------------------------------- /tools/scripts/make-root-ca-and-certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Taken from coolaj86's very useful nodejs-self-signed-certificate-example repo 4 | # (Apache licensed). 5 | # See https://github.com/coolaj86/nodejs-self-signed-certificate-example. 6 | 7 | FQDN=$1 8 | 9 | # make directories to work from 10 | mkdir -p certs/{server,client,ca,tmp} 11 | 12 | # Create your very own Root Certificate Authority 13 | openssl genrsa \ 14 | -out certs/ca/my-root-ca.key.pem \ 15 | 2048 16 | 17 | # Self-sign your Root Certificate Authority 18 | # Since this is private, the details can be as bogus as you like 19 | openssl req \ 20 | -x509 \ 21 | -new \ 22 | -nodes \ 23 | -key certs/ca/my-root-ca.key.pem \ 24 | -days 1024 \ 25 | -out certs/ca/my-root-ca.crt.pem \ 26 | -subj "/C=US/ST=Utah/L=Provo/O=ACME Signing Authority Inc/CN=example.com" 27 | 28 | # Create a Device Certificate for each domain, 29 | # such as example.com, *.example.com, awesome.example.com 30 | # NOTE: You MUST match CN to the domain name or ip address you want to use 31 | openssl genrsa \ 32 | -out certs/server/${FQDN}-server.key.pem \ 33 | 2048 34 | 35 | # Create a request from your Device, which your Root CA will sign 36 | openssl req -new \ 37 | -key certs/server/${FQDN}-server.key.pem \ 38 | -out certs/tmp/${FQDN}-server.csr.pem \ 39 | -subj "/C=US/ST=Utah/L=Provo/O=ACME Tech Inc/CN=${FQDN}" 40 | 41 | # Sign the request from Device with your Root CA 42 | # -CAserial certs/ca/my-root-ca.srl 43 | openssl x509 \ 44 | -req -in certs/tmp/${FQDN}-server.csr.pem \ 45 | -CA certs/ca/my-root-ca.crt.pem \ 46 | -CAkey certs/ca/my-root-ca.key.pem \ 47 | -CAcreateserial \ 48 | -out certs/server/${FQDN}-server.crt.pem \ 49 | -days 500 50 | 51 | # Create a public key, for funzies 52 | # see https://gist.github.com/coolaj86/f6f36efce2821dfb046d 53 | openssl rsa \ 54 | -in certs/server/${FQDN}-server.key.pem \ 55 | -pubout -out certs/client/${FQDN}-server.pub 56 | 57 | # Put things in their proper place 58 | rsync -a certs/ca/my-root-ca.crt.pem certs/server/ 59 | rsync -a certs/ca/my-root-ca.crt.pem certs/client/ 60 | -------------------------------------------------------------------------------- /tools/travis-linux-cargo_update.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | set -ev 4 | 5 | CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | source "$CURRENT_PATH/travis-linux-common.sh" 7 | 8 | 9 | build() { 10 | echo "build: updating Cargo.lock to the most recent version" 11 | cargo update 12 | cargo build 13 | } 14 | 15 | lint() { 16 | echo "lint: nothing to do. Skipping..." 17 | } 18 | 19 | set_up_tests() { 20 | echo "set_up_tests: nothing to do. Skipping..." 21 | } 22 | 23 | run_tests() { 24 | echo "run_tests: nothing to do. Skipping..." 25 | } 26 | -------------------------------------------------------------------------------- /tools/travis-linux-common.sh: -------------------------------------------------------------------------------- 1 | install_dependencies() { 2 | # Missing dependencies only. The regular ones are in done with the APT addon 3 | # defined in .travis.yml 4 | sudo apt-get -qq update 5 | # TODO: Move to apt addon once https://github.com/travis-ci/apt-package-whitelist/issues/1983 lands 6 | sudo apt-get install -y avahi-daemon libavahi-client-dev libavahi-common-dev libdbus-1-dev 7 | } 8 | -------------------------------------------------------------------------------- /tools/travis-linux.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | set -ev 4 | 5 | CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | source "$CURRENT_PATH/travis-linux-common.sh" 7 | 8 | _build_without_features() { 9 | echo '> Building foxbox without default features.' 10 | cargo build --no-default-features 11 | } 12 | 13 | _build_default() { 14 | echo '> Building foxbox with default features.' 15 | cargo build 16 | } 17 | 18 | build() { 19 | _build_without_features 20 | _build_default 21 | } 22 | 23 | lint() { 24 | jshint test/**/*.js \ 25 | static/main/js/*.js static/setup/js/*.js 26 | # There is a minified js in static/**/shared which breaks jshint 27 | } 28 | 29 | _set_up_unit_tests() { 30 | sudo usermod -a -G netdev "$USER" # "netdev" group membership allows to set custom host name via avahi-daemon. 31 | } 32 | 33 | _set_up_selenium_tests() { 34 | sh -e /etc/init.d/xvfb start 35 | export DISPLAY=:99.0 36 | wget http://selenium-release.storage.googleapis.com/2.53/selenium-server-standalone-2.53.0.jar 37 | java -jar selenium-server-standalone-2.53.0.jar > /dev/null & 38 | sleep 5 39 | nvm install 4.2 40 | nvm use 4.2 41 | npm install 42 | # We should not hardcode that path... 43 | export PATH=/home/travis/build/fxbox/foxbox/node_modules/.bin:$PATH 44 | } 45 | 46 | set_up_tests() { 47 | _set_up_unit_tests 48 | _set_up_selenium_tests 49 | } 50 | 51 | run_tests() { 52 | npm run test-selenium 53 | npm run test-integration-travis 54 | # TODO: Currently unit tests are executed twice. We need a way to filter out 55 | # tests with `cargo test` depending on where they are defined in the tree 56 | "$CURRENT_PATH/execute-all-rust-tests.sh" 57 | # Note: Cargo recompiles every dependency with dead code. That's why 58 | # this step is currently the last 59 | "$CURRENT_PATH/execute-unit-tests-with-coverage.sh" 60 | } 61 | -------------------------------------------------------------------------------- /tools/travis-osx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | CURRENT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" 6 | 7 | 8 | install_dependencies() { 9 | brew update 10 | brew install openssl libupnp sqlite 11 | source "$CURRENT_PATH/mac-os-x-setup.source.sh" 12 | } 13 | 14 | build() { 15 | cargo build 16 | } 17 | 18 | lint() { 19 | echo "lint: jshint is not installed on Mac. Skipping..." 20 | } 21 | 22 | set_up_tests() { 23 | echo "set_up_tests: no set up required. Skipping..." 24 | } 25 | 26 | run_tests() { 27 | echo "run_tests: no selenium installed. Skipping..." 28 | echo "run_tests: no npm installed. Skipping integration tests..." 29 | echo "run_tests: kcov is not supported on Mac. Running only the tests..." 30 | "$CURRENT_PATH/execute-all-rust-tests.sh" 31 | } 32 | --------------------------------------------------------------------------------