├── .bithoundrc
├── .eslintrc
├── .gitignore
├── .jsinitrc
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENCE.txt
├── PIGPIO
├── MakeRemote
├── Makefile
├── README
├── UNLICENCE
├── build
│ ├── lib.linux-x86_64-2.7
│ │ └── pigpio.py
│ └── lib
│ │ └── pigpio.py
├── command.c
├── command.h
├── command.o
├── custom.cext
├── libpigpio.so
├── libpigpiod_if.so
├── libpigpiod_if2.so
├── pig2vcd
├── pig2vcd.1
├── pig2vcd.c
├── pig2vcd.o
├── pigpio.3
├── pigpio.c
├── pigpio.h
├── pigpio.o
├── pigpio.py
├── pigpiod
├── pigpiod.1
├── pigpiod.c
├── pigpiod.o
├── pigpiod_if.3
├── pigpiod_if.c
├── pigpiod_if.h
├── pigpiod_if.o
├── pigpiod_if2.3
├── pigpiod_if2.c
├── pigpiod_if2.h
├── pigpiod_if2.o
├── pigs
├── pigs.1
├── pigs.c
├── pigs.o
├── setup.py
├── x_pigpio
├── x_pigpio.c
├── x_pigpio.o
├── x_pigpio.py
├── x_pigpiod_if
├── x_pigpiod_if.c
├── x_pigpiod_if.o
├── x_pigpiod_if2
├── x_pigpiod_if2.c
├── x_pigpiod_if2.o
├── x_pigs
└── x_pipe
├── README.md
├── docs
├── Buzzer.html
├── CompositeDevice.html
├── CompositeOutputDevice.html
├── Device.html
├── DigitalInputDevice.html
├── DigitalOutputDevice.html
├── GPIODevice.html
├── InputDevice.html
├── LED.html
├── LEDBoard.html
├── LEDCollection.html
├── MockPin.html
├── MockPulledUpPin.html
├── Motor.html
├── OutputDevice.html
├── PWMLED.html
├── PWMOutputDevice.html
├── PiTraffic.html
├── Pin.html
├── RGBLED.html
├── TrafficLights.html
├── assets
│ ├── anchor.js
│ ├── bass-addons.css
│ ├── bass.css
│ ├── fonts
│ │ ├── EOT
│ │ │ ├── SourceCodePro-Bold.eot
│ │ │ └── SourceCodePro-Regular.eot
│ │ ├── LICENSE.txt
│ │ ├── OTF
│ │ │ ├── SourceCodePro-Bold.otf
│ │ │ └── SourceCodePro-Regular.otf
│ │ ├── TTF
│ │ │ ├── SourceCodePro-Bold.ttf
│ │ │ └── SourceCodePro-Regular.ttf
│ │ ├── WOFF
│ │ │ ├── OTF
│ │ │ │ ├── SourceCodePro-Bold.otf.woff
│ │ │ │ └── SourceCodePro-Regular.otf.woff
│ │ │ └── TTF
│ │ │ │ ├── SourceCodePro-Bold.ttf.woff
│ │ │ │ └── SourceCodePro-Regular.ttf.woff
│ │ ├── WOFF2
│ │ │ ├── OTF
│ │ │ │ ├── SourceCodePro-Bold.otf.woff2
│ │ │ │ └── SourceCodePro-Regular.otf.woff2
│ │ │ └── TTF
│ │ │ │ ├── SourceCodePro-Bold.ttf.woff2
│ │ │ │ └── SourceCodePro-Regular.ttf.woff2
│ │ └── source-code-pro.css
│ ├── github.css
│ ├── site.js
│ └── style.css
├── boards.js.html
├── boards_LEDBoard.js.html
├── boards_LEDCollection.js.html
├── boards_PiTraffic.js.html
├── boards_TrafficLights.js.html
├── devices.js.html
├── devices_CompositeDevice.js.html
├── devices_Device.js.html
├── devices_GPIODevice.js.html
├── fonts
│ ├── OpenSans-Bold-webfont.eot
│ ├── OpenSans-Bold-webfont.svg
│ ├── OpenSans-Bold-webfont.woff
│ ├── OpenSans-BoldItalic-webfont.eot
│ ├── OpenSans-BoldItalic-webfont.svg
│ ├── OpenSans-BoldItalic-webfont.woff
│ ├── OpenSans-Italic-webfont.eot
│ ├── OpenSans-Italic-webfont.svg
│ ├── OpenSans-Italic-webfont.woff
│ ├── OpenSans-Light-webfont.eot
│ ├── OpenSans-Light-webfont.svg
│ ├── OpenSans-Light-webfont.woff
│ ├── OpenSans-LightItalic-webfont.eot
│ ├── OpenSans-LightItalic-webfont.svg
│ ├── OpenSans-LightItalic-webfont.woff
│ ├── OpenSans-Regular-webfont.eot
│ ├── OpenSans-Regular-webfont.svg
│ └── OpenSans-Regular-webfont.woff
├── index.html
├── index.js.html
├── input_devices_DigitalInputDevice.js.html
├── input_devices_InputDevice.js.html
├── output_devices.js.html
├── output_devices_Buzzer.js.html
├── output_devices_CompositeOutputDevice.js.html
├── output_devices_DigitalOutputDevice.js.html
├── output_devices_LED.js.html
├── output_devices_Motor.js.html
├── output_devices_OutputDevice.js.html
├── output_devices_PWMLED.js.html
├── output_devices_PWMOutputDevice.js.html
├── output_devices_RGBLED.js.html
├── pins_index.js.html
├── pins_mock.js.html
├── scripts
│ ├── linenumber.js
│ └── prettify
│ │ ├── Apache-License-2.0.txt
│ │ ├── lang-css.js
│ │ └── prettify.js
└── styles
│ ├── jsdoc-default.css
│ ├── jsdoc.css
│ ├── prettify-jsdoc.css
│ ├── prettify-tomorrow.css
│ └── prettify.css
├── gpiozero
├── Mixins
│ └── EventsMixin.js
├── boards
│ ├── LEDBoard.js
│ ├── LEDCollection.js
│ ├── PiTraffic.js
│ └── TrafficLights.js
├── compat.js
├── devices
│ ├── CompositeDevice.js
│ ├── Device.js
│ └── GPIODevice.js
├── exc.js
├── index.js
├── input_devices
│ ├── DigitalInputDevice.js
│ └── InputDevice.js
├── output_devices
│ ├── Buzzer.js
│ ├── CompositeOutputDevice.js
│ ├── DigitalOutputDevice.js
│ ├── LED.js
│ ├── Motor.js
│ ├── OutputDevice.js
│ ├── PWMLED.js
│ ├── PWMOutputDevice.js
│ └── RGBLED.js
├── pins
│ ├── index.js
│ ├── mock.js
│ └── wiringpi.js
└── tools.js
├── jsdoc.json
├── package.json
├── pre-commit.sh
├── renovate.json
└── test
├── boards.spec.js
├── devices.spec.js
├── eslint.spec.js
├── input_devices.spec.js
├── mocha.opts
└── output_devices.spec.js
/.bithoundrc:
--------------------------------------------------------------------------------
1 | {
2 | "ignore": [
3 | "**/deps/**",
4 | "**/node_modules/**",
5 | "**/thirdparty/**",
6 | "**/third_party/**",
7 | "**/vendor/**",
8 | "**/**-min-**",
9 | "**/**-min.**",
10 | "**/**.min.**",
11 | "**/**jquery.?(ui|effects)-*.*.?(*).?(cs|j)s",
12 | "**/**jquery-*.*.?(*).?(cs|j)s",
13 | "**/prototype?(*).js",
14 | "**/mootools*.*.*.js",
15 | "**/dojo.js",
16 | "**/MochiKit.js",
17 | "**/yahoo-*.js",
18 | "**/yui*.js",
19 | "**/ckeditor*.js",
20 | "**/tiny_mce*.js",
21 | "**/tiny_mce/?(langs|plugins|themes|utils)/**",
22 | "**/MathJax/**",
23 | "**/shBrush*.js",
24 | "**/shCore.js",
25 | "**/shLegacy.js",
26 | "**/modernizr.custom.?(*).js",
27 | "**/knockout-*.*.*.debug.js",
28 | "**/extjs/*.js",
29 | "**/extjs/*.xml",
30 | "**/extjs/*.txt",
31 | "**/extjs/*.html",
32 | "**/extjs/*.properties",
33 | "**/extjs/.sencha",
34 | "**/extjs/docs/**",
35 | "**/extjs/builds/**",
36 | "**/extjs/cmd/**",
37 | "**/extjs/examples/**",
38 | "**/extjs/locale/**",
39 | "**/extjs/packages/**",
40 | "**/extjs/plugins/**",
41 | "**/extjs/resources/**",
42 | "**/extjs/src/**",
43 | "**/extjs/welcome/**",
44 | "bower_components/**",
45 | "**/docs/**"
46 | ],
47 | "test": [
48 | "**/test/**",
49 | "**/tests/**",
50 | "**/spec/**",
51 | "**/specs/**"
52 | ]
53 | }
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "rules": {
4 | "no-var" : "off",
5 | "import/no-commonjs" : "off",
6 | "jsdoc/check-param-names": 1,
7 | "jsdoc/check-tag-names": 1,
8 | "jsdoc/check-types": 1,
9 | "jsdoc/newline-after-description": 1,
10 | "jsdoc/require-description-complete-sentence": 1,
11 | "jsdoc/require-hyphen-before-param-description": 1,
12 | "jsdoc/require-param": 1,
13 | "jsdoc/require-param-description": 1,
14 | "jsdoc/require-param-type": 1,
15 | "jsdoc/require-returns-description": 1,
16 | "jsdoc/require-returns-type": 1
17 | },
18 | "extends": ["node"],
19 | "plugins": [
20 | "jsdoc"
21 | ]
22 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | coverage
4 | .idea
5 | dist
6 |
--------------------------------------------------------------------------------
/.jsinitrc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/.jsinitrc
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | coverage
2 | test
3 | docs
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | cache:
3 | directories:
4 | - node_modules
5 | node_js:
6 | - '7'
7 | - '6'
8 | install:
9 | - npm install
10 | script:
11 | - npm test
12 | env:
13 | matrix:
14 | - CXX=g++-4.8
15 | global:
16 | secure: PmiPta2PsLKwMKi35LEle0f9n95hODkuBCFHzKbJ9r2Tn/1q31g/o3dJQ/5a2D+N0GhSrj+QA2lmeXp7UyMzNACWNsEhiqz+0rGMuBF0qzdfJN4ilYDg+HqZbUlplY/BISrdpI3VW995Lii3THlYFSxNMIzFV83LUdE4oPi9ETLHVLTRJcbkabq2Bn0NQ+Y0WAi8FVUluHUgRoDljpsivW/vRN9vnf0559ZuZRBBx4dwEcyW5/7/yug5fqdu476xyE53W27X1YBwrdHEy6IIC6aeagda0g5C2J7WrUzO6a2E3gIFYLr9CQkKzov8mKrg2xXAHxgXs51owreV1HstGtxUPcwFNZDGgSyPgawZojSKWYBwr4Mewu8UOQyrzZDZJa7sILBznMuHS8756N5rq7PXwU76H4UQv9aGPfV7dXIeL2UhCQdMllovVU2cd+YT/Fz/2FRTZsYF8h91Iowuyp8pMpqeeaFQ76YDLH4hYlYRPjKdK6XUPvidEpeOO5LDHzm2pNBNf/WEWZioH1gqP9viOBlhrEXuuh4Ugxj2we5BlwjLEcy/J/kqmW2uLrbcbNs8tLhG/0qhlAuHeWz+aHpJshwdMSural3fqkeZDMbEkeFTYwhRmLm6Pz09cSShdY+AUs1cG8qoxQ84SjbGk9ibTJnEYvrWc/6ZsJxABEY=
17 | addons:
18 | apt:
19 | sources:
20 | - ubuntu-toolchain-r-test
21 | packages:
22 | - g++-4.8
23 | before_script:
24 | - npm prune
25 | after_success:
26 | - npm run semantic-release
27 | branches:
28 | except:
29 | - /^v\d+\.\d+\.\d+$/
30 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | # [1.0.0](https://github.com/i-am-digital/js-gpiozero/compare/1.0.0...v1.0.0) (2016-12-29)
3 |
4 |
5 |
6 |
7 |
8 | ## [0.1.5](https://github.com/i-am-digital/js-gpiozero/compare/0.1.5...v0.1.5) (2016-12-27)
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # js-gpiozero is an OPEN Open Source Project
2 |
3 | -----------------------------------------
4 |
5 | ## What?
6 |
7 | Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.
8 |
9 | ## Rules
10 |
11 | There are a few basic ground-rules for contributors:
12 |
13 | 1. **No `--force` pushes** or modifying the Git history in any way.
14 | 1. **Non-master branches** ought to be used for ongoing work.
15 | 1. **External API changes and significant modifications** ought to be subject to an **internal pull-request** to solicit feedback from other contributors.
16 | 1. Internal pull-requests to solicit feedback are *encouraged* for any other non-trivial contribution but left to the discretion of the contributor.
17 | 1. Contributors should attempt to adhere to the prevailing code-style.
18 |
19 | ## Releases
20 |
21 | Declaring formal releases remains the prerogative of the project maintainer.
22 |
23 | ## Changes to this arrangement
24 |
25 | This is an experiment and feedback is welcome! This document may also be subject to pull-requests or changes by contributors where you believe you have something valuable to add or change.
26 |
27 | [this approach is totally cribbed from the excellent documentation project](https://github.com/documentationjs/documentation/blob/master/CONTRIBUTING.md)
28 |
29 | ----
30 |
31 | ## Releasing
32 |
33 | js-gpiozero uses [semantic-release](https://github.com/semantic-release/semantic-release) to deploy code as often as possible. We use [standard-changelog](https://github.com/conventional-changelog/standard-changelog)
34 | to generate CHANGELOG.md entries and [commitizen](https://github.com/commitizen/cz-cli) to standardize
35 | commit messages. Pull Request messages should be standardized to commitizen syntax (aka angular standard)
36 | before merge.
37 |
38 | Release process (completed by semantic-release):
39 |
40 | * Confirm that `master` passes CI tests
41 | * Bump version in `package.json`
42 | * Add Version Tag to Git
43 | * Run `npm run changelog`
44 | * Add updated CHANGELOG.md to master
45 | * Push commits and new tag
46 | * npm publish
47 |
48 |
--------------------------------------------------------------------------------
/LICENCE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2016 js-gpiozero
2 |
3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
4 |
5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--------------------------------------------------------------------------------
/PIGPIO/MakeRemote:
--------------------------------------------------------------------------------
1 | #
2 | CC = gcc
3 | SIZE = size
4 | SHLIB = gcc -shared
5 | STRIPLIB = strip --strip-unneeded
6 |
7 | CFLAGS += -O3 -Wall -pthread
8 |
9 | ALL = libpigpiod_if.so libpigpiod_if2.so pigs x_pigpiod_if x_pigpiod_if2
10 |
11 | prefix = /usr/local
12 | exec_prefix = $(prefix)
13 | bindir = $(exec_prefix)/bin
14 | includedir = $(prefix)/include
15 | libdir = $(prefix)/lib
16 | mandir = $(prefix)/man
17 |
18 | all: $(ALL) pigpio.py setup.py
19 |
20 | pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h
21 | $(CC) $(CFLAGS) -fpic -c -o pigpiod_if.o pigpiod_if.c
22 |
23 | pigpiod_if2.o: pigpiod_if2.c pigpio.h command.h pigpiod_if2.h
24 | $(CC) $(CFLAGS) -fpic -c -o pigpiod_if2.o pigpiod_if2.c
25 |
26 | command.o: command.c pigpio.h command.h
27 | $(CC) $(CFLAGS) -fpic -c -o command.o command.c
28 |
29 | pigs: command.o pigs.o
30 | $(CC) $(CFLAGS) -fpic -o pigs pigs.c command.c
31 |
32 | x_pigpiod_if: x_pigpiod_if.o $(LIB1)
33 | $(CC) -o x_pigpiod_if x_pigpiod_if.o $(LL1)
34 |
35 | x_pigpiod_if2: x_pigpiod_if2.o $(LIB2)
36 | $(CC) -o x_pigpiod_if2 x_pigpiod_if2.o $(LL2)
37 |
38 | clean:
39 | rm -f *.o *.i *.s *~ $(ALL)
40 |
41 | install: $(LIB1) $(LIB2)
42 | install -m 0755 -d $(DESTDIR)$(includedir)
43 | install -m 0644 pigpio.h $(DESTDIR)$(includedir)
44 | install -m 0644 pigpiod_if.h $(DESTDIR)$(includedir)
45 | install -m 0644 pigpiod_if2.h $(DESTDIR)$(includedir)
46 | install -m 0755 -d $(DESTDIR)$(libdir)
47 | install -m 0644 libpigpiod_if.so $(DESTDIR)$(libdir)
48 | install -m 0644 libpigpiod_if2.so $(DESTDIR)$(libdir)
49 | install -m 0755 -d $(DESTDIR)$(bindir)
50 | install -m 0755 pigs $(DESTDIR)$(bindir)
51 | python2 setup.py install
52 | python3 setup.py install
53 | install -m 0755 -d $(DESTDIR)$(mandir)/man1
54 | install -m 0644 *.1 $(DESTDIR)$(mandir)/man1
55 | install -m 0755 -d $(DESTDIR)$(mandir)/man3
56 | install -m 0644 *.3 $(DESTDIR)$(mandir)/man3
57 |
58 | uninstall:
59 | rm -f $(DESTDIR)$(includedir)/pigpio.h
60 | rm -f $(DESTDIR)$(includedir)/pigpiod_if.h
61 | rm -f $(DESTDIR)$(includedir)/pigpiod_if2.h
62 | rm -f $(DESTDIR)$(libdir)/libpigpiod_if.so
63 | rm -f $(DESTDIR)$(libdir)/libpigpiod_if2.so
64 | echo removing python2 files
65 | python2 setup.py install --record /tmp/pigpio >/dev/null
66 | xargs rm -f < /tmp/pigpio >/dev/null
67 | echo removing python3 files
68 | python3 setup.py install --record /tmp/pigpio >/dev/null
69 | xargs rm -f < /tmp/pigpio >/dev/null
70 | rm -f $(DESTDIR)$(bindir)/pigs
71 | rm -f $(DESTDIR)$(mandir)/man1/pig*.1
72 | rm -f $(DESTDIR)$(mandir)/man3/pig*.3
73 |
74 | LL1 = -L. -lpigpiod_if -pthread -lrt
75 | LL2 = -L. -lpigpiod_if2 -pthread -lrt
76 |
77 | LIB1 = libpigpiod_if.so
78 | OBJ1 = pigpiod_if.o command.o
79 |
80 | LIB2 = libpigpiod_if2.so
81 | OBJ2 = pigpiod_if2.o command.o
82 |
83 | $(LIB1): $(OBJ1)
84 | $(SHLIB) -o $(LIB1) $(OBJ1)
85 | $(STRIPLIB) $(LIB1)
86 | $(SIZE) $(LIB1)
87 |
88 | $(LIB2): $(OBJ2)
89 | $(SHLIB) -o $(LIB2) $(OBJ2)
90 | $(STRIPLIB) $(LIB2)
91 | $(SIZE) $(LIB2)
92 |
93 | # generated using gcc -MM *.c
94 |
95 | command.o: command.c pigpio.h command.h
96 | pigpiod.o: pigpiod.c pigpio.h
97 | pigpiod_if.o: pigpiod_if.c pigpio.h pigpiod_if.h command.h
98 | pigpiod_if2.o: pigpiod_if2.c pigpio.h pigpiod_if2.h command.h
99 | pigs.o: pigs.c pigpio.h command.h
100 |
101 |
102 |
--------------------------------------------------------------------------------
/PIGPIO/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # Set CROSS_PREFIX to prepend to all compiler tools at once for easier
3 | # cross-compilation.
4 | CROSS_PREFIX =
5 | CC = $(CROSS_PREFIX)gcc
6 | AR = $(CROSS_PREFIX)ar
7 | RANLIB = $(CROSS_PREFIX)ranlib
8 | SIZE = $(CROSS_PREFIX)size
9 | STRIP = $(CROSS_PREFIX)strip
10 | SHLIB = $(CC) -shared
11 | STRIPLIB = $(STRIP) --strip-unneeded
12 |
13 | CFLAGS += -O3 -Wall -pthread
14 |
15 | LIB1 = libpigpio.so
16 | OBJ1 = pigpio.o command.o
17 |
18 | LIB2 = libpigpiod_if.so
19 | OBJ2 = pigpiod_if.o command.o
20 |
21 | LIB3 = libpigpiod_if2.so
22 | OBJ3 = pigpiod_if2.o command.o
23 |
24 | LIB = $(LIB1) $(LIB2) $(LIB3)
25 |
26 | ALL = $(LIB) x_pigpio x_pigpiod_if x_pigpiod_if2 pig2vcd pigpiod pigs
27 |
28 | LL1 = -L. -lpigpio -pthread -lrt
29 |
30 | LL2 = -L. -lpigpiod_if -pthread -lrt
31 |
32 | LL3 = -L. -lpigpiod_if2 -pthread -lrt
33 |
34 | prefix = /usr/local
35 | exec_prefix = $(prefix)
36 | bindir = $(exec_prefix)/bin
37 | includedir = $(prefix)/include
38 | libdir = $(prefix)/lib
39 | mandir = $(prefix)/man
40 |
41 | all: $(ALL)
42 |
43 | pigpio.o: pigpio.c pigpio.h command.h custom.cext
44 | $(CC) $(CFLAGS) -fpic -c -o pigpio.o pigpio.c
45 |
46 | pigpiod_if.o: pigpiod_if.c pigpio.h command.h pigpiod_if.h
47 | $(CC) $(CFLAGS) -fpic -c -o pigpiod_if.o pigpiod_if.c
48 |
49 | pigpiod_if2.o: pigpiod_if2.c pigpio.h command.h pigpiod_if2.h
50 | $(CC) $(CFLAGS) -fpic -c -o pigpiod_if2.o pigpiod_if2.c
51 |
52 | command.o: command.c pigpio.h command.h
53 | $(CC) $(CFLAGS) -fpic -c -o command.o command.c
54 |
55 | x_pigpio: x_pigpio.o $(LIB1)
56 | $(CC) -o x_pigpio x_pigpio.o $(LL1)
57 |
58 | x_pigpiod_if: x_pigpiod_if.o $(LIB2)
59 | $(CC) -o x_pigpiod_if x_pigpiod_if.o $(LL2)
60 |
61 | x_pigpiod_if2: x_pigpiod_if2.o $(LIB3)
62 | $(CC) -o x_pigpiod_if2 x_pigpiod_if2.o $(LL3)
63 |
64 | pigpiod: pigpiod.o $(LIB1)
65 | $(CC) -o pigpiod pigpiod.o $(LL1)
66 | $(STRIP) pigpiod
67 |
68 | pigs: pigs.o command.o
69 | $(CC) -o pigs pigs.o command.o
70 | $(STRIP) pigs
71 |
72 | pig2vcd: pig2vcd.o
73 | $(CC) -o pig2vcd pig2vcd.o
74 | $(STRIP) pig2vcd
75 |
76 | clean:
77 | rm -f *.o *.i *.s *~ $(ALL)
78 |
79 | install: $(ALL)
80 | install -m 0755 -d $(DESTDIR)/opt/pigpio/cgi
81 | install -m 0755 -d $(DESTDIR)$(includedir)
82 | install -m 0644 pigpio.h $(DESTDIR)$(includedir)
83 | install -m 0644 pigpiod_if.h $(DESTDIR)$(includedir)
84 | install -m 0644 pigpiod_if2.h $(DESTDIR)$(includedir)
85 | install -m 0755 -d $(DESTDIR)$(libdir)
86 | install -m 0755 libpigpio.so $(DESTDIR)$(libdir)
87 | install -m 0755 libpigpiod_if.so $(DESTDIR)$(libdir)
88 | install -m 0755 libpigpiod_if2.so $(DESTDIR)$(libdir)
89 | install -m 0755 -d $(DESTDIR)$(bindir)
90 | install -m 0755 pig2vcd $(DESTDIR)$(bindir)
91 | install -m 0755 pigpiod $(DESTDIR)$(bindir)
92 | install -m 0755 pigs $(DESTDIR)$(bindir)
93 | if which python2; then python2 setup.py install; fi
94 | if which python3; then python3 setup.py install; fi
95 | install -m 0755 -d $(DESTDIR)$(mandir)/man1
96 | install -m 0644 *.1 $(DESTDIR)$(mandir)/man1
97 | install -m 0755 -d $(DESTDIR)$(mandir)/man3
98 | install -m 0644 *.3 $(DESTDIR)$(mandir)/man3
99 | ldconfig
100 |
101 | uninstall:
102 | rm -f $(DESTDIR)$(includedir)/pigpio.h
103 | rm -f $(DESTDIR)$(includedir)/pigpiod_if.h
104 | rm -f $(DESTDIR)$(includedir)/pigpiod_if2.h
105 | rm -f $(DESTDIR)$(libdir)/libpigpio.so
106 | rm -f $(DESTDIR)$(libdir)/libpigpiod_if.so
107 | rm -f $(DESTDIR)$(libdir)/libpigpiod_if2.so
108 | rm -f $(DESTDIR)$(bindir)/pig2vcd
109 | rm -f $(DESTDIR)$(bindir)/pigpiod
110 | rm -f $(DESTDIR)$(bindir)/pigs
111 | if which python2; then python2 setup.py install --record /tmp/pigpio >/dev/null; xargs rm -f < /tmp/pigpio >/dev/null; fi
112 | if which python3; then python3 setup.py install --record /tmp/pigpio >/dev/null; xargs rm -f < /tmp/pigpio >/dev/null; fi
113 | rm -f $(DESTDIR)$(mandir)/man1/pig*.1
114 | rm -f $(DESTDIR)$(mandir)/man3/pig*.3
115 | ldconfig
116 |
117 | $(LIB1): $(OBJ1)
118 | $(SHLIB) -o $(LIB1) $(OBJ1)
119 | $(STRIPLIB) $(LIB1)
120 | $(SIZE) $(LIB1)
121 |
122 | $(LIB2): $(OBJ2)
123 | $(SHLIB) -o $(LIB2) $(OBJ2)
124 | $(STRIPLIB) $(LIB2)
125 | $(SIZE) $(LIB2)
126 |
127 | $(LIB3): $(OBJ3)
128 | $(SHLIB) -o $(LIB3) $(OBJ3)
129 | $(STRIPLIB) $(LIB3)
130 | $(SIZE) $(LIB3)
131 |
132 | # generated using gcc -MM *.c
133 |
134 | pig2vcd.o: pig2vcd.c pigpio.h
135 | pigpiod.o: pigpiod.c pigpio.h
136 | pigs.o: pigs.c pigpio.h command.h
137 | x_pigpio.o: x_pigpio.c pigpio.h
138 | x_pigpiod_if.o: x_pigpiod_if.c pigpiod_if.h pigpio.h
139 | x_pigpiod_if2.o: x_pigpiod_if2.c pigpiod_if2.h pigpio.h
140 |
141 |
--------------------------------------------------------------------------------
/PIGPIO/README:
--------------------------------------------------------------------------------
1 | NOTE
2 |
3 | The initial part of the make, the compilation of pigpio.c,
4 | takes 100 seconds on early model Pis. Be patient. The overall
5 | install takes just over 3 minutes.
6 |
7 | INSTALL
8 |
9 | Extract the archive to a directory.
10 |
11 | IN THAT DIRECTORY
12 |
13 | Enter the following two commands (in this order)
14 |
15 | make
16 | sudo make install
17 |
18 | This will install
19 |
20 | o the library (libpigpio.so) in /usr/local/lib
21 | o the library (libpigpiod_if.so) in /usr/local/lib
22 | o the library (libpigpiod_if2.so) in /usr/local/lib
23 | o the header file (pigpio.h) in /usr/local/include
24 | o the header file (pigpiod_if.h) in /usr/local/include
25 | o the header file (pigpiod_if2.h) in /usr/local/include
26 | o the daemon (pigpiod) in /usr/local/bin
27 | o the socket interface (pigs) in /usr/local/bin
28 | o the utility pig2vcd in /usr/local/bin
29 | o man pages in /usr/local/man/man1 and /usr/local/man/man3
30 | o the Python module pigpio.py for Python 2 and 3
31 |
32 | TEST (optional)
33 |
34 | *** WARNING ************************************************
35 | * *
36 | * All the tests make extensive use of gpio 4 (pin P1/J8-7).*
37 | * Ensure that either nothing or just a LED is connected to *
38 | * gpio 4 before running any of the tests. *
39 | * *
40 | * Some tests are statistical in nature and so may on *
41 | * occasion fail. Repeated failures on the same test or *
42 | * many failures in a group of tests indicate a problem. *
43 | ************************************************************
44 |
45 | To test the library do
46 |
47 | sudo ./x_pigpio
48 |
49 | To test the pigpio daemon do
50 |
51 | sudo pigpiod
52 |
53 | ./x_pigpiod_if # test the C I/F to the pigpio daemon
54 | ./x_pigpiod_if2 # test the C I/F to the pigpio daemon
55 | ./x_pigpio.py # test the Python I/F to the pigpio daemon
56 | ./x_pigs # test the socket I/F to the pigpio daemon
57 | ./x_pipe # test the pipe I/F to the pigpio daemon
58 |
59 | EXAMPLE CODE
60 |
61 | x_pigpio.c, pig2vcd.c, and pigpiod.c show examples of interfacing
62 | with the pigpio library.
63 |
64 | pigs.c, pigpio.py, x_pigpiod_if, x_pigpiod_if2.c, x_pigpio.py,
65 | x_pigs, and x_pipe show examples of interfacing with the pigpio
66 | daemon. x_pipe uses the pipe interface, the others use the
67 | socket interface.
68 |
69 | DAEMON
70 |
71 | To launch the daemon do
72 |
73 | sudo pigpiod (pigpiod -? for options)
74 |
75 | Once the daemon is launched the socket and pipe interfaces will be
76 | available.
77 |
78 | When the library starts it locks
79 |
80 | /var/run/pigpio.pid
81 |
82 | The file should be automatically deleted when the library terminates.
83 |
84 | SOCKET INTERFACE
85 |
86 | Use pigs for the socket interface (pigs help for help).
87 |
88 | PIPE INTERFACE
89 |
90 | The pipe interface accepts commands written to /dev/pigpio.
91 |
92 | Results are read from /dev/pigout.
93 |
94 | Errors are output on /dev/pigerr.
95 |
96 | To test the pipe interface perhaps do
97 |
98 | cat /dev/pigout &
99 | cat /dev/pigerr &
100 |
101 | echo "help" >/dev/pigpio
102 |
103 | PYTHON MODULE
104 |
105 | The Python pigpio module is installed to the default Python location
106 | for Python 2 and Python 3.
107 |
108 | You can install it for additional Python versions by
109 |
110 | pythonx.y setup.py install
111 |
112 | where x.y is the Python version.
113 |
114 | STOP DAEMON
115 |
116 | To stop the pigpiod daemon
117 |
118 | sudo killall pigpiod
119 |
120 | RUNNING ON NON Pi's
121 |
122 | You can access the pigpiod daemon running on the Pi from any machine which
123 | is connected to it over the network. This access is via the socket interface.
124 |
125 | In particular this allows you to use the following on non-Pi's.
126 |
127 | o pigs
128 | o the pigpio Python module
129 | o the C socket I/F using libpigpiod_if (header file pigpiod_if.h)
130 | o the C socket I/F using libpigpiod_if2 (header file pigpiod_if2.h)
131 |
132 | On a Linux machine
133 |
134 | make -f MakeRemote clean
135 | make -f MakeRemote
136 | make -f MakeRemote install
137 |
138 | This will install
139 |
140 | o the library (libpigpiod_if.so) in /usr/local/lib
141 | o the library (libpigpiod_if2.so) in /usr/local/lib
142 | o the header file (pigpio.h) in /usr/local/include
143 | o the header file (pigpiod_if.h) in /usr/local/include
144 | o the header file (pigpiod_if2.h) in /usr/local/include
145 | o the socket interface (pigs) in /usr/local/bin
146 | o man pages in /usr/local/man/man1 and /usr/local/man/man3
147 | o the Python module pigpio.py
148 |
149 | On Windows machines (and possibly Macs)
150 |
151 | The Python module should install with
152 |
153 | python setup.py install
154 |
155 | pigs, pigpiod_if, and pigpiod_if2 will need minor mods to
156 | reflect the Windows/Mac socket interface.
157 |
158 | DOCUMENTATION
159 |
160 | The most up to date should be http://abyz.co.uk/rpi/pigpio/
161 |
162 | On the Pi try
163 |
164 | man pigs
165 | man pigpiod
166 | man pig2vcd
167 |
168 | man pigpio
169 | man pigpiod_if
170 | man pigpiod_if2
171 |
172 | pydoc pigpio
173 |
174 |
--------------------------------------------------------------------------------
/PIGPIO/UNLICENCE:
--------------------------------------------------------------------------------
1 | This is free and unencumbered software released into the public domain.
2 |
3 | Anyone is free to copy, modify, publish, use, compile, sell, or
4 | distribute this software, either in source code form or as a compiled
5 | binary, for any purpose, commercial or non-commercial, and by any
6 | means.
7 |
8 | In jurisdictions that recognize copyright laws, the author or authors
9 | of this software dedicate any and all copyright interest in the
10 | software to the public domain. We make this dedication for the benefit
11 | of the public at large and to the detriment of our heirs and
12 | successors. We intend this dedication to be an overt act of
13 | relinquishment in perpetuity of all present and future rights to this
14 | software under copyright law.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 | For more information, please refer to
25 |
26 |
--------------------------------------------------------------------------------
/PIGPIO/command.h:
--------------------------------------------------------------------------------
1 | /*
2 | This is free and unencumbered software released into the public domain.
3 |
4 | Anyone is free to copy, modify, publish, use, compile, sell, or
5 | distribute this software, either in source code form or as a compiled
6 | binary, for any purpose, commercial or non-commercial, and by any
7 | means.
8 |
9 | In jurisdictions that recognize copyright laws, the author or authors
10 | of this software dedicate any and all copyright interest in the
11 | software to the public domain. We make this dedication for the benefit
12 | of the public at large and to the detriment of our heirs and
13 | successors. We intend this dedication to be an overt act of
14 | relinquishment in perpetuity of all present and future rights to this
15 | software under copyright law.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 | OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | For more information, please refer to
26 | */
27 |
28 | /*
29 | This version is for pigpio version 57+
30 | */
31 |
32 | #ifndef COMMAND_H
33 | #define COMMAND_H
34 |
35 | #include
36 | #include
37 |
38 | #include "pigpio.h"
39 |
40 | #define CMD_MAX_PARAM 512
41 | #define CMD_MAX_EXTENSION (1<<16)
42 |
43 | #define CMD_UNKNOWN_CMD -1
44 | #define CMD_BAD_PARAMETER -2
45 | #define CMD_EXT_TOO_SMALL -3
46 |
47 | #define CMD_P_ARR 10
48 | #define CMD_V_ARR 10
49 |
50 | #define CMD_NUMERIC 1
51 | #define CMD_VAR 2
52 | #define CMD_PAR 3
53 |
54 | typedef struct
55 | {
56 | uint32_t cmd;
57 | uint32_t p1;
58 | uint32_t p2;
59 | union
60 | {
61 | uint32_t p3;
62 | uint32_t ext_len;
63 | uint32_t res;
64 | };
65 | } cmdCmd_t;
66 |
67 | typedef struct
68 | {
69 | int eaten;
70 | int8_t opt[4];
71 | } cmdCtlParse_t;
72 |
73 | typedef struct
74 | {
75 | int cmd; /* command number */
76 | char *name; /* command name */
77 | int vt; /* command verification type */
78 | int rv; /* command return value type */
79 | } cmdInfo_t;
80 |
81 | typedef struct
82 | {
83 | uint32_t tag;
84 | int step;
85 | } cmdTagStep_t;
86 |
87 | typedef struct
88 | {
89 | uint32_t p[5];
90 | int8_t opt[4];
91 | } cmdInstr_t;
92 |
93 | typedef struct
94 | {
95 | /*
96 | +-----------+---------+---------+----------------+
97 | | PARAMS... | VARS... | CMDS... | STRING AREA... |
98 | +-----------+---------+---------+----------------+
99 | */
100 | int *par;
101 | int *var;
102 | cmdInstr_t *instr;
103 | int instrs;
104 | char *str_area;
105 | int str_area_len;
106 | int str_area_pos;
107 | } cmdScript_t;
108 |
109 | extern cmdInfo_t cmdInfo[];
110 |
111 | extern char *cmdUsage;
112 |
113 | int cmdParse(char *buf, uint32_t *p, unsigned ext_len, char *ext, cmdCtlParse_t *ctl);
114 |
115 | int cmdParseScript(char *script, cmdScript_t *s, int diags);
116 |
117 | char *cmdErrStr(int error);
118 |
119 | char *cmdStr(void);
120 |
121 | #endif
122 |
123 |
--------------------------------------------------------------------------------
/PIGPIO/command.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/command.o
--------------------------------------------------------------------------------
/PIGPIO/custom.cext:
--------------------------------------------------------------------------------
1 | /*
2 | This version is for pigpio version 26+
3 |
4 | If you want customised functions replace this file with your own
5 | definitions for gpioCustom1 and gpioCustom2.
6 | */
7 |
8 | #include "pigpio.h"
9 |
10 | int gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned count)
11 | {
12 | int i;
13 | unsigned max;
14 |
15 | DBG(DBG_USER, "arg1=%d arg2=%d count=%d [%s]",
16 | arg1, arg2, count, myBuf2Str(count, argx));
17 |
18 | CHECK_INITED;
19 |
20 | /* for dummy just return max parameter */
21 |
22 | if (arg1 > arg2) max = arg1; else max = arg2;
23 |
24 | for (i=0; i max) max = argx[i];
25 |
26 | return max;
27 | }
28 |
29 |
30 | int gpioCustom2(unsigned arg1, char *argx, unsigned count,
31 | char *retBuf, unsigned retMax)
32 | {
33 | int i, j, t;
34 |
35 | DBG(DBG_USER, "arg1=%d count=%d [%s] retMax=%d",
36 | arg1, count, myBuf2Str(count, argx), retMax);
37 |
38 | CHECK_INITED;
39 |
40 | /* for dummy just return argx reversed */
41 |
42 | if (count > retMax) count = retMax;
43 |
44 | for (i=0, j=count-1; i<=j; i++, j--)
45 | {
46 | /* t used as argx and retBuf may be the same buffer */
47 | t = argx[i];
48 | retBuf[i] = argx[j];
49 | retBuf[j] = t;
50 | }
51 |
52 | return count;
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/PIGPIO/libpigpio.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/libpigpio.so
--------------------------------------------------------------------------------
/PIGPIO/libpigpiod_if.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/libpigpiod_if.so
--------------------------------------------------------------------------------
/PIGPIO/libpigpiod_if2.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/libpigpiod_if2.so
--------------------------------------------------------------------------------
/PIGPIO/pig2vcd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/pig2vcd
--------------------------------------------------------------------------------
/PIGPIO/pig2vcd.1:
--------------------------------------------------------------------------------
1 |
2 | ." Process this file with
3 | ." groff -man -Tascii pig2vcd.1
4 | ."
5 | .TH pig2vcd 1 2012-2015 Linux "pigpio archive"
6 | .SH NAME
7 | pig2vd - A utility to convert pigpio notifications to VCD.
8 |
9 | .SH SYNOPSIS
10 |
11 | pig2vcd file.VCD
12 | .SH DESCRIPTION
13 |
14 |
15 | .ad l
16 |
17 | .nh
18 | pig2vcd is a utility which reads notifications on stdin and writes the
19 | output as a Value Change Dump (VCD) file on stdout.
20 |
21 | .br
22 |
23 | .br
24 | The VCD file can be viewed using GTKWave.
25 |
26 | .br
27 |
28 | .br
29 | .SS Notifications
30 | .br
31 |
32 | .br
33 | Notifications consist of 12 bytes with the following binary format.
34 |
35 | .br
36 |
37 | .br
38 |
39 | .EX
40 | typedef struct
41 | .br
42 | {
43 | .br
44 | uint16_t seqno;
45 | .br
46 | uint16_t flags;
47 | .br
48 | uint32_t tick;
49 | .br
50 | uint32_t level;
51 | .br
52 | } gpioReport_t;
53 | .br
54 |
55 | .EE
56 |
57 | .br
58 |
59 | .br
60 | seqno: starts at 0 each time the handle is opened and then increments by one for each report.
61 |
62 | .br
63 |
64 | .br
65 | flags: two flags are defined, PI_NTFY_FLAGS_WDOG and PI_NTFY_FLAGS_ALIVE. If bit 5 is set (PI_NTFY_FLAGS_WDOG) then bits 0-4 of the flags indicate a gpio which has had a watchdog timeout; if bit 6 is set (PI_NTFY_FLAGS_ALIVE) this indicates a keep alive signal on the pipe/socket and is sent once a minute in the absence of other notification activity.
66 |
67 | .br
68 |
69 | .br
70 | tick: the number of microseconds since system boot. It wraps around after 1h12m.
71 |
72 | .br
73 |
74 | .br
75 | level: indicates the level of each gpio. If bit 1<
26 | */
27 |
28 | /*
29 | This version is for pigpio version 3+
30 | */
31 |
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 |
42 | #include "pigpio.h"
43 |
44 | /*
45 | This software converts pigpio notification reports
46 | into a VCD format understood by GTKWave.
47 | */
48 |
49 | #define RS (sizeof(gpioReport_t))
50 |
51 | static char * timeStamp()
52 | {
53 | static char buf[32];
54 |
55 | struct timeval now;
56 | struct tm tmp;
57 |
58 | gettimeofday(&now, NULL);
59 |
60 | localtime_r(&now.tv_sec, &tmp);
61 | strftime(buf, sizeof(buf), "%F %T", &tmp);
62 |
63 | return buf;
64 | }
65 |
66 | int symbol(int bit)
67 | {
68 | if (bit < 26) return ('A' + bit);
69 | else return ('a' + bit - 26);
70 | }
71 |
72 | int main(int argc, char * argv[])
73 | {
74 | int b, r, v;
75 | uint32_t t0;
76 | uint32_t lastLevel, changed;
77 |
78 | gpioReport_t report;
79 |
80 | r=read(STDIN_FILENO, &report, RS);
81 |
82 | if (r != RS) exit(-1);
83 |
84 | printf("$date %s $end\n", timeStamp());
85 | printf("$version pig2vcd V1 $end\n");
86 | printf("$timescale 1 us $end\n");
87 | printf("$scope module top $end\n");
88 |
89 | for (b=0; b<32; b++)
90 | printf("$var wire 1 %c %d $end\n", symbol(b), b);
91 |
92 | printf("$upscope $end\n");
93 | printf("$enddefinitions $end\n");
94 |
95 | t0 = report.tick;
96 | lastLevel =0;
97 |
98 | while ((r=read(STDIN_FILENO, &report, RS)) == RS)
99 | {
100 | if (report.level != lastLevel)
101 | {
102 | printf("#%u\n", report.tick - t0);
103 |
104 | changed = report.level ^ lastLevel;
105 |
106 | lastLevel = report.level;
107 |
108 | for (b=0; b<32; b++)
109 | {
110 | if (changed & (1<
26 | */
27 |
28 | /*
29 | This version is for pigpio version 56+
30 | */
31 |
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 |
43 | #include "pigpio.h"
44 | #include "command.h"
45 |
46 | /*
47 | This program provides a socket interface to some of
48 | the commands available from pigpio.
49 | */
50 |
51 | char command_buf[CMD_MAX_EXTENSION];
52 | char response_buf[CMD_MAX_EXTENSION];
53 |
54 | int printFlags = 0;
55 |
56 | #define SOCKET_OPEN_FAILED -1
57 |
58 | #define PRINT_HEX 1
59 | #define PRINT_ASCII 2
60 |
61 | void fatal(char *fmt, ...)
62 | {
63 | char buf[128];
64 | va_list ap;
65 |
66 | va_start(ap, fmt);
67 | vsnprintf(buf, sizeof(buf), fmt, ap);
68 | va_end(ap);
69 |
70 | fprintf(stderr, "%s\n", buf);
71 |
72 | fflush(stderr);
73 | }
74 |
75 | static int initOpts(int argc, char *argv[])
76 | {
77 | int opt, args;
78 |
79 | args = 1;
80 |
81 | while ((opt = getopt(argc, argv, "ax")) != -1)
82 | {
83 | switch (opt)
84 | {
85 | case 'a':
86 | printFlags |= PRINT_ASCII;
87 | args++;
88 | break;
89 |
90 | case 'x':
91 | printFlags |= PRINT_HEX;
92 | args++;
93 | break;
94 | }
95 | }
96 | return args;
97 | }
98 |
99 | static int openSocket(void)
100 | {
101 | int sock, err;
102 | struct addrinfo hints, *res, *rp;
103 | const char *addrStr, *portStr;
104 |
105 | portStr = getenv(PI_ENVPORT);
106 |
107 | if (!portStr) portStr = PI_DEFAULT_SOCKET_PORT_STR;
108 |
109 | addrStr = getenv(PI_ENVADDR);
110 |
111 | if (!addrStr) addrStr = PI_DEFAULT_SOCKET_ADDR_STR;
112 |
113 | memset (&hints, 0, sizeof (hints));
114 |
115 | hints.ai_family = PF_UNSPEC;
116 | hints.ai_socktype = SOCK_STREAM;
117 | hints.ai_flags |= AI_CANONNAME;
118 |
119 | err = getaddrinfo(addrStr, portStr, &hints, &res);
120 |
121 | if (err) return SOCKET_OPEN_FAILED;
122 |
123 | for (rp=res; rp!=NULL; rp=rp->ai_next)
124 | {
125 | sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
126 |
127 | if (sock == -1) continue;
128 |
129 | if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) break;
130 | }
131 |
132 | freeaddrinfo(res);
133 |
134 | if (rp == NULL) return SOCKET_OPEN_FAILED;
135 |
136 | return sock;
137 | }
138 |
139 | void print_result(int sock, int rv, cmdCmd_t cmd)
140 | {
141 | int i, r, ch;
142 | uint32_t *p;
143 |
144 | r = cmd.res;
145 |
146 | switch (rv)
147 | {
148 | case 0:
149 | case 1:
150 | if (r < 0)
151 | {
152 | printf("%d\n", r);
153 | fatal("ERROR: %s", cmdErrStr(r));
154 | }
155 | break;
156 |
157 | case 2:
158 | printf("%d\n", r);
159 | if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
160 | break;
161 |
162 | case 3:
163 | printf("%08X\n", cmd.res);
164 | break;
165 |
166 | case 4:
167 | printf("%u\n", cmd.res);
168 | break;
169 |
170 | case 5:
171 | printf("%s", cmdUsage);
172 | break;
173 |
174 | case 6: /*
175 | BI2CZ CF2 FL FR I2CPK I2CRD I2CRI I2CRK
176 | I2CZ SERR SLR SPIX SPIR
177 | */
178 | printf("%d", r);
179 | if (r < 0) fatal("ERROR: %s", cmdErrStr(r));
180 | if (r > 0)
181 | {
182 | if (printFlags == PRINT_ASCII) printf(" ");
183 |
184 | for (i=0; i 4)
233 | {
234 | if (printFlags == PRINT_ASCII) printf(" ");
235 |
236 | for (i=4; i 0)
279 | {
280 | recv(sock, response_buf, res, MSG_WAITALL);
281 | response_buf[res] = 0;
282 | }
283 | break;
284 | }
285 | }
286 |
287 | int main(int argc , char *argv[])
288 | {
289 | int sock, command;
290 | int args, idx, i, pp, l, len;
291 | cmdCmd_t cmd;
292 | uint32_t p[CMD_P_ARR];
293 | cmdCtlParse_t ctl;
294 | cmdScript_t s;
295 | char v[CMD_MAX_EXTENSION];
296 |
297 | sock = openSocket();
298 |
299 | args = initOpts(argc, argv);
300 |
301 | command_buf[0] = 0;
302 | l = 0;
303 | pp = 0;
304 |
305 | for (i=args; i= 0) && (ctl.eaten < len))
320 | {
321 | if ((idx=cmdParse(command_buf, p, CMD_MAX_EXTENSION, v, &ctl)) >= 0)
322 | {
323 | command = p[0];
324 |
325 | if (command < PI_CMD_SCRIPT)
326 | {
327 | if (command == PI_CMD_HELP)
328 | {
329 | printf("%s", cmdUsage);
330 | }
331 | else if (command == PI_CMD_PARSE)
332 | {
333 | cmdParseScript(v, &s, 1);
334 | if (s.par) free (s.par);
335 | }
336 | else
337 | {
338 | cmd.cmd = command;
339 | cmd.p1 = p[1];
340 | cmd.p2 = p[2];
341 | cmd.p3 = p[3];
342 |
343 | if (sock != SOCKET_OPEN_FAILED)
344 | {
345 | if (send(sock, &cmd, sizeof(cmdCmd_t), 0) ==
346 | sizeof(cmdCmd_t))
347 | {
348 | if (p[3]) send(sock, v, p[3], 0); /* send extensions */
349 |
350 | if (recv(sock, &cmd, sizeof(cmdCmd_t), MSG_WAITALL) ==
351 | sizeof(cmdCmd_t))
352 | {
353 | get_extensions(sock, command, cmd.res);
354 |
355 | print_result(sock, cmdInfo[idx].rv, cmd);
356 | }
357 | else fatal("socket receive failed");
358 | }
359 | else fatal("socket send failed");
360 | }
361 | else fatal("socket connect failed");
362 | }
363 | }
364 | else fatal("%s only allowed within a script", cmdInfo[idx].name);
365 | }
366 | else
367 | {
368 | if (idx == CMD_UNKNOWN_CMD)
369 | fatal("%s? unknown command, pigs h for help", cmdStr());
370 | else
371 | fatal("%s: bad parameter, pigs h for help", cmdStr());
372 | }
373 | }
374 |
375 | if (sock >= 0) close(sock);
376 |
377 | return 0;
378 | }
379 |
380 |
--------------------------------------------------------------------------------
/PIGPIO/pigs.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/pigs.o
--------------------------------------------------------------------------------
/PIGPIO/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from distutils.core import setup
4 |
5 | setup(name='pigpio',
6 | version='1.35',
7 | author='joan',
8 | author_email='joan@abyz.co.uk',
9 | maintainer='joan',
10 | maintainer_email='joan@abyz.co.uk',
11 | url='http://abyz.co.uk/rpi/pigpio/python.html/',
12 | description='Raspberry gpio module',
13 | long_description='Raspberry Python module to access the pigpio daemon',
14 | download_url='http://abyz.co.uk/rpi/pigpio/pigpio.zip',
15 | license='unlicense.org',
16 | py_modules=['pigpio']
17 | )
18 |
--------------------------------------------------------------------------------
/PIGPIO/x_pigpio:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/x_pigpio
--------------------------------------------------------------------------------
/PIGPIO/x_pigpio.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/x_pigpio.o
--------------------------------------------------------------------------------
/PIGPIO/x_pigpiod_if:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/x_pigpiod_if
--------------------------------------------------------------------------------
/PIGPIO/x_pigpiod_if.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/x_pigpiod_if.o
--------------------------------------------------------------------------------
/PIGPIO/x_pigpiod_if2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/x_pigpiod_if2
--------------------------------------------------------------------------------
/PIGPIO/x_pigpiod_if2.o:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/PIGPIO/x_pigpiod_if2.o
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # js-gpiozero
2 |
3 | [](https://travis-ci.org/miketrebilcock/js-gpiozero) [](https://codecov.io/gh/miketrebilcock/js-gpiozero) [](https://badge.fury.io/js/js-gpiozero) [](https://github.com/semantic-release/semantic-release)
4 |
5 | A port of the fanastic [python gpiozero](https://github.com/RPi-Distro/python-gpiozero) to javascript creating simple interface to everyday GPIO components used with Raspberry Pi on node.js.
6 |
7 | It's early days and a work in progress!
8 |
9 | ## Documentation
10 | The API Documentation is available at the repos [github-pages](https://miketrebilcock.github.io/js-gpiozero/).
11 |
12 | ## Using
13 | First of all we need to be running the latest version of nodejs (at least v6). The following command updates the Debian apt package repository to include the NodeSource packages
14 |
15 | ```bash
16 | $curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
17 | ```
18 |
19 | Now that we have added the NodeSource package repository, we can move on and install Node.js!
20 |
21 | ```bash
22 | $ sudo apt install nodejs
23 | ```
24 |
25 | We can then test and see what version of Node we are running
26 |
27 | ```bash
28 | $ node -v
29 | v7.3.0
30 |
31 | ```
32 |
33 | ## Contributing [](https://github.com/miketrebilcock/js-gpiozero/issues) [](http://commitizen.github.io/cz-cli/)
34 |
35 | The project is very much a work in progress. Some far the output part of gpiozero has been followed through, completing a near direct translation from the original Python. This means the operating model hasn't really taken advantage of the nodejs programming paradigm. That's next! It's mostly written in EMCAScript 5 with a splash of 6, the intention is to written everything in 6, then use babel to create an output that nodejs can use. The projects tab shows current work, planned and in progress, feel free to pick up a task and have a go.
36 |
37 | The documentation is produced by [jsdoc](https://www.npmjs.com/package/jsdoc), enabling the api documentation to be written within the source code. Upon committing to git, a pre-commit task will run, this runs all tests and updates the documentation. Checkout [Git Hooks](https://www.atlassian.com/git/tutorials/git-hooks/local-hooks) for more info.
38 |
39 | To enable this the follow line needs to be executed:
40 |
41 | ```bash
42 | $ln -s ../../pre-commit.sh .git/hooks/pre-commit
43 | ```
44 |
45 | or you can simply run the following command:
46 |
47 | ```bash
48 | $npm run docs
49 | ```
50 |
51 | More info about contributing can be found [here](https://github.com/miketrebilcock/js-gpiozero/blob/master/CONTRIBUTING.md)
52 |
53 | [](https://nodei.co/npm/js-gpiozero/)
54 |
55 |
--------------------------------------------------------------------------------
/docs/assets/anchor.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * AnchorJS - v1.2.1 - 2015-07-02
3 | * https://github.com/bryanbraun/anchorjs
4 | * Copyright (c) 2015 Bryan Braun; Licensed MIT
5 | */
6 |
7 | function AnchorJS(options) {
8 | 'use strict';
9 |
10 | this.options = options || {};
11 |
12 | this._applyRemainingDefaultOptions = function(opts) {
13 | this.options.icon = this.options.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'.
14 | this.options.visible = this.options.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always'
15 | this.options.placement = this.options.hasOwnProperty('placement') ? opts.placement : 'right'; // Also accepts 'left'
16 | this.options.class = this.options.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name.
17 | };
18 |
19 | this._applyRemainingDefaultOptions(options);
20 |
21 | this.add = function(selector) {
22 | var elements,
23 | elsWithIds,
24 | idList,
25 | elementID,
26 | i,
27 | roughText,
28 | tidyText,
29 | index,
30 | count,
31 | newTidyText,
32 | readableID,
33 | anchor;
34 |
35 | this._applyRemainingDefaultOptions(this.options);
36 |
37 | // Provide a sensible default selector, if none is given.
38 | if (!selector) {
39 | selector = 'h1, h2, h3, h4, h5, h6';
40 | } else if (typeof selector !== 'string') {
41 | throw new Error('The selector provided to AnchorJS was invalid.');
42 | }
43 |
44 | elements = document.querySelectorAll(selector);
45 | if (elements.length === 0) {
46 | return false;
47 | }
48 |
49 | this._addBaselineStyles();
50 |
51 | // We produce a list of existing IDs so we don't generate a duplicate.
52 | elsWithIds = document.querySelectorAll('[id]');
53 | idList = [].map.call(elsWithIds, function assign(el) {
54 | return el.id;
55 | });
56 |
57 | for (i = 0; i < elements.length; i++) {
58 |
59 | if (elements[i].hasAttribute('id')) {
60 | elementID = elements[i].getAttribute('id');
61 | } else {
62 | roughText = elements[i].textContent;
63 |
64 | // Refine it so it makes a good ID. Strip out non-safe characters, replace
65 | // spaces with hyphens, truncate to 32 characters, and make toLowerCase.
66 | //
67 | // Example string: // '⚡⚡⚡ Unicode icons are cool--but they definitely don't belong in a URL fragment.'
68 | tidyText = roughText.replace(/[^\w\s-]/gi, '') // ' Unicode icons are cool--but they definitely dont belong in a URL fragment'
69 | .replace(/\s+/g, '-') // '-Unicode-icons-are-cool--but-they-definitely-dont-belong-in-a-URL-fragment'
70 | .replace(/-{2,}/g, '-') // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL-fragment'
71 | .substring(0, 64) // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
72 | .replace(/^-+|-+$/gm, '') // 'Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
73 | .toLowerCase(); // 'unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-url'
74 |
75 | // Compare our generated ID to existing IDs (and increment it if needed)
76 | // before we add it to the page.
77 | newTidyText = tidyText;
78 | count = 0;
79 | do {
80 | if (index !== undefined) {
81 | newTidyText = tidyText + '-' + count;
82 | }
83 | // .indexOf is supported in IE9+.
84 | index = idList.indexOf(newTidyText);
85 | count += 1;
86 | } while (index !== -1);
87 | index = undefined;
88 | idList.push(newTidyText);
89 |
90 | // Assign it to our element.
91 | // Currently the setAttribute element is only supported in IE9 and above.
92 | elements[i].setAttribute('id', newTidyText);
93 |
94 | elementID = newTidyText;
95 | }
96 |
97 | readableID = elementID.replace(/-/g, ' ');
98 |
99 | // The following code builds the following DOM structure in a more effiecient (albeit opaque) way.
100 | // '';
101 | anchor = document.createElement('a');
102 | anchor.className = 'anchorjs-link ' + this.options.class;
103 | anchor.href = '#' + elementID;
104 | anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID);
105 | anchor.setAttribute('data-anchorjs-icon', this.options.icon);
106 |
107 | if (this.options.visible === 'always') {
108 | anchor.style.opacity = '1';
109 | }
110 |
111 | if (this.options.icon === '\ue9cb') {
112 | anchor.style.fontFamily = 'anchorjs-icons';
113 | anchor.style.fontStyle = 'normal';
114 | anchor.style.fontVariant = 'normal';
115 | anchor.style.fontWeight = 'normal';
116 | anchor.style.lineHeight = 1;
117 | }
118 |
119 | if (this.options.placement === 'left') {
120 | anchor.style.position = 'absolute';
121 | anchor.style.marginLeft = '-1em';
122 | anchor.style.paddingRight = '0.5em';
123 | elements[i].insertBefore(anchor, elements[i].firstChild);
124 | } else { // if the option provided is `right` (or anything else).
125 | anchor.style.paddingLeft = '0.375em';
126 | elements[i].appendChild(anchor);
127 | }
128 | }
129 |
130 | return this;
131 | };
132 |
133 | this.remove = function(selector) {
134 | var domAnchor,
135 | elements = document.querySelectorAll(selector);
136 | for (var i = 0; i < elements.length; i++) {
137 | domAnchor = elements[i].querySelector('.anchorjs-link');
138 | if (domAnchor) {
139 | elements[i].removeChild(domAnchor);
140 | }
141 | }
142 | return this;
143 | };
144 |
145 | this._addBaselineStyles = function() {
146 | // We don't want to add global baseline styles if they've been added before.
147 | if (document.head.querySelector('style.anchorjs') !== null) {
148 | return;
149 | }
150 |
151 | var style = document.createElement('style'),
152 | linkRule =
153 | ' .anchorjs-link {' +
154 | ' opacity: 0;' +
155 | ' text-decoration: none;' +
156 | ' -webkit-font-smoothing: antialiased;' +
157 | ' -moz-osx-font-smoothing: grayscale;' +
158 | ' }',
159 | hoverRule =
160 | ' *:hover > .anchorjs-link,' +
161 | ' .anchorjs-link:focus {' +
162 | ' opacity: 1;' +
163 | ' }',
164 | anchorjsLinkFontFace =
165 | ' @font-face {' +
166 | ' font-family: "anchorjs-icons";' +
167 | ' font-style: normal;' +
168 | ' font-weight: normal;' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above
169 | ' src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype");' +
170 | ' }',
171 | pseudoElContent =
172 | ' [data-anchorjs-icon]::after {' +
173 | ' content: attr(data-anchorjs-icon);' +
174 | ' }',
175 | firstStyleEl;
176 |
177 | style.className = 'anchorjs';
178 | style.appendChild(document.createTextNode('')); // Necessary for Webkit.
179 |
180 | // We place it in the head with the other style tags, if possible, so as to
181 | // not look out of place. We insert before the others so these styles can be
182 | // overridden if necessary.
183 | firstStyleEl = document.head.querySelector('[rel="stylesheet"], style');
184 | if (firstStyleEl === undefined) {
185 | document.head.appendChild(style);
186 | } else {
187 | document.head.insertBefore(style, firstStyleEl);
188 | }
189 |
190 | style.sheet.insertRule(linkRule, style.sheet.cssRules.length);
191 | style.sheet.insertRule(hoverRule, style.sheet.cssRules.length);
192 | style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length);
193 | style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length);
194 | };
195 | }
196 |
197 | var anchors = new AnchorJS();
198 |
--------------------------------------------------------------------------------
/docs/assets/bass-addons.css:
--------------------------------------------------------------------------------
1 | .input {
2 | font-family: inherit;
3 | display: block;
4 | width: 100%;
5 | height: 2rem;
6 | padding: .5rem;
7 | margin-bottom: 1rem;
8 | border: 1px solid #ccc;
9 | font-size: .875rem;
10 | border-radius: 3px;
11 | box-sizing: border-box;
12 | }
13 |
--------------------------------------------------------------------------------
/docs/assets/fonts/EOT/SourceCodePro-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/EOT/SourceCodePro-Bold.eot
--------------------------------------------------------------------------------
/docs/assets/fonts/EOT/SourceCodePro-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/EOT/SourceCodePro-Regular.eot
--------------------------------------------------------------------------------
/docs/assets/fonts/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
2 |
3 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
4 |
5 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
6 |
7 |
8 | -----------------------------------------------------------
9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10 | -----------------------------------------------------------
11 |
12 | PREAMBLE
13 | The goals of the Open Font License (OFL) are to stimulate worldwide
14 | development of collaborative font projects, to support the font creation
15 | efforts of academic and linguistic communities, and to provide a free and
16 | open framework in which fonts may be shared and improved in partnership
17 | with others.
18 |
19 | The OFL allows the licensed fonts to be used, studied, modified and
20 | redistributed freely as long as they are not sold by themselves. The
21 | fonts, including any derivative works, can be bundled, embedded,
22 | redistributed and/or sold with any software provided that any reserved
23 | names are not used by derivative works. The fonts and derivatives,
24 | however, cannot be released under any other type of license. The
25 | requirement for fonts to remain under this license does not apply
26 | to any document created using the fonts or their derivatives.
27 |
28 | DEFINITIONS
29 | "Font Software" refers to the set of files released by the Copyright
30 | Holder(s) under this license and clearly marked as such. This may
31 | include source files, build scripts and documentation.
32 |
33 | "Reserved Font Name" refers to any names specified as such after the
34 | copyright statement(s).
35 |
36 | "Original Version" refers to the collection of Font Software components as
37 | distributed by the Copyright Holder(s).
38 |
39 | "Modified Version" refers to any derivative made by adding to, deleting,
40 | or substituting -- in part or in whole -- any of the components of the
41 | Original Version, by changing formats or by porting the Font Software to a
42 | new environment.
43 |
44 | "Author" refers to any designer, engineer, programmer, technical
45 | writer or other person who contributed to the Font Software.
46 |
47 | PERMISSION & CONDITIONS
48 | Permission is hereby granted, free of charge, to any person obtaining
49 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
50 | redistribute, and sell modified and unmodified copies of the Font
51 | Software, subject to the following conditions:
52 |
53 | 1) Neither the Font Software nor any of its individual components,
54 | in Original or Modified Versions, may be sold by itself.
55 |
56 | 2) Original or Modified Versions of the Font Software may be bundled,
57 | redistributed and/or sold with any software, provided that each copy
58 | contains the above copyright notice and this license. These can be
59 | included either as stand-alone text files, human-readable headers or
60 | in the appropriate machine-readable metadata fields within text or
61 | binary files as long as those fields can be easily viewed by the user.
62 |
63 | 3) No Modified Version of the Font Software may use the Reserved Font
64 | Name(s) unless explicit written permission is granted by the corresponding
65 | Copyright Holder. This restriction only applies to the primary font name as
66 | presented to the users.
67 |
68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69 | Software shall not be used to promote, endorse or advertise any
70 | Modified Version, except to acknowledge the contribution(s) of the
71 | Copyright Holder(s) and the Author(s) or with their explicit written
72 | permission.
73 |
74 | 5) The Font Software, modified or unmodified, in part or in whole,
75 | must be distributed entirely under this license, and must not be
76 | distributed under any other license. The requirement for fonts to
77 | remain under this license does not apply to any document created
78 | using the Font Software.
79 |
80 | TERMINATION
81 | This license becomes null and void if any of the above conditions are
82 | not met.
83 |
84 | DISCLAIMER
85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93 | OTHER DEALINGS IN THE FONT SOFTWARE.
94 |
--------------------------------------------------------------------------------
/docs/assets/fonts/OTF/SourceCodePro-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/OTF/SourceCodePro-Bold.otf
--------------------------------------------------------------------------------
/docs/assets/fonts/OTF/SourceCodePro-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/OTF/SourceCodePro-Regular.otf
--------------------------------------------------------------------------------
/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf
--------------------------------------------------------------------------------
/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/source-code-pro.css:
--------------------------------------------------------------------------------
1 | @font-face{
2 | font-family: 'Source Code Pro';
3 | font-weight: 400;
4 | font-style: normal;
5 | font-stretch: normal;
6 | src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'),
7 | url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'),
8 | url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'),
9 | url('OTF/SourceCodePro-Regular.otf') format('opentype'),
10 | url('TTF/SourceCodePro-Regular.ttf') format('truetype');
11 | }
12 |
13 | @font-face{
14 | font-family: 'Source Code Pro';
15 | font-weight: 700;
16 | font-style: normal;
17 | font-stretch: normal;
18 | src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'),
19 | url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'),
20 | url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'),
21 | url('OTF/SourceCodePro-Bold.otf') format('opentype'),
22 | url('TTF/SourceCodePro-Bold.ttf') format('truetype');
23 | }
24 |
--------------------------------------------------------------------------------
/docs/assets/github.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | github.com style (c) Vasily Polovnyov
4 |
5 | */
6 |
7 | .hljs {
8 | display: block;
9 | overflow-x: auto;
10 | padding: 0.5em;
11 | color: #333;
12 | background: #f8f8f8;
13 | -webkit-text-size-adjust: none;
14 | }
15 |
16 | .hljs-comment,
17 | .diff .hljs-header,
18 | .hljs-javadoc {
19 | color: #998;
20 | font-style: italic;
21 | }
22 |
23 | .hljs-keyword,
24 | .css .rule .hljs-keyword,
25 | .hljs-winutils,
26 | .nginx .hljs-title,
27 | .hljs-subst,
28 | .hljs-request,
29 | .hljs-status {
30 | color: #1184CE;
31 | }
32 |
33 | .hljs-number,
34 | .hljs-hexcolor,
35 | .ruby .hljs-constant {
36 | color: #ed225d;
37 | }
38 |
39 | .hljs-string,
40 | .hljs-tag .hljs-value,
41 | .hljs-phpdoc,
42 | .hljs-dartdoc,
43 | .tex .hljs-formula {
44 | color: #ed225d;
45 | }
46 |
47 | .hljs-title,
48 | .hljs-id,
49 | .scss .hljs-preprocessor {
50 | color: #900;
51 | font-weight: bold;
52 | }
53 |
54 | .hljs-list .hljs-keyword,
55 | .hljs-subst {
56 | font-weight: normal;
57 | }
58 |
59 | .hljs-class .hljs-title,
60 | .hljs-type,
61 | .vhdl .hljs-literal,
62 | .tex .hljs-command {
63 | color: #458;
64 | font-weight: bold;
65 | }
66 |
67 | .hljs-tag,
68 | .hljs-tag .hljs-title,
69 | .hljs-rules .hljs-property,
70 | .django .hljs-tag .hljs-keyword {
71 | color: #000080;
72 | font-weight: normal;
73 | }
74 |
75 | .hljs-attribute,
76 | .hljs-variable,
77 | .lisp .hljs-body {
78 | color: #008080;
79 | }
80 |
81 | .hljs-regexp {
82 | color: #009926;
83 | }
84 |
85 | .hljs-symbol,
86 | .ruby .hljs-symbol .hljs-string,
87 | .lisp .hljs-keyword,
88 | .clojure .hljs-keyword,
89 | .scheme .hljs-keyword,
90 | .tex .hljs-special,
91 | .hljs-prompt {
92 | color: #990073;
93 | }
94 |
95 | .hljs-built_in {
96 | color: #0086b3;
97 | }
98 |
99 | .hljs-preprocessor,
100 | .hljs-pragma,
101 | .hljs-pi,
102 | .hljs-doctype,
103 | .hljs-shebang,
104 | .hljs-cdata {
105 | color: #999;
106 | font-weight: bold;
107 | }
108 |
109 | .hljs-deletion {
110 | background: #fdd;
111 | }
112 |
113 | .hljs-addition {
114 | background: #dfd;
115 | }
116 |
117 | .diff .hljs-change {
118 | background: #0086b3;
119 | }
120 |
121 | .hljs-chunk {
122 | color: #aaa;
123 | }
124 |
--------------------------------------------------------------------------------
/docs/assets/site.js:
--------------------------------------------------------------------------------
1 | /* global anchors */
2 |
3 | // add anchor links to headers
4 | anchors.options.placement = 'left';
5 | anchors.add('h3');
6 |
7 | // Filter UI
8 | var tocElements = document.getElementById('toc')
9 | .getElementsByTagName('li');
10 |
11 | document.getElementById('filter-input')
12 | .addEventListener('keyup', function (e) {
13 |
14 | var i, element, children;
15 |
16 | // enter key
17 | if (e.keyCode === 13) {
18 | // go to the first displayed item in the toc
19 | for (i = 0; i < tocElements.length; i++) {
20 | element = tocElements[i];
21 | if (!element.classList.contains('display-none')) {
22 | location.replace(element.firstChild.href);
23 | return e.preventDefault();
24 | }
25 | }
26 | }
27 |
28 | var match = function () {
29 | return true;
30 | };
31 |
32 | var value = this.value.toLowerCase();
33 |
34 | if (!value.match(/^\s*$/)) {
35 | match = function (element) {
36 | return element.firstChild.innerHTML.toLowerCase().indexOf(value) !== -1;
37 | };
38 | }
39 |
40 | for (i = 0; i < tocElements.length; i++) {
41 | element = tocElements[i];
42 | children = Array.from(element.getElementsByTagName('li'));
43 | if (match(element) || children.some(match)) {
44 | element.classList.remove('display-none');
45 | } else {
46 | element.classList.add('display-none');
47 | }
48 | }
49 | });
50 |
51 | var toggles = document.getElementsByClassName('toggle-step-sibling');
52 | for (var i = 0; i < toggles.length; i++) {
53 | toggles[i].addEventListener('click', toggleStepSibling);
54 | }
55 |
56 | function toggleStepSibling() {
57 | var stepSibling = this.parentNode.parentNode.parentNode.getElementsByClassName('toggle-target')[0];
58 | var klass = 'display-none';
59 | if (stepSibling.classList.contains(klass)) {
60 | stepSibling.classList.remove(klass);
61 | stepSibling.innerHTML = '▾';
62 | } else {
63 | stepSibling.classList.add(klass);
64 | stepSibling.innerHTML = '▸';
65 | }
66 | }
67 |
68 | var items = document.getElementsByClassName('toggle-sibling');
69 | for (var j = 0; j < items.length; j++) {
70 | items[j].addEventListener('click', toggleSibling);
71 | }
72 |
73 | function toggleSibling() {
74 | var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0];
75 | var icon = this.getElementsByClassName('icon')[0];
76 | var klass = 'display-none';
77 | if (stepSibling.classList.contains(klass)) {
78 | stepSibling.classList.remove(klass);
79 | icon.innerHTML = '▾';
80 | } else {
81 | stepSibling.classList.add(klass);
82 | icon.innerHTML = '▸';
83 | }
84 | }
85 |
86 | function showHashTarget(targetId) {
87 | var hashTarget = document.getElementById(targetId);
88 | // new target is hidden
89 | if (hashTarget && hashTarget.offsetHeight === 0 &&
90 | hashTarget.parentNode.parentNode.classList.contains('display-none')) {
91 | hashTarget.parentNode.parentNode.classList.remove('display-none');
92 | }
93 | }
94 |
95 | window.addEventListener('hashchange', function() {
96 | showHashTarget(location.hash.substring(1));
97 | });
98 |
99 | showHashTarget(location.hash.substring(1));
100 |
101 | var toclinks = document.getElementsByClassName('pre-open');
102 | for (var k = 0; k < toclinks.length; k++) {
103 | toclinks[k].addEventListener('mousedown', preOpen, false);
104 | }
105 |
106 | function preOpen() {
107 | showHashTarget(this.hash.substring(1));
108 | }
109 |
--------------------------------------------------------------------------------
/docs/assets/style.css:
--------------------------------------------------------------------------------
1 | .documentation {
2 | font-family: Helvetica, sans-serif;
3 | color: #666;
4 | line-height: 1.5;
5 | background: #f5f5f5;
6 | }
7 |
8 | .black {
9 | color: #666;
10 | }
11 |
12 | .bg-white {
13 | background-color: #fff;
14 | }
15 |
16 | h4 {
17 | margin: 20px 0 10px 0;
18 | }
19 |
20 | .documentation h3 {
21 | color: #000;
22 | }
23 |
24 | .border-bottom {
25 | border-color: #ddd;
26 | }
27 |
28 | a {
29 | color: #1184CE;
30 | text-decoration: none;
31 | }
32 |
33 | .documentation a[href]:hover {
34 | text-decoration: underline;
35 | }
36 |
37 | a:hover {
38 | cursor: pointer;
39 | }
40 |
41 | .py1-ul li {
42 | padding: 5px 0;
43 | }
44 |
45 | .max-height-100 {
46 | max-height: 100%;
47 | }
48 |
49 | section:target h3 {
50 | font-weight:700;
51 | }
52 |
53 | .documentation td,
54 | .documentation th {
55 | padding: .25rem .25rem;
56 | }
57 |
58 | h1:hover .anchorjs-link,
59 | h2:hover .anchorjs-link,
60 | h3:hover .anchorjs-link,
61 | h4:hover .anchorjs-link {
62 | opacity: 1;
63 | }
64 |
65 | .fix-3 {
66 | width: 25%;
67 | max-width: 244px;
68 | }
69 |
70 | .fix-3 {
71 | width: 25%;
72 | max-width: 244px;
73 | }
74 |
75 | @media (min-width: 52em) {
76 | .fix-margin-3 {
77 | margin-left: 25%;
78 | }
79 | }
80 |
81 | .pre, pre, code, .code {
82 | font-family: Source Code Pro,Menlo,Consolas,Liberation Mono,monospace;
83 | font-size: 14px;
84 | }
85 |
86 | .fill-light {
87 | background: #F9F9F9;
88 | }
89 |
90 | .width2 {
91 | width: 1rem;
92 | }
93 |
94 | .input {
95 | font-family: inherit;
96 | display: block;
97 | width: 100%;
98 | height: 2rem;
99 | padding: .5rem;
100 | margin-bottom: 1rem;
101 | border: 1px solid #ccc;
102 | font-size: .875rem;
103 | border-radius: 3px;
104 | box-sizing: border-box;
105 | }
106 |
107 | table {
108 | border-collapse: collapse;
109 | }
110 |
111 | .prose table th,
112 | .prose table td {
113 | text-align: left;
114 | padding:8px;
115 | border:1px solid #ddd;
116 | }
117 |
118 | .prose table th:nth-child(1) { border-right: none; }
119 | .prose table th:nth-child(2) { border-left: none; }
120 |
121 | .prose table {
122 | border:1px solid #ddd;
123 | }
124 |
125 | .prose-big {
126 | font-size: 18px;
127 | line-height: 30px;
128 | }
129 |
130 | .quiet {
131 | opacity: 0.7;
132 | }
133 |
134 | .minishadow {
135 | box-shadow: 2px 2px 10px #f3f3f3;
136 | }
137 |
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-Bold-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-Bold-webfont.eot
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-Bold-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-Bold-webfont.woff
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-BoldItalic-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-BoldItalic-webfont.eot
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-BoldItalic-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-BoldItalic-webfont.woff
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-Italic-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-Italic-webfont.eot
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-Italic-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-Italic-webfont.woff
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-Light-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-Light-webfont.eot
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-Light-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-Light-webfont.woff
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-LightItalic-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-LightItalic-webfont.eot
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-LightItalic-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-LightItalic-webfont.woff
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-Regular-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-Regular-webfont.eot
--------------------------------------------------------------------------------
/docs/fonts/OpenSans-Regular-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/miketrebilcock/js-gpiozero/8d02c3b65604cdd34a0f5ce7c8f905647237dc21/docs/fonts/OpenSans-Regular-webfont.woff
--------------------------------------------------------------------------------
/docs/scripts/linenumber.js:
--------------------------------------------------------------------------------
1 | /*global document */
2 | (function() {
3 | var source = document.getElementsByClassName('prettyprint source linenums');
4 | var i = 0;
5 | var lineNumber = 0;
6 | var lineId;
7 | var lines;
8 | var totalLines;
9 | var anchorHash;
10 |
11 | if (source && source[0]) {
12 | anchorHash = document.location.hash.substring(1);
13 | lines = source[0].getElementsByTagName('li');
14 | totalLines = lines.length;
15 |
16 | for (; i < totalLines; i++) {
17 | lineNumber++;
18 | lineId = 'line' + lineNumber;
19 | lines[i].id = lineId;
20 | if (lineId === anchorHash) {
21 | lines[i].className += ' selected';
22 | }
23 | }
24 | }
25 | })();
26 |
--------------------------------------------------------------------------------
/docs/scripts/prettify/lang-css.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
3 |
--------------------------------------------------------------------------------
/docs/styles/jsdoc-default.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Open Sans';
3 | font-weight: normal;
4 | font-style: normal;
5 | src: url('../fonts/OpenSans-Regular-webfont.eot');
6 | src:
7 | local('Open Sans'),
8 | local('OpenSans'),
9 | url('../fonts/OpenSans-Regular-webfont.eot?#iefix') format('embedded-opentype'),
10 | url('../fonts/OpenSans-Regular-webfont.woff') format('woff'),
11 | url('../fonts/OpenSans-Regular-webfont.svg#open_sansregular') format('svg');
12 | }
13 |
14 | @font-face {
15 | font-family: 'Open Sans Light';
16 | font-weight: normal;
17 | font-style: normal;
18 | src: url('../fonts/OpenSans-Light-webfont.eot');
19 | src:
20 | local('Open Sans Light'),
21 | local('OpenSans Light'),
22 | url('../fonts/OpenSans-Light-webfont.eot?#iefix') format('embedded-opentype'),
23 | url('../fonts/OpenSans-Light-webfont.woff') format('woff'),
24 | url('../fonts/OpenSans-Light-webfont.svg#open_sanslight') format('svg');
25 | }
26 |
27 | html
28 | {
29 | overflow: auto;
30 | background-color: #fff;
31 | font-size: 14px;
32 | }
33 |
34 | body
35 | {
36 | font-family: 'Open Sans', sans-serif;
37 | line-height: 1.5;
38 | color: #4d4e53;
39 | background-color: white;
40 | }
41 |
42 | a, a:visited, a:active {
43 | color: #0095dd;
44 | text-decoration: none;
45 | }
46 |
47 | a:hover {
48 | text-decoration: underline;
49 | }
50 |
51 | header
52 | {
53 | display: block;
54 | padding: 0px 4px;
55 | }
56 |
57 | tt, code, kbd, samp {
58 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
59 | }
60 |
61 | .class-description {
62 | font-size: 130%;
63 | line-height: 140%;
64 | margin-bottom: 1em;
65 | margin-top: 1em;
66 | }
67 |
68 | .class-description:empty {
69 | margin: 0;
70 | }
71 |
72 | #main {
73 | float: left;
74 | width: 70%;
75 | }
76 |
77 | article dl {
78 | margin-bottom: 40px;
79 | }
80 |
81 | section
82 | {
83 | display: block;
84 | background-color: #fff;
85 | padding: 12px 24px;
86 | border-bottom: 1px solid #ccc;
87 | margin-right: 30px;
88 | }
89 |
90 | .variation {
91 | display: none;
92 | }
93 |
94 | .signature-attributes {
95 | font-size: 60%;
96 | color: #aaa;
97 | font-style: italic;
98 | font-weight: lighter;
99 | }
100 |
101 | nav
102 | {
103 | display: block;
104 | float: right;
105 | margin-top: 28px;
106 | width: 30%;
107 | box-sizing: border-box;
108 | border-left: 1px solid #ccc;
109 | padding-left: 16px;
110 | }
111 |
112 | nav ul {
113 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
114 | font-size: 100%;
115 | line-height: 17px;
116 | padding: 0;
117 | margin: 0;
118 | list-style-type: none;
119 | }
120 |
121 | nav ul a, nav ul a:visited, nav ul a:active {
122 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
123 | line-height: 18px;
124 | color: #4D4E53;
125 | }
126 |
127 | nav h3 {
128 | margin-top: 12px;
129 | }
130 |
131 | nav li {
132 | margin-top: 6px;
133 | }
134 |
135 | footer {
136 | display: block;
137 | padding: 6px;
138 | margin-top: 12px;
139 | font-style: italic;
140 | font-size: 90%;
141 | }
142 |
143 | h1, h2, h3, h4 {
144 | font-weight: 200;
145 | margin: 0;
146 | }
147 |
148 | h1
149 | {
150 | font-family: 'Open Sans Light', sans-serif;
151 | font-size: 48px;
152 | letter-spacing: -2px;
153 | margin: 12px 24px 20px;
154 | }
155 |
156 | h2, h3.subsection-title
157 | {
158 | font-size: 30px;
159 | font-weight: 700;
160 | letter-spacing: -1px;
161 | margin-bottom: 12px;
162 | }
163 |
164 | h3
165 | {
166 | font-size: 24px;
167 | letter-spacing: -0.5px;
168 | margin-bottom: 12px;
169 | }
170 |
171 | h4
172 | {
173 | font-size: 18px;
174 | letter-spacing: -0.33px;
175 | margin-bottom: 12px;
176 | color: #4d4e53;
177 | }
178 |
179 | h5, .container-overview .subsection-title
180 | {
181 | font-size: 120%;
182 | font-weight: bold;
183 | letter-spacing: -0.01em;
184 | margin: 8px 0 3px 0;
185 | }
186 |
187 | h6
188 | {
189 | font-size: 100%;
190 | letter-spacing: -0.01em;
191 | margin: 6px 0 3px 0;
192 | font-style: italic;
193 | }
194 |
195 | table
196 | {
197 | border-spacing: 0;
198 | border: 0;
199 | border-collapse: collapse;
200 | }
201 |
202 | td, th
203 | {
204 | border: 1px solid #ddd;
205 | margin: 0px;
206 | text-align: left;
207 | vertical-align: top;
208 | padding: 4px 6px;
209 | display: table-cell;
210 | }
211 |
212 | thead tr
213 | {
214 | background-color: #ddd;
215 | font-weight: bold;
216 | }
217 |
218 | th { border-right: 1px solid #aaa; }
219 | tr > th:last-child { border-right: 1px solid #ddd; }
220 |
221 | .ancestors { color: #999; }
222 | .ancestors a
223 | {
224 | color: #999 !important;
225 | text-decoration: none;
226 | }
227 |
228 | .clear
229 | {
230 | clear: both;
231 | }
232 |
233 | .important
234 | {
235 | font-weight: bold;
236 | color: #950B02;
237 | }
238 |
239 | .yes-def {
240 | text-indent: -1000px;
241 | }
242 |
243 | .type-signature {
244 | color: #aaa;
245 | }
246 |
247 | .name, .signature {
248 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
249 | }
250 |
251 | .details { margin-top: 14px; border-left: 2px solid #DDD; }
252 | .details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; }
253 | .details dd { margin-left: 70px; }
254 | .details ul { margin: 0; }
255 | .details ul { list-style-type: none; }
256 | .details li { margin-left: 30px; padding-top: 6px; }
257 | .details pre.prettyprint { margin: 0 }
258 | .details .object-value { padding-top: 0; }
259 |
260 | .description {
261 | margin-bottom: 1em;
262 | margin-top: 1em;
263 | }
264 |
265 | .code-caption
266 | {
267 | font-style: italic;
268 | font-size: 107%;
269 | margin: 0;
270 | }
271 |
272 | .prettyprint
273 | {
274 | border: 1px solid #ddd;
275 | width: 80%;
276 | overflow: auto;
277 | }
278 |
279 | .prettyprint.source {
280 | width: inherit;
281 | }
282 |
283 | .prettyprint code
284 | {
285 | font-size: 100%;
286 | line-height: 18px;
287 | display: block;
288 | padding: 4px 12px;
289 | margin: 0;
290 | background-color: #fff;
291 | color: #4D4E53;
292 | }
293 |
294 | .prettyprint code span.line
295 | {
296 | display: inline-block;
297 | }
298 |
299 | .prettyprint.linenums
300 | {
301 | padding-left: 70px;
302 | -webkit-user-select: none;
303 | -moz-user-select: none;
304 | -ms-user-select: none;
305 | user-select: none;
306 | }
307 |
308 | .prettyprint.linenums ol
309 | {
310 | padding-left: 0;
311 | }
312 |
313 | .prettyprint.linenums li
314 | {
315 | border-left: 3px #ddd solid;
316 | }
317 |
318 | .prettyprint.linenums li.selected,
319 | .prettyprint.linenums li.selected *
320 | {
321 | background-color: lightyellow;
322 | }
323 |
324 | .prettyprint.linenums li *
325 | {
326 | -webkit-user-select: text;
327 | -moz-user-select: text;
328 | -ms-user-select: text;
329 | user-select: text;
330 | }
331 |
332 | .params .name, .props .name, .name code {
333 | color: #4D4E53;
334 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
335 | font-size: 100%;
336 | }
337 |
338 | .params td.description > p:first-child,
339 | .props td.description > p:first-child
340 | {
341 | margin-top: 0;
342 | padding-top: 0;
343 | }
344 |
345 | .params td.description > p:last-child,
346 | .props td.description > p:last-child
347 | {
348 | margin-bottom: 0;
349 | padding-bottom: 0;
350 | }
351 |
352 | .disabled {
353 | color: #454545;
354 | }
355 |
--------------------------------------------------------------------------------
/docs/styles/prettify-jsdoc.css:
--------------------------------------------------------------------------------
1 | /* JSDoc prettify.js theme */
2 |
3 | /* plain text */
4 | .pln {
5 | color: #000000;
6 | font-weight: normal;
7 | font-style: normal;
8 | }
9 |
10 | /* string content */
11 | .str {
12 | color: #006400;
13 | font-weight: normal;
14 | font-style: normal;
15 | }
16 |
17 | /* a keyword */
18 | .kwd {
19 | color: #000000;
20 | font-weight: bold;
21 | font-style: normal;
22 | }
23 |
24 | /* a comment */
25 | .com {
26 | font-weight: normal;
27 | font-style: italic;
28 | }
29 |
30 | /* a type name */
31 | .typ {
32 | color: #000000;
33 | font-weight: normal;
34 | font-style: normal;
35 | }
36 |
37 | /* a literal value */
38 | .lit {
39 | color: #006400;
40 | font-weight: normal;
41 | font-style: normal;
42 | }
43 |
44 | /* punctuation */
45 | .pun {
46 | color: #000000;
47 | font-weight: bold;
48 | font-style: normal;
49 | }
50 |
51 | /* lisp open bracket */
52 | .opn {
53 | color: #000000;
54 | font-weight: bold;
55 | font-style: normal;
56 | }
57 |
58 | /* lisp close bracket */
59 | .clo {
60 | color: #000000;
61 | font-weight: bold;
62 | font-style: normal;
63 | }
64 |
65 | /* a markup tag name */
66 | .tag {
67 | color: #006400;
68 | font-weight: normal;
69 | font-style: normal;
70 | }
71 |
72 | /* a markup attribute name */
73 | .atn {
74 | color: #006400;
75 | font-weight: normal;
76 | font-style: normal;
77 | }
78 |
79 | /* a markup attribute value */
80 | .atv {
81 | color: #006400;
82 | font-weight: normal;
83 | font-style: normal;
84 | }
85 |
86 | /* a declaration */
87 | .dec {
88 | color: #000000;
89 | font-weight: bold;
90 | font-style: normal;
91 | }
92 |
93 | /* a variable name */
94 | .var {
95 | color: #000000;
96 | font-weight: normal;
97 | font-style: normal;
98 | }
99 |
100 | /* a function name */
101 | .fun {
102 | color: #000000;
103 | font-weight: bold;
104 | font-style: normal;
105 | }
106 |
107 | /* Specify class=linenums on a pre to get line numbering */
108 | ol.linenums {
109 | margin-top: 0;
110 | margin-bottom: 0;
111 | }
112 |
--------------------------------------------------------------------------------
/docs/styles/prettify-tomorrow.css:
--------------------------------------------------------------------------------
1 | /* Tomorrow Theme */
2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */
3 | /* Pretty printing styles. Used with prettify.js. */
4 | /* SPAN elements with the classes below are added by prettyprint. */
5 | /* plain text */
6 | .pln {
7 | color: #4d4d4c; }
8 |
9 | @media screen {
10 | /* string content */
11 | .str {
12 | color: #718c00; }
13 |
14 | /* a keyword */
15 | .kwd {
16 | color: #8959a8; }
17 |
18 | /* a comment */
19 | .com {
20 | color: #8e908c; }
21 |
22 | /* a type name */
23 | .typ {
24 | color: #4271ae; }
25 |
26 | /* a literal value */
27 | .lit {
28 | color: #f5871f; }
29 |
30 | /* punctuation */
31 | .pun {
32 | color: #4d4d4c; }
33 |
34 | /* lisp open bracket */
35 | .opn {
36 | color: #4d4d4c; }
37 |
38 | /* lisp close bracket */
39 | .clo {
40 | color: #4d4d4c; }
41 |
42 | /* a markup tag name */
43 | .tag {
44 | color: #c82829; }
45 |
46 | /* a markup attribute name */
47 | .atn {
48 | color: #f5871f; }
49 |
50 | /* a markup attribute value */
51 | .atv {
52 | color: #3e999f; }
53 |
54 | /* a declaration */
55 | .dec {
56 | color: #f5871f; }
57 |
58 | /* a variable name */
59 | .var {
60 | color: #c82829; }
61 |
62 | /* a function name */
63 | .fun {
64 | color: #4271ae; } }
65 | /* Use higher contrast and text-weight for printable form. */
66 | @media print, projection {
67 | .str {
68 | color: #060; }
69 |
70 | .kwd {
71 | color: #006;
72 | font-weight: bold; }
73 |
74 | .com {
75 | color: #600;
76 | font-style: italic; }
77 |
78 | .typ {
79 | color: #404;
80 | font-weight: bold; }
81 |
82 | .lit {
83 | color: #044; }
84 |
85 | .pun, .opn, .clo {
86 | color: #440; }
87 |
88 | .tag {
89 | color: #006;
90 | font-weight: bold; }
91 |
92 | .atn {
93 | color: #404; }
94 |
95 | .atv {
96 | color: #060; } }
97 | /* Style */
98 | /*
99 | pre.prettyprint {
100 | background: white;
101 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
102 | font-size: 12px;
103 | line-height: 1.5;
104 | border: 1px solid #ccc;
105 | padding: 10px; }
106 | */
107 |
108 | /* Specify class=linenums on a pre to get line numbering */
109 | ol.linenums {
110 | margin-top: 0;
111 | margin-bottom: 0; }
112 |
113 | /* IE indents via margin-left */
114 | li.L0,
115 | li.L1,
116 | li.L2,
117 | li.L3,
118 | li.L4,
119 | li.L5,
120 | li.L6,
121 | li.L7,
122 | li.L8,
123 | li.L9 {
124 | /* */ }
125 |
126 | /* Alternate shading for lines */
127 | li.L1,
128 | li.L3,
129 | li.L5,
130 | li.L7,
131 | li.L9 {
132 | /* */ }
133 |
--------------------------------------------------------------------------------
/docs/styles/prettify.css:
--------------------------------------------------------------------------------
1 | .pln {
2 | color: #ddd;
3 | }
4 |
5 | /* string content */
6 | .str {
7 | color: #61ce3c;
8 | }
9 |
10 | /* a keyword */
11 | .kwd {
12 | color: #fbde2d;
13 | }
14 |
15 | /* a comment */
16 | .com {
17 | color: #aeaeae;
18 | }
19 |
20 | /* a type name */
21 | .typ {
22 | color: #8da6ce;
23 | }
24 |
25 | /* a literal value */
26 | .lit {
27 | color: #fbde2d;
28 | }
29 |
30 | /* punctuation */
31 | .pun {
32 | color: #ddd;
33 | }
34 |
35 | /* lisp open bracket */
36 | .opn {
37 | color: #000000;
38 | }
39 |
40 | /* lisp close bracket */
41 | .clo {
42 | color: #000000;
43 | }
44 |
45 | /* a markup tag name */
46 | .tag {
47 | color: #8da6ce;
48 | }
49 |
50 | /* a markup attribute name */
51 | .atn {
52 | color: #fbde2d;
53 | }
54 |
55 | /* a markup attribute value */
56 | .atv {
57 | color: #ddd;
58 | }
59 |
60 | /* a declaration */
61 | .dec {
62 | color: #EF5050;
63 | }
64 |
65 | /* a variable name */
66 | .var {
67 | color: #c82829;
68 | }
69 |
70 | /* a function name */
71 | .fun {
72 | color: #4271ae;
73 | }
74 |
75 | /* Specify class=linenums on a pre to get line numbering */
76 | ol.linenums {
77 | margin-top: 0;
78 | margin-bottom: 0;
79 | }
80 |
--------------------------------------------------------------------------------
/gpiozero/Mixins/EventsMixin.js:
--------------------------------------------------------------------------------
1 |
2 | function EventsMixin () {
3 | this._active_event = false;
4 | this._inactive_event = false;
5 | this.when_activated = null;
6 | this.when_deactivated = null;
7 | this._last_state = null;
8 | this._last_changed = (new Date()).getTime();
9 | }
10 |
11 | exports.EventsMixin = EventsMixin;
12 |
13 | EventsMixin.prototype._fire_events = function() {
14 | const old_state = this._last_state;
15 | const new_state = this._last_state = this.is_active();
16 | if (old_state === null) {
17 | // Initial "indeterminate" state; set events but don't fire
18 | // callbacks as there's not necessarily an edge
19 | if (new_state !== false) {
20 | this._active_event = true;
21 | } else {
22 | this._inactive_event = true;
23 | }
24 | } else if (old_state !== new_state) {
25 | this._last_changed = (new Date()).getTime();
26 | if (new_state !== false) {
27 | this._inactive_event = false;
28 | this._active_event = true;
29 | this._fire_activated();
30 | } else {
31 | this._active_event = false;
32 | this._inactive_event = true;
33 | this._fire_deactivated();
34 | }
35 | }
36 | };
37 |
38 | /**
39 | * These methods are largely here to be overridden by descendents.
40 | *
41 | * @private
42 | */
43 | EventsMixin.prototype._fire_activated = function () {
44 | if (this.when_activated !== null) {
45 | this.when_activated();
46 | }
47 | };
48 |
49 | /**
50 | * These methods are largely here to be overridden by descendents.
51 | *
52 | * @private
53 | */
54 | EventsMixin.prototype._fire_deactivated = function () {
55 | if (this.when_deactivated !== null) {
56 | this.when_deactivated();
57 | }
58 | };
59 |
60 | /*
61 | def wait_for_active(self, timeout=None):
62 | """
63 | Pause the script until the device is activated, or the timeout is
64 | reached.
65 |
66 | :param float timeout:
67 | Number of seconds to wait before proceeding. If this is ``None``
68 | (the default), then wait indefinitely until the device is active.
69 | """
70 | return self._active_event.wait(timeout)
71 |
72 | def wait_for_inactive(self, timeout=None):
73 | """
74 | Pause the script until the device is deactivated, or the timeout is
75 | reached.
76 |
77 | :param float timeout:
78 | Number of seconds to wait before proceeding. If this is ``None``
79 | (the default), then wait indefinitely until the device is inactive.
80 | """
81 | return self._inactive_event.wait(timeout)
82 |
83 | @property
84 | def when_activated(self):
85 | """
86 | The function to run when the device changes state from inactive to
87 | active.
88 |
89 | This can be set to a function which accepts no (mandatory) parameters,
90 | or a Python function which accepts a single mandatory parameter (with
91 | as many optional parameters as you like). If the function accepts a
92 | single mandatory parameter, the device that activated will be passed
93 | as that parameter.
94 |
95 | Set this property to ``None`` (the default) to disable the event.
96 | """
97 | return self._when_activated
98 |
99 | @when_activated.setter
100 | def when_activated(self, value):
101 | self._when_activated = self._wrap_callback(value)
102 |
103 | @property
104 | def when_deactivated(self):
105 | """
106 | The function to run when the device changes state from active to
107 | inactive.
108 |
109 | This can be set to a function which accepts no (mandatory) parameters,
110 | or a Python function which accepts a single mandatory parameter (with
111 | as many optional parameters as you like). If the function accepts a
112 | single mandatory parameter, the device that deactivated will be
113 | passed as that parameter.
114 |
115 | Set this property to ``None`` (the default) to disable the event.
116 | """
117 | return self._when_deactivated
118 |
119 | @when_deactivated.setter
120 | def when_deactivated(self, value):
121 | self._when_deactivated = self._wrap_callback(value)
122 |
123 | @property
124 | def active_time(self):
125 | """
126 | The length of time (in seconds) that the device has been active for.
127 | When the device is inactive, this is ``None``.
128 | """
129 | if self._active_event.is_set():
130 | return time() - self._last_changed
131 | else:
132 | return None
133 |
134 | @property
135 | def inactive_time(self):
136 | """
137 | The length of time (in seconds) that the device has been inactive for.
138 | When the device is active, this is ``None``.
139 | """
140 | if self._inactive_event.is_set():
141 | return time() - self._last_changed
142 | else:
143 | return None
144 |
145 | def _wrap_callback(self, fn):
146 | if fn is None:
147 | return None
148 | elif not callable(fn):
149 | raise BadEventHandler('value must be None or a callable')
150 | # If fn is wrapped with partial (i.e. partial, partialmethod, or wraps
151 | # has been used to produce it) we need to dig out the "real" function
152 | # that's been wrapped along with all the mandatory positional args
153 | # used in the wrapper so we can test the binding
154 | args = ()
155 | wrapped_fn = fn
156 | while isinstance(wrapped_fn, partial):
157 | args = wrapped_fn.args + args
158 | wrapped_fn = wrapped_fn.func
159 | if inspect.isbuiltin(wrapped_fn):
160 | # We can't introspect the prototype of builtins. In this case we
161 | # assume that the builtin has no (mandatory) parameters; this is
162 | # the most reasonable assumption on the basis that pre-existing
163 | # builtins have no knowledge of gpiozero, and the sole parameter
164 | # we would pass is a gpiozero object
165 | return fn
166 | else:
167 | # Try binding ourselves to the argspec of the provided callable.
168 | # If this works, assume the function is capable of accepting no
169 | # parameters
170 | try:
171 | inspect.getcallargs(wrapped_fn, *args)
172 | return fn
173 | except TypeError:
174 | try:
175 | # If the above fails, try binding with a single parameter
176 | # (ourselves). If this works, wrap the specified callback
177 | inspect.getcallargs(wrapped_fn, *(args + (self,)))
178 | @wraps(fn)
179 | def wrapper():
180 | return fn(self)
181 | return wrapper
182 | except TypeError:
183 | raise BadEventHandler(
184 | 'value must be a callable which accepts up to one '
185 | 'mandatory parameter')
186 | */
187 |
--------------------------------------------------------------------------------
/gpiozero/boards/LEDBoard.js:
--------------------------------------------------------------------------------
1 | const LEDCollection = require ('./LEDCollection.js').LEDCollection;
2 | const inherit = require ('../tools.js').inherit;
3 | const extend = require ('../tools.js').extend;
4 | const ReadWriteLock = require('rwlock');
5 |
6 | exports.LEDBoard = LEDBoard;
7 |
8 | /**
9 | * Represents a generic LED board or collection of LEDs.
10 | * The following example turns on all the LEDs on a board containing 5 LEDs attached to GPIO pins 2 through 6.
11 | *
12 | * @example
13 | * const LEDBoard = require('gpiozero').LEDBoard;
14 | * var leds = new LEDBoard([2, 3, 4, 5, 6]);
15 | * leds.on();
16 | *
17 | * @param {Array} pins - Specify the GPIO pins that the LEDs of the board are attached to. You can designate as many pins as necessary.
18 | * @param {Array} kwpins - Specify an array of arrays that has the Name of the device and the GPIO pins that the LEDs of the board are attached to.
19 | * You can designate as many pins as necessary.
20 | * @param {Object} _options - Set options for the Collection:
21 | * * pwm: Default: false, If true, creates PWMLED instances for each pin, else LED.
22 | * * active_high: Default: true, If true, the on method will set all the associated pins to HIGH.
23 | * If false, the on method will set all pins to LOW (the `off` method always does the opposite).
24 | * * initial_value: If false, all LEDs will be off initially, if true the device will be Switched on initialled.
25 | * @augments LEDCollection
26 | * @class
27 | */
28 | function LEDBoard(pins, kwpins, _options) {
29 | "use strict";
30 | const defaults = {
31 | pwm: false,
32 | active_high: true,
33 | initial_value: false,
34 | };
35 | this.options = extend(defaults, _options);
36 | this._blink_leds = [];
37 | this._blink_lock = new ReadWriteLock();
38 | LEDCollection.call(this, pins, kwpins, this.options);
39 | }
40 | LEDBoard.prototype = inherit(LEDCollection.prototype);
41 | LEDBoard.prototype.constructor = LEDBoard;
42 |
43 | LEDBoard.prototype.close = function () {
44 | LEDCollection.prototype.close.call(this);
45 | }
46 |
47 | /*
48 | class LEDBoard(LEDCollection):
49 |
50 | def close(self):
51 | self._stop_blink()
52 | super(LEDBoard, self).close()
53 |
54 | def on(self, *args):
55 | self._stop_blink()
56 | if args:
57 | for index in args:
58 | self[index].on()
59 | else:
60 | super(LEDBoard, self).on()
61 |
62 | def off(self, *args):
63 | self._stop_blink()
64 | if args:
65 | for index in args:
66 | self[index].off()
67 | else:
68 | super(LEDBoard, self).off()
69 |
70 | def toggle(self, *args):
71 | self._stop_blink()
72 | if args:
73 | for index in args:
74 | self[index].toggle()
75 | else:
76 | super(LEDBoard, self).toggle()
77 |
78 | def blink(
79 | self, on_time=1, off_time=1, fade_in_time=0, fade_out_time=0,
80 | n=None, background=True):
81 | """
82 | Make all the LEDs turn on and off repeatedly.
83 |
84 | :param float on_time:
85 | Number of seconds on. Defaults to 1 second.
86 |
87 | :param float off_time:
88 | Number of seconds off. Defaults to 1 second.
89 |
90 | :param float fade_in_time:
91 | Number of seconds to spend fading in. Defaults to 0. Must be 0 if
92 | ``pwm`` was ``False`` when the class was constructed
93 | (:exc:`ValueError` will be raised if not).
94 |
95 | :param float fade_out_time:
96 | Number of seconds to spend fading out. Defaults to 0. Must be 0 if
97 | ``pwm`` was ``False`` when the class was constructed
98 | (:exc:`ValueError` will be raised if not).
99 |
100 | :param int n:
101 | Number of times to blink; ``None`` (the default) means forever.
102 |
103 | :param bool background:
104 | If ``True``, start a background thread to continue blinking and
105 | return immediately. If ``False``, only return when the blink is
106 | finished (warning: the default value of *n* will result in this
107 | method never returning).
108 | """
109 | for led in self.leds:
110 | if isinstance(led, LED):
111 | if fade_in_time:
112 | raise ValueError('fade_in_time must be 0 with non-PWM LEDs')
113 | if fade_out_time:
114 | raise ValueError('fade_out_time must be 0 with non-PWM LEDs')
115 | self._stop_blink()
116 | self._blink_thread = GPIOThread(
117 | target=self._blink_device,
118 | args=(on_time, off_time, fade_in_time, fade_out_time, n)
119 | )
120 | self._blink_thread.start()
121 | if not background:
122 | self._blink_thread.join()
123 | self._blink_thread = None
124 |
125 | def _stop_blink(self, led=None):
126 | if led is None:
127 | if self._blink_thread:
128 | self._blink_thread.stop()
129 | self._blink_thread = None
130 | else:
131 | with self._blink_lock:
132 | self._blink_leds.remove(led)
133 |
134 | def pulse(self, fade_in_time=1, fade_out_time=1, n=None, background=True):
135 | """
136 | Make the device fade in and out repeatedly.
137 |
138 | :param float fade_in_time:
139 | Number of seconds to spend fading in. Defaults to 1.
140 |
141 | :param float fade_out_time:
142 | Number of seconds to spend fading out. Defaults to 1.
143 |
144 | :param int n:
145 | Number of times to blink; ``None`` (the default) means forever.
146 |
147 | :param bool background:
148 | If ``True`` (the default), start a background thread to continue
149 | blinking and return immediately. If ``False``, only return when the
150 | blink is finished (warning: the default value of *n* will result in
151 | this method never returning).
152 | """
153 | on_time = off_time = 0
154 | self.blink(
155 | on_time, off_time, fade_in_time, fade_out_time, n, background
156 | )
157 |
158 | def _blink_device(self, on_time, off_time, fade_in_time, fade_out_time, n, fps=25):
159 | sequence = []
160 | if fade_in_time > 0:
161 | sequence += [
162 | (i * (1 / fps) / fade_in_time, 1 / fps)
163 | for i in range(int(fps * fade_in_time))
164 | ]
165 | sequence.append((1, on_time))
166 | if fade_out_time > 0:
167 | sequence += [
168 | (1 - (i * (1 / fps) / fade_out_time), 1 / fps)
169 | for i in range(int(fps * fade_out_time))
170 | ]
171 | sequence.append((0, off_time))
172 | sequence = (
173 | cycle(sequence) if n is None else
174 | chain.from_iterable(repeat(sequence, n))
175 | )
176 | with self._blink_lock:
177 | self._blink_leds = list(self.leds)
178 | for led in self._blink_leds:
179 | if led._controller not in (None, self):
180 | led._controller._stop_blink(led)
181 | led._controller = self
182 | for value, delay in sequence:
183 | with self._blink_lock:
184 | if not self._blink_leds:
185 | break
186 | for led in self._blink_leds:
187 | led._write(value)
188 | if self._blink_thread.stopping.wait(delay):
189 | break
190 | */
191 |
--------------------------------------------------------------------------------
/gpiozero/boards/LEDCollection.js:
--------------------------------------------------------------------------------
1 | const inherit = require ('../tools.js').inherit;
2 | const extend = require ('../tools.js').extend;
3 | const CompositeOutputDevice = require ('../output_devices/CompositeOutputDevice.js').CompositeOutputDevice;
4 | const PWMLED = require('../output_devices/PWMLED.js').PWMLED;
5 | const LED = require('../output_devices/LED.js').LED;
6 |
7 | exports.LEDCollection = LEDCollection;
8 |
9 | /**
10 | * Abstract base class for @link{LEDBoard} and @link{LEDBarGraph}.
11 | *
12 | * @param {Array} [_pins] - Array of pins that LEDs are connect to.
13 | * @param {Array} [_kwpins] - Array of tuples listing names for each pin eg [['red',17], ['amber',22]].
14 | * @param {Object} [_options] - Set options for the Collection:
15 | * * pwm: Default: false, If true, creates PWMLED instances for each pin, else LED.
16 | * * active_high: Default: true, If true, the on method will set all the associated pins to HIGH.
17 | * If false, the on method will set all pins to LOW
18 | * (the `off` method always does the opposite).
19 | * * initial_value: If false, all LEDs will be off initially, if true the device will be Switched on initialled.
20 | * @augments CompositeOutputDevice
21 | * @class
22 | */
23 | function LEDCollection(_pins, _kwpins, _options) {
24 | "use strict";
25 | const defaults = {
26 | pwm: false,
27 | active_high: true,
28 | initial_value: false,
29 | };
30 | this.options = extend(defaults, _options);
31 | this._leds = [];
32 | this._kwleds = [];
33 | let i;
34 | if (_pins !== undefined) {
35 | for (i = 0; i < _pins.length; i++) {
36 | this._leds.push(this.options.pwm ? new PWMLED(_pins[i]) : new LED(_pins[i]));
37 | }
38 | }
39 |
40 | if (_kwpins !== undefined) {
41 | for (i = 0; i < _kwpins.length; i++) {
42 | this._kwleds.push([
43 | _kwpins[i][0],
44 | this.options.pwm ? new PWMLED(_kwpins[i][1]) : new LED(_kwpins[i][1])
45 | ]);
46 | }
47 | }
48 | CompositeOutputDevice.call(this, this._leds, this._kwleds);
49 | }
50 |
51 | LEDCollection.prototype = inherit(CompositeOutputDevice.prototype);
52 | LEDCollection.prototype.constructor = LEDCollection;
53 |
54 | /**
55 | * @returns {Array} - A flat array of tuples of all LEDs contained in this collection (and all sub-collections).
56 | */
57 | LEDCollection.prototype.leds = function (){
58 | return this._leds;
59 | };
60 |
61 | /**
62 | *
63 | * @returns {boolean} Indicates whether the device is active high (true) or low (false).
64 | */
65 | LEDCollection.prototype.active_high = function (){
66 | return this[0].active_high;
67 | };
--------------------------------------------------------------------------------
/gpiozero/boards/PiTraffic.js:
--------------------------------------------------------------------------------
1 | const TrafficLights = require ('./TrafficLights.js').TrafficLights;
2 | const inherit = require ('../tools.js').inherit;
3 | const extend = require ('../tools.js').extend;
4 |
5 | /**
6 | * Represents the {@link http://lowvoltagelabs.com/products/pi-traffic/|Low Voltage Labs PI-TRAFFIC} vertical traffic lights board when attached to GPIO pins 9, 10, and 11.
7 | * There's no need to specify the pins if the PI-TRAFFIC is connected to the default pins (9, 10, 11).
8 | *
9 | * @param {Object} [_options] - Device Options:
10 | * * pwm: default: false. If true, creates PWMLED instances, else LED.
11 | * * initial_value: default: false. If false, all LEDs will be off initially, if true the device will be switched on initialled.
12 | * @class
13 | * @augments TrafficLights
14 | */
15 | function PiTraffic(_options){
16 | "use strict";
17 | const defaults = {
18 | pwm: false,
19 | initial_value: false
20 | };
21 | this.options = extend(defaults, _options);
22 | TrafficLights.call(this, 9,10,11, this.options);
23 | }
24 |
25 | exports.PiTraffic = PiTraffic;
26 | PiTraffic.prototype = inherit(TrafficLights.prototype);
27 | PiTraffic.prototype.constructor = PiTraffic;
--------------------------------------------------------------------------------
/gpiozero/boards/TrafficLights.js:
--------------------------------------------------------------------------------
1 | const LEDBoard = require ('./LEDBoard.js').LEDBoard;
2 | const inherit = require ('../tools.js').inherit;
3 | const extend = require ('../tools.js').extend;
4 | const exc = require('../exc.js');
5 |
6 | exports.TrafficLights = TrafficLights;
7 |
8 | /**
9 | * Represents a traffic light device containing red, amber, and green LEDs.
10 | *
11 | * @param {number} red - The GPIO pin that the red LED is attached to.
12 | * @param {number} amber - The GPIO pin that the amber LED is attached to.
13 | * @param {number} green - The GPIO pin that the green LED is attached to.
14 | * @param {Object} [_options] - Options for device:
15 | * * pwm: default: false. If true, creates PWMLED instances, else LED.
16 | * * initial_value: default: false. If false, all LEDs will be off initially, if true the device will be switched on initialled.
17 | * @augments LEDBoards
18 | * @class
19 | */
20 | function TrafficLights(red, amber, green, _options) {
21 | "use strict";
22 | const defaults = {
23 | pwm: false,
24 | initial_value: false
25 | };
26 | this.options = extend(defaults, _options);
27 |
28 | if (red === undefined ||
29 | amber === undefined ||
30 | green === undefined) {
31 | throw new exc.GPIOPinMissing('Pins must be provided for all LEDs');
32 | }
33 | this.devices = [['red', red],['amber',amber],['green',green]];
34 | LEDBoard.call(this,undefined, this.devices, this.options);
35 | }
36 |
37 | TrafficLights.prototype = inherit(LEDBoard.prototype);
38 | TrafficLights.prototype.constructor = TrafficLights;
--------------------------------------------------------------------------------
/gpiozero/compat.js:
--------------------------------------------------------------------------------
1 | var exc = require('./exc.js');
2 |
3 |
4 | // ported from python 3.5; see
5 | // github.com/PythonCHB/close_pep/blob/master/is_close.py for original
6 | // implementation
7 | function isclose(a, b, rel_tol, abs_tol) {
8 | abs_tol = (abs_tol === undefined? 0.0 : abs_tol);
9 | rel_tol = (rel_tol === undefined? 1e-9 : rel_tol);
10 |
11 | if (rel_tol < 0.0 || abs_tol < 0.0) {
12 | throw exc.ValueError('error tolerances must be non-negative');
13 | }
14 |
15 | if (a === b) { // fast-path for exact equality
16 | return true;
17 | }
18 | if (!isFinite(a) || !isFinite(b)){
19 | return false;
20 | }
21 | var diff = Math.abs(b - a);
22 | return (
23 | (diff <= Math.abs(rel_tol * b)) ||
24 | (diff <= Math.abs(rel_tol * a)) ||
25 | (diff <= abs_tol)
26 | );
27 | }
28 |
29 | exports.isclose = isclose;
--------------------------------------------------------------------------------
/gpiozero/devices/CompositeDevice.js:
--------------------------------------------------------------------------------
1 | const Device = require ('./Device.js').Device;
2 | const inherit = require('../tools.js').inherit;
3 |
4 | /**
5 | * Represents a device composed of multiple devices like simple HATs, H-bridge motor controllers, robots composed of multiple motors, etc.
6 | * The constructor accepts subordinate devices as positional or keyword arguments.
7 | * Positional arguments form unnamed devices accessed via the (@link CompositeDevice#all|all) attribute,
8 | * while keyword arguments are added to the device as named attributes.
9 | *
10 | * @param {Array} devices - An Array of positional devices.
11 | * @param {Array} kwdevices - An Array of tuples containing device name and device.
12 | * @class
13 | * @augments Device
14 | */
15 | function CompositeDevice(devices, kwdevices) {
16 | this._all = [];
17 | this._namedtuple = [];
18 | let i;
19 | if(devices !== undefined) {
20 | for (i = 0; i < devices.length; i++) {
21 | this[i] = devices[i];
22 | this._namedtuple.push('_' + i);
23 | this._all.push(devices[i]);
24 | }
25 | }
26 |
27 | if(kwdevices !== undefined) {
28 | for (i = 0; i < kwdevices.length; i++) {
29 | const device_name = kwdevices[i][0];
30 | this[device_name] = kwdevices[i][1];
31 | this._namedtuple.push(kwdevices[i][0]);
32 | this._all.push(kwdevices[i][1]);
33 | }
34 | }
35 | Device.call(this);
36 | }
37 |
38 | CompositeDevice.prototype = inherit(Device.prototype);
39 | CompositeDevice.prototype.constructor = CompositeDevice;
40 |
41 | /**
42 | *
43 | * @returns {number} - The number of subordinate devices.
44 | */
45 | CompositeDevice.prototype.length = function() {
46 | return this._all.length;
47 | };
48 |
49 | /**
50 | *
51 | * @returns {Array} - An array of subordinate device names.
52 | */
53 | CompositeDevice.prototype.namedtuple = function() {
54 | return this._namedtuple;
55 | };
56 |
57 | /**
58 | *
59 | * @returns {Array} - An array of all subordinate device values.
60 | */
61 | CompositeDevice.prototype.value = function () {
62 | let i;
63 | const result = [];
64 | for (i = 0; i < this._all.length; i++) {
65 | result[i] = this._all[i].value();
66 | }
67 | return result;
68 | };
69 |
70 | /**
71 | *
72 | * @returns {boolean} - An array of each subordinate devices active state.
73 | */
74 | CompositeDevice.prototype.is_active = function () {
75 | let i;
76 | for (i = 0; i < this._all.length; i++) {
77 | if (this._all[i].value()) {
78 | return true;
79 | }
80 | }
81 | return false;
82 | };
83 |
84 | /**
85 | * Close all subordinate devices.
86 | */
87 | CompositeDevice.prototype.close = function () {
88 | this._all.forEach((device) => {
89 | device.close();
90 | });
91 | };
92 |
93 | exports.CompositeDevice = CompositeDevice;
94 | /*
95 | class CompositeDevice(Device):
96 |
97 | :param list _order:
98 | If specified, this is the order of named items specified by keyword
99 | arguments (to ensure that the :attr:`value` tuple is constructed with a
100 | specific order). All keyword arguments *must* be included in the
101 | collection. If omitted, an alphabetically sorted order will be selected
102 | for keyword arguments.
103 | """
104 | def __init__(self, *args, **kwargs):
105 | self._all = ()
106 | self._named = frozendict({})
107 | self._namedtuple = None
108 | self._order = kwargs.pop('_order', None)
109 | if self._order is None:
110 | self._order = sorted(kwargs.keys())
111 | else:
112 | for missing_name in set(kwargs.keys()) - set(self._order):
113 | raise CompositeDeviceBadOrder('%s missing from _order' % missing_name)
114 | self._order = tuple(self._order)
115 | super(CompositeDevice, self).__init__()
116 | for name in set(self._order) & set(dir(self)):
117 | raise CompositeDeviceBadName('%s is a reserved name' % name)
118 | self._all = args + tuple(kwargs[v] for v in self._order)
119 | for dev in self._all:
120 | if not isinstance(dev, Device):
121 | raise CompositeDeviceBadDevice("%s doesn't inherit from Device" % dev)
122 | self._named = frozendict(kwargs)
123 | self._namedtuple = namedtuple('%sValue' % self.__class__.__name__, chain(
124 | (str(i) for i in range(len(args))), self._order),
125 | rename=True)
126 |
127 | def __getattr__(self, name):
128 | # if _named doesn't exist yet, pretend it's an empty dict
129 | if name == '_named':
130 | return frozendict({})
131 | try:
132 | return self._named[name]
133 | except KeyError:
134 | raise AttributeError("no such attribute %s" % name)
135 |
136 | def __setattr__(self, name, value):
137 | # make named components read-only properties
138 | if name in self._named:
139 | raise AttributeError("can't set attribute %s" % name)
140 | return super(CompositeDevice, self).__setattr__(name, value)
141 |
142 | def __repr__(self):
143 | try:
144 | self._check_open()
145 | return "" % (
146 | self.__class__.__name__,
147 | len(self), ','.join(self._order),
148 | len(self) - len(self._named)
149 | )
150 | except DeviceClosed:
151 | return "" % (self.__class__.__name__)
152 |
153 | def __getitem__(self, index):
154 | return self._all[index]
155 |
156 | def __iter__(self):
157 | return iter(self._all)
158 |
159 | @property
160 | def all(self):
161 | # XXX Deprecate this in favour of using the instance as a container
162 | return self._all
163 |
164 | def close(self):
165 | if self._all:
166 | for device in self._all:
167 | device.close()
168 |
169 | @property
170 | def closed(self):
171 | return all(device.closed for device in self)
172 |
173 | @property
174 | def namedtuple(self):
175 | return self._namedtuple
176 |
177 | @property
178 | def value(self):
179 | return self.namedtuple(*(device.value for device in self))
180 |
181 | @property
182 | def is_active(self):
183 | return any(self.value)
184 |
185 | */
--------------------------------------------------------------------------------
/gpiozero/devices/Device.js:
--------------------------------------------------------------------------------
1 | const exc = require('../exc.js');
2 |
3 | /**
4 | * Represents a single device of any type; GPIO-based, SPI-based, I2C-based,
5 | * etc. This is the base class of the device hierarchy. It defines the
6 | * basic services applicable to all devices (specifically the {@link Device#is_active|is_active}
7 | * property, the {@link Device#value|value} property, and the {@link Device#close|close} method).
8 | *
9 | * @class
10 | */
11 | function Device() {
12 | // eslint-disable-next-line no-empty-function
13 | }
14 | /**
15 | * Returns a value representing the device's state. Frequently, this is a
16 | * boolean value, or a number between 0 and 1 but some devices use larger
17 | * ranges (e.g. -1 to +1) and composite devices usually use tuples to
18 | * return the states of all their subordinate components.
19 | */
20 | Device.prototype.value = function() {
21 |
22 | throw new exc.NotImplementedError();
23 | };
24 |
25 | /**
26 | * Returns `true` if the device is currently active and `false`
27 | * otherwise. This property is usually derived from `value` attribute. Unlike
28 | * `value` attribute, this is *always* a boolean.
29 | */
30 | Device.prototype.is_active = function() {
31 |
32 | return (this.value !== undefined);
33 | };
34 | /**
35 | * Internal method to check if device is available.
36 | *
37 | * @private
38 | */
39 | Device.prototype._check_open = function() {
40 | if (this.closed()) {
41 | throw new exc.DeviceClosed('is closed or uninitialized');
42 | }
43 | };
44 | /**
45 | * @abstract
46 | */
47 | Device.prototype.close = function() {
48 | return;
49 | };
50 |
51 | exports.Device = Device;
--------------------------------------------------------------------------------
/gpiozero/devices/GPIODevice.js:
--------------------------------------------------------------------------------
1 | const Device = require ('./Device.js').Device;
2 | const inherit = require('../tools.js').inherit;
3 | const wiringpi = require('../pins/wiringpi.js').WiringPiPin;
4 | const ReadWriteLock = require('rwlock');
5 | const exc = require('../exc.js');
6 |
7 | const _PINS = new Set();
8 | const _PINS_LOCK = new ReadWriteLock(); //Yes, this needs to be re-entrant
9 |
10 | /* /*if(name == undefined) {
11 | name=process.env.GPIOZERO_PIN_FACTORY;
12 | }
13 | var group = 'gpiozero_pin_factories'
14 | if (name == undefined) {
15 | /*# If no factory is explicitly specified, try various names in
16 | # "preferred" order. Note that in this case we only select from
17 | # gpiozero distribution so without explicitly specifying a name (via
18 | # the environment) it's impossible to auto-select a factory from
19 | # outside the base distribution
20 | #
21 | # We prefer RPi.GPIO here as it supports PWM, and all Pi revisions. If
22 | # no third-party libraries are available, however, we fall back to a
23 | # pure Python implementation which supports platforms like PyPy
24 | dist = pkg_resources.get_distribution('gpiozero')
25 | for name in ('RPiGPIOPin', 'RPIOPin', 'PiGPIOPin', 'NativePin'):
26 | try:
27 | return pkg_resources.load_entry_point(dist, group, name)
28 | except ImportError:
29 | pass
30 | raise BadPinFactory('Unable to locate any default pin factory!')
31 | } else {
32 | for factory in pkg_resources.iter_entry_points(group, name):
33 | return factory.load()
34 | raise BadPinFactory('Unable to locate pin factory "%s"' % name)
35 | }*/
36 |
37 | //}
38 |
39 |
40 | //var pin_factory = _default_pin_factory();
41 |
42 | /**
43 | * Represents a generic GPIO device and provides the services common to all single-pin GPIO devices
44 | * (like ensuring two GPIO devices do no share a {@link Pin}).
45 | *
46 | * @param {(int | Pin)} pin - The GPIO pin (in BCM numbering) or a instance of {@link Pin} that the device is connected to.
47 | *
48 | * @throws {GPIOPinMissing} - If pin is 'undefined'
49 | * @throws {GPIOPinInUse} - If the pin is already in use by another device
50 | * @class
51 | * @augments Device
52 | */
53 | function GPIODevice(pin) {
54 | Device.call(this);
55 | this._pin = undefined;
56 | if (pin === undefined) {
57 | throw new exc.GPIOPinMissing('No pin given');
58 | }
59 | if (Number.isInteger(pin)) {
60 | pin = new wiringpi(pin);
61 | }
62 |
63 | _PINS_LOCK.readLock((release) => {
64 | if (_PINS.has(pin)) {
65 | throw new exc.GPIOPinInUse('pin ' + pin.toString() + ' is already in use by another gpiozero object');
66 | }
67 | _PINS.add(pin);
68 | release();
69 | });
70 |
71 | this._pin = pin;
72 | this._active_state = true;
73 | this._inactive_state = false;
74 | }
75 |
76 | GPIODevice.prototype = inherit(Device.prototype);
77 | GPIODevice.prototype.constructor = GPIODevice;
78 |
79 | /**
80 | * Close the device and remove the pin allocation allowing it to be reused.
81 | */
82 | GPIODevice.prototype.close = function() {
83 | const that = this;
84 | _PINS_LOCK.readLock((release) => {
85 | const pin = that._pin;
86 | if (_PINS.has(pin)) {
87 | _PINS.delete(pin);
88 | that._pin.close();
89 | }
90 | that._pin = undefined;
91 | release();
92 | });
93 | };
94 |
95 | /**
96 | *
97 | * @returns {boolean} - Is ``true`` is no pin is allocated.
98 | */
99 | GPIODevice.prototype.closed = function() {
100 | return (this._pin === undefined);
101 | };
102 |
103 | /**
104 | *
105 | * @returns {undefined|*|int|Pin} - The {@link Pin} that the device is connected to. This will be ``undefined``
106 | * if the device has been closed (see the :meth:`close` method). When dealing with GPIO pins, query ``pin.number``
107 | * to discover the GPIO pin (in BCM numbering) that the device is connected to.
108 | */
109 | GPIODevice.prototype.pin = function() {
110 | return this._pin;
111 | };
112 |
113 | /**
114 | * @returns {int|Boolean} - Current value of the pin.
115 | */
116 | GPIODevice.prototype.value = function() {
117 | return this._read();
118 | };
119 |
120 | /**
121 | * Internal method to read the pin value.
122 | *
123 | * @private
124 | */
125 | GPIODevice.prototype._read = function() {
126 | this._check_open();
127 | return this._state_to_value(this.pin().state());
128 | };
129 |
130 | /**
131 | * Internal method to apply active state high and convert the actual value to a logical value.
132 | *
133 | * @param {boolean|float} state - The value to be converted.
134 | * @returns {boolean} - The logical value of the pin.
135 | * @private
136 | */
137 | GPIODevice.prototype._state_to_value = function(state) {
138 | return Boolean(state === this._active_state);
139 | };
140 | /**
141 | *
142 | * @returns {boolean} - Is true is the device value is currently set.
143 | */
144 | GPIODevice.prototype.is_active = function() {
145 | return Boolean(this.value());
146 | };
147 |
148 | /**
149 | *
150 | * @returns {string} - Description of the device.
151 | */
152 | GPIODevice.prototype.toString = function() {
153 | return "";
154 | };
155 |
156 | exports.GPIODevice = GPIODevice;
--------------------------------------------------------------------------------
/gpiozero/exc.js:
--------------------------------------------------------------------------------
1 | var inherit = require ('./tools.js').inherit;
2 |
3 | function NotImplementedError (message) {
4 | message = message !== undefined?message:"The method is not yet implemented";
5 | Error.call(this, message);
6 | }
7 |
8 | NotImplementedError.prototype = inherit(Error.prototype);
9 | NotImplementedError.prototype.constructor = NotImplementedError;
10 |
11 | exports.NotImplementedError = NotImplementedError;
12 |
13 | function GPIOZeroError (message) {
14 | message = message !== undefined?message:"Base class for all exceptions in GPIO Zero";
15 | Error.call(this, message);
16 | }
17 |
18 | GPIOZeroError.prototype = inherit(Error.prototype);
19 | GPIOZeroError.prototype.constructor = GPIOZeroError;
20 |
21 | /*var NotImplementedError = GPIOZeroError.extend({
22 | init : function (message){
23 | this._super(message!=undefined?message:"Function not Implemented");
24 | }
25 | });*/
26 |
27 | function GPIODeviceError (message) {
28 | GPIOZeroError.call(this, message !== undefined ? message:"Base class for errors specific to the GPIODevice hierarchy");
29 | }
30 | GPIODeviceError.prototype = inherit(GPIOZeroError.prototype);
31 | GPIODeviceError.prototype.constructor = GPIODeviceError;
32 |
33 | function DeviceClosed (message) {
34 | GPIOZeroError.call(this, message !== undefined ? message:"Base class for errors specific to the GPIODevice hierarchy");
35 | }
36 | DeviceClosed.prototype = inherit(GPIOZeroError.prototype);
37 | DeviceClosed.prototype.constructor = DeviceClosed;
38 | exports.DeviceClosed = DeviceClosed;
39 |
40 | function GPIOPinMissing (message) {
41 | GPIODeviceError.call(this, message !== undefined ? message:"Error raised when a pin number is not specified");
42 | }
43 | GPIOPinMissing.prototype = inherit(GPIODeviceError.prototype);
44 | GPIOPinMissing.prototype.constructor = GPIOPinMissing;
45 | exports.GPIOPinMissing = GPIOPinMissing;
46 |
47 |
48 | function GPIOPinInUse (message) {
49 | GPIODeviceError.call(this, message !== undefined?message:"Error raised when attempting to use a pin already in use by another device");
50 | }
51 | GPIOPinInUse.prototype = inherit(GPIODeviceError.prototype);
52 | GPIOPinInUse.prototype.constructor = GPIOPinInUse;
53 | exports.GPIOPinInUse = GPIOPinInUse;
54 |
55 | function PinError(message) {
56 | GPIOZeroError.call(this, message !== undefined?message:"Base class for errors related to pin implementations");
57 | }
58 | PinError.prototype = inherit(GPIOZeroError.prototype);
59 | PinError.prototype.constructor = PinError;
60 |
61 | function PinInvalidFunction (message) {
62 | PinError.call(this, message);
63 | }
64 | PinInvalidFunction.prototype = inherit(PinError.prototype);
65 | PinInvalidFunction.prototype.constructor = PinInvalidFunction;
66 |
67 | function PinSetInput (message) {
68 | PinError.call(this, message);
69 | }
70 | PinSetInput.prototype = inherit(PinError.prototype);
71 | PinSetInput.prototype.constructor = PinSetInput;
72 | exports.PinSetInput = PinSetInput;
73 |
74 | function OutputDeviceError (message) {
75 | GPIOZeroError.call(this, message !== undefined?message:"Base class for errors specific to the GPIODevice hierarchy");
76 | }
77 | OutputDeviceError.prototype = inherit(GPIOZeroError.prototype);
78 | OutputDeviceError.prototype.constructor = OutputDeviceError;
79 |
80 | function OutputDeviceBadValue(message){
81 | OutputDeviceError.call(this, message !== undefined?message:"Error Raised when unacceptable value receieved");
82 | }
83 | OutputDeviceBadValue.prototype = inherit(OutputDeviceError.prototype);
84 | OutputDeviceBadValue.prototype.constructor = OutputDeviceBadValue;
85 | exports.OutputDeviceBadValue = OutputDeviceBadValue;
86 |
87 | function AttributeError (message) {
88 | GPIOZeroError.call(this, message !== undefined?message:"Base class for attribute errors");
89 | }
90 | AttributeError.prototype = inherit(GPIOZeroError.prototype);
91 | AttributeError.prototype.constructor = AttributeError;
92 |
93 | function PinPWMUnsupported(message) {
94 | AttributeError.call(this, message !== undefined?message:"PWM Not Support in this Pin");
95 | }
96 |
97 | PinPWMUnsupported.prototype = inherit(AttributeError.prototype);
98 | PinPWMUnsupported.prototype.constructor = PinPWMUnsupported;
99 | exports.PinPWMUnsupported = PinPWMUnsupported;
100 |
101 | function PinFixedPull(message) {
102 | AttributeError.call(this, message !== undefined?message:"PError raised when attempting to set the pull of a pin with fixed pull-up");
103 | }
104 |
105 | PinFixedPull.prototype = inherit(AttributeError.prototype);
106 | PinPWMUnsupported.prototype.constructor = PinFixedPull;
107 | exports.PinFixedPull = PinFixedPull;
--------------------------------------------------------------------------------
/gpiozero/index.js:
--------------------------------------------------------------------------------
1 | const exc = require('./exc.js');
2 | const GPIODeviceClass = require('./devices/GPIODevice.js').GPIODevice;
3 | const CompositeDeviceClass = require('./devices/CompositeDevice.js').CompositeDevice;
4 | const OutputDeviceClass = require ('./output_devices/OutputDevice.js').OutputDevice;
5 | const DigitalOutputDeviceClass = require ('./output_devices/DigitalOutputDevice.js').DigitalOutputDevice;
6 | const PWMOutputDeviceClass = require ('./output_devices/PWMOutputDevice.js').PWMOutputDevice;
7 | const CompositeOutputDeviceClass = require('./output_devices/CompositeOutputDevice.js').CompositeOutputDevice;
8 | const InputDeviceClass = require ('./input_devices/InputDevice.js').InputDevice;
9 | const DigitalInputDeviceClass = require ('./input_devices/DigitalInputDevice.js').DigitalInputDevice;
10 | const LEDClass = require ('./output_devices/LED.js').LED;
11 | const RGBLEDClass = require ('./output_devices/RGBLED.js').RGBLED;
12 | const PWMLEDClass = require ('./output_devices/PWMLED.js').PWMLED;
13 | const BuzzerClass = require ('./output_devices/Buzzer.js').Buzzer;
14 | const MotorClass = require ('./output_devices/Motor.js').Motor;
15 | const tools = require('./tools.js');
16 | const TrafficLightsClass = require('./boards/TrafficLights.js').TrafficLights;
17 | const PiTrafficClass = require('./boards/PiTraffic.js').PiTraffic;
18 |
19 | //noinspection JSUnresolvedVariable
20 | module.exports = {
21 | GPIOPinInUse : exc.GPIOPinInUse
22 | ,GPIOPinMissing : exc.GPIOPinMissing
23 | ,OutputDeviceBadValue : exc.OutputDeviceBadValue
24 | ,PinPWMUnsupported : exc.PinPWMUnsupported
25 | ,PinInputState : exc.PinInputState
26 | ,PinFixedPull : exc.PinFixedPull
27 |
28 | ,CompositeDevice : CompositeDeviceClass
29 | ,GPIODevice : GPIODeviceClass
30 |
31 |
32 | ,OutputDevice : OutputDeviceClass
33 | ,DigitalOutputDevice: DigitalOutputDeviceClass
34 | ,PWMOutputDevice : PWMOutputDeviceClass
35 | ,CompositeOutputDevice : CompositeOutputDeviceClass
36 |
37 | ,InputDevice : InputDeviceClass
38 | ,DigitalInputDevice : DigitalInputDeviceClass
39 |
40 | ,LED : LEDClass
41 | ,Buzzer : BuzzerClass
42 | ,Motor : MotorClass
43 | ,PWMLED : PWMLEDClass
44 | ,RGBLED : RGBLEDClass
45 |
46 | ,TrafficLights : TrafficLightsClass
47 | ,PiTraffic: PiTrafficClass
48 |
49 | ,with_close : tools.with_close
50 | ,inherit : tools.inherit
51 | };
52 |
--------------------------------------------------------------------------------
/gpiozero/input_devices/DigitalInputDevice.js:
--------------------------------------------------------------------------------
1 | const InputDevice = require('./InputDevice.js').InputDevice;
2 | const inherit = require('../tools.js').inherit;
3 | const _extend_object = require('../tools.js')._extend_object;
4 | const EventsMixin = require ('../Mixins/EventsMixin.js').EventsMixin;
5 |
6 | exports.DigitalInputDevice = DigitalInputDevice;
7 |
8 | /**
9 | * Represents a generic input device with typical on/off behaviour.
10 | *
11 | * This class extends {@link InputDevice|InputDevice} with machinery to fire the active
12 | * and inactive events for devices that operate in a typical digital manner
13 | * straight forward on / off states with (reasonably) clean transitions between the two.
14 | *
15 | * @param {int} pin - The GPIO pin (in Broadcom numbering) that the device is connected to.
16 | * @param {boolean} [pull_up] - If `true`, the pin will be pulled high with an internal resistor. If
17 | * `false` (the default), the pin will be pulled low.
18 | * @param {float} [bounce_time] - Specifies the length of time (in seconds) that the component will
19 | * ignore changes in state after an initial change. This defaults to
20 | * `undefined` which indicates that no bounce compensation will be performed.
21 | * @class
22 | * @augments InputDevice
23 | */
24 | function DigitalInputDevice(pin, pull_up, bounce_time) {
25 | InputDevice.call(this, pin, pull_up);
26 | _extend_object(this, EventsMixin.prototype);
27 | EventsMixin.call(this);
28 | this._pin.bounce = bounce_time;
29 | this._pin.edges = 'both';
30 | const that = this;
31 | this._pin.when_changed( ()=>{ that._fire_events();});
32 | //Call _fire_events once to set initial state of events
33 | this._fire_events();
34 |
35 | }
36 |
37 | DigitalInputDevice.prototype = inherit(InputDevice.prototype);
38 | DigitalInputDevice.prototype.constructor = DigitalInputDevice;
--------------------------------------------------------------------------------
/gpiozero/input_devices/InputDevice.js:
--------------------------------------------------------------------------------
1 | const GPIODevice = require('../devices/GPIODevice.js').GPIODevice;
2 | const inherit = require('../tools.js').inherit;
3 |
4 | exports.InputDevice = InputDevice;
5 |
6 | /**
7 | * Represents a generic GPIO input device.
8 | * This class extends {@link GPIODevice} to add facilities common to GPIO
9 | * input devices. The constructor adds the optional *pull_up* parameter to
10 | * specify how the pin should be pulled by the internal resistors. The
11 | * {@link InputDevice#is_active|is_active} property is adjusted accordingly so that
12 | * ``true`` still means active regardless of the {@link InputDevice#pull_up|pullup} setting.
13 | *
14 | * @param {int | Pin} pin - The GPIO pin (in Broadcom numbering) that the device is connected to.
15 | * @param {boolean} [pullup] - If ``true``, the pin will be pulled high with an internal resistor. If
16 | * ``false`` (the default), the pin will be pulled low.
17 | * @class
18 | * @augments GPIODevice
19 | * @throws GPIODeviceError
20 | */
21 | function InputDevice (pin, pullup) {
22 | GPIODevice.call(this, pin);
23 |
24 | if (typeof pullup === 'undefined') {
25 | pullup = false;
26 | }
27 |
28 | const pull = pullup ? 'up' : 'down';
29 | if (this._pin.pull() !== pull) {
30 | this._pin.pull(pull);
31 | }
32 | this._active_state = !pullup;
33 | this._inactive_state = pullup;
34 | }
35 |
36 | InputDevice.prototype = inherit(GPIODevice.prototype);
37 | InputDevice.prototype.constructor = InputDevice;
38 |
39 | /**
40 | * If ``true``, the device uses a pull-up resistor to set the GPIO pin "high" by default.
41 | */
42 | InputDevice.prototype.pull_up = function () {
43 | return (this._pin.pull() === 'up');
44 | };
45 |
46 | InputDevice.prototype.toString = function () {
47 | return '';
48 | }
--------------------------------------------------------------------------------
/gpiozero/output_devices/Buzzer.js:
--------------------------------------------------------------------------------
1 | const inherit = require('../tools.js').inherit;
2 | const DigitalOutputDevice = require('./DigitalOutputDevice.js').DigitalOutputDevice;
3 |
4 | exports.Buzzer = Buzzer;
5 | /**
6 | * Represents a digital buzzer component.
7 | *
8 | * @example const Buzzer = require ('gpiozero').Buzzer;
9 | * bz = new Buzzer(3);
10 | * bz.on();
11 | *
12 | * @param {int | Pin} pin - The GPIO pin which the buzzer is attached to.
13 | * @param {boolean} active_high - If ``true`` (the default), the buzzer will operate normally with the circuit described above.
14 | * If ``false`` you should wire the cathode to the GPIO pin, and the anode to a 3V3 pin.
15 | * @param {boolean} initial_value - If ``false`` (the default), the buzzer will be silent initially.
16 | * If ``undefined``, the buzzer will be left in whatever state the pin is found in
17 | * when configured for output (warning: this can be on). If ``true``, the buzzer will be switched on initially.
18 | * @class
19 | * @augments DigitalOutputDevice
20 | */
21 | function Buzzer(pin, active_high, initial_value) {
22 | DigitalOutputDevice.call(this, pin, active_high, initial_value);
23 | }
24 |
25 | Buzzer.prototype = inherit(DigitalOutputDevice.prototype);
26 | Buzzer.prototype.constructor = Buzzer;
27 |
28 | /**
29 | * Make the buzzer switch on and off once a second.
30 | */
31 | Buzzer.prototype.beep = function() {
32 | this.blink();
33 | };
34 |
35 |
--------------------------------------------------------------------------------
/gpiozero/output_devices/CompositeOutputDevice.js:
--------------------------------------------------------------------------------
1 | const exc = require('../exc.js');
2 | const CompositeDevice = require('../devices/CompositeDevice.js').CompositeDevice;
3 | const OutputDevice = require('../output_devices/OutputDevice.js').OutputDevice;
4 | const inherit = require('../tools.js').inherit;
5 |
6 | /**
7 | * Extends {@link CompositeDevice} with {@link CompositeDevice#on|on}, {@link CompositeDevice#off|off},
8 | * and {@link CompositeDevice#toggle|toggle} methods for controlling subordinate output devices
9 | * and extends {@link CompositeDevice#value|value} to be writable.
10 | *
11 | * @param {Array} [devices] - An array of devices that create this composite device.
12 | * @param {Array} [kwdevices] - An array of tuples that contain the device name and device eg ['red', new LED(1)].
13 | * @param {Array} [options] -
14 | * @augments CompositeDevice
15 | * @class
16 | */
17 | function CompositeOutputDevice (devices, kwdevices, options) {
18 | "use strict";
19 | CompositeDevice.call(this, devices, kwdevices, options);
20 | }
21 |
22 | CompositeOutputDevice.prototype = inherit(CompositeDevice.prototype);
23 | CompositeOutputDevice.prototype.constructor = CompositeOutputDevice;
24 |
25 | exports.CompositeOutputDevice = CompositeOutputDevice;
26 |
27 | /**
28 | * Calls the on method on all child devices within this composite device.
29 | */
30 | CompositeOutputDevice.prototype.on = function () {
31 | this._all.forEach((device) => {
32 | if (device instanceof OutputDevice || device instanceof CompositeOutputDevice) {
33 | device.on();
34 | }
35 | });
36 | };
37 |
38 | /**
39 | * Calls the off method on all child devices within this composite device.
40 | */
41 | CompositeOutputDevice.prototype.off = function () {
42 | this._all.forEach((device) => {
43 | if (device instanceof OutputDevice || device instanceof CompositeOutputDevice) {
44 | device.off();
45 | }
46 | });
47 | };
48 |
49 |
50 | /**
51 | * Calls the toggle method on all child devices within this composite device.
52 | **/
53 | CompositeOutputDevice.prototype.toggle = function () {
54 | this._all.forEach((device) => {
55 | if (device instanceof OutputDevice || device instanceof CompositeOutputDevice) {
56 | device.toggle();
57 | }
58 | });
59 | };
60 |
61 | /**
62 | * When value is undefined then the function returns the value of all child
63 | * devices as an array.
64 | * When value is set, all child devices will have their value set according
65 | * to the value array.
66 | *
67 | * @param {Array} [value] - The value to set all of the child devices to.
68 | * @returns {Array} - The current value of each output device returned as an array.
69 | */
70 | CompositeOutputDevice.prototype.value = function (value) {
71 | if (value === undefined) {
72 | return CompositeDevice.prototype.value.call(this);
73 | }
74 | if (value.length !== this._all.length) {
75 | throw new exc.OutputDeviceError();
76 | }
77 | let i = 0;
78 | for (i = 0; i 1 || value < -1) {
74 | throw new exc.OutputDeviceBadValue("Motor value must be between -1 and 1, actual=:" + value);
75 | }
76 |
77 | if (value > 0) {
78 | this.forward(value);
79 | } else if (value < 0) {
80 | this.backward(-value);
81 | } else {
82 | this.stop();
83 | }
84 | };
85 | /**
86 | *
87 | * @returns {boolean} - If the motor is currently running then ``true`` otherwise ``false``.
88 | */
89 | Motor.prototype.is_active = function() {
90 | /*
91 |
92 | */
93 | return this.value() !== 0;
94 | };
95 |
96 | /**
97 | * Drive the motor forwards.
98 | *
99 | * @param {float} speed - The speed at which the motor should turn. Can be any value between 0 (stopped)
100 | * and the default 1 (maximum speed) if ``pwm`` was ``true`` when the class was constructed (and only 0 or 1 if not).
101 | *
102 | * @throws ValueError - When the speed is less than 0 or greater than 1.
103 | * @throws ValueError - When the speed is between 0 and 1 on non-pwm motors.
104 | */
105 | Motor.prototype.forward = function(speed) {
106 | if (speed === undefined) {
107 | speed = 1;
108 | }
109 |
110 | if (speed < 0 || speed > 1) {
111 | throw new exc.ValueError('forward speed must be between 0 and 1');
112 | }
113 |
114 | if (this.forward_device instanceof DigitalOutputDevice && speed !== 1 && speed !== 0) {
115 | throw new exc.ValueError('forward speed must be 0 or 1 with non-PWM Motors');
116 | }
117 |
118 | this.backward_device.off();
119 | this.forward_device.value(speed);
120 | };
121 |
122 | /**
123 | * Drive the motor backwards.
124 | *
125 | * @param {float} speed - The speed at which the motor should turn. Can be any value between 0 (stopped)
126 | * and the default 1 (maximum speed) if ``pwm`` was ``true`` when the class was constructed (and only 0 or 1 if not).
127 | *
128 | * @throws ValueError - When the speed is less than 0 or greater than 1.
129 | * @throws ValueError - When the speed is between 0 and 1 on non-pwm motors.
130 | */
131 | Motor.prototype.backward = function(speed) {
132 | if (speed === undefined) {
133 | speed = 1;
134 | }
135 |
136 | if (speed < 0 || speed > 1) {
137 | throw new exc.ValueError('backward speed must be between 0 and 1');
138 | }
139 |
140 | if (this.backward_device instanceof DigitalOutputDevice && speed !== 1 && speed !== 0) {
141 | throw new exc.ValueError('backward speed must be 0 or 1 with non-PWM Motors');
142 | }
143 |
144 | this.forward_device.off();
145 | this.backward_device.value(speed);
146 | };
147 |
148 | /**
149 | * Reverse the current direction of the motor. If the motor is currently
150 | * idle this does nothing. Otherwise, the motor's direction will be
151 | * reversed at the current speed.
152 | */
153 | Motor.prototype.reverse = function() {
154 | this.value(-1 * this.value());
155 | };
156 |
157 | /**
158 | * Stop the motor.
159 | */
160 | Motor.prototype.stop = function() {
161 | this.forward_device.off();
162 | this.backward_device.off();
163 | };
164 |
--------------------------------------------------------------------------------
/gpiozero/output_devices/OutputDevice.js:
--------------------------------------------------------------------------------
1 | const GPIODevice = require('../devices/GPIODevice.js').GPIODevice;
2 | const Lock = require('rwlock');
3 | const inherit = require('../tools.js').inherit;
4 |
5 | exports.OutputDevice = OutputDevice;
6 | /**
7 | * Represents a generic GPIO output device.
8 | * Provides facilities common to GPIO output devices an {@link OutputDevice#on|on} method to switch the device on, a
9 | * corresponding {@link OutputDevice#off|off} method, and a {@link OutputDevice#toggle|toggle} method.
10 | *
11 | * @param {(int | Pin)} pin - The GPIO pin (in BCM numbering) or an instance of Pin that the device is connected to.
12 | * @param {boolean} [active_high] - If `true` (the default), the {@link OutputDevice#on|on} method will set the GPIO to HIGH.
13 | * If `false`, the :{@link OutputDevice#on|on} method will set the GPIO to LOW (the {@link OutputDevice#off|off} method always does the opposite).
14 | * @param {boolean} [initial_value] - If `false` (the default), the device will be off initially.
15 | * If `undefined`, the device will be left in whatever state the pin is found in when configured for output (warning: this can be on). If `true`, the device will be switched on initially.
16 | *
17 | * @throws GPIOPinMissing - When pin is undefined.
18 | * @class
19 | * @augments GPIODevice
20 | */
21 | function OutputDevice(pin, active_high, initial_value) {
22 | GPIODevice.call(this, pin);
23 | this._lock = new Lock();
24 | this.active_high((active_high === undefined) ? true : active_high);
25 |
26 | if (initial_value === undefined) {
27 | this._pin.pin_function('output');
28 | } else {
29 | this._pin.output_with_state(this._value_to_state(initial_value));
30 | }
31 | }
32 |
33 |
34 | OutputDevice.prototype = inherit(GPIODevice.prototype);
35 | OutputDevice.prototype.constructor = OutputDevice;
36 |
37 | /**
38 | * Internal method to apply active state high and convert the actual value to a logical value.
39 | *
40 | * @param {boolean|float} value - The value to be converted.
41 | * @returns {boolean} - The logical value of the pin.
42 | * @private
43 | */
44 | OutputDevice.prototype._value_to_state = function(value) {
45 | return (value) ? this._active_state : this._inactive_state;
46 | };
47 |
48 | /**
49 | * Internal method used to write to the pin after mapping the request value.
50 | *
51 | * @param {float | boolean} value - The logical value that the pin should be changed to.
52 | * @private
53 | */
54 | OutputDevice.prototype._write = function(value) {
55 | this._check_open(this);
56 | this._pin.state(this._value_to_state(value));
57 | };
58 |
59 | /**
60 | * Turns the device on.
61 | **/
62 | OutputDevice.prototype.on = function() {
63 | this._pin._stop_blink();
64 | this._write(true);
65 | };
66 |
67 | /**
68 | * Turns the device off.
69 | */
70 | OutputDevice.prototype.off = function() {
71 | this._pin._stop_blink();
72 | this._write(false);
73 | };
74 |
75 | /**
76 | *
77 | * This property can be set after construction; be warned that changing it
78 | * will invert {@link OutputDevice#value|value} (i.e. changing this property doesn't change
79 | * the device's pin state - it just changes how that state is interpreted).
80 | *
81 | * @param {boolean} [value] - When ``true``, the {@link OutputDevice#value|value} property is ``true`` when the device's
82 | * {@link OutputDevice#pin|pin} is high. When ``false`` the {@link OutputDevice#value|value} property is
83 | * ``true`` when the device's pin is low (i.e. the value is inverted).
84 | *
85 | */
86 | OutputDevice.prototype.active_high = function(value) {
87 | if (value === undefined) {
88 | return this._active_state;
89 | }
90 | this._active_state = value;
91 | this._inactive_state = !value;
92 | };
93 |
94 | /**
95 | *
96 | * @param {boolean | float} [value] - When supplied the device output is changed to the value.
97 | * @returns {boolean | float} - When value is undefined, the function returns the current value of the device.
98 | */
99 | OutputDevice.prototype.value = function(value) {
100 | if (value === undefined) {
101 | return this._read();
102 | }
103 | this._pin._stop_blink();
104 | this._write(value);
105 | };
106 |
107 | /**
108 | * Reverse the state of the device. If it's on, turn it off; if it's off, turn it on.
109 | */
110 | OutputDevice.prototype.toggle = function() {
111 | const that = this;
112 | this._lock.readLock((release) => {
113 | if (that.is_active()) {
114 | that.off();
115 | } else {
116 | that.on();
117 | }
118 | release();
119 | });
120 | };
121 |
--------------------------------------------------------------------------------
/gpiozero/output_devices/PWMLED.js:
--------------------------------------------------------------------------------
1 | const inherit = require('../tools.js').inherit;
2 | const PWMOutputDevice = require('./PWMOutputDevice.js').PWMOutputDevice;
3 |
4 | exports.PWMLED = PWMLED;
5 |
6 | /**
7 | * Represents a light emitting diode (LED) with variable brightness.
8 | *
9 | * A typical configuration of such a device is to connect a GPIO pin to the
10 | * anode (long leg) of the LED, and the cathode (short leg) to ground, with
11 | * an optional resistor to prevent the LED from burning out.
12 | *
13 | * @param {int} pin - The GPIO pin which the LED is attached to.
14 | * @param {boolean} [active_high] - If ``true`` (the default), the {@link PWMLED#on|on} method will set the GPIO to HIGH.
15 | * If ``false``, the {@link PWMLED#on|on} method will set the GPIO to LOW (the {@link PWMLED#off|off} method always does
16 | * the opposite).
17 | * @param {float} [initial_value] - If ``0`` (the default), the LED will be off initially. Other values
18 | * between 0 and 1 can be specified as an initial brightness for the LED. Note that ``undefined`` cannot be specified
19 | * (unlike the parent class) as there is no way to tell PWM not to alter the state of the pin.
20 | * @param {int} [frequency] - The frequency (in Hz) of pulses emitted to drive the LED. Defaults to 100Hz.
21 | * @class
22 | * @augments PWMOutputDevice
23 | */
24 | function PWMLED(pin, active_high, initial_value, frequency) {
25 | PWMOutputDevice.call(this, pin, active_high, initial_value, frequency);
26 | }
27 |
28 | PWMLED.prototype = inherit(PWMOutputDevice.prototype);
29 | PWMLED.prototype.constructor = PWMLED;
30 |
31 | /**
32 | *
33 | * @returns {boolean} - Alias for {@link PWMOutputDevice#is_active|is_active}.
34 | */
35 | PWMLED.prototype.is_lit = function() {
36 | return this.is_active();
37 | };
38 |
--------------------------------------------------------------------------------
/gpiozero/output_devices/PWMOutputDevice.js:
--------------------------------------------------------------------------------
1 | const inherit = require('../tools.js').inherit;
2 | const OutputDevice = require('./OutputDevice.js').OutputDevice;
3 | const exc = require('../exc.js');
4 |
5 | exports.PWMOutputDevice = PWMOutputDevice;
6 |
7 | /**
8 | * Generic output device configured for pulse-width modulation (PWM).
9 | *
10 | * @param {int | Pin} pin - The GPIO pin which the device is attached to.
11 | * @param {boolean} active_high - If ``true`` (the default), the {@link PWMOutputDevice#on|on} method will set the GPIO to HIGH.
12 | * If ``false``, the {@link PWMOutputDevice#on|on} method will set the GPIO to LOW (the {@link PWMOutputDevice#off|off} method always does the opposite).
13 | * @param {int} initial_value - If ``0`` (the default), the device's duty cycle will be 0 initially.
14 | * Other values between 0 and 1 can be specified as an initial duty cycle.
15 | * Note that ``undefined`` cannot be specified (unlike the parent class) as there is no way to tell PWM not to alter the state of the pin.
16 | * @param {int} frequency - The frequency (in Hz) of pulses emitted to drive the device. Defaults to 100Hz.
17 | * @class
18 | *
19 | * @throws OutputDeviceBadValue - When intial_value is ``undefined``.
20 | */
21 | function PWMOutputDevice(pin, active_high, initial_value, frequency) {
22 | if (initial_value !== undefined) {
23 | if (initial_value < 0 || initial_value > 1) {
24 | throw new exc.OutputDeviceBadValue("initial_value must be between 0 and 1, actual=:" + initial_value);
25 | }
26 | }
27 |
28 | OutputDevice.call(this, pin, active_high, initial_value);
29 |
30 | try {
31 | this._pin.frequency(frequency === undefined ? 100 : frequency);
32 | this.value(initial_value === undefined ? 0 : initial_value);
33 | } catch (e) {
34 | this.close();
35 | throw e;
36 | }
37 | }
38 |
39 | PWMOutputDevice.prototype = inherit(OutputDevice.prototype);
40 | PWMOutputDevice.prototype.constructor = PWMOutputDevice;
41 | /**
42 | * The duty cycle of the PWM device. 0.0 is off, 1.0 is fully on.
43 | * Values in between may be specified for varying levels of power in the device.
44 | *
45 | * @param {float} [value] - When defined then sets the device duty cycle.
46 | * @returns {float} - When value is undefined then the current duty cycle is returned.
47 | */
48 | PWMOutputDevice.prototype.value = function(value) {
49 | if (value === undefined) {
50 | return this._read();
51 | }
52 | this._pin._stop_blink();
53 | this._write(value);
54 | };
55 | /**
56 | * Internal method that converts the actual pin value to it's logical value.
57 | *
58 | * @returns {number} - Logical pin value.
59 | * @private
60 | */
61 | PWMOutputDevice.prototype._read = function() {
62 | this._check_open();
63 | if (this.active_high()) {
64 | return this._pin.state();
65 | }
66 | return 1 - this._pin.state();
67 | };
68 |
69 | /**
70 | * Internal method used to convert a logical value to the state the pin needs to change to.
71 | *
72 | * @param {float} value - Logical value to set the device to.
73 | * @private
74 | * @throws OutputDeviceBadValue - Occurs if the value specified is not between 0 and 1.
75 | */
76 | PWMOutputDevice.prototype._write = function(value) {
77 | if (!this.active_high()) {
78 | value = 1 - value;
79 | }
80 | if (value < 0 || value > 1) {
81 | throw new exc.OutputDeviceBadValue("PWM value must be between 0 and 1");
82 | }
83 | this._check_open();
84 | this._pin.state(value);
85 | };
86 |
87 | /**
88 | * Sets or Gets the device frequency.
89 | *
90 | * @param {int} [value] - The new frequency for the device.
91 | * @returns {int} - If value is undefined then the current device frequency is returned.
92 | */
93 | PWMOutputDevice.prototype.frequency = function(value) {
94 | if (value === undefined) {
95 | return this._pin.frequency();
96 | }
97 | this._pin.frequency(value);
98 | };
99 |
100 | /**
101 | *
102 | * @returns {boolean} - If the device has a value other than 0 then true.
103 | */
104 | PWMOutputDevice.prototype.is_active = function() {
105 | return this.value() !== 0;
106 | };
107 |
108 | /**
109 | * Turn the device fully on.
110 | */
111 | PWMOutputDevice.prototype.on = function() {
112 | this._pin._stop_blink();
113 | this._write(1);
114 | };
115 |
116 | /**
117 | * Turn the device off.
118 | */
119 | PWMOutputDevice.prototype.off = function() {
120 | this._pin._stop_blink();
121 | this._write(0);
122 | };
123 |
124 | /**
125 | * Toggle the state of the device. If the device is currently off (value` is 0.0),
126 | * this changes it to "fully" on (`value` is 1.0).
127 | * If the device has a duty cycle (`value`) of 0.1, this will toggle it to 0.9, and so on.
128 | */
129 | PWMOutputDevice.prototype.toggle = function() {
130 | this._pin._stop_blink();
131 | const newValue = 1 - this.value();
132 | this.value(newValue);
133 | };
134 |
135 | /**
136 | * Stop any actions such as blink and unlink from pin.
137 | */
138 | PWMOutputDevice.prototype.close = function() {
139 | this._pin._stop_blink();
140 | this._pin.frequency(-1);
141 | OutputDevice.prototype.close.call(this);
142 | };
143 |
144 | /**
145 | * Make the device turn on and off repeatedly.
146 | *
147 | * @param {float} [on_time] - Number of seconds on. Defaults to 1 second.
148 | * @param {float} [off_time] - Number of seconds off. Defaults to 1 second.
149 | * @param {float} [fade_in_time] - Number of seconds to spend fading in. Defaults to 0.
150 | * @param {float} [fade_out_time] - Number of seconds to spend fading out. Defaults to 0.
151 | * @param {int} [n] - Number of times to blink; ``undefined`` (the default) means forever.
152 | * @param {@callback} [callback] - Function to be called after n loops.
153 | */
154 | PWMOutputDevice.prototype.blink = function(on_time, off_time, fade_in_time, fade_out_time, n, callback) {
155 | this._pin.blink(on_time, off_time, fade_in_time, fade_out_time, n, undefined, callback);
156 | };
157 |
158 | /**
159 | * Make the device fade in and out repeatedly.
160 | *
161 | * @param {float} [fade_in_time] - Number of seconds to spend fading in. Defaults to 0.
162 | * @param {float} [fade_out_time] - Number of seconds to spend fading out. Defaults to 0.
163 | * @param {int} [n] - Number of times to blink; ``undefined`` (the default) means forever.
164 | * @param {@callback} [callback] - Function to be called after n loops.
165 | */
166 | PWMOutputDevice.prototype.pulse = function(fade_in_time, fade_out_time, n, callback) {
167 | const on_time = 0,
168 | off_time = 0;
169 |
170 | this._pin.blink(on_time, off_time, fade_in_time, fade_out_time, n, undefined, callback);
171 | };
172 |
--------------------------------------------------------------------------------
/gpiozero/output_devices/RGBLED.js:
--------------------------------------------------------------------------------
1 | const Device = require('../devices/Device.js').Device;
2 | const exc = require('../exc.js');
3 | const inherit = require('../tools.js').inherit;
4 | const PWMLED = require ('./PWMLED.js').PWMLED;
5 | const LED = require ('./LED.js').LED;
6 |
7 | exports.RGBLED = RGBLED;
8 |
9 | /**
10 | *
11 | * Represents a full color LED component (composed of red, green, and blue LEDs).
12 | *
13 | * Connect the common cathode (longest leg) to a ground pin; connect each of
14 | * the other legs (representing the red, green, and blue anodes) to any GPIO
15 | * pins. You can either use three limiting resistors (one per anode) or a
16 | * single limiting resistor on the cathode.
17 | *
18 | * @param {int} red - The GPIO pin that controls the red component of the RGB LED.
19 | * @param {int} green - The GPIO pin that controls the green component of the RGB LED.
20 | * @param {int} blue - The GPIO pin that controls the blue component of the RGB LED.
21 | * @param {boolean} [active_high] - Set to ``true`` (the default) for common cathode RGB LEDs. If you are
22 | * using a common anode RGB LED, set this to ``false``.
23 | * @param {Array} [initial_value] - The initial color for the RGB LED. Defaults to black ``[0, 0, 0]``.
24 | * @param {boolean} [pwm] - If ``true`` (the default), construct {@link PWMLED} instances for
25 | * each component of the RGBLED. If ``false``, construct regular {@link LED} instances,
26 | * which prevents smooth color graduations.
27 | * @class
28 | * @augments Device
29 | * @throws GPIOPinMissing - If one of the pins is not specified.
30 | */
31 | function RGBLED(red, green, blue, active_high, initial_value, pwm) {
32 | this._leds = [];
33 | if (red === undefined || blue === undefined || green === undefined) {
34 | throw new exc.GPIOPinMissing('red, green, and blue pins must be provided');
35 | }
36 | pwm = (pwm === undefined ? true : pwm);
37 | var LEDClass = pwm ? PWMLED : LED;
38 | Device.call(this);
39 | this._leds = [new LEDClass(red, active_high), new LEDClass(green, active_high), new LEDClass(blue, active_high)];
40 | if (initial_value === undefined) {
41 | initial_value = [0, 0, 0];
42 | }
43 | this.value(initial_value);
44 | }
45 |
46 | RGBLED.prototype = inherit(Device.prototype);
47 | RGBLED.prototype.constructor = RGBLED;
48 |
49 | /**
50 | * Represents the color of the LED as an RGB 3-tuple of ``[red, green, blue]``
51 | * where each value is between 0 and 1 if ``pwm`` was ``true`` when the class was constructed
52 | * (and only 0 or 1 if not).
53 | *
54 | * @param {Array} [value] - If set, the value for each component will be updated.
55 | * @returns {Array} - If ``value`` is ``undefined`` then returns the current value for each component.
56 | *
57 | * @throws OutputDeviceBadValue - If three values are not passed as an array in value.
58 | * @throws OutputDeviceBadValue - If any of the RGB values are not between 0 and 1.
59 | * @throws OutputDeviceBadValue - If pwm is false but a value is between 0 and 1.
60 | */
61 | RGBLED.prototype.value = function(value) {
62 | if (value === undefined) {
63 | return [this.red, this.green, this.blue];
64 | }
65 | if (value.length < 3) {
66 | throw new exc.OutputDeviceBadValue('RGB values must be an array of three components');
67 | }
68 | var i;
69 | for (i = 0; i < 3; i++) {
70 | if (value[i] < 0 || value[i] > 1) {
71 | throw new exc.OutputDeviceBadValue('each RGB component must be between 0 and 1');
72 | }
73 | if (this._leds[i] instanceof LED) {
74 | if (value[i] !== 0 && value[i] !== 1) {
75 | throw new exc.OutputDeviceBadValue('each RGB color component must be 0 or 1 with non-PWM RGBLEDs');
76 | }
77 | }
78 | }
79 |
80 | for (i = 0; i < 3; i++) {
81 | this._leds[i].value(value[i]);
82 | }
83 | this.red = this._leds[0].value();
84 | this.green = this._leds[1].value();
85 | this.blue = this._leds[2].value();
86 | };
87 |
88 | /**
89 | * Close each pin and release for reuse.
90 | */
91 | RGBLED.prototype.close = function() {
92 | var i;
93 | for (i = 0; i < 3; i++) {
94 | if (this._leds[i] !== undefined) {
95 | this._leds[i].close();
96 | this._leds[i] = undefined;
97 | }
98 | }
99 | this._leds = [];
100 | Device.prototype.close.call(this);
101 | };
102 |
103 | /**
104 | *
105 | * @returns {boolean} - If the LED is currently active (not black) then ``true`` otherwise ``false``.
106 | */
107 | RGBLED.prototype.is_active = function() {
108 | return (this.value()[0] + this.value()[1] + this.value()[2] > 0);
109 | };
110 |
111 | /**
112 | * Turn the LED on. This equivalent to setting the LED color to white ``[1, 1, 1]``.
113 | */
114 | RGBLED.prototype.on = function() {
115 | this.value([1, 1, 1]);
116 | };
117 |
118 | /**
119 | * Turn the LED off. This equivalent to setting the LED color to black ``[0, 0, 0]``.
120 | */
121 | RGBLED.prototype.off = function() {
122 | this.value([0, 0, 0]);
123 | };
124 |
125 | /**
126 | * Toggle the state of the device. If the device is currently off (`value` is ``[0, 0, 0[``),
127 | * this changes it to "fully" on (`value` is ``[1, 1, 1]``).
128 | * If the device has a specific color, this method inverts the color.
129 | */
130 | RGBLED.prototype.toggle = function() {
131 | var current = this.value();
132 | this.value([1 - current[0], 1 - current[1], 1 - current[2]]);
133 | };
134 |
135 | RGBLED.prototype.closed = function() {
136 | return this._leds.length === 0;
137 | };
138 |
139 | /*RGBLED.prototype.blink = function(on_time, off_time, fade_in_time, fade_out_time, on_color, off_color, n, callback) {
140 |
141 | /*
142 | Make the device turn on and off repeatedly.
143 |
144 | :param float on_time:
145 | Number of seconds on. Defaults to 1 second.
146 |
147 | :param float off_time:
148 | Number of seconds off. Defaults to 1 second.
149 |
150 | :param float fade_in_time:
151 | Number of seconds to spend fading in. Defaults to 0.
152 |
153 | :param float fade_out_time:
154 | Number of seconds to spend fading out. Defaults to 0.
155 |
156 | :param tuple on_color:
157 | The color to use when the LED is "on". Defaults to white.
158 |
159 | :param tuple off_color:
160 | The color to use when the LED is "off". Defaults to black.
161 |
162 | :param int n:
163 | Number of times to blink; ``None`` (the default) means forever.
164 |
165 |
166 | if (this._leds[0] instanceof LED) {
167 | if (fade_in_time !== undefined) {
168 | throw new exc.ValueError('fade_in_time must be 0 with non-PWM RGBLEDs');
169 | }
170 | if (fade_out_time !== undefined) {
171 | throw new exc.ValueError('fade_out_time must be 0 with non-PWM RGBLEDs');
172 | }
173 | }
174 |
175 | this._leds[0].blink (on_time, off_time, fade_in_time, fade_out_time, n, callback);
176 | this._leds[1].blink (on_time, off_time, fade_in_time, fade_out_time, n, callback);
177 | this._leds[2].blink (on_time, off_time, fade_in_time, fade_out_time, n, callback);
178 |
179 | };
180 |
181 | RGBLED.prototype._stop_blink = function () {
182 | this._leds[0]._pin._stop_blink();
183 | this._leds[1]._pin._stop_blink();
184 | this._leds[2]._pin._stop_blink();
185 | }
186 |
187 | /* def _blink_device(
188 | self, on_time, off_time, fade_in_time, fade_out_time, on_color,
189 | off_color, n, fps=25):
190 | # Define some simple lambdas to perform linear interpolation between
191 | # off_color and on_color
192 | lerp = lambda t, fade_in: tuple(
193 | (1 - t) * off + t * on
194 | if fade_in else
195 | (1 - t) * on + t * off
196 | for off, on in zip(off_color, on_color)
197 | )
198 | sequence = []
199 | if fade_in_time > 0:
200 | sequence += [
201 | (lerp(i * (1 / fps) / fade_in_time, True), 1 / fps)
202 | for i in range(int(fps * fade_in_time))
203 | ]
204 | sequence.append((on_color, on_time))
205 | if fade_out_time > 0:
206 | sequence += [
207 | (lerp(i * (1 / fps) / fade_out_time, False), 1 / fps)
208 | for i in range(int(fps * fade_out_time))
209 | ]
210 | sequence.append((off_color, off_time))
211 | sequence = (
212 | cycle(sequence) if n is None else
213 | chain.from_iterable(repeat(sequence, n))
214 | )
215 | for l in self._leds:
216 | l._controller = self
217 | for value, delay in sequence:
218 | for l, v in zip(self._leds, value):
219 | l._write(v)
220 | if self._blink_thread.stopping.wait(delay):
221 | break
222 | */
223 |
224 |
225 | /*
226 | class RGBLED(SourceMixin, Device):
227 |
228 |
229 | def blink(
230 | self, on_time=1, off_time=1, fade_in_time=0, fade_out_time=0,
231 | on_color=(1, 1, 1), off_color=(0, 0, 0), n=None, background=True):
232 | """
233 | Make the device turn on and off repeatedly.
234 |
235 | :param float on_time:
236 | Number of seconds on. Defaults to 1 second.
237 |
238 | :param float off_time:
239 | Number of seconds off. Defaults to 1 second.
240 |
241 | :param float fade_in_time:
242 | Number of seconds to spend fading in. Defaults to 0. Must be 0 if
243 | ``pwm`` was ``False`` when the class was constructed
244 | (:exc:`ValueError` will be raised if not).
245 |
246 | :param float fade_out_time:
247 | Number of seconds to spend fading out. Defaults to 0. Must be 0 if
248 | ``pwm`` was ``False`` when the class was constructed
249 | (:exc:`ValueError` will be raised if not).
250 |
251 | :param tuple on_color:
252 | The color to use when the LED is "on". Defaults to white.
253 |
254 | :param tuple off_color:
255 | The color to use when the LED is "off". Defaults to black.
256 |
257 | :param int n:
258 | Number of times to blink; ``None`` (the default) means forever.
259 |
260 | :param bool background:
261 | If ``True`` (the default), start a background thread to continue
262 | blinking and return immediately. If ``False``, only return when the
263 | blink is finished (warning: the default value of *n* will result in
264 | this method never returning).
265 | """
266 | if isinstance(self._leds[0], LED):
267 | if fade_in_time:
268 | raise ValueError('fade_in_time must be 0 with non-PWM RGBLEDs')
269 | if fade_out_time:
270 | raise ValueError('fade_out_time must be 0 with non-PWM RGBLEDs')
271 |
272 | def pulse(
273 | self, fade_in_time=1, fade_out_time=1,
274 | on_color=(1, 1, 1), off_color=(0, 0, 0), n=None, background=True):
275 | """
276 | Make the device fade in and out repeatedly.
277 |
278 | :param float fade_in_time:
279 | Number of seconds to spend fading in. Defaults to 1.
280 |
281 | :param float fade_out_time:
282 | Number of seconds to spend fading out. Defaults to 1.
283 |
284 | :param tuple on_color:
285 | The color to use when the LED is "on". Defaults to white.
286 |
287 | :param tuple off_color:
288 | The color to use when the LED is "off". Defaults to black.
289 |
290 | :param int n:
291 | Number of times to pulse; ``None`` (the default) means forever.
292 |
293 | :param bool background:
294 | If ``True`` (the default), start a background thread to continue
295 | pulsing and return immediately. If ``False``, only return when the
296 | pulse is finished (warning: the default value of *n* will result in
297 | this method never returning).
298 | """
299 | on_time = off_time = 0
300 | self.blink(
301 | on_time, off_time, fade_in_time, fade_out_time,
302 | on_color, off_color, n, background
303 | )
304 |
305 | def _stop_blink(self, led=None):
306 | # If this is called with a single led, we stop all blinking anyway
307 | if self._blink_thread:
308 | self._blink_thread.stop()
309 | self._blink_thread = None
310 |
311 |
312 |
313 |
314 | */
--------------------------------------------------------------------------------
/gpiozero/pins/wiringpi.js:
--------------------------------------------------------------------------------
1 | const wpi = require("wiring-pi");
2 | const p = require("./index.js");
3 | const exc = require("../exc.js");
4 | const inherit = require('../tools.js').inherit;
5 | const Pin = require("./index.js").Pin;
6 |
7 | var _PINS = {},
8 | WIRING_PI,
9 | PI_INFO,
10 | GPIO_FUNCTIONS = {
11 | 'input': wpi.INPUT,
12 | 'output': wpi.OUTPUT,
13 | //'i2c': GPIO.I2C,
14 | //'spi': GPIO.SPI,
15 | 'pwm': wpi.PWM_OUTPUT,
16 | //'serial': GPIO.SERIAL,
17 | //'unknown': GPIO.UNKNOWN,
18 | },
19 | GPIO_PULL_UPS = {
20 | 'up': wpi.PUD_UP,
21 | 'down': wpi.PUD_DOWN,
22 | 'floating': wpi.PUD_OFF,
23 | };
24 |
25 | exports.WiringPiPin = WiringPiPin;
26 |
27 | function WiringPiPin(number) {
28 | /*
29 | Uses the `wiringPi`_ library to interface to the Pi's GPIO pins. This is
30 | the default pin implementation.
31 | Supports all features including PWM (via software).
32 |
33 | Because this is the default pin implementation you can use it simply by
34 | specifying an integer number for the pin in most operations, e.g.::
35 |
36 | from gpiozero import LED
37 |
38 | led = LED(12)
39 |
40 | However, you can also construct RPi.GPIO pins manually if you wish::
41 |
42 | from gpiozero.pins.rpigpio import RPiGPIOPin
43 | from gpiozero import LED
44 |
45 | led = LED(RPiGPIOPin(12))
46 |
47 |
48 | */
49 | if (WIRING_PI === undefined) {
50 | wpi.setup('gpio');
51 | WIRING_PI = true;
52 | }
53 | /*
54 |
55 | GPIO_EDGES = {
56 | 'both': GPIO.BOTH,
57 | 'rising': GPIO.RISING,
58 | 'falling': GPIO.FALLING,
59 | }
60 |
61 | GPIO_FUNCTION_NAMES = {v: k for (k, v) in GPIO_FUNCTIONS.items()}
62 | GPIO_PULL_UP_NAMES = {v: k for (k, v) in GPIO_PULL_UPS.items()}
63 | GPIO_EDGES_NAMES = {v: k for (k, v) in GPIO_EDGES.items()}
64 | */
65 |
66 |
67 |
68 | if (PI_INFO === undefined) {
69 | PI_INFO = wpi.piBoardRev();
70 | }
71 | if (number < 0 || number > 54) {
72 | throw new Error('invalid pin ' + number.toString() + ' specified (must be 0..53)');
73 | }
74 |
75 | if (_PINS[number] !== undefined) {
76 | return _PINS[number];
77 | }
78 | p.Pin.call(this);
79 | this._number = number;
80 | this._pwm = undefined;
81 | this._frequency = undefined;
82 | this._duty_cycle = undefined;
83 | this._bounce = -666;
84 | this._when_changed = undefined;
85 | this._function = 'input';
86 | this._state = false;
87 | this._pull = 'floating';
88 | this._bounce = undefined;
89 | this._edges = 'both';
90 |
91 | wpi.pinMode(number, wpi.INPUT);
92 | _PINS[number] = this;
93 | return this;
94 | }
95 |
96 | WiringPiPin.prototype = inherit(p.LocalPin.prototype);
97 | WiringPiPin.prototype.constructor = WiringPiPin;
98 |
99 | WiringPiPin.prototype.toString = function() {
100 | return "GPIO " + this._number.toString();
101 | };
102 | WiringPiPin.prototype.when_changed = function(next) {
103 | this._when_changed = next;
104 | }
105 |
106 | WiringPiPin.prototype.number = function() {
107 | return this._number();
108 | };
109 |
110 | WiringPiPin.prototype.close = function() {
111 | this._frequency = undefined;
112 | this._when_changed = undefined;
113 | wpi.pullUpDnControl(this._number, wpi.PUD_OFF);
114 | };
115 |
116 | WiringPiPin.prototype.output_with_state = function(state) {
117 | this._pull = 'floating';
118 | this.pin_function ('output');
119 | wpi.digitalWrite(this._number, state);
120 | };
121 |
122 | WiringPiPin.prototype.input_with_pull = function(pull) {
123 | // if (pull != 'up' and self.PI_INFO.pulled_up('GPIO%d' % self._number):
124 | // raise PinFixedPull('%r has a physical pull-up resistor' % self)
125 | //try:
126 | wpi.pinMode(this._number, wpi.IN);
127 | //GPIO.setup(self._number, GPIO.IN, self.GPIO_PULL_UPS[pull])
128 | wpi.pullUpDnControl(this._number, wpi.PUD_UP);
129 | this._pull = pull;
130 | //except KeyError:
131 | // raise PinInvalidPull('invalid pull "%s" for pin %r' % (pull, self))
132 | };
133 |
134 | WiringPiPin.prototype.pin_function = function(value) {
135 | if (value === undefined) {
136 | return this._function;
137 | }
138 | if (value !== 'input') {
139 | this._pull = 'floating';
140 | }
141 | if (value === 'input' || value === 'output') {
142 | wpi.pinMode(this._number, GPIO_FUNCTIONS[value]);
143 | wpi.pullUpDnControl(this._number, GPIO_PULL_UPS[this._pull]);
144 | this._function = value;
145 | } else {
146 | throw exc.PinInvalidFunction('invalid function " + value + " for pin ' + this._number.toString());
147 | }
148 | };
149 |
150 | WiringPiPin.prototype.state = function(value) {
151 | if (value === undefined) {
152 | if (this._pwm !== undefined) {
153 | return this._duty_cycle;
154 | }
155 | return wpi.digitalRead(this._number);
156 | }
157 | if (this._pwm !== undefined) {
158 | wpi.pwmWrite(this._number, value);
159 | this._duty_cycle = value;
160 | } else {
161 | wpi.digitalWrite(this._number, value ? 1 : 0);
162 | }
163 | };
164 |
165 | WiringPiPin.prototype.pull = function(value) {
166 | if (value === undefined) {
167 | return this._pull;
168 | }
169 | if (this.function !== 'input') {
170 | throw new exc.PinFixedPull('cannot set pull on non-input pin ' + this._number.toString());
171 | }
172 | /*if value != 'up' and self.PI_INFO.pulled_up('GPIO%d' % self._number):
173 | raise PinFixedPull('%r has a physical pull-up resistor' % self)
174 | }*/
175 | this._pull = value;
176 | wpi.pullUpDnControl(this._number, this.GPIO_PULL_UPS[this._pull]);
177 | };
178 |
179 | WiringPiPin.prototype.frequency = function(value) {
180 | if (value === undefined) {
181 | return this._frequency;
182 | }
183 | if (this._function !== 'output') {
184 | throw new exc.PinSetInput("Pin is not set for output function");
185 | }
186 | if (value === -1) {
187 | this._frequency = undefined;
188 | this._pwm = undefined;
189 | wpi.pwmToneWrite(this._number, 0);
190 | } else {
191 | if (this._frequency === undefined) {
192 | this._pwm = wpi.pinMode(this._number, wpi.PWM_OUTPUT);
193 | }
194 | wpi.pwmToneWrite(this._number, value);
195 | this._frequency = value;
196 | }
197 | };
198 |
199 | WiringPiPin.prototype.blink = function(on_time, off_time, fade_in_time, fade_out_time, n, fps, callback) {
200 |
201 | if(this._pwm === undefined) {
202 | Pin.prototype.blink.call(this, on_time, off_time, n, callback);
203 | return;
204 | }
205 | this.on_time = (on_time === undefined ? 1 : on_time);
206 | this.off_time = (off_time === undefined ? 1 : off_time);
207 | this.fade_in_time = (fade_in_time === undefined ? 0 : fade_in_time);
208 | this.fade_out_time = (fade_out_time === undefined ? 0 : fade_out_time);
209 | this.fps = (fps === undefined ? 50 : fps);
210 | this.n = (n === undefined ? 0 : n);
211 | this.sequence = [];
212 | this.blink_callback = callback;
213 | var i = 0;
214 |
215 | if (this.fade_in_time > 0) {
216 | for (i = 0; i < this.fps * this.fade_in_time; i++) {
217 | this.sequence.push({
218 | value: i * (1 / this.fps) / this.fade_in_time,
219 | delay: 1 / this.fps
220 | });
221 | }
222 | }
223 | this.sequence.push({
224 | value: 1,
225 | delay: this.on_time
226 | });
227 |
228 | if (this.fade_out_time > 0) {
229 | for (i = 0; i < this.fps * this.fade_out_time; i++) {
230 | this.sequence.push({
231 | value: 1 - (i * (1 / this.fps)) / this.fade_out_time,
232 | delay: 1 / this.fps
233 | });
234 | }
235 | }
236 | this.sequence.push({
237 | value: 0,
238 | delay: this.off_time
239 | });
240 |
241 | if (this.n > 0) {
242 | for (i = 0; i < (this.n - 1); i++) {
243 | this.sequence = this.sequence.concat(this.sequence);
244 | }
245 |
246 | var nextStep = this.sequence.pop();
247 | this.state(nextStep.value);
248 | var that = this;
249 | this._blink_timer = setTimeout(that._run_blink, nextStep.delay, this.sequence, this);
250 | }
251 | };
252 |
253 | WiringPiPin.prototype._run_blink = function(sequence, that) {
254 | if (sequence.length > 0) {
255 | var nextStep = sequence.pop();
256 | that.state(nextStep.value);
257 | that._blink_timer = setTimeout(that._run_blink, nextStep.delay, sequence, that);
258 | } else if (that.blink_callback !== undefined) {
259 | that.blink_callback();
260 | }
261 | };
262 |
263 | /*
264 |
265 | def _get_bounce(self):
266 | return None if self._bounce == -666 else (self._bounce / 1000)
267 |
268 | def _set_bounce(self, value):
269 | if value is not None and value < 0:
270 | raise PinInvalidBounce('bounce must be 0 or greater')
271 | f = self.when_changed
272 | self.when_changed = None
273 | try:
274 | self._bounce = -666 if value is None else int(value * 1000)
275 | finally:
276 | self.when_changed = f
277 |
278 | def _get_edges(self):
279 | return self.GPIO_EDGES_NAMES[self._edges]
280 |
281 | def _set_edges(self, value):
282 | f = self.when_changed
283 | self.when_changed = None
284 | try:
285 | self._edges = self.GPIO_EDGES[value]
286 | finally:
287 | self.when_changed = f
288 |
289 | def _get_when_changed(self):
290 | return self._when_changed
291 |
292 | def _set_when_changed(self, value):
293 | if self._when_changed is None and value is not None:
294 | self._when_changed = value
295 | GPIO.add_event_detect(
296 | self._number, self._edges,
297 | callback=lambda channel: self._when_changed(),
298 | bouncetime=self._bounce)
299 | elif self._when_changed is not None and value is None:
300 | GPIO.remove_event_detect(self._number)
301 | self._when_changed = None
302 | else:
303 | self._when_changed = value
304 |
305 | */
--------------------------------------------------------------------------------
/gpiozero/tools.js:
--------------------------------------------------------------------------------
1 | exports.with_close = function(device, method) {
2 | method(device);
3 | device.close();
4 | };
5 |
6 |
7 | exports.inherit = function(proto) {
8 | /*eslint no-empty-function: off*/
9 | function F() {}
10 | F.prototype = proto;
11 | return new F();
12 | };
13 |
14 | // Pass in the objects to merge as arguments.
15 | // For a deep extend, set the first argument to `true`.
16 | exports.extend = extend;
17 |
18 | /*eslint prefer-rest-params: off*/
19 | function extend() {
20 |
21 | // Variables
22 | const extended = {};
23 | let deep = false;
24 | let i = 0;
25 | const length = arguments.length;
26 |
27 | // Check if a deep merge
28 | if (Object.prototype.toString.call(arguments[0]) === '[object Boolean]') {
29 | deep = arguments[0];
30 | i++;
31 | }
32 |
33 | // Merge the object into the extended object
34 | const merge = function(obj) {
35 | for (const prop in obj) {
36 | if (Object.prototype.hasOwnProperty.call(obj, prop)) {
37 | // If deep merge and property is an object, merge properties
38 | if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') {
39 | extended[prop] = extend(true, extended[prop], obj[prop]);
40 | } else {
41 | extended[prop] = obj[prop];
42 | }
43 | }
44 | }
45 | };
46 |
47 | // Loop through each object and conduct a merge
48 | for (; i < length; i++) {
49 | const obj = arguments[i];
50 | merge(obj);
51 | }
52 |
53 | return extended;
54 | }
55 |
56 | /*eslint prefer-rest-params: off*/
57 | function _extend_object() {
58 |
59 | // Variables
60 |
61 | let deep = false;
62 | let i = 0;
63 | const length = arguments.length;
64 |
65 | // Check if a deep merge
66 | if (Object.prototype.toString.call(arguments[0]) === '[object Boolean]') {
67 | deep = arguments[0];
68 | i++;
69 | }
70 | const extended = arguments[i];
71 | i++;
72 |
73 | // Merge the object into the extended object
74 | const merge = function(obj) {
75 | for (const prop in obj) {
76 | if (Object.prototype.hasOwnProperty.call(obj, prop)) {
77 | // If deep merge and property is an object, merge properties
78 | if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') {
79 | extended[prop] = extend(true, extended[prop], obj[prop]);
80 | } else {
81 | extended[prop] = obj[prop];
82 | }
83 | }
84 | }
85 | };
86 | // Loop through each object and conduct a merge
87 | for (; i < length; i++) {
88 | const obj = arguments[i];
89 | merge(obj);
90 | }
91 | }
92 |
93 | // Pass in the objects to merge as arguments.
94 | // For a deep extend, set the first argument to `true`.
95 | exports._extend_object = _extend_object;
--------------------------------------------------------------------------------
/jsdoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "opts": {
3 | "template": "node_modules/docdash/",
4 | "encoding": "utf8",
5 | "destination": "docs/",
6 | "recurse": true,
7 | "verbose": true
8 | },
9 | "templates": {
10 | "cleverLinks": false,
11 | "monospaceLinks": false
12 | }
13 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0",
3 | "name": "js-gpiozero",
4 | "description": "A simple interface to GPIO devices with Raspberry Pi using nodejs",
5 | "main": "./gpiozero/index.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "https://github.com/miketrebilcock/js-gpiozero.git"
9 | },
10 | "bugs": {
11 | "url": "https://github.com/miketrebilcock/js-gpiozero/issues"
12 | },
13 | "scripts": {
14 | "test": "istanbul cover node_modules/mocha/bin/_mocha && codecov",
15 | "changelog": "standard-changelog -i CHANGELOG.md -w",
16 | "lint": "eslint ./gpiozero/**/*.js ./test/**/*.js",
17 | "docs": "jsdoc ./gpiozero -R ./README.md -d docs -c jsdoc.json",
18 | "semantic-release": "semantic-release pre && npm publish && semantic-release post"
19 | },
20 | "dependencies": {
21 | "rwlock": "5.0.0",
22 | "wiring-pi": "^2.2.1"
23 | },
24 | "devDependencies": {
25 | "chai": "3.5.0",
26 | "codecov": "3.6.5",
27 | "cz-conventional-changelog": "1.2.0",
28 | "docdash": "0.4.0",
29 | "eslint": "3.19.0",
30 | "eslint-config-airbnb-base": "11.3.2",
31 | "eslint-config-node": "1.6.0",
32 | "eslint-plugin-import": "2.20.2",
33 | "eslint-plugin-jsdoc": "2.4.0",
34 | "istanbul": "0.4.5",
35 | "jsdoc": "3.6.4",
36 | "mocha": "3.5.3",
37 | "mocha-eslint": "3.0.1",
38 | "semantic-release": "6.3.6"
39 | },
40 | "keywords": [
41 | "wiringPi",
42 | "gpio",
43 | "raspberry",
44 | "pi",
45 | "raspberrypi",
46 | "bcm2835"
47 | ],
48 | "author": "Mike Trebilcock ",
49 | "contributors": [],
50 | "license": "ISC",
51 | "homepage": "https://miketrebilcock.github.io/js-gpiozero/",
52 | "directories": {
53 | "doc": "docs",
54 | "test": "tests"
55 | },
56 | "config": {
57 | "commitizen": {
58 | "path": "./node_modules/cz-conventional-changelog"
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/pre-commit.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # We only want to test the commited files
3 | # so get rid of everything else
4 | git stash -q --keep-index
5 |
6 | npm test
7 | RESULT=$?
8 |
9 | npm run docs
10 | git add ./docs/**
11 |
12 | ## Restore the stashed files so the directory
13 | ## is as it was at the start
14 | git stash pop -q
15 |
16 | [ $RESULT -ne 0 ] && exit 1
17 | exit 0
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/test/devices.spec.js:
--------------------------------------------------------------------------------
1 | /*global it describe afterEach */
2 |
3 | const expect = require('chai').expect;
4 | const assert = require('chai').assert;
5 | const gz = require('../gpiozero/');
6 | const mp = require('../gpiozero/pins/mock.js');
7 | const with_close = require('../gpiozero/').with_close;
8 |
9 | describe('devices', () => {
10 |
11 | afterEach(() => {
12 | mp.clear_pins();
13 | });
14 |
15 | it('no_pin_throws_error', () => {
16 | expect(() => {
17 | /*eslint no-new: off*/
18 | new gz.GPIODevice();
19 | }).to.throw(gz.GPIOPinMissing);
20 | });
21 |
22 | it('device_init', () => {
23 | var pin = new mp.MockPin(1);
24 | with_close(new gz.GPIODevice(pin), (device) => {
25 | assert(device.closed() === false, "Device is incorrectly reporting closed");
26 | assert(device.pin() === pin, "Device has not returned correct pin");
27 | });
28 | });
29 |
30 | it('device_init_twice_on_same_pin_fails', () => {
31 | var pin = new mp.MockPin(1);
32 | with_close(new gz.GPIODevice(pin), () => {
33 | expect(() => {
34 | /*eslint no-new: off*/
35 | new gz.GPIODevice(pin);
36 | }).to.throw(gz.GPIOPinInUse);
37 | });
38 | });
39 |
40 | it('device_init_twice_on_diffent_pins_suceeds', () => {
41 | var pin = new mp.MockPin(1),
42 | pin2 = new mp.MockPin(2);
43 | with_close(new gz.GPIODevice(pin), (device1) => {
44 | with_close(new gz.GPIODevice(pin2), (device2) => {
45 | assert(device1.pin() === pin, "Device has not returned correct pin");
46 | assert(device2.pin() === pin2, "Device has not returned correct pin");
47 | });
48 | });
49 | });
50 |
51 | it('device_close', () => {
52 | var pin = new mp.MockPin(1),
53 | device = new gz.GPIODevice(pin);
54 | device.close();
55 | assert(device.closed() === true, "Device is incorrectly reporting open");
56 | assert(device.pin() === undefined, "Device still holding onto pin");
57 | });
58 |
59 | it('reopen_same_pin', () => {
60 | var pin = new mp.MockPin(1),
61 | device = new gz.GPIODevice(pin);
62 | device.close();
63 | var device2 = new gz.GPIODevice(pin);
64 | assert(device2.closed() === false, "Device is incorrectly reporting closed");
65 | assert(device2.pin() === pin, "Device has not returned correct pin");
66 | assert(device.closed() === true, "Device is incorrectly reporting open");
67 | assert(device.pin() === undefined, "Device still holding onto pin");
68 | device2.close();
69 | });
70 |
71 | it('device_toString', () => {
72 | var pin = new mp.MockPin(1);
73 | with_close(new gz.GPIODevice(pin), (device) => {
74 | expect(device.toString()).to.equal("");
75 | });
76 | });
77 |
78 | it('compsite_device_sequence', () => {
79 | with_close(new gz.CompositeDevice([new gz.OutputDevice(new mp.MockPin(2)),
80 | new gz.OutputDevice(new mp.MockPin(3))]),
81 | (device) => {
82 | assert(device.length() === 2, "CompositeDevice length is not 2");
83 | assert(device[0]._pin.number() === 2);
84 | assert(device[1]._pin.number() === 3);
85 | assert(device.namedtuple()[0] === '_0', "CompositeDevice NamedTuple returned "+device.namedtuple());
86 | assert(device.namedtuple()[1] === '_1', "CompositeDevice NamedTuple returned "+device.namedtuple());
87 | });
88 | });
89 |
90 | it('compsite_device_values', () => {
91 | with_close(new gz.CompositeDevice([new gz.OutputDevice(new mp.MockPin(2)),
92 | new gz.OutputDevice(new mp.MockPin(3))]),
93 | (device) => {
94 | assert(device.value()[0] === false, "CompositeDevice value[0] is not false");
95 | assert(device.value()[1] === false, "CompositeDevice value[1] is not false");
96 | assert(device.is_active() === false, "CompositeDevice is_active is not false");
97 | device[0]._pin.state(true);
98 | assert(true === device.value()[0], "CompositeDevice value[0] is not true");
99 | assert(false === device.value()[1], "CompositeDevice value[1] is not false");
100 | assert(true === device.is_active(), "CompositeDevice is_active is not true");
101 | });
102 | });
103 |
104 | it('compsite_device_named', () => {
105 | with_close(new gz.CompositeDevice(undefined,[
106 | ['foo', new gz.OutputDevice(new mp.MockPin(2))],
107 | ['bar', new gz.OutputDevice(new mp.MockPin(3))]
108 | ]),
109 | (device) => {
110 | assert(device.namedtuple()[0] === 'foo', "CompositeDevice NamedTuple returned "+device.namedtuple());
111 | assert(device.namedtuple()[1] === 'bar', "CompositeDevice NamedTuple returned "+device.namedtuple());
112 | assert(device.value()[0] === false, "CompositeDevice value[0] is not false");
113 | assert(device.value()[1] === false, "CompositeDevice value[1] is not false");
114 | assert(device.is_active() === false, "CompositeDevice is_active is not false");
115 | assert(device.foo.value() === false, "CompositeDevice value[0] is not false");
116 | assert(device.bar.value() === false, "CompositeDevice value[1] is not false");
117 | device.foo._pin.state(true);
118 | assert(device.foo.value() === true, "CompositeDevice value[0] is not true");
119 | });
120 | });
121 |
122 | /*
123 |
124 | def test_composite_device_bad_init():
125 | with pytest.raises(ValueError):
126 | CompositeDevice(foo=1, bar=2, _order=('foo',))
127 | with pytest.raises(ValueError):
128 | CompositeDevice(close=1)
129 | with pytest.raises(ValueError):
130 | CompositeDevice(2)
131 | with pytest.raises(ValueError):
132 | CompositeDevice(MockPin(2))
133 |
134 | def test_composite_device_read_only():
135 | device = CompositeDevice(
136 | foo=InputDevice(MockPin(2)),
137 | bar=InputDevice(MockPin(3))
138 | )
139 | with pytest.raises(AttributeError):
140 | device.foo = 1
141 |
142 | */
143 |
144 | });
145 |
146 | /*
147 | def test_device_repr():
148 | pin = MockPin(2)
149 | with GPIODevice(pin) as device:
150 | assert repr(device) == '' % pin
151 |
152 | def test_device_repr_after_close():
153 | pin = MockPin(2)
154 | device = GPIODevice(pin)
155 | device.close()
156 | assert repr(device) == ''
157 |
158 |
159 | */
--------------------------------------------------------------------------------
/test/eslint.spec.js:
--------------------------------------------------------------------------------
1 | const lint = require('mocha-eslint');
2 |
3 | // Array of paths to lint
4 | // Note: a seperate Mocha test will be run for each path and each file which
5 | // matches a glob pattern
6 | const paths = [
7 | 'gpiozero/**/*.js',
8 | 'test/**/*spec.js',
9 | ];
10 |
11 | var options = {
12 | // Specify style of output
13 | //formatter: 'compact', // Defaults to `stylish`
14 |
15 | // Only display warnings if a test is failing
16 | //alwaysWarn: false, // Defaults to `true`, always show warnings
17 |
18 | // Increase the timeout of the test if linting takes to long
19 | //timeout: 5000, // Defaults to the global mocha `timeout` option
20 |
21 | // Increase the time until a test is marked as slow
22 | //slow: 1000, // Defaults to the global mocha `slow` option
23 |
24 | // Consider linting warnings as errors and return failure
25 | strict: true // Defaults to `false`, only notify the warnings
26 | };
27 |
28 | // Run the tests
29 | lint(paths, options);
--------------------------------------------------------------------------------
/test/input_devices.spec.js:
--------------------------------------------------------------------------------
1 | /*global it describe afterEach context */
2 | const expect = require('chai').expect;
3 | const assert = require('chai').assert;
4 | const gz = require('../gpiozero/index.js');
5 | const mp = require('../gpiozero/pins/mock.js');
6 | const with_close = require ('../gpiozero/tools.js').with_close;
7 |
8 | describe('input_devices', () => {
9 |
10 | afterEach(() => {
11 | mp.clear_pins();
12 | });
13 | context('input_device', ()=> {
14 | it('initial_values', () => {
15 | const pin = new mp.MockPin(2);
16 | with_close(new gz.InputDevice(pin, true), (device) => {
17 | assert(pin.pin_function() === 'input', 'Input pin function is not set to input');
18 | assert(pin.pull() === 'up', 'Input pin is not set to pull up');
19 | assert(device.pull_up(), 'Device pull_up is not true');
20 | device.close();
21 | device = new gz.InputDevice(pin);
22 | assert(pin.pull() === 'down', 'Input pin is not set to pull down');
23 | assert(device.pull_up() === false, 'Device pull_up is not false');
24 | });
25 | });
26 |
27 | it('is_active_low', () => {
28 | const pin = new mp.MockPin(2);
29 | with_close(new gz.InputDevice(pin, true), (device) => {
30 | pin.drive_high();
31 | assert(device.is_active() === false, 'Device should not be active');
32 | assert(device.toString() === '', 'ToString is incorrect:'+device.toString());
33 | pin.drive_low();
34 | assert(device.is_active() === true, 'Device should be active');
35 | assert(device.toString() === '', 'ToString is incorrect:'+device.toString());
36 | });
37 | });
38 |
39 | it('is_active_high', () => {
40 | const pin = new mp.MockPin(2);
41 | with_close(new gz.InputDevice(pin), (device) => {
42 | pin.drive_high();
43 | assert(device.is_active() === true, 'Device should be active');
44 | assert(device.toString() === '', 'ToString is incorrect:'+device.toString());
45 | pin.drive_low();
46 | assert(device.is_active() === false, 'Device should not be active');
47 | assert(device.toString() === '', 'ToString is incorrect:'+device.toString());
48 | });
49 | });
50 |
51 | it('is pulled up', () => {
52 | const pin = new mp.MockPulledUpPin(2);
53 | expect(() => {
54 | /*eslint no-new: off*/
55 | new gz.InputDevice(pin, true);
56 | }).to.throw(gz.PinFixedPull);
57 | });
58 | });
59 | context('digital_input_device', ()=> {
60 | it('is event activated', () => {
61 | let event = false;
62 | const pin = new mp.MockPin(2);
63 | with_close(new gz.DigitalInputDevice(pin), (device) => {
64 | device.when_activated = function (){
65 | event = true;
66 | };
67 | assert (event === false, "Event is not set to false");
68 | pin.drive_high();
69 | assert (event === true, "Event is not set to true");
70 | });
71 | });
72 | it('is event activated', () => {
73 | let event = false;
74 | const pin = new mp.MockPin(2);
75 | with_close(new gz.DigitalInputDevice(pin), (device) => {
76 | device.when_deactivated = function (){
77 | event = true;
78 | };
79 | assert (event === false, "Event is not set to false");
80 | pin.drive_high();
81 | assert (event === false, "Event is not set to false");
82 | pin.drive_low();
83 | assert (event === true, "Event is not set to true");
84 | });
85 | });
86 | });
87 | });
--------------------------------------------------------------------------------
/test/mocha.opts:
--------------------------------------------------------------------------------
1 | --reporter spec
2 | --ui bdd
3 | --recursive
4 |
--------------------------------------------------------------------------------