I don’t think this idea has been written up anywhere else, and someone might be interested in playing with it.
All the siriproxy/vera code I’ve seen so far requires you to hard-code devices and commands into the siriproxy Ruby script. Which is a bit redundant as Vera knows what devices there are and what they can do.
Here’s some siriproxy-example code which collects the device and scene list from Vera at run time. Commands are therefore dynamic, depending on the device type.
[code]
require ‘cora’
require ‘siri_objects’
require ‘pp’
require ‘open-uri’
require ‘json’
########################################################
Improved Vera Voice Control plugin for Siri Proxy on Raspberry Pi
Version: 0.0.1
Date: 20130624
By: ARM
class SiriProxy::Plugin::Example < SiriProxy::Plugin
def initialize(config)
@actionUrl = “http://192.168.2.19:3480/data_request?id=lu_action&”
@dataUrl = “http://192.168.2.19:3480/data_request?”
end
#On/Off devices
def checkOnOff(device)
end
listen_for /test home automation/i do
say “Vera plugin for Siri Proxy is up and running!”
request_completed
end
@userData = JSON.parse(open(“http://192.168.2.19:3480/data_request?id=user_data2” ).read)
#Devices
@userData[“devices”].each do |device|
case device[“device_type”]
#SWITCHABLE LIGHTS ++++++++++++++++++++++
when "urn:schemas-upnp-org:device:BinaryLight:1"
#example: BEDROOM LIGHT ON
listen_for /(#{device["name"]}) (on|off)/i do |name,command|
signal = (command == "on") ? "1" : "0"
say "Switching " + name + " " + command
service = "&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue="
open(@actionUrl + 'DeviceNum=' + device["id"] + service + signal)
request_completed
end
#DIMMERS ++++++++++++++++++++++++++++++++
when "urn:schemas-upnp-org:device:DimmableLight:1"
#example: BEDROOM LIGHT ON
listen_for /(#{device["name"]}) (on|off)/i do |name,command|
signal = (command == "on") ? "1" : "0"
say "Switching " + name + " " + command
service = "&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue="
open(@actionUrl + 'DeviceNum=' + device["id"] + service + signal)
request_completed
end
#example: BEDROOM LIGHT FIFTY
listen_for /(#{device["name"]}) ([0-9,].*[0-9])/i do |name,level|
say "Setting" + name + " to " + level + "%"
service = "&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget="
open(@actionUrl + 'DeviceNum=' + device["id"] + service + level)
request_completed
end
#DOOR LOCKS +++++++++++++++++++++++++++++
when "urn:schemas-micasaverde-com:device:DoorLock:1"
#example: UNLOCK THE FRONT DOOR
listen_for /(unlock|lock)(?: the)? (#{device["name"]})/i do |command,name|
if command == "Unlock"
signal = "0"
verb = "Unlocking the"
else #default to lock
signal = "1"
verb = "Locking the "
end
say verb + " " + name
service = "&serviceId=urn:micasaverde-com:serviceId:DoorLock1&action=SetTarget&newTargetValue="
open(@actionUrl + 'DeviceNum=' + device["id"] + service + signal)
request_completed
end
#example: IS THE FRONT DOOR LOCKED
listen_for /is(?: the)? (#{device["name"]}) locked/i do |name|
service = "&serviceId=urn:micasaverde-com:serviceId:DoorLock1&Variable=Status"
llock = open(@dataUrl + 'id=lu_variableget&DeviceNum=' + device["id"] + service)
if llock.read[0] == "1"
say "The " + name + " is locked."
else
response = ask "The " + name + " is unlocked. Would you like me to lock it for you?"
if(response =~ /yes/i) #process their response
signal = "1"
verb = "Locking the "
say verb + " " + name
service = "&serviceId=urn:micasaverde-com:serviceId:DoorLock1&action=SetTarget&newTargetValue="
open(@actionUrl + 'DeviceNum=' + device["id"] + service + signal)
request_completed
else
say "OK. No problem!"
request_completed
end #if
end #if
end #listen_for
#THERMOSTATS +++++++++++++++++++++++++++++
when "urn:schemas-upnp-org:device:HVAC_ZoneThermostat:1"
#example:WHAT IS THE TEMPERATURE INSIDE?
listen_for /temperature inside/i do
service = "&serviceId=urn:upnp-org:serviceId:TemperatureSensor1&Variable=CurrentTemperature"
ltemp = open(@dataUrl + 'id=lu_variableget&DeviceNum=' + device["id"] + service)
say "The temperature in the living room is #{ltemp.read} degrees."
request_completed
end
#example: SET COOLING TWENTY ONE
listen_for /Set cooling.*([0-9,].*[0-9])/i do |level|
say "Setting your cooling target to " + level + " degrees"
service = "&serviceId=urn:upnp-org:serviceId:TemperatureSetpoint1_Cool&action=SetCurrentSetpoint&NewCurrentSetpoint="
open(@actionUrl + 'DeviceNum=' + device["id"] + service + level)
request_completed
end
#example: SET HEATING TWENTY FOUR
listen_for /Set heating.*([0-9,].*[0-9])/i do |level|
say "Setting your heating target to " + level + " degrees"
service = "&serviceId=urn:upnp-org:serviceId:TemperatureSetpoint1_Heat&action=SetCurrentSetpoint&NewCurrentSetpoint="
open(@actionUrl + 'DeviceNum=' + device["id"] + service + level)
request_completed
end
#example: AIR CONDITIONING ON / OFF
listen_for /Air conditioning (on|off)/i do |command|
signal = (command == "on") ? "CoolOn" : "Off"
say "Switching air conditioning " + command
service = "&serviceId=urn:upnp-org:serviceId:HVAC_UserOperatingMode1&action=SetModeTarget&NewModeTarget="
open(@actionUrl + 'DeviceNum=' + device["id"] + service + signal)
request_completed
end
#example: HEATING ON / OFF
listen_for /Heating (on|off)/i do |command|
signal = (command == "on") ? "HeatOn" : "Off"
say "Switching heating " + command
service = "&serviceId=urn:upnp-org:serviceId:HVAC_UserOperatingMode1&action=SetModeTarget&NewModeTarget="
open(@actionUrl + 'DeviceNum=' + device["id"] + service + signal)
request_completed
end
end #case
end #foreach device
#now check through scenes
@userData[“scenes”].each do |scene|
listen_for /(#{scene[“name”]})/i do |name|
say "OK, setting " + name
service = “serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=RunScene&SceneNum=”
open(@actionUrl + service + scene[“id”].to_s)
request_completed
end #listen_for
end #foreach scene
########################################
end[/code]
- to run a scene, just say the scene name, eg LIVING ROOM LIGHTS MEDIUM
- to open a door say UNLOCK - eg UNLOCK FRONT DOOR
- to switch on (or off) a lamp say ON or OFF - eg TABLE LAMP OFF
- to dim a lamp, say - eg BEDROOM LAMP FIFTY
I only have one thermostat, so the first thermostat item in the device list is controlled as:
AIR CONDITIONING ON
AIR CONDITIONING OFF
HEATING ON
HEATING OFF
SET HEATING - eg SET HEATING TWENTYTHREE
SET COOLING
I cribbed the
IS THE LOCKED? idea from WSeverino whose code I started with - so thanks to him (or her) although there’s not much of that code left.
There’s no error handling or checking of return codes (yet)
You have to put your Vera’s IP address in the code, that should move to the config.yml eventually, but I’ve a lot to learn about the file structure of Ruby gems, yet.
If I ever get a UPnP tv, guess what I’m going to be using as a remote
ps. Make sure to choose device and scene names carefully, so that Siri can work out what you’re talking about.
EDIT: code updated