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"
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