first commit
This commit is contained in:
BIN
python/.AppleDouble/.Parent
Normal file
BIN
python/.AppleDouble/.Parent
Normal file
Binary file not shown.
BIN
python/.AppleDouble/domoticz.py
Normal file
BIN
python/.AppleDouble/domoticz.py
Normal file
Binary file not shown.
BIN
python/.AppleDouble/googlepubsub.py
Normal file
BIN
python/.AppleDouble/googlepubsub.py
Normal file
Binary file not shown.
BIN
python/.AppleDouble/reloader.py
Normal file
BIN
python/.AppleDouble/reloader.py
Normal file
Binary file not shown.
BIN
python/.AppleDouble/script_device_PIRsmarter.py
Normal file
BIN
python/.AppleDouble/script_device_PIRsmarter.py
Normal file
Binary file not shown.
158
python/domoticz.py
Normal file
158
python/domoticz.py
Normal file
@@ -0,0 +1,158 @@
|
||||
"""
|
||||
Helper module for python+domoticz
|
||||
Every script_device_*.py script has the following variables
|
||||
* changed_device: the current device that changed (object of Device)
|
||||
* changed_device_name: name of current device (same as changed_device.name)
|
||||
* is_daytime: boolean, true when it is is daytime
|
||||
* is_nighttime: same for the night
|
||||
* sunrise_in_minutes: integer
|
||||
* sunset_in_minutes: integer
|
||||
* user_variables: dictionary from string to value
|
||||
|
||||
For more advanced project, you may want to use modules.
|
||||
say you have a file heating.py
|
||||
You can do
|
||||
import heating
|
||||
heating.check_heating()
|
||||
|
||||
But heating has a different scope, and won't have access to these variables.
|
||||
By importing this module, you can have access to them in a standard way
|
||||
import domoticz
|
||||
domoticz.changed_device
|
||||
|
||||
And you also have access to more:
|
||||
* same as in the device scripts (changed_device ... user_variables)
|
||||
* devices: dictionary from string to Device
|
||||
|
||||
|
||||
"""
|
||||
#try:
|
||||
import DomoticzEvents as domoticz_ #
|
||||
#except:
|
||||
# pass
|
||||
|
||||
import reloader
|
||||
import datetime
|
||||
import re
|
||||
|
||||
# Enable plugins to do:
|
||||
# from Domoticz import Devices, Images, Parameters, Settings
|
||||
try:
|
||||
Devices
|
||||
except NameError:
|
||||
Devices = {}
|
||||
domoticz_.Log(1, "Devices was not created by Domoticz C++ code")
|
||||
|
||||
try:
|
||||
Images
|
||||
except NameError:
|
||||
Images = {}
|
||||
domoticz_.Log(1, "Images was not created by Domoticz C++ code")
|
||||
|
||||
try:
|
||||
Parameters
|
||||
except NameError:
|
||||
Parameters = {}
|
||||
domoticz_.Log(1, "Parameters was not created by Domoticz C++ code")
|
||||
|
||||
try:
|
||||
Settings
|
||||
except NameError:
|
||||
Settings = {}
|
||||
domoticz_.Log(1, "Settings was not created by Domoticz C++ code")
|
||||
|
||||
#def _log(type, text): # 'virtual' function, will be modified to call
|
||||
# pass
|
||||
|
||||
def log(*args):
|
||||
domoticz_.Log(0, " ".join([str(k) for k in args]))
|
||||
|
||||
def error(*args):
|
||||
domoticz_.Log(1, " ".join([str(k) for k in args]))
|
||||
|
||||
reloader.auto_reload(__name__)
|
||||
|
||||
# this will be filled in by the c++ part
|
||||
devices = {}
|
||||
device = None
|
||||
|
||||
|
||||
testing = False
|
||||
commands = []
|
||||
|
||||
event_system = None # will be filled in by domoticz
|
||||
def command(name, action, file):
|
||||
if testing:
|
||||
commands.append((name, action))
|
||||
else:
|
||||
event_system.command(name, action, file)
|
||||
|
||||
def process_commands():
|
||||
for name, action in commands:
|
||||
device = devices[name]
|
||||
if action == "On":
|
||||
device.n_value = 1
|
||||
print ("\tsetting %s On" % name)
|
||||
elif action == "Off":
|
||||
device.n_value = 0
|
||||
print ("\tsetting %s On" % name)
|
||||
else:
|
||||
print ("unknown command", name, action)
|
||||
del commands[:]
|
||||
|
||||
class Device(object):
|
||||
def __init__(self, id, name, type, sub_type, switch_type, n_value, n_value_string, s_value, last_update):
|
||||
devices[name] = self
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.sub_type = sub_type
|
||||
self.switch_type = switch_type
|
||||
self.n_value = n_value
|
||||
self.n_value_string = n_value_string
|
||||
self.s_value = s_value
|
||||
self.last_update_string = last_update
|
||||
# from http://stackoverflow.com/questions/127803/how-to-parse-iso-formatted-date-in-python
|
||||
if self.last_update_string:
|
||||
# from http://stackoverflow.com/questions/127803/how-to-parse-iso-formatted-date-in-python
|
||||
try:
|
||||
self.last_update = datetime.datetime(*map(int, re.split('[^\d]', self.last_update_string)[:]))
|
||||
if str(self.last_update_string) != str(self.last_update):
|
||||
log("Error parsing date:", self.last_update_string, " parsed as", str(self.last_update))
|
||||
except:
|
||||
log("Exception while parsing date:", self.last_update_string)
|
||||
else:
|
||||
self.last_update = None
|
||||
|
||||
def __str__(self):
|
||||
return "Device(%s, %s, %s, %s)" % (self.id, self.name, self.n_value, self.s_value)
|
||||
def __repr__(self):
|
||||
return "Device(%s, %s, %s, %s)" % (self.id, self.name, self.n_value, self.s_value)
|
||||
|
||||
def last_update_was_ago(self, **kwargs):
|
||||
"""Arguments can be: days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]"""
|
||||
return self.last_update + datetime.deltatime(**kwargs) < datetime.datetime.now()
|
||||
|
||||
def is_on(self):
|
||||
return self.n_value == 1
|
||||
|
||||
def is_off(self):
|
||||
return self.n_value == 0
|
||||
|
||||
def on(self, after=None, reflect=False):
|
||||
if self.is_off() or after is not None:
|
||||
self._command("On" , after=after)
|
||||
if reflect:
|
||||
self.n_value = 1
|
||||
|
||||
def off(self, after=None, reflect=False):
|
||||
if self.is_on() or after is not None:
|
||||
self._command("Off" , after=after)
|
||||
if reflect:
|
||||
self.n_value = 0
|
||||
|
||||
def _command(self, action, after=None):
|
||||
if after is not None:
|
||||
command(self.name, "%s AFTER %d" % (action, after), __file__)
|
||||
else:
|
||||
command(self.name, action, __file__)
|
||||
BIN
python/domoticz.pyc
Normal file
BIN
python/domoticz.pyc
Normal file
Binary file not shown.
56
python/googlepubsub.py
Normal file
56
python/googlepubsub.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import httplib2
|
||||
import argparse
|
||||
import base64
|
||||
import csv
|
||||
import datetime
|
||||
import random
|
||||
import sys
|
||||
import time
|
||||
import base64
|
||||
import domoticz
|
||||
|
||||
# This script connects Domoticz with Google Cloud PubSub API
|
||||
# To make it works :
|
||||
# 1 - Install the Google API Client Python Library : pip install --upgrade google-api-python-client (or see https://cloud.google.com/pubsub/libraries)
|
||||
# 2 - Activate the Google Cloud PubSub API in the Google Cloud Console
|
||||
# 3 - Generate a Service account key in the Google Cloud Console and download the private key in JSON format
|
||||
# 4 - Transfer the json key into the domoticz install dir
|
||||
# 5 - Set the ENV variable GOOGLE_APPLICATION_CREDENTIALS to the path of your Service account key
|
||||
# 6 - Create a topic in the "PubSub" Google Cloud Console
|
||||
# 7 - Modify the variable PUBSUB_TOPICNAME below with the topic name
|
||||
|
||||
# Required library to make pubsub google api working fine
|
||||
from apiclient import discovery
|
||||
from oauth2client import client as oauth2client
|
||||
|
||||
# Required privileges
|
||||
PUBSUB_SCOPES = ['https://www.googleapis.com/auth/pubsub']
|
||||
|
||||
# Topic name defined in the Google Cloud PubSub Console
|
||||
PUBSUB_TOPICNAME = 'projects/affable-enigma-136123/topics/domoticz'
|
||||
|
||||
def create_pubsub_client(http=None):
|
||||
credentials = oauth2client.GoogleCredentials.get_application_default()
|
||||
if credentials.create_scoped_required():
|
||||
credentials = credentials.create_scoped(PUBSUB_SCOPES)
|
||||
if not http:
|
||||
http = httplib2.Http()
|
||||
credentials.authorize(http)
|
||||
|
||||
return discovery.build('pubsub', 'v1', http=http)
|
||||
|
||||
def publish_message(client,topicname,message):
|
||||
message1 = base64.b64encode(message)
|
||||
body = {
|
||||
'messages': [
|
||||
{'data': message1}
|
||||
]
|
||||
}
|
||||
resp = client.projects().topics().publish(topic=topicname, body=body).execute()
|
||||
|
||||
def main(argv):
|
||||
client = create_pubsub_client()
|
||||
publish_message(client,PUBSUB_TOPICNAME,data) # noqa: F821
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
43
python/reloader.py
Normal file
43
python/reloader.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""
|
||||
Python only loads modules once, so domoticz will only load a module the first time it is needed. Code changes will not be reflected, only after a restart of domoticz. Note that doesn't hold for scripts, they always get reloaded.
|
||||
To have your module reloaded, you can enter the following code in it.
|
||||
import reloader
|
||||
reloader.auto_reload(__name__)
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
reload # Python 2
|
||||
except NameError:
|
||||
from importlib import reload # Python 3
|
||||
|
||||
|
||||
# mark module as a module to reload
|
||||
def auto_reload(module_name):
|
||||
import domoticz as dz
|
||||
path = _py_source(sys.modules[module_name])
|
||||
_module_mtimes[module_name] = os.path.getmtime(path)
|
||||
|
||||
|
||||
# below this is internal stuff
|
||||
|
||||
# maps from module name to modification time (mtime)
|
||||
_module_mtimes = {}
|
||||
|
||||
# convert module to python source filename
|
||||
def _py_source(module):
|
||||
path = module.__file__
|
||||
if path[:-1].endswith("py"):
|
||||
path = path[:-1]
|
||||
return path
|
||||
|
||||
def _check_reload():
|
||||
for module_name, loaded_mtime in _module_mtimes.items():
|
||||
path = _py_source(sys.modules[module_name])
|
||||
# if file is changed, the current mtime is greater
|
||||
if loaded_mtime < os.path.getmtime(path):
|
||||
reload(sys.modules[module_name]) # and reload
|
||||
else:
|
||||
pass
|
||||
BIN
python/reloader.pyc
Normal file
BIN
python/reloader.pyc
Normal file
Binary file not shown.
18
python/script_device_demo.py
Normal file
18
python/script_device_demo.py
Normal file
@@ -0,0 +1,18 @@
|
||||
import DomoticzEvents as DE
|
||||
|
||||
DE.Log("Python: Changed: " + DE.changed_device.Describe())
|
||||
|
||||
if DE.changed_device_name == "Test":
|
||||
if DE.Devices["Test_Target"].n_value_string == "On":
|
||||
DE.Command("Test_Target", "Off")
|
||||
|
||||
if DE.Devices["Test_Target"].n_value_string == "Off":
|
||||
DE.Command("Test_Target", "On")
|
||||
|
||||
DE.Log("Python: Number of user_variables: " + str(len(DE.user_variables)))
|
||||
|
||||
# All user_variables are treated as strings, convert as necessary
|
||||
for key, value in DE.user_variables.items():
|
||||
DE.Log("Python: User-variable '{0}' has value: {1}".format(key, value))
|
||||
|
||||
# Description of Device_object should go here...
|
||||
11
python/script_time_demo.py
Normal file
11
python/script_time_demo.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import DomoticzEvents as DE
|
||||
|
||||
if DE.is_daytime:
|
||||
DE.Log("Python: It's daytime!")
|
||||
|
||||
if DE.is_nighttime:
|
||||
DE.Log("Python: It's nighttime!")
|
||||
|
||||
DE.Log("Python: Sunrise in minutes: " + str(DE.sunrise_in_minutes))
|
||||
DE.Log("Python: Sunset in minutes: " + str(DE.sunset_in_minutes))
|
||||
DE.Log("Python: Minutes since midnight: " + str(DE.minutes_since_midnight))
|
||||
Reference in New Issue
Block a user