Just trying to get some outlets off before I wake up.

This commit is contained in:
ccostan 2018-01-17 11:39:08 -05:00
parent f732c17845
commit a3da0bf185
8 changed files with 252 additions and 55 deletions

View File

@ -24,7 +24,7 @@
] | random + "#HomeAutomation"}}
- delay: '00:{{ (range(1, 55)|random|int) }}:00'
- service: light.turn_off
- service: homeassistant.turn_off
entity_id:
- group.exterior_lights
- group.outdoor_front_lights

View File

@ -17,9 +17,10 @@
tweet: >
{{ [
"Right before sunset, I turn on the outdoor lights.",
"Since it gets dark around sunset, I turn on the landscaping lights.",
"Since it gets dark around sunset, I will turn on the landscaping lights.",
"Time to turn on the Landscaping lights.",
"Daytime is over, Time to turn on the exterior lights.",
"Once the Sun goes down, we turn on the exterior lights.",
"Since it is sunset, I will turn on the exterior lights."
] | random + [
" #Sunset",

View File

@ -3,7 +3,7 @@ Interior Switches:
- switch.den_outlet
- switch.living_room_outlet
- switch.foyer_outlet
- switch.kitchen_Accents
- switch.kitchen_accents
- switch.kitchen_accent_2
- switch.printer_outlet
- switch.front_door_outlet

View File

@ -54,6 +54,13 @@ sensor:
duration:
hours: 24
- platform: rest
name: July 4th Countdown
resource: http://api.wolframalpha.com/v1/result?appid=JIUY8U-4V8KY45VT1&i=How%20many%20days%20until%204th%20July%202018
value_template: "{{ (value|replace(' days', '')) | int }}"
unit_of_measurement: Days
scan_interval: 43200```
group:
tweet_stats:
entities:
@ -164,7 +171,7 @@ automation:
"I am running Home Assistant version {{states.sensor.ha_installed_version.state}} (https://github.com/CCOSTAN/Home-AssistantConfig)",
"{{states.sensor.doorbell_presses.state}} doorbell presses occurred in the last 24 hours.",
"I keep the average humidity of the house at {{states.sensor.downstairs_thermostat_humidity.state}} percent. Outside is {{states.sensor.dark_sky_humidity.state}} #Nest (http://amzn.to/2BWNk5N)",
"Outside is {{states.sensor.dark_sky_temperature.state}}. I keep the average temperature at {{states.sensor.downstairs_thermostat_temperature.state}}. #Nest (http://amzn.to/2BWNk5N)",
"Outside is {{states.sensor.dark_sky_temperature.state}}. I keep the average temperature at {{states.sensor.downstairs_thermostat_temperature.state}}. #Weather (http://amzn.to/2BWNk5N)",
"I know that it will be {{states.sensor.dark_sky_minutely_summary.state}} So I will adjust the Heating/Cooling, irrigation and lighting accordingly. #Nest #Rachio #Hue",
"Average internet stats are Download: {{states.sensor.speedtest_download.state}} Mbit/s & Upload {{states.sensor.speedtest_upload.state}} Mbit/s.",
"Todays Sleep Number is {{states.sensor.sleepnumber_carlo_stacey_sleepnumber.state}}. Wifi connected Bed FTW! #SleepStat (http://amzn.to/2D10BcQ)",

View File

@ -7,7 +7,7 @@
interior_off:
sequence:
- service: light.turn_off
- service: homeassistant.turn_off
entity_id:
- group.interior_lights
- service: script.switch_turn_off_all

View File

@ -15,8 +15,6 @@ rules:
class: 'button-on'
- state: 'off'
class: 'button-off'
action:
service: homeassistant.toggle
- name: thermostats_temp
entities:
@ -95,8 +93,6 @@ rules:
class: 'switch-on'
- state: 'off'
class: 'switch-off'
action:
service: homeassistant.toggle
- name: custom_switches
entities:
@ -106,8 +102,6 @@ rules:
class: 'light-blue-on'
- state: 'off'
class: 'outdoor-light-off'
action:
service: homeassistant.toggle
- name: Lights
entities:
@ -149,8 +143,6 @@ rules:
class: 'light-on'
- state: 'off'
class: 'light-off'
action:
service: homeassistant.toggle
- name: Outdoor Lights
entities:
@ -172,8 +164,6 @@ rules:
class: 'light-on'
- state: 'off'
class: 'outdoor-light-off'
action:
service: homeassistant.toggle
- name: Nest Protects
entities:

View File

@ -1,5 +1,5 @@
date_format: MMM-DD-YYYY
#log_level: error
#log_level: debug
fully_kiosk:

View File

@ -1,8 +1,8 @@
/*
Floorplan Fully Kiosk for Home Assistant
Version: 1.0.7.42
By Petar Kozul
https://github.com/pkozul/ha-floorplan
Floorplan Fully Kiosk for Home Assistant
Version: 1.0.7.50
By Petar Kozul
https://github.com/pkozul/ha-floorplan
*/
'use strict';
@ -14,14 +14,16 @@
class FullyKiosk {
constructor(floorplan) {
this.version = '1.0.7.42';
this.version = '1.0.7.50';
this.floorplan = floorplan;
this.authToken = (window.localStorage && window.localStorage.authToken) ? window.localStorage.authToken : '';
this.fullyInfo = {};
this.fullyState = {};
this.iBeacons = {};
this.beacons = {};
this.throttledFunctions = {};
}
/***************************************************************************************************************************/
@ -31,6 +33,13 @@
init() {
this.logInfo('VERSION', `Fully Kiosk v${this.version}`);
/*
let uuid = 'a445425b-c718-461c-a876-aa647abd99d4';
let deviceId = uuid.replace(/[-_]/g, '').toUpperCase();
let payload = { room: 'entry hall', id: uuid, distance: 123.45 };
this.PostToHomeAssistant(`/api/room_presence/${deviceId}`, payload);
*/
if (typeof fully === "undefined") {
this.logInfo('FULLY_KIOSK', `Fully Kiosk is not running or not enabled. You can enable it via Settings > Other Settings > Enable Website Integration (PLUS).`);
return;
@ -76,6 +85,8 @@
screensaverLightEntityId: device.screensaver_light,
mediaPlayerEntityId: device.media_player,
locationName: device.presence_detection ? device.presence_detection.location_name : undefined,
startUrl: fully.getStartUrl(),
currentLocale: fully.getCurrentLocale(),
ipAddressv4: fully.getIp4Address(),
@ -134,8 +145,15 @@
window.addEventListener('fully.onScreensaverStop', this.onScreensaverStop.bind(this));
window.addEventListener('fully.onBatteryLevelChanged', this.onBatteryLevelChanged.bind(this));
window.addEventListener('fully.onMotion', this.onMotion.bind(this));
window.addEventListener('fully.onMovement', this.onMovement.bind(this));
window.addEventListener('fully.onIBeacon', this.onIBeacon.bind(this));
if (this.fullyInfo.supportsGeolocation) {
window.addEventListener('fully.onMovement', this.onMovement.bind(this));
}
if (this.fullyInfo.locationName) {
this.logInfo('KIOSK', 'Listening for beacon messages');
window.addEventListener('fully.onIBeacon', this.onIBeacon.bind(this));
}
fully.bind('screenOn', 'onFullyEvent("fully.screenOn");')
fully.bind('screenOff', 'onFullyEvent("fully.screenOff");')
@ -221,8 +239,19 @@
this.sendMotionState();
}
onMovement() {
this.logDebug('FULLY_KIOSK', 'Movement detected');
onMovement(e) {
let functionId = 'onMovement';
let throttledFunc = this.throttledFunctions[functionId];
if (!throttledFunc) {
throttledFunc = this.throttle(this.onMovementThrottled.bind(this), 10000);
this.throttledFunctions[functionId] = throttledFunc;
}
return throttledFunc(e);
}
onMovementThrottled() {
this.logDebug('FULLY_KIOSK', 'Movement detected (throttled)');
if (this.fullyInfo.supportsGeolocation) {
this.updateCurrentPosition()
@ -233,19 +262,28 @@
}
onIBeacon(e) {
let iBeacon = e.detail;
let functionId = e.detail.uuid;
let throttledFunc = this.throttledFunctions[functionId];
if (!throttledFunc) {
throttledFunc = this.throttle(this.onIBeaconThrottled.bind(this), 10000);
this.throttledFunctions[functionId] = throttledFunc;
}
this.logDebug('FULLY_KIOSK', `iBeacon (${JSON.stringify(iBeacon)})`);
return throttledFunc(e);
}
let iBeaconId = iBeacon.uuid;
iBeaconId += (iBeacon.major ? `_${iBeacon.major}` : '');
iBeaconId += (iBeacon.minor ? `_${iBeacon.minor}` : '');
onIBeaconThrottled(e) {
let beacon = e.detail;
this.iBeacons[iBeaconId] = iBeacon;
this.logDebug('FULLY_KIOSK', `Received (throttled) beacon message (${JSON.stringify(beacon)})`);
this.sendMotionState();
let beaconId = beacon.uuid;
beaconId += (beacon.major ? `_${beacon.major}` : '');
beaconId += (beacon.minor ? `_${beacon.minor}` : '');
this.sendIBeaconState(iBeacon);
this.beacons[beaconId] = beacon;
this.sendBeaconState(beacon);
}
/***************************************************************************************************************************/
@ -329,30 +367,61 @@
this.PostToHomeAssistant(`/api/fully_kiosk/media_player/${this.fullyInfo.mediaPlayerEntityId}`, this.newPayload(state));
}
sendIBeaconState(iBeacon) {
sendBeaconState(beacon) {
if (!this.fullyInfo.motionBinarySensorEntityId) {
return;
}
/*
let payload = {
name: this.fullyInfo.locationName,
address: this.fullyInfo.macAddress,
device: beacon.uuid,
beaconUUID: beacon.uuid,
latitude: this.position ? this.position.coords.latitude : undefined,
longitude: this.position ? this.position.coords.longitude : undefined,
entry: 1,
}
this.PostToHomeAssistant(`/api/geofency`, payload, undefined, false);
*/
/*
let payload = {
mac: undefined,
dev_id: iBeacon.uuid.replace(/-/g, '_'),
dev_id: beacon.uuid.replace(/-/g, '_'),
host_name: undefined,
location_name: this.fullyInfo.macAddress,
gps: this.position ? [this.position.coords.latitude, this.position.coords.longitude] : undefined,
gps_accuracy: undefined,
battery: undefined,
uuid: iBeacon.uuid,
major: iBeacon.major,
minor: iBeacon.minor,
uuid: beacon.uuid,
major: beacon.major,
minor: beacon.minor,
};
//this.PostToHomeAssistant(`/api/services/device_tracker/see`, payload);
this.PostToHomeAssistant(`/api/services/device_tracker/see`, payload);
*/
/*
let fullyId = this.fullyInfo.macAddress.replace(/[:-]/g, "_");
payload = { topic: `room_presence/${fullyId}`, payload: `{ \"id\": \"${iBeacon.uuid}\", \"distance\": ${iBeacon.distance} }` };
payload = { topic: `room_presence/${fullyId}`, payload: `{ \"id\": \"${beacon.uuid}\", \"distance\": ${beacon.distance} }` };
this.floorplan.hass.callService('mqtt', 'publish', payload);
*/
let deviceId = beacon.uuid.replace(/[-_]/g, '').toUpperCase();
let payload = {
room: this.fullyInfo.locationName,
uuid: beacon.uuid,
major: beacon.major,
minor: beacon.minor,
distance: beacon.distance,
latitude: this.position ? this.position.coords.latitude : undefined,
longitude: this.position ? this.position.coords.longitude : undefined,
};
this.PostToHomeAssistant(`/api/room_presence/${deviceId}`, payload);
}
newPayload(state) {
@ -376,7 +445,7 @@
_isScreensaverOn: this.fullyState.isScreensaverOn,
_latitude: this.position && this.position.coords.latitude,
_longitude: this.position && this.position.coords.longitude,
_iBeacons: JSON.stringify(Object.keys(this.iBeacons).map(iBeaconId => this.iBeacons[iBeaconId])),
_beacons: JSON.stringify(Object.keys(this.beacons).map(beaconId => this.beacons[beaconId])),
}
};
@ -568,22 +637,152 @@
/* Utility functions
/***************************************************************************************************************************/
debounce(func, wait, immediate) {
let timeout;
return function () {
let context = this, args = arguments;
debounce(func, wait, options) {
let lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime
let later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
let lastInvokeTime = 0
let leading = false
let maxing = false
let trailing = true
let callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (typeof func != 'function') {
throw new TypeError('Expected a function')
}
wait = +wait || 0
if (options) {
leading = !!options.leading
maxing = 'maxWait' in options
maxWait = maxing ? Math.max(+options.maxWait || 0, wait) : maxWait
trailing = 'trailing' in options ? !!options.trailing : trailing
}
if (callNow) func.apply(context, args);
};
function invokeFunc(time) {
const args = lastArgs
const thisArg = lastThis
lastArgs = lastThis = undefined
lastInvokeTime = time
result = func.apply(thisArg, args)
return result
}
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTime = time
// Start the timer for the trailing edge.
timerId = setTimeout(timerExpired, wait)
// Invoke the leading edge.
return leading ? invokeFunc(time) : result
}
function remainingWait(time) {
const timeSinceLastCall = time - lastCallTime
const timeSinceLastInvoke = time - lastInvokeTime
const timeWaiting = wait - timeSinceLastCall
return maxing
? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting
}
function shouldInvoke(time) {
const timeSinceLastCall = time - lastCallTime
const timeSinceLastInvoke = time - lastInvokeTime
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait))
}
function timerExpired() {
const time = Date.now()
if (shouldInvoke(time)) {
return trailingEdge(time)
}
// Restart the timer.
timerId = setTimeout(timerExpired, remainingWait(time))
}
function trailingEdge(time) {
timerId = undefined
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgs) {
return invokeFunc(time)
}
lastArgs = lastThis = undefined
return result
}
function cancel() {
if (timerId !== undefined) {
clearTimeout(timerId)
}
lastInvokeTime = 0
lastArgs = lastCallTime = lastThis = timerId = undefined
}
function flush() {
return timerId === undefined ? result : trailingEdge(Date.now())
}
function pending() {
return timerId !== undefined
}
function debounced(...args) {
const time = Date.now()
const isInvoking = shouldInvoke(time)
lastArgs = args
lastThis = this
lastCallTime = time
if (isInvoking) {
if (timerId === undefined) {
return leadingEdge(lastCallTime)
}
if (maxing) {
// Handle invocations in a tight loop.
timerId = setTimeout(timerExpired, wait)
return invokeFunc(lastCallTime)
}
}
if (timerId === undefined) {
timerId = setTimeout(timerExpired, wait)
}
return result
}
debounced.cancel = cancel
debounced.flush = flush
debounced.pending = pending
return debounced
}
throttle(func, wait, options) {
let leading = true
let trailing = true
if (typeof func != 'function') {
throw new TypeError('Expected a function');
}
if (options) {
leading = 'leading' in options ? !!options.leading : leading
trailing = 'trailing' in options ? !!options.trailing : trailing
}
return this.debounce(func, wait, {
'leading': leading,
'maxWait': wait,
'trailing': trailing
})
}
}