-
Notifications
You must be signed in to change notification settings - Fork 7
/
mycodo_custom_output_remote_gpio_pwm.py
151 lines (127 loc) · 4.93 KB
/
mycodo_custom_output_remote_gpio_pwm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# coding=utf-8
#
# mycodo_custom_output_remote_gpio_pwm.py - PWM Remote GPIO Output
#
from flask_babel import lazy_gettext
from mycodo.outputs.base_output import AbstractOutput
from mycodo.utils.influx import add_measurements_influxdb
# Measurements
measurements_dict = {
0: {
'measurement': 'duty_cycle',
'unit': 'percent'
}
}
channels_dict = {
0: {
'types': ['pwm'],
'measurements': [0]
}
}
# Output information
OUTPUT_INFORMATION = {
'output_name_unique': 'remote_gpio_pwm_1_1',
'output_name': "{} v1.1".format(lazy_gettext('PWM Remote GPIO')),
'output_library': 'gpiozero',
'measurements_dict': measurements_dict,
'channels_dict': channels_dict,
'on_state_internally_handled': False,
'output_types': ['pwm'],
'message':
'NOTE: This is a work in progress.'
'<br>This output was developed to be able to operate from Mycodo installed on a Raspberry Pi '
'or from Mycodo running within a docker container on a PC and control GPIO pins of a remote host, '
'be it an IP address or a Pi Zero connected via USB '
'(<a href="https://github.com/gpiozero/gpiozero" target="_blank">more info</a>). Set up '
'dependencies manually, then restart the Mycodo daemon, before using the output. '
'The method of installing dependencies may differ depending on the host device and operating '
'system and the client device (see '
'<a href="https://gpiozero.readthedocs.io/en/stable/installing.html" target="_blank">this</a> and '
'<a href="https://gpiozero.readthedocs.io/en/stable/pi_zero_otg.html" target="_blank">this</a>).',
'options_enabled': [
'gpio_pin',
'pwm_frequency',
'pwm_invert_signal',
'pwm_state_startup',
'pwm_state_shutdown',
'trigger_functions_startup',
'button_send_duty_cycle'
],
'options_disabled': [
'interface'
],
'dependencies_module': [
('pip-pypi', 'gpiozero', 'gpiozero'),
],
'interfaces': ['GPIO'],
# 'custom_options_message': 'This is a message displayed for custom options.',
'custom_options': [
{
'id': 'host',
'type': 'text',
'default_value': '192.168.0.10',
'name': lazy_gettext('Host'),
'phrase': lazy_gettext('The host to connect and control a remote GPIO pin')
}
],
}
class OutputModule(AbstractOutput):
"""
An output support class that operates an output
"""
def __init__(self, output, testing=False):
super(OutputModule, self).__init__(output, testing=testing, name=__name__)
self.output_setup = None
self.gpio_pin = None
self.pwm_hertz = None
self.output_device = None
self.host = None
self.setup_custom_options(
OUTPUT_INFORMATION['custom_options'], output)
if not testing:
self.initialize_output()
def initialize_output(self):
self.gpio_pin = self.output.pin
self.pwm_hertz = self.output.pwm_hertz
def output_switch(self, state, output_type=None, amount=None, duty_cycle=None):
"""Switch the output on or off"""
measure_dict = measurements_dict.copy()
if state == 'on' and duty_cycle != 0:
self.output_device.value = duty_cycle / 100.0
self.logger.debug("Output turned on")
elif state == 'off' or duty_cycle == 0:
self.output_device.value = 0
self.logger.debug("Output turned off")
measure_dict[0]['value'] = duty_cycle
add_measurements_influxdb(self.output_unique_id, measure_dict)
def is_on(self):
"""Return the state of the output"""
if self.is_setup():
try:
return self.output_device.value * 100.0
except Exception as e:
self.logger.error(
"Status check error: {}".format(e))
def is_setup(self):
"""Return whether the output has successfully been set up"""
return self.output_setup
def setup_output(self):
"""Code executed when Mycodo starts up to initialize the output"""
if not self.gpio_pin or not self.host:
self.logger.error("Need GPIO pin and host to set up remote GPIO")
return
try:
from gpiozero.pins.pigpio import PiGPIOFactory
from gpiozero import PWMOutputDevice
factory = PiGPIOFactory(host=self.host)
self.logger.debug("Setting up remote GPIO pin {pin} on host {host}".format(
pin=self.gpio_pin, host=self.host))
self.output_device = PWMOutputDevice(
pin=self.gpio_pin,
frequency=self.pwm_hertz,
pin_factory=factory)
self.logger.debug("Output set up")
self.output_setup = True
except Exception:
self.logger.exception("Output Setup")
self.output_setup = False