forked from platypush/platypush
Added GPIO web panel
This commit is contained in:
parent
d33494419a
commit
a23f5446da
5 changed files with 130 additions and 11 deletions
|
@ -0,0 +1,39 @@
|
||||||
|
@import 'common/vars';
|
||||||
|
|
||||||
|
.gpio-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.refresh {
|
||||||
|
border-bottom: $default-border-2;
|
||||||
|
background: $default-bg-5;
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: 0;
|
||||||
|
&:hover {
|
||||||
|
color: $default-hover-fg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pins {
|
||||||
|
.pin {
|
||||||
|
padding: 1em;
|
||||||
|
border-bottom: $default-border-2;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background: $modal-header-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $hover-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
35
platypush/backend/http/static/js/plugins/gpio/index.js
Normal file
35
platypush/backend/http/static/js/plugins/gpio/index.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
Vue.component('gpio', {
|
||||||
|
template: '#tmpl-gpio',
|
||||||
|
props: ['config'],
|
||||||
|
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
pins: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
refresh: async function() {
|
||||||
|
const pins = await request('gpio.read_all');
|
||||||
|
this.pins = pins.reduce((pins, pin) => {
|
||||||
|
pins[pin.pin] = {
|
||||||
|
name: pin.name,
|
||||||
|
number: pin.pin,
|
||||||
|
on: !!pin.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
return pins;
|
||||||
|
}, {});
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle: async function(pin) {
|
||||||
|
await request('gpio.write', {pin: pin, value: +(!this.pins[pin].on)});
|
||||||
|
this.refresh();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted: function() {
|
||||||
|
this.refresh();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
'camera.pi': 'fab fa-raspberry-pi',
|
'camera.pi': 'fab fa-raspberry-pi',
|
||||||
'camera.ir.mlx90640': 'fas fa-sun',
|
'camera.ir.mlx90640': 'fas fa-sun',
|
||||||
'execute': 'fas fa-play',
|
'execute': 'fas fa-play',
|
||||||
|
'gpio': 'fas fa-plug',
|
||||||
|
'gpio.zeroborg': 'fas fa-robot',
|
||||||
'light.hue': 'fa fa-lightbulb',
|
'light.hue': 'fa fa-lightbulb',
|
||||||
'media.mplayer': 'fa fa-film',
|
'media.mplayer': 'fa fa-film',
|
||||||
'media.mpv': 'fa fa-film',
|
'media.mpv': 'fa fa-film',
|
||||||
|
|
21
platypush/backend/http/templates/plugins/gpio/index.html
Normal file
21
platypush/backend/http/templates/plugins/gpio/index.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<script type="text/x-template" id="tmpl-gpio">
|
||||||
|
<div class="gpio-container">
|
||||||
|
<div class="refresh pull-right">
|
||||||
|
<button class="btn btn-default btn-refresh" title="Refresh">
|
||||||
|
<i class="fa fa-retweet">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pins">
|
||||||
|
<div class="pin"
|
||||||
|
v-for="(pin, number) in pins"
|
||||||
|
:key="number">
|
||||||
|
<div class="col-10 name" v-text="pin.name || number"></div>
|
||||||
|
<div class="col-2 toggle pull-right">
|
||||||
|
<toggle-switch :value="pin.on" @toggled="toggle(number)"></toggle-switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
.. moduleauthor:: Fabio Manganiello <blacklight86@gmail.com>
|
.. moduleauthor:: Fabio Manganiello <blacklight86@gmail.com>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import threading
|
||||||
from typing import Any, Optional, Dict, Union
|
from typing import Any, Optional, Dict, Union
|
||||||
|
|
||||||
from platypush.plugins import Plugin, action
|
from platypush.plugins import Plugin, action
|
||||||
|
@ -34,10 +35,23 @@ class GpioPlugin(Plugin):
|
||||||
|
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.mode = self._get_mode(mode)
|
self.mode = self._get_mode(mode)
|
||||||
|
self._initialized = False
|
||||||
|
self._init_lock = threading.RLock()
|
||||||
|
self._initialized_pins = {}
|
||||||
self.pins_by_name = pins if pins else {}
|
self.pins_by_name = pins if pins else {}
|
||||||
self.pins_by_number = {number: name
|
self.pins_by_number = {number: name
|
||||||
for (name, number) in self.pins_by_name.items()}
|
for (name, number) in self.pins_by_name.items()}
|
||||||
|
|
||||||
|
def _init_board(self):
|
||||||
|
import RPi.GPIO as gpio
|
||||||
|
|
||||||
|
with self._init_lock:
|
||||||
|
if self._initialized:
|
||||||
|
return
|
||||||
|
|
||||||
|
gpio.setmode(self.mode)
|
||||||
|
self._initialized = True
|
||||||
|
|
||||||
def _get_pin_number(self, pin):
|
def _get_pin_number(self, pin):
|
||||||
try:
|
try:
|
||||||
pin = int(str(pin))
|
pin = int(str(pin))
|
||||||
|
@ -58,15 +72,13 @@ class GpioPlugin(Plugin):
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def write(self, pin: Union[int, str], value: Union[int, bool],
|
def write(self, pin: Union[int, str], value: Union[int, bool],
|
||||||
name: Optional[str] = None, mode: Optional[str] = None) -> Dict[str, Any]:
|
name: Optional[str] = None) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Write a byte value to a pin.
|
Write a byte value to a pin.
|
||||||
|
|
||||||
:param pin: PIN number or configured name
|
:param pin: PIN number or configured name
|
||||||
:param name: Optional name for the written value (e.g. "temperature" or "humidity")
|
:param name: Optional name for the written value (e.g. "temperature" or "humidity")
|
||||||
:param value: Value to write
|
:param value: Value to write
|
||||||
:param mode: If a PIN number is specified then you can override the default 'mode'
|
|
||||||
default parameter
|
|
||||||
|
|
||||||
Response::
|
Response::
|
||||||
|
|
||||||
|
@ -80,10 +92,14 @@ class GpioPlugin(Plugin):
|
||||||
|
|
||||||
import RPi.GPIO as gpio
|
import RPi.GPIO as gpio
|
||||||
|
|
||||||
|
self._init_board()
|
||||||
name = name or pin
|
name = name or pin
|
||||||
pin = self._get_pin_number(pin)
|
pin = self._get_pin_number(pin)
|
||||||
mode = self._get_mode(mode) if mode else self.mode
|
|
||||||
gpio.setmode(mode)
|
if pin not in self._initialized_pins or self._initialized_pins[pin] != gpio.OUT:
|
||||||
|
gpio.setup(pin, gpio.OUT)
|
||||||
|
self._initialized_pins[pin] = gpio.OUT
|
||||||
|
|
||||||
gpio.setup(pin, gpio.OUT)
|
gpio.setup(pin, gpio.OUT)
|
||||||
gpio.output(pin, value)
|
gpio.output(pin, value)
|
||||||
|
|
||||||
|
@ -95,15 +111,12 @@ class GpioPlugin(Plugin):
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def read(self, pin: Union[int, str], name: Optional[str] = None,
|
def read(self, pin: Union[int, str], name: Optional[str] = None) -> Dict[str, Any]:
|
||||||
mode: Optional[str] = None) -> Dict[str, Any]:
|
|
||||||
"""
|
"""
|
||||||
Reads a value from a PIN.
|
Reads a value from a PIN.
|
||||||
|
|
||||||
:param pin: PIN number or configured name.
|
:param pin: PIN number or configured name.
|
||||||
:param name: Optional name for the read value (e.g. "temperature" or "humidity")
|
:param name: Optional name for the read value (e.g. "temperature" or "humidity")
|
||||||
:param mode: If a PIN number is specified then you can override the default 'mode'
|
|
||||||
default parameter
|
|
||||||
|
|
||||||
Response::
|
Response::
|
||||||
|
|
||||||
|
@ -117,10 +130,14 @@ class GpioPlugin(Plugin):
|
||||||
|
|
||||||
import RPi.GPIO as gpio
|
import RPi.GPIO as gpio
|
||||||
|
|
||||||
|
self._init_board()
|
||||||
name = name or pin
|
name = name or pin
|
||||||
pin = self._get_pin_number(pin)
|
pin = self._get_pin_number(pin)
|
||||||
gpio.setmode(gpio.BCM)
|
|
||||||
gpio.setup(pin, gpio.IN)
|
if pin not in self._initialized_pins:
|
||||||
|
gpio.setup(pin, gpio.IN)
|
||||||
|
self._initialized_pins[pin] = gpio.IN
|
||||||
|
|
||||||
val = gpio.input(pin)
|
val = gpio.input(pin)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -154,8 +171,13 @@ class GpioPlugin(Plugin):
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
|
"""
|
||||||
|
Cleanup the state of the GPIO and resets PIN values.
|
||||||
|
"""
|
||||||
import RPi.GPIO as gpio
|
import RPi.GPIO as gpio
|
||||||
gpio.cleanup()
|
gpio.cleanup()
|
||||||
|
self._initialized_pins = {}
|
||||||
|
self._initialized = False
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
Loading…
Reference in a new issue