Skip to content

Commit 16a1bab

Browse files
authored
Merge pull request #17 from myDevicesIoT/feature/restore-actuator-state
Feature/restore actuator state
2 parents 8b2890b + 9cb81b4 commit 16a1bab

File tree

4 files changed

+47
-20
lines changed

4 files changed

+47
-20
lines changed

myDevices/devices/digital/gpio.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
class NativeGPIO(Singleton, GPIOPort):
3838
IN = 0
3939
OUT = 1
40+
OUT_LOW = 2
41+
OUT_HIGH = 3
4042

4143
ASUS_GPIO = 44
4244

@@ -295,11 +297,9 @@ def __setFunction__(self, channel, value):
295297
self.checkDigitalChannelExported(channel)
296298
self.checkPostingFunctionAllowed()
297299
try:
298-
if value == self.IN:
299-
value = 'in'
300-
else:
301-
value = 'out'
302-
try:
300+
value_dict = {self.IN: 'in', self.OUT: 'out', self.OUT_LOW: 'low', self.OUT_HIGH: 'high'}
301+
value = value_dict[value]
302+
try:
303303
self.functionFile[channel].write(value)
304304
self.functionFile[channel].seek(0)
305305
except:

myDevices/devices/digital/helper.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,17 @@ def __str__(self):
6363
return "MotionSensor"
6464

6565
class DigitalActuator(DigitalSensor):
66-
def __init__(self, gpio, channel, invert=False):
66+
def __init__(self, gpio, channel, invert=False, last_state=None):
6767
DigitalSensor.__init__(self, gpio, channel, invert)
68-
self.gpio.setFunction(self.channel, GPIO.OUT)
68+
function = GPIO.OUT
69+
if gpio == 'GPIO' and last_state is not None:
70+
if self.invert:
71+
last_state = int(not last_state)
72+
if last_state == 1:
73+
function = GPIO.OUT_HIGH
74+
elif last_state == 0:
75+
function = GPIO.OUT_LOW
76+
self.gpio.setFunction(self.channel, function)
6977

7078
def __str__(self):
7179
return "DigitalActuator"
@@ -82,30 +90,29 @@ def write(self, value):
8290
return self.read()
8391

8492
class LightSwitch(DigitalActuator):
85-
def __init__(self, gpio, channel, invert=False):
86-
DigitalActuator.__init__(self, gpio, channel, invert)
93+
def __init__(self, gpio, channel, invert=False, last_state=None):
94+
DigitalActuator.__init__(self, gpio, channel, invert, last_state)
8795

8896
def __str__(self):
8997
return "LightSwitch"
9098

9199
class MotorSwitch(DigitalActuator):
92-
def __init__(self, gpio, channel, invert=False):
93-
DigitalActuator.__init__(self, gpio, channel, invert)
100+
def __init__(self, gpio, channel, invert=False, last_state=None):
101+
DigitalActuator.__init__(self, gpio, channel, invert, last_state)
94102

95103
def __str__(self):
96104
return "MotorSwitch"
97105

98106
class RelaySwitch(DigitalActuator):
99-
def __init__(self, gpio, channel, invert=False):
100-
DigitalActuator.__init__(self, gpio, channel, invert)
107+
def __init__(self, gpio, channel, invert=False, last_state=None):
108+
DigitalActuator.__init__(self, gpio, channel, invert, last_state)
101109

102110
def __str__(self):
103111
return "RelaySwitch"
104112

105113
class ValveSwitch(DigitalActuator):
106-
def __init__(self, gpio, channel, invert=False):
107-
DigitalActuator.__init__(self, gpio, channel, invert)
114+
def __init__(self, gpio, channel, invert=False, last_state=None):
115+
DigitalActuator.__init__(self, gpio, channel, invert, last_state)
108116

109117
def __str__(self):
110118
return "ValveSwitch"
111-

myDevices/devices/manager.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def findDeviceClass(name):
5858
return getattr(module, name)
5959
return None
6060

61-
def saveDevice(name, install_date):
61+
def saveDevice(name, install_date=None):
6262
with mutex:
6363
logger.debug('saveDevice: ' + str(name))
6464
if name not in DEVICES:
@@ -67,7 +67,8 @@ def saveDevice(name, install_date):
6767
if DEVICES[name]['origin'] == 'manual':
6868
return
6969
DYNAMIC_DEVICES[name] = DEVICES[name]
70-
DEVICES[name]['install_date'] = install_date
70+
if install_date:
71+
DEVICES[name]['install_date'] = install_date
7172
json_devices = getJSON(DYNAMIC_DEVICES)
7273
with open(DEVICES_JSON_FILE, 'w') as outfile:
7374
outfile.write(json_devices)
@@ -138,6 +139,19 @@ def updateDevice(name, json):
138139

139140
return (c, d, t)
140141

142+
def updateDeviceState(name, value):
143+
with mutex:
144+
try:
145+
if not name in DEVICES:
146+
return
147+
device = DEVICES[name]
148+
if 'last_state' not in device['args'] or device['args']['last_state'] != value:
149+
logger.info('Saving state {} for device {}'.format(value, name))
150+
device['args'].update({'last_state': value})
151+
saveDevice(name)
152+
except:
153+
pass
154+
141155
def addDevice(name, device, description, args, origin):
142156
with mutex:
143157
if name in DEVICES:

myDevices/sensors/sensors.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,10 @@ def SensorsInfo(self):
181181
channel = '{}:{}'.format(device['name'], device_type.lower())
182182
else:
183183
channel = device['name']
184-
cayennemqtt.DataChannel.add(sensors_info, cayennemqtt.DEV_SENSOR, channel, value=self.CallDeviceFunction(func), name=display_name, **sensor_type['data_args'])
184+
value = self.CallDeviceFunction(func)
185+
cayennemqtt.DataChannel.add(sensors_info, cayennemqtt.DEV_SENSOR, channel, value=value, name=display_name, **sensor_type['data_args'])
186+
if 'DigitalActuator' == device_type and value in (0, 1):
187+
manager.updateDeviceState(device['name'], value)
185188
except:
186189
exception('Failed to get sensor data: {} {}'.format(device_type, device['name']))
187190
# else:
@@ -368,13 +371,16 @@ def SensorCommand(self, command, sensorId, channel, value):
368371
info('Sensor not found')
369372
return result
370373
if command in commands:
371-
info('Sensor found: {}'.format(instance.DEVICES[sensorId]))
374+
device = instance.DEVICES[sensorId]
375+
info('Sensor found: {}'.format(device))
372376
func = getattr(sensor, commands[command]['function'])
373377
value = commands[command]['value_type'](value)
374378
if channel:
375379
result = self.CallDeviceFunction(func, int(channel), value)
376380
else:
377381
result = self.CallDeviceFunction(func, value)
382+
if 'DigitalActuator' in device['type']:
383+
manager.updateDeviceState(sensorId, value)
378384
return result
379385
warn('Command not implemented: {}'.format(command))
380386
return result

0 commit comments

Comments
 (0)