piBeacon 17: How to use mysensors .py and myoutput.py

Posted on
Fri May 11, 2018 11:19 am
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

piBeacon 17: How to use mysensors .py and myoutput.py

1. mysensor.py will be started by master.py if there is a device defined . It will then read the device props (every 2 minutes or so) you set in indigo (freeParameter)
then it will loop and will send the results of YOUR coding to indigo and indigo will fill INPUT_0 ..INPUT_9 states with your input

2. myprogram.py is is just a skeleton and it is all up to you how to use it. There are some snippets on how to read a sensor

3. myOutput.py purpose: it will receive commands from indigo and then does action YOU have to program into the code



[b. MYSENSORS.py[/b]
They send data to indigo through method U.sendURL(data). Data contains a json dump like the following
Code: Select all
{"pi":"11","sensors":{"mysensors":{"656107235":{"pi":"11","sensors":{"mysensors":{"656107235":{"INPUT_6":"4","INPUT_7":"5","INPUT_4":"2","INPUT_5":"3","INPUT_2":"0","INPUT_3":"1","INPUT_0":"1526055394.79","INPUT_1":"763027697.397","INPUT_8":"6","INPUT_9":"7"}}},"program":"mysensors","ipAddress":"192.168.1.31","ts":{"tz":"CDT","time":1526055394.802326}}UT_7":"5","INPUT_4":"2","INPUT_5":"3","INPUT_2":"0","INPUT_3":"1","INPUT_0":"1526055394.79","INPUT_1":"763027697.397","INPUT_8":"6","INPUT_9":"7"}}},"program":"mysensors","ipAddress":"192.168.1.31","ts":{"tz":"CDT","time":1526055394.802326}}
then indigo receives that string and puts the info into device states: "INPUT_0" .."INPUT_9"
it contains the key "sensors" the name of the sensor type "mysensors", the indigo id and then data = {"INPUT_6":"4","INPUT ...
you can have multiply "mysensors" devices the will be distinguished through their indigo id

here is a tested version that sends static data back to the plugin. Save as mysensors.py on your RPI:
Code: Select all
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# by Karl Wachs
# may 11 2018
# exampel program to get data and send it to indigo
import  sys
import os
import time
import json
import datetime
import subprocess
import copy

sys.path.append(os.getcwd())
import  piBeaconUtils   as U
import  piBeaconGlobals as G
G.program = "mysensors"


# ===========================================================================
# read params do not change
# ===========================================================================
def readParams():
        global debug, sensorList,freeParameter,sensorRefreshSecs, sensors

        sensorList  = "0"
        oldfreeParameter = copy.copy(freeParameter)
        inp,inRaw = U.doRead()

        U.getGlobalParams(inp)
        if u"debugRPI"          in inp:  G.debug=                    int(inp["debugRPI"]["debugRPImystuff"])
        if "sensors"            in inp:  sensors =                   (inp["sensors"])

        if G.program not in sensors:
            exit()
        sensor = sensors[G.program]
        for id in sensor:
            if "freeParameter"  in sensor[id]:  freeParameter[id] =             sensor[id]["freeParameter"]

        # check if anything new
        if id not in oldfreeParameter or freeParameter[id] != oldfreeParameter[id]:
            startMySensors(freeParameter[id])



# ===========================================================================
# sensor start  adopt to your needs
# ===========================================================================

def startMySensors(parameter):
        try:
            # do your init here

            ## add any init code here for address # addr
            U.toLog(-1, u"starting my sensors " + unicode(parameter) )
        except  Exception, e:
            U.toLog(-1, u"in Line '%s' has error='%s'" % (sys.exc_traceback.tb_lineno, e))
            U.toLog(-1, u"channel used: " + unicode(parameter) )

def getMySensors(parameter):
        try:
            v = ["","","","","","","","","","",]   # set return to empty
            # do your stuff here, this if for testing to something into the data
            x = time.time()  # some dummy data
            v = [str(x), str(x/2), "0", "1", "2", "3", "4", "5", "6", "7"]  ## <-- this is your data to be send back
            return v
        except  Exception, e:
            U.toLog(-1, u"in Line '%s' has error='%s'" % (sys.exc_traceback.tb_lineno, e))
        return ""


# ===========================================================================
# sensor end
# ===========================================================================


# ===========================================================================
# Main, should ok as is
# ===========================================================================


global debug, sensorList, externalSensor,freeParameter,indigoIds, ipAddress, sensors

debug             = 5 # will be overwritten in readParams
nInputs           = 10 # number of input channels 1...10 max

loopCount         = 0  # for loop,  not used could be deleted, but you might need it
sensorRefreshSecs = 10 # will be overwritten in readParams, number of seconds to sleep in each loop
sensorList        = [] # list of sensor, we are looking for "mysensors"
freeParameter     = {}  # store address / parameters we get from indigo in device config of mysensors in readParams

sensor            = G.program
readParams()           # get parameters send from indigo

if U.getIPNumber() > 0:
    print "mysensor  no ip number  exit "
    time.sleep(10)
    exit()

myPID             = str(os.getpid())
U.killOldPgm(myPID, G.program+".py")# kill old instances of myself if they are still running

quick    = False
lastData = {}
loopCount = 0

while True:  # loop for ever
        loopCount +=1
        data={}
        try:
            ### get data
           
            if sensor in sensors:# do mysensor
                data["sensors"]={sensor:{}}
                for id in sensors[sensor]:
                    v = getMySensors(freeParameter[id])
                    if v != "" :
                        data["sensors"][sensor][id] = {}
                        for ii in range(min(nInputs,len(v))):
                            data["sensors"][sensor][id]["INPUT_"+str(ii)]  = v[ii]
            ### send data to plugin
            if loopCount%1 == 0 or quick or lastData != data:
                U.sendURL(data)
            lastData = copy.copy(data)
           
            # make data file for debugging
            U.makeDATfile(G.program, data)

            # check if we should send data now, requested by plugin
            quick = U.checkNowFile(G.program)               

            # make alive file for mast to signal we are still running
            if loopCount %20 ==0:
                U.echoLastAlive(G.program)

        except  Exception, e :
            U.toLog(-1, u"in Line '%s' has error='%s'" % (sys.exc_traceback.tb_lineno, e))

        time.sleep(sensorRefreshSecs) # sleep the requested amount
        readParams()  # check if we have new parameetrs

sys.exit(0)             




MYOUTPUT.py:

To send text do
- indigo/menu/set MYOUTPUT.py parameters
- select RPI and the test string to be send (use ' ' to encapsulate the text, then it will be send as ONE parameter)

OR create an action w piBeacon/Send text to myouput.py. same input, but it offers a delay feature

The program will then print the text , anything else is up to you

Code: Select all
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# by Karl Wachs
# march 2
# this program will be called if indigo plugin sends a myoutput command
##
import json
import sys
import subprocess
import time
import datetime
import os


sys.path.append(os.getcwd())
import  piBeaconUtils   as U
import  piBeaconGlobals as G
G.program = "myoutput"
## ===========================================================================
# utils do not chnage
#  ===========================================================================

def readParams():
    inp,inpRaw = U.doRead()
    if inp == "": return
    try:
            if u"debugRPI"          in inp:  debug=             int(inp["debugRPI"]["debugRPImystuff"])
    except:
        pass

# ===========================================================================
# Main
# ===========================================================================


try:
        readParams()

        myPID = str(os.getpid())
        U.killOldPgm(myPID,"myoutput.py")# kill  old instances of myself if they are still running

        U.toLog(-1, "myoutput  received text :"+unicode(sys.argv))
        print "myoutput  received text :"+unicode(sys.argv)

        # rest is up to you  the text indgo has send is in sys.argv[1] [2] ....
        if len(sys.argv) >1 :
            text = sys.argv[1]

            #eg reboot if you send the reboot command
            if unicode(text).find("reboot") > -1 :
                os.system("reboot")


            # if set gpio high ..
            elif unicode(text).find("gpio 21 high") > -1:
                import RPi.GPIO as GPIO
                GPIO.setmode(GPIO.BCM)
                GPIO.setwarnings(False)
                GPIO.setup(21, GPIO.OUT)
                GPIO.output(21, True)


except  Exception, e:
        U.toLog(-1, u"in Line '%s' has error='%s'" % (sys.exc_traceback.tb_lineno, e))
        print u"in Line '%s' has error='%s'" % (sys.exc_traceback.tb_lineno, e)

exit(0)

Karl

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 3 guests