Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial Commit

Control individual or all lights to switch power or adjust brightness
relative to the current setting
commit 3cdbfc8919906d254da71e349727c5822af720f5 0 parents
Brandon Evans authored
1  .gitignore
... ... @@ -0,0 +1 @@
  1 +.DS_Store
4 Gemfile
... ... @@ -0,0 +1,4 @@
  1 +source "http://rubygems.org"
  2 +
  3 +# Specify your gem's dependencies in siriproxy-example.gemspec
  4 +gemspec
1  Rakefile
... ... @@ -0,0 +1 @@
  1 +require "bundler/gem_tasks"
166 lib/siriproxy-hue.rb
... ... @@ -0,0 +1,166 @@
  1 +require "cora"
  2 +require "siri_objects"
  3 +require "pp"
  4 +require "rest_client" # HTTP requests
  5 +require "json" # Parse Hue responses
  6 +
  7 +################################################################################
  8 +#
  9 +# Hue got me babe
  10 +#
  11 +################################################################################
  12 +
  13 +
  14 +class HueEntity
  15 + @@hueIP = "10.0.1.12"
  16 + @@hueKey = "7dcdc2716a5c8796367968c47ad7d44c"
  17 +
  18 + attr_accessor :type
  19 + attr_accessor :name
  20 + attr_accessor :number
  21 +
  22 + def initialize (capturedString)
  23 + response = RestClient.get("#{@@hueIP}/api/#{@@hueKey}")
  24 + data = JSON.parse(response)
  25 + lights = data["lights"].map do |key, light|
  26 + {type: :light, name: light["name"].to_s, number: key.to_i}
  27 + end
  28 + lights.push({type: :group, name: "all", number: 0})
  29 + result = lights.select { |light| light[:name].to_s.downcase == capturedString }
  30 + result = result[0]
  31 +
  32 + if result.empty? then return false end
  33 +
  34 + @type = result[:type]
  35 + @number = result[:number]
  36 + @name = result[:name]
  37 + end
  38 +
  39 + def power (value)
  40 + if self.type == :group
  41 + url = "#{@@hueIP}/api/#{@@hueKey}/groups/#{@number}/action"
  42 + else
  43 + url = "#{@@hueIP}/api/#{@@hueKey}/lights/#{@number}/state"
  44 + end
  45 + RestClient.put(url, {on: value}.to_json, content_type: :json)
  46 + end
  47 +
  48 + def brightness (*args)
  49 + if args.size < 1
  50 + url = "#{@@hueIP}/api/#{@@hueKey}/lights/#{@number}"
  51 + response = RestClient.get(url)
  52 + data = JSON.parse(response)
  53 + brightness = data["state"]["bri"].to_i
  54 + return brightness
  55 + elsif args.size == 1
  56 + value = args[0]
  57 + if (value > 254) then value = 254
  58 + elsif (value < 0) then value = 0
  59 + end
  60 + url = "#{@@hueIP}/api/#{@@hueKey}/lights/#{@number}/state"
  61 + RestClient.put(url, {:bri => value}.to_json, content_type: :json)
  62 + end
  63 + end
  64 +
  65 + def color (value)
  66 +
  67 + end
  68 +end
  69 +
  70 +class SiriProxy::Plugin::Hue < SiriProxy::Plugin
  71 + def parseNumbers (value)
  72 + value = value.sub_numbers
  73 + if (value =~ /%/)
  74 + value = value.delete("%").to_i * 254 / 100
  75 + end
  76 + end
  77 +
  78 + def is_numeric?(obj)
  79 + obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
  80 + end
  81 +
  82 + # Binary state
  83 + listen_for /turn (on|off)(?: the)? ([a-z]*)/i do |state, entity|
  84 + unless(matchedEntity = HueEntity.new(entity))
  85 + say "I couldn't find any lights by that name."
  86 + request_completed
  87 + end
  88 +
  89 + if (state == "on") then matchedEntity.power(true)
  90 + else matchedEntity.power(false)
  91 + end
  92 + if matchedEntity.type == :group
  93 + if matchedEntity.name == "all"
  94 + say "I've turned #{state} all of the lights for you."
  95 + else
  96 + say "I've turned #{state} the #{entity} lights for you."
  97 + end
  98 + else
  99 + say "I've turned #{state} the #{entity} light for you."
  100 + end
  101 +
  102 + request_completed
  103 + end
  104 +
  105 + # Relative brightness change
  106 + listen_for /turn (up|down)(?: the)? ([a-z]*)/i do |change, entity|
  107 + unless(matchedEntity = HueEntity.new(entity))
  108 + say "I couldn't find any lights by that name."
  109 + request_completed
  110 + end
  111 +
  112 + currentBrightness = matchedEntity.brightness
  113 +
  114 + if (change == "up") then newBrightness = currentBrightness + 50
  115 + else newBrightness = currentBrightness - 50
  116 + end
  117 + matchedEntity.brightness(newBrightness)
  118 +
  119 + response = ask "Is that enough?"
  120 +
  121 + if (response =~ /yes/i)
  122 + say "I'm happy to help."
  123 + elsif (response =~ /more|no/i)
  124 + if (change == "up") then newBrightness += 50
  125 + else newBrightness -= 50
  126 + end
  127 + matchedEntity.brightness(newBrightness)
  128 + say "You're right, that does look better"
  129 + end
  130 +
  131 + request_completed
  132 + end
  133 +
  134 + # Absolute brightness/color change
  135 + # Numbers (0-254) and percentages (0-100) are treated as brightness values
  136 + # Strings are used as a color query to lookup HSV values
  137 + listen_for /set(?: the)? ([a-z]*) to ([a-z0-9%]*)/i do |entity, value|
  138 + unless(matchedEntity = HueEntity.new(entity))
  139 + say "I couldn't find any lights by that name."
  140 + request_completed
  141 + end
  142 +
  143 + value = parseNumbers(value)
  144 + if (is_numeric? value)
  145 + log value
  146 + matchedEntity.brightness(value.to_i)
  147 + else
  148 + # query color for hsl value
  149 + query = "http://www.colourlovers.com/api/colors?keywords=#{query}&numResults=1&format=json"
  150 + # set entity to color value
  151 + end
  152 +
  153 + say "There you go."
  154 +
  155 + request_completed
  156 + end
  157 +
  158 + # Scenes
  159 + listen_for /make it look like a (.+)/i do |scene|
  160 + # do a google image request
  161 + # use the first result
  162 + # pull n colors, where n is the number of lights
  163 + # set each light to color[i]
  164 + request_completed
  165 + end
  166 +end
21 siriproxy-hue.gemspec
... ... @@ -0,0 +1,21 @@
  1 +# -*- encoding: utf-8 -*-
  2 +$:.push File.expand_path("../lib", __FILE__)
  3 +
  4 +Gem::Specification.new do |s|
  5 + s.name = "siriproxy-hue"
  6 + s.version = "0.0.1"
  7 + s.authors = "interstateone"
  8 + s.email = "brandon@brandonevans.ca"
  9 + s.homepage = "http://www.brandonevans.ca"
  10 + s.summary = %q{Hue got me babe}
  11 + s.description = %q{This lets you control Philips Hue lights with Siri}
  12 +
  13 + s.files = `git ls-files 2> /dev/null`.split("\n")
  14 + s.test_files = `git ls-files -- {test,spec,features}/* 2> /dev/null`.split("\n")
  15 + s.executables = `git ls-files -- bin/* 2> /dev/null`.split("\n").map{ |f| File.basename(f) }
  16 + s.require_paths = ["lib"]
  17 +
  18 + # specify any dependencies here; for example:
  19 + s.add_runtime_dependency "rest-client"
  20 + s.add_runtime_dependency "json"
  21 +end

0 comments on commit 3cdbfc8

Please sign in to comment.
Something went wrong with that request. Please try again.