whaleygeek / pyenergenie

A python interface to the Energenie line of products
MIT License
81 stars 51 forks source link

Looking for help with motion sensors- not necessarily an issue #97

Closed sblakegit closed 6 years ago

sblakegit commented 6 years ago

Hi, I have a few of the motion sensors and the Rpi board setup. I have explored control_any_auto.py and have hacked a copy of the setup file just to report the status of the motion sensors included below.

I find that when motion is detected it never resets. I was wondering if there was a way of elegantly monitoring the motion sensor so that i can MQTT it into node-RED. any help would be appreciated. steve


import time import energenie

if name == "main": energenie.init() try: while True: energenie.loop() # allow receive processing print('-' * 80) names = energenie.registry.names() for name in names: device = energenie.registry.get(name) readings = device.get_readings_summary() print("%s %s" % (name, readings)) finally: energenie.finished()

whaleygeek commented 6 years ago

Hi,

It is possible that the MIHO032 motion sensor only sends a message on switch activation (which sets the switch_state to True) but never sends a reset.

An elegant way to do this would be, once you have processed the readings, set the flag to False like this:

device.readings.switch_state = False

You could add this into your test script, or you could add it into the device class, making sure that the caller reads the readings first then they get reset. However, the get_readings_summary() is in the base class Device.

You could add a get_readings_summary to the MIHO032 class that calls the parent get_readings_summary, then sets the switch state to false like this, in the Devices.py file:

def get_readings_summary(self): # add to the Device class
  r = MiHomeDevice.get_readings_summary(self)
  self.readings.switch_state = False
  return r
sblakegit commented 6 years ago

David, Mod to Devices.py works a treat.

If i have named my sensor motion1 is there a way of accessing it like motion1.readings.switch_state e.g. if (motion1.readings.switch_state == True): Print "motion1: True" i would then attempt to pipe the output into MQTT.

I tried this: loaded registry from file REGISTERED DEVICES: motion1 -> MIHO032(0x805) motion2 -> MIHO032(0x803) ROUTES: Traceback (most recent call last): Traceback (most recent call last): File "./steve10.py", line 36, in if(motion1.readings.switch_state == False): print (False) NameError: name 'motion1' is not defined

my Python is pretty poor. Steve

whaleygeek commented 6 years ago

Hi Steve,

Great, glad it works!

Providing your device is in the registry, you can auto-load the registry to similarly named global variables in your main script. Each auto-created global variable is then the instance of that specific device with all the correct address details remembered, so you can access it's methods directly.

See: https://github.com/whaleygeek/pyenergenie/blob/master/src/control_any_auto.py for an example

whaleygeek commented 6 years ago

If you don't want to use the registry at all, you can create your device variable manually, providing you know it's type and address.

For an example of that, see: https://github.com/whaleygeek/pyenergenie/blob/master/src/control_any_noreg.py

In that specific example, socket 6 is a MiHome device and it's class and address is known.

Don't forget to call energenie.loop() in your main loop though, so that incoming radio messages are processed and routed automatically to your motion sensor object.

sblakegit commented 6 years ago

David, still pulling a bit of a bank. I have tried the manual version ++++++++++++++ _PIR1 = energenie.Devices.MIHO032(0x805) readings = PIR1.get_readingssummary() print("%s %s" % (PIR1, readings)) +++++++++++++ all seems to work.

but when i try to access the switch_state - _if(PIR1.readings.switchstate == True): print (True)

I get: No route to an object, for device:(4, 12, 2053) message from unknown device:(4, 12, 2053)

any ideas? steve

sblakegit commented 6 years ago

David,

I think i got it to work.

import time
import energenie
import sys
import paho.mqtt.publish as publish
if __name__ == "__main__":
        energenie.init()
        try:
                while True:
                        energenie.loop() # allow receive processing
                        names = energenie.registry.names()
                        for name in names:
                                device = energenie.registry.get(name)
                                readings = device.get_readings_summary()
                                if (device.readings.switch_state == True): publish.single("pir", "%s %s" % (name, readings))
                                device.readings.switch_state = False
                        time.sleep(.5)
        finally:
                energenie.finished()

I think the problem i am having relates to where i start the program.

sudo /home/pi/pyenergenie-master/src/steve.py = problematic cd /pyenergenie-master/src and run sudo ./steve.py = ok

I have it working in node-red.

whaleygeek commented 6 years ago

It's probably because it tries to load the registry file from the current directory. The registry is cached in memory and a Registry.Router object then consults that RAM copy to find the destination object that matches that address/type. If the registry data file cannot be found when your script starts, it fails silently but then there are no objects constructed and nothing will accept that incoming message. Hence that error message.

Put a registry.list() call in your code to confirm what it has or has not loaded for each of those executable paths. Perhaps move your registry.kvs file into whatever the current directory is when the shell runs that command.

whaleygeek commented 6 years ago

Great news it works in Node Red now!!!

sblakegit commented 6 years ago

David,

got past it - startup script line: cd /home/pi/pyenergenie-master/src/ && sudo ./steve.py thanks for all your help.

steve