Archive for Blog’ Category

10

Apr
2022
Comments Off on Automating Your Home Climate Control With Home Assistant

Automating Your Home Climate Control With Home Assistant

About a year or so ago, I moved away from HomeKit and starting using Home Assistant. HomeKit was just too unreliable when it came to automating things, not to mention that Siri is very moody about when it wants to work or not.

My Home Assistant setup now controls all my HomeKit, Zigbee, and Z-Wave devices and they are all exposed back to HomeKit so I can use Siri for voice control. I must say, that I am pretty impressed with the setup and its reliability.

But, we are here to talk about your home’s climate control, so let’s begin.

I live in Montreal and the weather here gets pretty darn cold in the Winter which means high electricity bills. To that end our utility company, Hydro Quebec, has started new programs for peak hours to let folks lower their electricity bills and I am participating in that. The way it works is that they send an email the day before to tell you that tomorrow there may be a peak event during the morning, evening or both. So, I wanted a way to automate it all so I don’t have to adjust things manually.

The Setup

My home heating is with forced air, but I do have a few baseboard heaters around and floor heaters in the bathrooms, so they all have to work in concert.

  • Main HVAC: Ecobee3
  • Baseboard heaters (mix of Z-Wave, and HomeKit)
  • Floor heaters (Zigbee)
  • Gmail for peak event notifications

The Goal

Below is what I set out to achieve:

  1. Climate settings should have Home, Away, Sleep settings
  2. Climate settings should take into account peak events
  3. Climate settings should differentiate between workdays and weekends/holidays
  4. Climate settings should be aware of Summer/Winter temperatures
  5. All of the above should be easily adjustable.

How it works

In order to do all the goals I had set, the first thing was to take away the Ecobee’s programming, so I changed a few settings:

  • Everyday of the week is only set to have 1 comfort setting which is the temperature range that I use for both Winter/Summer
  • The hold setting is set to not change automatically, so if I change the temperature, it will keep that until I manually change it again.

Side Note: As much as I love the Ecobee, there is no way to have it resume unless you use it with HomeKit directly (i.e. only the Ecobee itself can add the resume to HomeKit, there is no HomeKit command for it). Also, I don’t like that it communicates with home base so much but I want the wether so I don’t like to let it know if I am home/away/on holiday.

One other item I should point out is that the way I prep for a peak time is that I preheat my house prior to peak time and then turn everything down for the duration so heating is used less and hopefully the house can stay somewhat warm during the event.

From this point on, I am going to refer to the file attached here and explain how it works. I think that would be best.

Adjustable Settings

The following is a list of inputs I used to achieve gaol #5:

  • input_datetime
    • peak_morning_start_time: The time that a morning peak event starts
    • peak_morning_end_time: The time that a morning peak event ends
    • peak_evening_start_time: The time that a evening peak event starts
    • peak_evening_end_time: The time that a evening peak event ends
  • input_number
    • peak_pre_time (range 0-180 min): The time needed to preheat the home prior to a peak event
    • winter_summer_threshold (range (-10 to 10 ºC): The temperature above which summer settings should be used.
  • input_boolean
    • peak_demand_morning_today: Whether today has a morning peak event
    • peak_demand_evening_today: Whether today has a evening peak event
    • peak_demand_morning_tomorrow: Whether tomorrow has a morning peak event
    • peak_demand_evening_tomorrow: Whether tomorrow has a evening peak event

Besides the above, there are a few other things that are also leveraged:

  • work_wakeup_time: The time that the house wakes up for a work day
  • work_quiet_time: The time that the house is in sleep mode for a work day
  • holiday_wakeup_time: The time that the house wakes up for a holiday (or weekend)
  • holiday_quiet_time: The time that the house is in sleep mode for a holiday (or weekend)
  • workday
    • workday_today: Whether it is a work day today
    • workday_tomorrow: Whether it is a work day tomorrow.
  • IMAP Email Content: To check email for peak time (Note: I get this in English)
  • peak_demand_morning_notification: a sensor that is set when a peak time email is received containing peak time for tomorrow morning.
  • peak_demand_evening_notification: a sensor that is set when a peak time email is received containing peak time for tomorrow evening.
  • household: This is a group of household members that indicates if we are home or not using sensors for each person.
  • peak_time_now: A sensor indicating whether we are in a peak time at this moment.
  • house_mode: A sensor indicating whether the house is in Home, Sleep, or Away mode. This is dependent on whether household is home or away and whether tomorrow and today are workdays or not (if tomorrow is not a workday, then the house goes to sleep mode at holiday_quiet_time instead of workday_quiet_time).

Implementation

The climate settings are controlled via scenes:

  • Climate: Main Thermostat Away: This scene sets the temperature range for the Ecobee when we are away. The Ecobee is set to auto cool/heat and the range is such that it is the same for Summer and Winter.
  • Climate: Main Thermostat Home: This scene sets the temperature range for the Ecobee when we are home.
  • Climate: Main Thermostat Sleep: This scene sets the temperature range for the Ecobee when we are asleep.
  • Climate: Other Thermostats Summer: This scene sets the temperature for each of the baseboard and floor heaters for the Summer time. Basically, turns them off.
  • Climate: Other Thermostats Away – Winter: This scene sets the temperature for each of the baseboard and floor heaters for the Winter when the household is away.
  • Climate: Other Thermostats Home – Winter: This scene sets the temperature for each of the baseboard and floor heaters for the Winter when the household is home.
  • Climate: Other Thermostats Sleep – Winter: This scene sets the temperature for each of the baseboard and floor heaters for the Winter when the household is asleep.
  • Climate: All Thermostats Peak Time: This scene sets the temperature for all (including Ecobee) heaters while we are in peak time.

Since the email for peak time comes the day before, the email sensor checks and set tomorrow’s peak inputs first (hydro_email). Then at 1AM, an automation copies the values to today’s peak input and resets tomorrow’s peak inputs back to off (Peak Time: Copy tomorrows values).

Then depending on whether it is a workday, holiday, or peak time automations control the heaters:

  • Climate: Preheat at morning peak start time: This automation triggers at preheat time (peak start timepreheat time) only if there is a morning peak event, and household is home to make sure the house is heated and ready to use less heating during the morning peak time.
    • Scene: Climate: Main Thermostat Home
    • Scene: Climate: Other Thermostats Home – Winter
  • Climate: Preheat at evening peak start time: Same as the morning automation but for the evening peak time
    • Scene: Climate: Main Thermostat Home
    • Scene: Climate: Other Thermostats Home – Winter
  • Climate: Set peak mode at peak start time: This automation is triggered when the peak_time_now sensor is turned on and household is home
    • Scene: Climate: All Thermostats Peak Time
  • Climate: Reset peak mode at peak end time: This automation reset the climate settings to what they should be once peak time is over (i.e. if house_mode is set to sleep, then set the sleep time settings , etc).
    • If home:
      • Scene: Climate: Main Thermostat Home
      • Scene: Climate: Other Thermostats Home – Winter
    • If asleep:
      • Scene: Climate: Main Thermostat Sleep
      • Scene: Climate: Other Thermostats Sleep – Winter
    • Otherwise:
      • Scene: Climate: Main Thermostat Away
      • Scene: Climate: Other Thermostats Away – Winter
  • Climate: Preheat before morning wake time or at wake time: This automation sets the climate settings to home at preheat time or at wakeup time if household is home and it is not a peak_time_now.
    • Scene: Climate: Main Thermostat Home
    • If temperature is below threshold (winter_summer_threshold):
      • Scene: Climate: Other Thermostats Home – Winter
    • Otherwise:
      • Scene: Climate: Other Thermostats Summer
  • Climate: Pre Cool or stop heating before sleep time or at sleep time: This automation sets the climate settings to sleep at preheat time or at sleep time if household is home and it is not a peak_time_now.
    • Scene: Climate: Main Thermostat Sleep
    • If temperature is below threshold (winter_summer_threshold):
      • Scene: Climate: Other Thermostats Sleep – Winter
    • Otherwise:
      • Scene: Climate: Other Thermostats Summer
  • Climate: Household leaves: This automation sets the climate settings to away when household is not home.
    • Scene: Climate: Main Thermostat Away
    • If temperature is below threshold (winter_summer_threshold):
      • Scene: Climate: Other Thermostats Away – Winter
    • Otherwise:
      • Scene: Climate: Other Thermostats Summer
  • Climate: Household arrives: This automation sets the climate settings to home when household comes home (i.e. first person arrives home).
    • If house_mode is set to sleep:
      • Scene: Climate: Main Thermostat Sleep
      • If temperature is below threshold (winter_summer_threshold):
        • Scene: Climate: Other Thermostats Sleep – Winter
    • Otherwise:
      • Scene: Climate: Main Thermostat Home
      • If temperature is below threshold (winter_summer_threshold):
        • Scene: Climate: Other Thermostats Home – Winter
      • Otherwise:
        • Scene: Climate: Other Thermostats Summer

YAML

here is the Yaml for the above so you can see how it is implemented exactly. Note that some inputs/sensors are external to this file but they are explained in here so you know what they do.

input_datetime:
  # This indicates the start time of peak demand time in the morning
  peak_morning_start_time:
    name: Peak Demand Morning Start
    has_date: false
    has_time: true
    icon: mdi:clock-time-six
  # This indicates the end time of peak demand time in the morning
  peak_morning_end_time:
    name: Peak Demand Morning End
    has_date: false
    has_time: true
    icon: mdi:clock-time-nine
  # This indicates the start time of peak demand time in the evening
  peak_evening_start_time:
    name: Peak Demand Evening Start
    has_date: false
    has_time: true
    icon: mdi:clock-time-four-outline
  # This indicates the end time of peak demand time in the evening
  peak_evening_end_time:
    name: Peak Demand Evening End
    has_date: false
    has_time: true
    icon: mdi:clock-time-eight-outline

input_number:
  # This input sets the time needed to cool/heat the house prior to Peak time
  peak_pre_time:
    name: Peak Pre Time
    min: 0
    max: 180
    step: 5
    mode: slider
    icon: mdi:timelapse
  winter_summer_threshold:
    name: Winter/Summer Threshold
    min: -10
    max: 10
    step: 1
    mode: slider
    icon: mdi:car-speed-limiter

input_boolean:
  # This input determines whether peak demand morning time is enabled for today or not
  peak_demand_morning_today:
    name: Peak Demand Morning Today
    icon: mdi:summit
  # This input determines whether peak demand evening time is enabled for today or not
  peak_demand_evening_today:
    name: Peak Demand Evening Today
    icon: mdi:summit
  # This input determines whether peak demand morning time is enabled for tomorrow or not
  peak_demand_morning_tomorrow:
    name: Peak Demand Morning Tomorrow
    icon: mdi:summit
  # This input determines whether peak demand evening time is enabled for tomorrow or not
  peak_demand_evening_tomorrow:
    name: Peak Demand Evening Tomorrow
    icon: mdi:summit

sensor:
  # https://www.home-assistant.io/integrations/imap_email_content/
  - platform: imap_email_content
    name: hydro_email
    server: imap.gmail.com
    port: 993
    username: !secret peak_email_username
    password: !secret peak_email_password
    senders:
      - hydroquebec@communication.hydroquebec.com
    value_template: >-
      {% if ( 'Peak demand event notification' in subject) %}
      peak
      {% else %}
      off
      {% endif %}
  - platform: template
    sensors:
      peak_demand_morning_notification:
        friendly_name: "Peak Demand Morning Notification" #Thu, 20 Jan 2022 12:52:16 -0500
        value_template: >-
          {% if ( states('sensor.hydro_email') == 'peak' and strptime(state_attr('sensor.hydro_email','date'), '%a, %d %b %Y %H:%M:%S %z').strftime('%d%m%Y') == now().strftime('%d%m%Y') and state_attr('sensor.hydro_email','body') is search('from 6 to 9 a.m.', ignorecase=True) ) %}
          on
          {% else %}
          off 
          {% endif %}
      peak_demand_evening_notification:
        friendly_name: "Peak Demand Evening Notification"
        value_template: >-
          {% if ( states('sensor.hydro_email') == 'peak' and strptime(state_attr('sensor.hydro_email','date'), '%a, %d %b %Y %H:%M:%S %z').strftime('%d%m%Y') == now().strftime('%d%m%Y') and state_attr('sensor.hydro_email','body') is search('from 4 to 8 p.m.', ignorecase=True) ) %}
          on
          {% else %}
          off
          {% endif %}
      peak_time_now:
        friendly_name: "Peak Time Now"
        value_template: >-
          {% if ( is_state('input_boolean.peak_demand_morning_today', 'on') and 
                now().strftime('%H:%M') >= (state_attr('input_datetime.peak_morning_start_time', 'timestamp') | timestamp_custom('%H:%M', False)) and 
                now().strftime('%H:%M') <= (state_attr('input_datetime.peak_morning_end_time', 'timestamp') | timestamp_custom('%H:%M', False)) ) or
                ( is_state('input_boolean.peak_demand_evening_today', 'on') and 
                now().strftime('%H:%M') >= (state_attr('input_datetime.peak_evening_start_time', 'timestamp') | timestamp_custom('%H:%M', False)) and 
                now().strftime('%H:%M') <= (state_attr('input_datetime.peak_evening_end_time', 'timestamp') | timestamp_custom('%H:%M', False)) ) %}
            on
          {%  else %}
            off
          {% endif %}

scene:
  ######
  # Climate: Main Thermostat Away
  - name: "Climate: Main Thermostat Away"
    id: bb18cf20-57ae-47e3-a80e-c9896745673f
    entities:
      climate.sedhvac:
        state: "heat_cool"
        target_temp_high: 29
        target_temp_low: 14

  #####
  # Climate: Main Thermostat Home
  - name: "Climate: Main Thermostat Home"
    id: bab27c18-3237-4a0b-83f9-6606865e0ec9
    entities:
      climate.sedhvac:
        state: "heat_cool"
        target_temp_high: 25
        target_temp_low: 19.5

  #####
  # Climate: Main Thermostat Sleep
  - name: "Climate: Main Thermostat Sleep"
    id: b0d722cc-8480-4229-a07c-7ae21309945a
    entities:
      climate.sedhvac:
        state: "heat_cool"
        target_temp_high: 23.5
        target_temp_low: 17.5

  ######
  # Climate: Other Thermostats Summer
  - name: "Climate: Other Thermostats Summer"
    id: 68cb636e-b76d-4148-93cf-cc65e8d6f45c
    entities:
      climate.bedroom3_thermostat:
        state: "heat"
        temperature: 6
      climate.guest_bedroom_thermostat:
        state: "heat"
        temperature: 6
      climate.family_room_thermostat:
        state: "off"
      climate.garage_thermostat:
        state: "off"
      climate.downstairs_bathroom_thermostat:
        state: "off"
      climate.master_bathroom_thermostat:
        state: "off"
      climate.upstairs_bathroom_thermostat:
        state: "off"

  ######
  # Climate: Other Thermostats Away - Winter
  - name: "Climate: Other Thermostats Away - Winter"
    id: d86d5909-8eb2-4dd2-a51f-8aae0599a0c6
    entities:
      climate.bedroom3_thermostat:
        state: "heat"
        temperature: 12
      climate.guest_bedroom_thermostat:
        state: "heat"
        temperature: 12
      climate.family_room_thermostat:
        state: "heat"
        temperature: 12
      climate.garage_thermostat:
        state: "heat"
        temperature: 8
      climate.downstairs_bathroom_thermostat:
        state: "heat"
        temperature: 12
      climate.master_bathroom_thermostat:
        state: "heat"
        temperature: 12
      climate.upstairs_bathroom_thermostat:
        state: "heat"
        temperature: 12

  #####
  # Climate: Other Thermostats Home - Winter
  - name: "Climate: Other Thermostats Home - Winter"
    id: 411533f6-ef26-450b-9acb-2e44a4c5cd50
    entities:
      climate.bedroom3_thermostat:
        state: "heat"
        temperature: 18
      climate.family_room_thermostat:
        state: "heat"
        temperature: 18
      climate.guest_bedroom_thermostat:
        state: "heat"
        temperature: 18
      climate.garage_thermostat:
        state: "heat"
        temperature: 14
      climate.downstairs_bathroom_thermostat:
        state: "heat"
        temperature: 20
      climate.master_bathroom_thermostat:
        state: "heat"
        temperature: 20
      climate.upstairs_bathroom_thermostat:
        state: "heat"
        temperature: 20

  #####
  # Climate: Other Thermostats Sleep - Winter
  - name: "Climate: Other Thermostats Sleep - Winter"
    id: 4b8b86c5-035a-4b8b-a934-f31571cd71e6
    entities:
      climate.bedroom3_thermostat:
        state: "heat"
        temperature: 17
      climate.family_room_thermostat:
        state: "heat"
        temperature: 17
      climate.guest_bedroom_thermostat:
        state: "heat"
        temperature: 17
      climate.garage_thermostat:
        state: "heat"
        temperature: 12
      climate.downstairs_bathroom_thermostat:
        state: "heat"
        temperature: 18
      climate.master_bathroom_thermostat:
        state: "heat"
        temperature: 18
      climate.upstairs_bathroom_thermostat:
        state: "heat"
        temperature: 18

  #####
  # Climate: All Thermostats Peak Time
  - name: "Climate: All Thermostats Peak Time"
    id: 794a89e7-1ecc-4e02-977b-21a0e8260b0f
    entities:
      climate.sedhvac:
        state: "heat_cool"
        target_temp_high: 25
        target_temp_low: 18
      climate.bedroom3_thermostat:
        state: "heat"
        temperature: 17
      climate.family_room_thermostat:
        state: "heat"
        temperature: 17
      climate.guest_bedroom_thermostat:
        state: "heat"
        temperature: 15
      climate.garage_thermostat:
        state: "heat"
        temperature: 10
      climate.downstairs_bathroom_thermostat:
        state: "heat"
        temperature: 17
      climate.master_bathroom_thermostat:
        state: "heat"
        temperature: 17
      climate.upstairs_bathroom_thermostat:
        state: "heat"
        temperature: 17

automation:
  ######
  # Climate: Preheat at morning peak start time
  - alias: "Climate: Preheat at morning peak start time"
    id: "7e432873-c8b7-4d75-9ff4-cfb3c6753bc6"
    description: ""
    mode: single
    trigger:
      - platform: template
        value_template: "{{ states('sensor.time') == ((state_attr('input_datetime.peak_morning_start_time', 'timestamp') - (states('input_number.peak_pre_time')|float * 60) ) | timestamp_custom('%H:%M', False)) }}"
    condition:
      alias: Household is home and today is peak time
      condition: and
      conditions:
        - condition: state
          entity_id: input_boolean.peak_demand_morning_today
          state: "on"
        - condition: state
          entity_id: group.household
          state: "home"
        - condition: template
          value_template: "{{ state_attr('weather.home', 'temperature') < (states('input_number.winter_summer_threshold')|float) }}"
    action:
      - scene: scene.climate_main_thermostat_home
      - scene: scene.climate_other_thermostats_home_winter
  ######
  # limate: Preheat at evening peak start time
  - alias: "Climate: Preheat at evening peak start time"
    id: "5310be81-0d3d-4a82-baf6-e4c455e5beb5"
    description: ""
    mode: single
    trigger:
      - platform: template
        value_template: "{{ states('sensor.time') == ((state_attr('input_datetime.peak_evening_start_time', 'timestamp') - (states('input_number.peak_pre_time')|float * 60) ) | timestamp_custom('%H:%M', False)) }}"
    condition:
      alias: Household is home and today is peak time
      condition: and
      conditions:
        - condition: state
          entity_id: input_boolean.peak_demand_evening_today
          state: "on"
        - condition: state
          entity_id: group.household
          state: "home"
        - condition: template
          value_template: "{{ state_attr('weather.home', 'temperature') < (states('input_number.winter_summer_threshold')|float) }}"
    action:
      - scene: scene.climate_main_thermostat_home
      - scene: scene.climate_other_thermostats_home_winter
  ######
  # Climate: Set peak mode at peak start time
  - alias: "Climate: Set peak mode at peak start time"
    id: "f2a9c6d3-6e3c-46bd-a72f-843c48e6ba80"
    description: ""
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.peak_time_now
        from: "off"
        to: "on"
    condition:
      # if it is peak time then the temp must be below threshold, but we check anyways
      alias: Only do this if the temperature is below threshold and household is home
      condition: and
      conditions:
        - condition: state
          entity_id: group.household
          state: "home"
        - condition: template
          value_template: "{{ state_attr('weather.home', 'temperature') < (states('input_number.winter_summer_threshold')|float) }}"
    action:
      - scene: scene.climate_all_thermostats_peak_time
  ######
  # Climate: Reset peak mode at evening peak end time
  - alias: "Climate: Reset peak mode at peak end time"
    id: "957f2036-23a9-42c2-92e5-bb03cf7445eb"
    description: ""
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.peak_time_now
        from: "on"
        to: "off"
    condition: []
    action:
      - alias: Set home/sleep/away mode appropriately
        choose:
          - conditions:
              - condition: state
                entity_id: sensor.house_mode
                state: "Home"
            sequence:
              - scene: scene.climate_main_thermostat_home
              - scene: scene.climate_other_thermostats_home_winter
          - conditions:
              - condition: state
                entity_id: sensor.house_mode
                state: "Sleep"
            sequence:
              - scene: scene.climate_main_thermostat_sleep_2
              - scene: scene.climate_other_thermostats_sleep_winter
        default:
          - scene: scene.climate_main_thermostat_away
          - scene: scene.climate_other_thermostats_away_winter
  ######
  # Climate: Preheat before morning wake time or at wake time
  - alias: "Climate: Preheat before morning wake time or at wake time"
    id: "e950b43b-0314-4f9b-9092-08cfd87e9b74"
    description: ""
    mode: single
    trigger:
      - platform: template
        value_template: "{{ states('binary_sensor.workday_today') == 'off' and states('sensor.time') == ((state_attr('input_datetime.holiday_wakeup_time', 'timestamp') - (states('input_number.peak_pre_time')|float * 60) ) | timestamp_custom('%H:%M', False)) }}"
      - platform: template
        value_template: "{{ states('binary_sensor.workday_today') == 'on' and states('sensor.time') == ((state_attr('input_datetime.work_wakeup_time', 'timestamp') - (states('input_number.peak_pre_time')|float * 60) ) | timestamp_custom('%H:%M', False)) }}"
      - platform: template
        value_template: "{{ states('binary_sensor.workday_today') == 'off' and states('sensor.time') == ( state_attr('input_datetime.holiday_wakeup_time', 'timestamp') | timestamp_custom('%H:%M', False) ) }}"
      - platform: template
        value_template: "{{ states('binary_sensor.workday_today') == 'on' and states('sensor.time') == ( state_attr('input_datetime.work_wakeup_time', 'timestamp') | timestamp_custom('%H:%M', False) ) }}"
    condition:
      alias: Household is home and NOT peak time now
      condition: and
      conditions:
        - condition: state
          entity_id: sensor.peak_time_now
          state: "off"
        - condition: state
          entity_id: group.household
          state: "home"
    action:
      - scene: scene.climate_main_thermostat_home
      - alias: Also set the other thermostats if temp is below threshold
        choose:
          - conditions:
              - condition: template
                value_template: "{{ state_attr('weather.home', 'temperature') < (states('input_number.winter_summer_threshold')|float) }}"
            sequence:
              - scene: scene.climate_other_thermostats_home_winter
        default:
          - scene: scene.climate_other_thermostats_summer
  ######
  # Climate: Pre Cool or stop heating before sleep time or at sleep time
  - alias: "Climate: Pre Cool or stop heating before sleep time or at sleep time"
    id: "9684f644-4b38-4782-8de5-3d81c3448622"
    description: ""
    mode: single
    trigger:
      - platform: template
        value_template: "{{ states('binary_sensor.workday_tomorrow') == 'off' and states('sensor.time') == ((state_attr('input_datetime.holiday_quiet_time', 'timestamp') - (states('input_number.peak_pre_time')|float * 60) ) | timestamp_custom('%H:%M', False)) }}"
      - platform: template
        value_template: "{{ states('binary_sensor.workday_tomorrow') == 'on' and states('sensor.time') == ((state_attr('input_datetime.work_quiet_time', 'timestamp') - (states('input_number.peak_pre_time')|float * 60) ) | timestamp_custom('%H:%M', False)) }}"
      - platform: template
        value_template: "{{ states('binary_sensor.workday_tomorrow') == 'off' and states('sensor.time') == ( state_attr('input_datetime.holiday_quiet_time', 'timestamp') | timestamp_custom('%H:%M', False) ) }}"
      - platform: template
        value_template: "{{ states('binary_sensor.workday_tomorrow') == 'on' and states('sensor.time') == ( state_attr('input_datetime.work_quiet_time', 'timestamp') | timestamp_custom('%H:%M', False) ) }}"
    condition:
      alias: Household is home and NOT peak time now
      condition: and
      conditions:
        - condition: state
          entity_id: sensor.peak_time_now
          state: "off"
        - condition: state
          entity_id: group.household
          state: "home"
    action:
      - scene: scene.climate_main_thermostat_sleep_2
      - alias: Also set the other thermostats if temp is below threshold
        choose:
          - conditions:
              - condition: template
                value_template: "{{ state_attr('weather.home', 'temperature') < (states('input_number.winter_summer_threshold')|float) }}"
            sequence:
              - scene: scene.climate_other_thermostats_sleep_winter
        default:
          - scene: scene.climate_other_thermostats_summer
  ######
  # Peak Time: Set tomorrow's morning values
  - alias: "Peak Time: Set tomorrows morning value"
    id: "ebf235ee-74cf-45d4-8eec-054eb3c03e6a"
    description: ""
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.peak_demand_morning_notification
        from: "off"
        to: "on"
    condition: []
    action:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.peak_demand_morning_tomorrow
  ######
  # Peak Time: Set tomorrow's evening values
  - alias: "Peak Time: Set tomorrows evening value"
    id: "73f52595-c64e-41ea-b437-aa13272ffb31"
    description: ""
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.peak_demand_evening_notification
        from: "off"
        to: "on"
    condition: []
    action:
      - service: input_boolean.turn_on
        target:
          entity_id: input_boolean.peak_demand_evening_tomorrow
  ######
  # Peak Time: Copy tomorrow's values
  - alias: "Peak Time: Copy tomorrows values"
    id: "0dd12a22-7418-426a-9439-402cce7bb7e5"
    description: ""
    mode: single
    trigger:
      - platform: time
        at: 00:01:00
    condition: []
    action:
      - alias: Copy morning value and set tomorrow to off
        choose:
          - conditions:
              - condition: state
                entity_id: input_boolean.peak_demand_morning_tomorrow
                state: "on"
            sequence:
              - service: input_boolean.turn_on
                target:
                  entity_id: input_boolean.peak_demand_morning_today
        default:
          - service: input_boolean.turn_off
            target:
              entity_id: input_boolean.peak_demand_morning_today
      - alias: Copy evening value and set tomorrow to off
        choose:
          - conditions:
              - condition: state
                entity_id: input_boolean.peak_demand_evening_tomorrow
                state: "on"
            sequence:
              - service: input_boolean.turn_on
                target:
                  entity_id: input_boolean.peak_demand_evening_today
        default:
          - service: input_boolean.turn_off
            target:
              entity_id: input_boolean.peak_demand_evening_today
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.peak_demand_morning_tomorrow
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.peak_demand_evening_tomorrow
  ######
  # Climate: Household leaves
  - alias: "Climate: Household leaves"
    id: 0e666717-db83-4d67-b784-eca6edc92431
    description: When everyone leaves
    mode: single
    trigger:
      - platform: state
        entity_id: group.household
        from: home
        to: not_home
    condition: []
    action:
      - scene: scene.climate_main_thermostat_away
      - alias: Also set the other thermostats if temp is below threshold
        choose:
          - conditions:
              - condition: template
                value_template: "{{ state_attr('weather.home', 'temperature') < (states('input_number.winter_summer_threshold')|float) }}"
            sequence:
              - scene: scene.climate_other_thermostats_away_winter
        default:
          - scene: scene.climate_other_thermostats_summer
  ######
  # Climate: Household Arrives
  - alias: "Climate: Household Arrives"
    id: 0c6be006-26e6-4d15-b6d4-0615c3aca80f
    description: When first person arrives
    mode: single
    trigger:
      - platform: state
        entity_id: group.household
        from: not_home
        to: home
    condition: []
    action:
      - alias: For the main thermostat, if it is past sleep time, then set to sleep, otherwise home
        choose:
          - conditions:
              - condition: state
                entity_id: sensor.house_mode
                state: "Sleep"
            sequence:
              - scene: scene.climate_main_thermostat_sleep_2
        default:
          - scene: scene.climate_main_thermostat_home
          - scene: scene.mm_monitor_on
      - alias: Also set the other thermostats depending on sleep mode and current temperature
        choose:
          - conditions:
              - condition: state
                entity_id: sensor.house_mode
                state: "Sleep"
              - condition: template
                value_template: "{{ state_attr('weather.home', 'temperature') < (states('input_number.winter_summer_threshold')|float) }}"
            sequence:
              - scene: scene.climate_other_thermostats_sleep_winter
          - conditions:
              - condition: state
                entity_id: sensor.house_mode
                state: "Home"
              - condition: template
                value_template: "{{ state_attr('weather.home', 'temperature') < (states('input_number.winter_summer_threshold')|float) }}"
            sequence:
              - scene: scene.climate_other_thermostats_home_winter
        default:
          - scene: scene.climate_other_thermostats_summer
read more

19

Jul
2019
Comments Off on Fixing a bricked EdgeRouter Lite

Fixing a bricked EdgeRouter Lite

Last week the EdgeRouter I use for my office did not come back after a reboot or perhaps I was too impatient, so I tried to reset it and that is when things went wrong.

Long story short, somehow I got the router into a state where it would not boot up anymore and the only way into it was the console port, for which I did not have a cable. Then I managed to find an old article which messed up my the routers USB drive so things took a turn for the worst. But fear not, it all worked out in the end, even though the only help I got from UBNT support was absolute zilch.

Here I outline some useful links for anyone else that may run into this issue, but mostly so I have it documented for next time ;). Before I get started here, the credit on everything here goes to others who documented this well on various locations.

Connecting to the console

In order to connect to the console, you will need a USB to RJ45 cable. I bought one off of Amazon which worked great right out of the box for me.

In order to connect (on a Mac), all you need to do is run:

> ls -ltr /dev/*usb*
crw-rw-rw-  1 root  wheel   21,   3 Jul  17 15:48 /dev/cu.usbserial-AI038TPF
crw-rw-rw-  1 root  wheel   21,   2 Jul  17 08:56 /dev/tty.usbserial-AI038TPF

> screen /dev/tty.usbserial-AI038TPF 115200

Useful links

There are a few links that were helpful here and I have them listed here, but I am going to outline what I had to do ultimately since I followed the first one and it messed me up more.

(ARCHIVED) EdgeRouter – Last Resort Recovery – DO NOT USE, Only as reference.

Recovering an unresponsive Ubiquiti EdgeRouter Lite router – DO NOT USE, Only as reference

EdgeRouter – Manual TFTP Recovery – Try this link first.

mkeosfs – easily generate USB image for EdgeRouter

mkeosimg

The third link above is perhaps the first thing you should try if you have not messed up your router bad enough, but I had to use the 4th and 5th links.

The EdgeRouter’s USB Drive

I kept reading about this, and could not believe that there was a usb drive in the edge router, but I guess ultimately that was a good design for when it goes bad and these routers used to have a history of the drives going bad.

There are three screws on the back of the router that you can open and the router comes apart (Note: you may void your warranty by doing this). Then the flash drive is right in your face.

ER-Lite with the USB drive pulled out

Recovering the file system

Once the USB drive is unplugged, connect it to your PC/Mac and run the commands to recreate the drive. I found the easiest way was to use the mkeosdrive script provided in the last link above.

I ran the commands below, but if you read the GitHub site properly, there is a way to recreate the drive and include your backup in there as well.

# Get the path to the USB drive
> sudo disk -l

# Then run the command to create the drive
> sudo ./mkeosdrive /dev/sdb ER-e100.v2.0.4.5199165.tar

Rebooting the router

Once the USB drive is ready, plug it back into your router, close things up. Then just wire it up and wait for it to boot. It should be back to normal.

I also found other links where folks talk about creating a backup of the USB drive in case something like this happens again, but what are the chances of that……right? 😉

read more

15

Apr
2018
Comments Off on Dealing with SQLite files in mobile apps

Dealing with SQLite files in mobile apps

Recently I found myself wanting to inspect what was in the application database outside of the mobile application I was working on, which as usual lead me to search for a solution on DuckDuckGo.

I found a great link here, which basically says:

  1. Download and install SQLite command line tools if necessary (OSX comes with one).
  2. Find the SQLite file you want to inspect
  3. Run the command to open the database and inspect it:
sqlite3 /Users/<username>/Library/Developer/CoreSimulator/Devices/<Simulator device ID>/data/Containers/Data/Application/<App id>/Library/Private\ Documents/_alloy_.sql 
sqlite> .tables 
user order item 
sqlite> .schema user 
CREATE TABLE user (id INETGER PRIMARY KEY, uname TEXT, fname TEXT, lname TEXT); 
sqlite>select * from user; 
1|jsmith|John|Smith
read more

11

Apr
2018
Comments Off on How to determine and set your default java version on OSX

How to determine and set your default java version on OSX

Open terminal and do the following:
[korey@localhost ~]$ cd /Library/Java/JavaVirtualMachines
[korey@localhost /Library/Java/JavaVirtualMachines]$ ls -al
This will give you a list of JDKs that you have installed. To set the default java version to 1.8.0_131 for example, use the following command:
[korey@localhost ~]$ /usr/libexec/java_home -v 1.8.0_131 --exec javac -version
Related link read more

17

Jan
2018
Comments Off on IoT Devices and Network Security

IoT Devices and Network Security

Image credits: isBuzzNews

This is going to be a multi-part post about securing your home/business network and separating your IoT devices into their own to keep them and yourself “safer”. With the explosion of IoT in the recent years, it is hard to find anything without some sort of “smart” capabilities. Whether it is a TV, Sonos, Nest thermostat, or even a fridge or a washing machine, more and more manufacturers are adding internet capabilities to their devices. This could be a topic of its own, but we are here to discuss network security. For most home owners with regular wireless gateways, there simply isn’t any possibility of creating a complex network with the stock firmware. To boot, most devices encourage or expect you to install the device on the same network as your PC or mobile so it can more easily connect. You have to either be lucky enough to own a router that can be upgraded to one of the open source firmware options, or do your research and purchase a router that is supported. Of those supported devices, you still have to be lucky enough to have one that will work well with the custom firmware. In some cases, you may have poor WiFi signal or lose a WiFi band (more about this later). The other option, is to use a used/cheap business class router. Some of these are actually cheaper than the higher end wireless routers. No matter the path you choose, you have to do lots of searching and learn a lot about networking to be able to do this sort of setup. So for the rest of this article, I’m going to provide an overview of the options and then get deeper into how the network should be setup. Follow up articles will detail specific applications or devices and how they should be setup.

Consumer grade hardware and custom firmware

This is the first option that we talked about. Here you could go with a router like the Asus AC-RT66U or the Linksys WRT series, but make sure to do your due diligence and confirm that the router you have or you want to get is supported. This includes reading the forums on other users that have setup these routers to see if they have run into issues or not. Here are some of your options for custom firmware:
  • DD-WRT – This is perhaps the most popular option and the one with the widest support for consumer grade routers. Its UI layout is smart enough that basic setup should be a breeze, but it is capable of so much more if you spend the time to dig into it.
  • Tomato – This one has a few versions, but I’ve linked to the more popular version of it. This is like DD-WRT on Steriods since it also provides you live refresh and better statistics tracking right out of the box.
  • Advanced Tomato – This is the same as Tomato but with much nicer UI. I really enjoyed using this briefly. If you like Tomato, you’e gonna love this.
  • OpenWRT / LEDE – LEDE was a fork of OpenWRT, but they have recently announced that they are merging again. This has the least number of supported devices and relieves are less frequent, but if you know your networking, its the best option. This is the only one that includes a package manager UI to you can add other packages easily through the UI. This also makes it easier to add functionality that the other firmwares may not provide out of the box.
Note: This is not for the faint of heart. you could brick your router and have a hell of a time getting it back to its stock firmware, so proceed with caution.

Business grade hardware

As a stepping stone, I recommend you play around by installing one of the custom firmwares mentioned previously on the router that you have so you get familiar with the concepts, and once you get fed up of fighting to get things working, you move up to business grade hardware. I am assuming that you are not reading this far unless you’re a noob. The options here are endless and so are the expenses, so I’ll stick to the option that I’ve had experience with (installing at costomer locations), which gives you a big bang for the buck. Ubiquiti! They provide a range of wired and wireless products that are pretty much in line with high end consumer devices in price, but from a stability and functionality perspective, they are flawless (as much as can be). For example, an Edge Router Lite 3 plus a Unifi AC Pro model can cost less than a Linksys Max-Stream AC4000 MU-MIMO Wi-Fi Tri-Band Router and provide way more functionality and most probably better performance. Setting up a network in a 2700sq.ft. space, I ended up replacing two wireless routers, with just the one Unifi AC Pro. Of course had to use the Edge Router Lite as well since the Unifi by itself does not have everything you need, and you may need a (managed) switch as well if setting up a more complex VLAN. The one downside to the Unifi line of products is that they require a controller software be running on a PC or the cloud key so you can control them (i.e. there is no web interface without the controller software), but still this is a great setup.

The Network

Now the real part. As Spiderman’s wise uncle Ben said, “With great power comes great responsibility.” So the more smart devices you have (more power), the more you need to be careful (responsible). There have been numerous articles about many smart devices that have been either communicating in the open (intentionally or otherwise) or are left open to hacking, so it only makes sense to separate these devices from the rest of your network. We’ll start with the base setup and then make things more complicated optionally. Lets talk in more detail about how this should work:
  • VLAN 10 is the business/home network. Computers and devices on this network have full internet access, as well as full access to the IoT network (VLAN 20).
  • VLAN 20 is the IoT network. This network is isolated from both the business/home network and the guest network. You could provide full internet access to this network or optionally limit access here as well to well known protocols like HTTP/S, DNS, NTP, etc.
  • VLAN 30 is the guest network which should not have access to either of the other networks; just Internet. Again, internet access here could be limited to just a few protocols as well. You could further protect yourself and your guests by using the AP isolation feature of your Wireless Access Point if it has it.
Where things get complicated is when you try to setup the firewall rules to make all this work and depending on your router the instructions are different. I’ll cover the details of the setup in future articles. read more

16

Apr
2017
Comments Off on Solving Appcelerator Compile Issue – Invalid Request

Solving Appcelerator Compile Issue – Invalid Request

After updating the Appcelerator CLI, my build started failing. The log message was not very helpful, but Google was and it lead me to this link. The gist of it is here:
result from /build-verify=> {"success":false,"error":"invalid request","code":"com.appcelerator.security.invalid.session"}, err=null
The answer, perform the following
 
[korey@localhost ~]$ appc logout                                                                                                                                                                                                                                                
Appcelerator Command-Line Interface, version 6.2.0
Copyright (c) 2014-2017, Appcelerator, Inc.  All Rights Reserved.


*** Logged Out ***

[korey@localhost ~]$ appc login                                                                                                                                                                                                                                                 
Appcelerator Command-Line Interface, version 6.2.0
Copyright (c) 2014-2017, Appcelerator, Inc.  All Rights Reserved.

Appcelerator Login required to continue ...

? Appcelerator ID: me@company.com
? Password: *********
Generating Developer Certificate and Private/Public Keys...
me@company.com logged into organization company.com [100011118]
read more

28

Jun
2015
Comments Off on Manage Apache on OSX (Updated or Yosemite)

Manage Apache on OSX (Updated or Yosemite)

Here is a little tip for customizing apache on OSX. The first thing you have to do is turn on Web Sharing in your System Preferences. This will start the local Apache server and you can access it by going to http://localhost. From here, you can start modifying it to your will. Apache customization is a big topic and you can find all you need on the Apache website. Here are a few tips:
  • Apache is installed at: /etc/apache2
  • Apache config is at: /etc/apach2/httpd.conf
  • Apache user config is at: /etc/apach2/users/<username>.conf
  • Apache extra config is at: /etc/apach2/extra/*.conf
  • You can customize your own virtual server by modifying: /etc/apach2/users/<username>.conf
  • You can start/stop Apache by:
    • Enabling/disabling Web Sharing in System Preferences
    • running the following in terminal:
      sudo apachectl 
In order for you to get going and have a user directory, you will need to make sure the following is done.
  • Create folder to host your files (e.g. /Users/<my_username>/Sites/)
  • Create an index file in the above folder with a message so you know when it is working.
  • In /etc/apach2/httpd.conf, make sure:
    • userdir_module is loaded (i.e. not commented out).
      LoadModule userdir_module libexec/apache2/mod_userdir.so
    • httpd-userdir.conf is included.
      Include /etc/apache2/extra/httpd-userdir.conf
  • In /etc/apache2/extra/httpd-userdir.conf, make sure that user configuration files are included.
    Include /private/etc/apache2/users/*.conf
  • In /etc/apache2/users, make sure to create a user file for yourself (note: you will have to use sudo to make sure permissions on the file are set to 644 and owned by root:wheel).
    /etc/apache2/users/<my_username>.conf
    Contents:
    <Directory "/Users/<my_username>/Sites/">
      Options Indexes MultiViews
      AllowOverride All
      Require all granted
      DirectoryIndex index.html
    </Directory>
At this point you can should be able to start (or restart) Apache and test your setup. http://localhost/~<my_username> read more

10

Apr
2015
Comments Off on Have you ordered your Apple Watch?

Have you ordered your Apple Watch?

awatchThe Apple Watch went on sale starting 3AM EST this morning, and its shipping date has already slipped to June, but was it a success? This is exactly what many are trying to determine since Apple got super smart about how it handled the launch. While you can go to an Apple Store to get a feel for the new gadget, you cannot buy one in store. Instead, you will have to go to the Apple Online Store to order it. In this way, Apple can shield itself in case the launch is not the success many have come to expect since it will not release those numbers immediately or even at all unless they are record breaking. Given how expensive the watch is, and how people have come to expect their electronics to be replaced every year with the latest iteration, I know many folks who are very skeptical. More specifically, the first iteration of many products is never as good as the second. Remember the iPad 2? it was the longest lasting Apple gadget that I recall….in fact it is still relevant and upgradable to iOS8. So the big question here is will Apple release a new watch next year? I certainly hope that the Apple Watch has a much slower release cycle than other Apple products given its cost. Most likely future versions will just be iterative improvements in battery and screen, rather than a complete replacement like the iPhone’s current 2 year life cycle. Only time will tell now. read more

18

Mar
2015

Getting Fancy with Terminal

One of my recent adventures into NodeJS has led me down the path of MEAN and reading various articles on that, I came across various Terminal alternatives and enhancements. I know, I know, I am late to the party, but when I saw FishShell, I was sold. Then I saw Powerline and liked that too, so here is how to set these up. First thing is to make sure you have Homebrew installed. Then you can install fish simply by running the following command:
[korey@localhost ~]$ brew install fish
Now that fish is installed, you will have a few options in making it your default shell. Homebrew provides instructions already, but I just wanted it on my account for Terminal, so I changed the shell command in Terminal’s preferences. term_prefs Great, now you can use fish anytime you open terminal, but what about getting Powerline setup? The instructions are here, but I will include what I did here for completeness.
[korey@localhost ~]$ brew install python
[korey@localhost ~]$ pip install powerline-status
The next step is to install the patched fonts so your prompt will not have strange characters on it. For this part, you need to download the patched fonts zip from github, and then run the install.sh script included there. The last step here is equally important; you should change the font used by your selected terminal profile to one of the fonts for Powerline. term_prefs2 Now that Powerline is installed, you will need to update your Fish config to load it.
[korey@localhost ~]$ vi ~/.config/fish/config.fish
# source autojump
[ -f /usr/local/share/autojump/autojump.fish ]; and . /usr/local/share/autojump/autojump.fish

#source powerline
set fish_function_path $fish_function_path "/usr/local/lib/python2.7/site-packages/powerline/bindings/fish"
powerline-setup
My last step was to install auto jump, which is another great tool and you can see that it has also been included in the above listing in my Fish config.
[korey@localhost ~]$ brew install autojump
You should now end up with a autocomplete terminal similar to this: terminal read more

17

Mar
2015
Comments Off on Installing MongoDB on OSX (Yosemite)

Installing MongoDB on OSX (Yosemite)

Installing MongoDB on OS X is an easy task. However, if you want the service to start each time your computer is restarted, some additional effort is required. The easiest way to get MongoDB installers is to use Homebrew.
[korey@localhost ~]$ brew install mongodb
At this point MongoDB is installed. To start it manually, first create the location where the DB will be stored (default is /data/db):
[korey@localhost ~]$ mkdir /data/db
[korey@localhost ~]$ mongd
Note that the user running mongod needs to have write access to the DB folder. The downside here is that the DB needs to be started manually each time and it will run as your userid. In order to automatically start the service, it is necessary to create a LaunchDaemon which will allow the service to start as soon as the computer starts.
    1. The first step is to create a service account so the service does not run as root. 2. Next, is to create a proper location for the log and database location:
    [korey@localhost ~]$ sudo mkdir -p /var/lib/mongodb
    [korey@localhost ~]$ sudo mkdir -p /var/log/mongo
    [korey@localhost ~]$ sudo chown -R _mongo:_mongo /var/lib/mongodb
    [korey@localhost ~]$ sudo chown -R _mongo:_mongo /var/log/mongo
    
    3. Now that we have an account and location, it is time to create the daemon plist file:
    
    
    
      
        Label
        org.mongo.mongod
        ProgramArguments
        
          /usr/local/bin/mongod
          --dbpath
          /var/lib/mongodb/
          --logpath
          /var/log/mongo/mongodb.log
        
        KeepAlive
        
        UserName
        _mongo
        GroupName
        _mongo    
      
    
    
    Store this file at: /Library/LaunchDaemons and name it: org.mongo.mongod.plist.
Now you can start and stop the service without having to restart your computer by using the following commands:
[korey@localhost ~]$ sudo launchctl load /Library/LaunchDaemons/org.mongo.mongod.plist
[korey@localhost ~]$ sudo launchctl unload /Library/LaunchDaemons/org.mongo.mongod.plist
read more

Page 1 of 912345...Last »