Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lucid migration #91

Merged
merged 15 commits into from
May 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import os
from configuration import autoremote_configuration

def sendMessage(message, ttl=300, sender='openHAB'):
'''
Sends an autoremote message
'''

# Use GCM Server for delivery
cmd = 'curl -s -G "https://autoremotejoaomgcd.appspot.com/sendmessage" ' \
+ '--data-urlencode "key='+autoremote_configuration['key']+'" ' \
+ '--data-urlencode "password='+autoremote_configuration['password']+'" ' \
+ '--data-urlencode "message='+message+'" ' \
+ '--data-urlencode "sender='+sender+'" ' \
+ '--data-urlencode "ttl='+str(ttl)+'" ' \
+ ' 1>/dev/null 2>&1 &'

os.system(cmd)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
autoremote_configuration = {
'password': 'secret',
'key': 'very-long-key-goes-here',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# -*- coding: utf-8 -*-
"""
python module which can be used to send SMS messages via the Clickatell HTTP/S API
Interface on https://api.clickatell.com/
License
Copyright (c) 2006-2012 Jacques Marneweck. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
This file was originally published at https://github.com/jacques/pyclickatell
2018-07-07 B. Synnerlig added smsEncode() function
"""

import urllib, urllib2

try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO

__author__ = "Jacques Marneweck <[email protected]>, Arne Brodowski <[email protected]>"
__version__ = "0.1.1-alpha"
__copyright__ = "Copyright (c) 2006 Jacques Marneweck, 2008 Arne Brodowski. All rights reserved."
__license__ = "The MIT License"

def smsEncode(my_str):
# Convert to GSM 03.38 character set and URL-encode
utf8Chars=['%','\n',' ','"','&',',','.',u'/',':',';','<','=','>','?',u'¡',u'£','#',u'¥',u'§',u'Ä',u'Å',u'à',u'ä',u'å',u'Æ',u'Ç',u'É',u'è',u'é',u'ì',u'Ñ',u'ñ',u'ò',u'ö',u'Ø',u'Ö',u'Ü',u'ù',u'ü',u'ß',u'\\',u'*',u'\'','(',u')',u'@',u'+',u'$',u'[',u']',u'^',u'{',u'|',u'}',u'~']
gsmChars=['%25','%0D','%20','%22','%26','%2C','%2E','%2F','%3A','%3B','%3C','%3D','%3E','%3F','%A1','%A3','%A4','%A5','%A7','%C4','%C5','%E0','%E4','%E5','%C6','%C7','%C9','%E8','%E9','%EC','%D1','%F1','%F2','%F6','%D8','%D6','%DC','%F9','%FC','%DF','%5C','%2A','%27','%28','%29','%40','%2B','%24','%5B','%5D','%5E','%7B','%7C','%7D','%7E']

for i in range(0,len(gsmChars)):
my_str = my_str.replace(utf8Chars[i],gsmChars[i])
return my_str

def require_auth(func):
"""
decorator to ensure that the Clickatell object is authed before proceeding
"""
def inner(self, *args, **kwargs):
if not self.has_authed:
self.auth()
return func(self, *args, **kwargs)
return inner

class ClickatellError(Exception):
"""
Base class for Clickatell errors
"""

class ClickatellAuthenticationError(ClickatellError):
pass

class Clickatell(object):
"""
Provides a wrapper around the Clickatell HTTP/S API interface
"""

def __init__ (self, username, password, api_id, sender):
"""
Initialise the Clickatell class
Expects:
- username - your Clickatell Central username
- password - your Clickatell Central password
- api_id - your Clickatell Central HTTP API identifier
"""
self.has_authed = False

self.username = username
self.password = password
self.api_id = api_id
self.sender = sender

self.session_id = None


def auth(self, url='https://api.clickatell.com/http/auth'):
"""
Authenticate against the Clickatell API server
"""
post = [
('user', self.username),
('password', self.password),
('api_id', self.api_id),
]

result = self.curl(url, post)

if result[0] == 'OK':
assert (32 == len(result[1]))
self.session_id = result[1]
self.has_authed = True
return True
else:
raise ClickatellAuthenticationError, ': '.join(result)

@require_auth
def getbalance(self, url='https://api.clickatell.com/http/getbalance'):
"""
Get the number of credits remaining at Clickatell
"""
post = [
('session_id', self.session_id),
]

result = self.curl(url, post)
if result[0] == 'Credit':
assert (0 <= result[1])
return result[1]
else:
return False

@require_auth
def getmsgcharge(self, apimsgid, url='https://api.clickatell.com/http/getmsgcharge'):
"""
Get the message charge for a previous sent message
"""
assert (32 == len(apimsgid))
post = [
('session_id', self.session_id),
('apimsgid', apimsgid),
]

result = self.curl(url, post)
result = ' '.join(result).split(' ')

if result[0] == 'apiMsgId':
assert (apimsgid == result[1])
assert (0 <= result[3])
return result[3]
else:
return False

@require_auth
def ping(self, url='https://api.clickatell.com/http/ping'):
"""
Ping the Clickatell API interface to keep the session open
"""
post = [
('session_id', self.session_id),
]

result = self.curl(url, post)

if result[0] == 'OK':
return True
else:
self.has_authed = False
return False

@require_auth
def sendmsg(self, message, url = 'https://api.clickatell.com/http/sendmsg'):
"""
Send a mesage via the Clickatell API server
Takes a message in the following format:

message = {
'to': 'to_msisdn',
'text': 'This is a test message',
}
Return a tuple. The first entry is a boolean indicating if the message
was send successfully, the second entry is an optional message-id.
Example usage::
result, uid = clickatell.sendmsg(message)
if result == True:
print "Message was sent successfully"
print "Clickatell returned %s" % uid
else:
print "Message was not sent"
"""
if not (message.has_key('to') or message.has_key('text')):
raise ClickatellError, "A message must have a 'to' and a 'text' value"

message['text'] = smsEncode(message['text'])

post = [
('session_id', self.session_id),
('from', self.sender),
('to', message['to']),
]
postStr = urllib.urlencode(post)
postStr += '&text='+ message['text']

result = self.curl(url, postStr, False)

if result[0] == 'ID':
assert (result[1])
return (True, result[1])
else:
return (False, None)

@require_auth
def tokenpay(self, voucher, url='https://api.clickatell.com/http/token_pay'):
"""
Redeem a voucher via the Clickatell API interface
"""
assert (16 == len(voucher))
post = [
('session_id', self.session_id),
('token', voucher),
]

result = self.curl(url, post)

if result[0] == 'OK':
return True
else:
return False

def curl(self, url, post, urlEncode=True):
"""
Inteface for sending web requests to the Clickatell API Server
"""
try:
if urlEncode:
data = urllib2.urlopen(url, urllib.urlencode(post))
else:
data = urllib2.urlopen(url, post)
except urllib2.URLError, v:
raise ClickatellError, v

return data.read().split(": ")
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from core.log import logging, LOG_PREFIX
from community.clickatell import Clickatell
from configuration import clickatell_configuration

def sms(message, subscriber='Default'):
'''
Sends an SMS message through ClickaTell gateway.
Example: sms("Hello")
Example: sms("Hello", 'Amanda')
@param param1: SMS Text
@param param2: Subscriber. A numeric phone number or a phonebook name entry (String)
'''
log = logging.getLogger(LOG_PREFIX + ".community.clickatell.sendsms")
phoneNumber = clickatell_configuration['phonebook'].get(subscriber, None)
if phoneNumber is None:
if subscriber.isdigit():
phoneNumber = subscriber
else:
log.warn("Subscriber [{}] wasn't found in the phone book".format(subscriber))
return
gateway = Clickatell(clickatell_configuration['user'], clickatell_configuration['password'], clickatell_configuration['apiid'], clickatell_configuration['sender'])
message = {'to': phoneNumber, 'text': message}
log.info("Sending SMS to: [{}]".format(phoneNumber))
retval, msg = gateway.sendmsg(message)
if retval == True:
log.info("SMS sent: [{}]".format(msg))
else:
log.warn("Error while sending SMS: [{}]".format(retval))
return
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
clickatell_configuration = {
'sender': '49123456789',
'user': 'xxxxxxxxxxxx',
'password': 'xxxxxxxxxxxxxxxxx',
'apiid': 999999999999,
'phonebook': {
'Default': '49123456789',
'Carl': '49987654321',
'Betty': '4911111111',
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'''
This script speaks a random greeting every minute on your Sonos speaker system.
To use this, you should set up astro.py as described here
https://github.com/OH-Jython-Scripters/openhab2-jython/blob/master/Design%20Pattern%20Examples/Time%20of%20Day.
It also assumes that you've set up an openHAB contact items to represent the presence of
persons to be greeted. Each item should belong to the item group "G_Presence_Family".

Finally make sure that you add the contents of the configuration.py.example file
into your own configuration file:
'''
import random

from core.rules import rule
from core.triggers import when
from community.sonos.speak import tts, greeting, PRIO
from core.utils import getItemValue

@rule("Greeting example")
@when("Time cron 0 * * * * ?")
def exampleGreeting(event):
greetings = [greeting(), 'Hello', 'How are you', 'How are you doing', 'Good to see you', 'Long time no see', 'Its been a while']
peopleAtHome = []
for member in itemRegistry.getItem('G_Presence_Family').getAllMembers():
if member.state == OPEN: peopleAtHome.append(member.label)
random.shuffle(peopleAtHome)
msg = random.choice(greetings)
for i in range(len(peopleAtHome)):
person = peopleAtHome[i]
msg += ' '+person
if i+2 == len(peopleAtHome):
msg +=' and'
elif i+1 == len(peopleAtHome):
msg +='.'
elif i+2 < len(peopleAtHome):
msg +=','
#tts(msg, PRIO['HIGH'], ttsRoom='Kitchen', ttsVol=42, ttsLang='en-GB', ttsVoice='Brian')
tts(msg, PRIO['HIGH'], ttsRoom='Kitchen', ttsVol=42, ttsLang='en-IN', ttsVoice='Aditi')
#tts(msg, PRIO['HIGH'], ttsRoom='Kitchen', ttsVol=42, ttsLang='en-US', ttsVoice='Matthew')
#tts(msg, None, ttsRoom='All', ttsLang='de-DE', ttsVoice='Vicki')
#tts(msg) # Also works if you accept the defaults
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from core.rules import rule
from core.triggers import when
from community.sonos.speak import tts

@rule("Example speak test in string Item", description="This script will speak the text located in the Speak_This Item when an update is received")
@when("Item Speak_This received update")
def exampleSpeakTextInStringItem(event):
tts(event.itemState)
Empty file.
Loading