Skip to content

Commit

Permalink
Count up (#14)
Browse files Browse the repository at this point in the history
* Handle Scandanavian characters

* Add count up option

* Update README.md

* Update info.md

* Update README.md

* Update README.md

* Update info.md
  • Loading branch information
Marc Forth committed May 16, 2020
1 parent 0b3ba57 commit 8fc440e
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 39 deletions.
36 changes: 33 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ A python script for Homeassistant that counts down the days to birthdays, annive
[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg?style=for-the-badge)](https://github.com/custom-components/hacs)

## How it works
This script creates a sensor that a counts down to the next occurrance of a date, like a birthday or anniversary and gives the number of years as an attribute
This script creates a sensor that a counts down to the next occurrence of a date, like a birthday or anniversary and gives the number of years as an attribute.

You can optionally reverse the counter so it counts up from the last occurrence of a date, such as when you quit smoking.

Requires `python_script:` to be enabled in your configuration

Expand All @@ -19,6 +21,7 @@ key | required | type | description
`date:` | True | string | Date, in format DD/MM/YYYY
`friendly_name:` | False | string | Display name of the sensor
`icon:` | False | string | Icon of the sensor, defaults to 'mdi:calendar-star'
`reverse:` | False | boolean | Reverses the sensor to count up instead of down. (Defaults to False)

The date can be in the future if you want to countdown to the date itself, and then the anniversaries thereafter.

Expand All @@ -38,6 +41,12 @@ icon: "mdi:ICON_OF_DATE"
friendly_name: FRIENDLY_NAME_OF_DATE
```

And you can reverse the sensor so it counts up from a date:

```
reverse: True
```

examples:

```
Expand All @@ -55,6 +64,15 @@ date: 14/02/1994
icon: "mdi:ring"
```

or

```
name: Quit Smoking
type: celebration
date: 01/10/2008
reverse: True
```

## Generated sensors
Each sensor is given the following automatically:

Expand All @@ -66,7 +84,7 @@ nextoccur: <Date of next occurance>
years: <Number of years it will be>
```

So, the two sensors we created above would come out as:
So, the three sensors we created above would come out as:

```
sensor.birthday_john
Expand All @@ -80,12 +98,18 @@ friendly_name: Our wedding anniversary
state: However many days to 14th February
nextoccur: 14/02/YYYY (either this year or next year as appropriate)
years: How many years you will have been married on that day
sensor.celebration_quit_smoking
friendly_name: Quit smoking celebration
state: However many days SINCE 1st October
nextOccur: 01/10/YYYY (either this year or next year as appropriate)
years: How many years SINCE you quit smoking
```

Note that if the type is 'birthday' the sensor will automatically add an apostrophe.

## Example configuration.yaml entry
An example automation to create and refresh the above two sensors daily would be:
An example automation to create and refresh the above three sensors daily would be:

```yaml
automation:
Expand All @@ -107,6 +131,12 @@ automation:
type: anniversary
date: 14/02/1994
icon: "mdi:ring"
- service: python_script.date_countdown
data:
name: Quit smoking
type: celebration
date: 01/10/2008
reverse: True
```

## Example automation
Expand Down
36 changes: 33 additions & 3 deletions info.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## How it works
This script creates a sensor that a counts down to the next occurrance of a date, like a birthday or anniversary and gives the number of years as an attribute
This script creates a sensor that a counts down to the next occurrence of a date, like a birthday or anniversary and gives the number of years as an attribute.

You can optionally reverse the counter so it counts up from the last occurrence of a date, such as when you quit smoking.

Requires `python_script:` to be enabled in your configuration

Expand All @@ -14,6 +16,7 @@ key | required | type | description
`date:` | True | string | Date, in format DD/MM/YYYY
`friendly_name:` | False | string | Display name of the sensor
`icon:` | False | string | Icon of the sensor, defaults to 'mdi:calendar-star'
`reverse:` | False | boolean | Reverses the sensor to count up instead of down. (Defaults to False)

The date can be in the future if you want to countdown to the date itself, and then the anniversaries thereafter.

Expand All @@ -33,6 +36,12 @@ icon: "mdi:ICON_OF_DATE"
friendly_name: FRIENDLY_NAME_OF_DATE
```

And you can reverse the sensor so it counts up from a date:

```
reverse: True
```

examples:

```
Expand All @@ -50,6 +59,15 @@ date: 14/02/1994
icon: "mdi:ring"
```

or

```
name: Quit Smoking
type: celebration
date: 01/10/2008
reverse: True
```

## Generated sensors
Each sensor is given the following automatically:

Expand All @@ -61,7 +79,7 @@ nextoccur: <Date of next occurance>
years: <Number of years it will be>
```

So, the two sensors we created above would come out as:
So, the three sensors we created above would come out as:

```
sensor.birthday_john
Expand All @@ -75,12 +93,18 @@ friendly_name: Our wedding anniversary
state: However many days to 14th February
nextoccur: 14/02/YYYY (either this year or next year as appropriate)
years: How many years you will have been married on that day
sensor.celebration_quit_smoking
friendly_name: Quit smoking celebration
state: However many days SINCE 1st October
nextOccur: 01/10/YYYY (either this year or next year as appropriate)
years: How many years SINCE you quit smoking
```

Note that if the type is 'birthday' the sensor will automatically add an apostrophe.

## Example configuration.yaml entry
An example automation to create and refresh the above two sensors daily would be:
An example automation to create and refresh the above three sensors daily would be:

```yaml
automation:
Expand All @@ -102,6 +126,12 @@ automation:
type: anniversary
date: 14/02/1994
icon: "mdi:ring"
- service: python_script.date_countdown
data:
name: Quit smoking
type: celebration
date: 01/10/2008
reverse: True
```

## Example automation
Expand Down
85 changes: 52 additions & 33 deletions python_scripts/date_countdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
today = datetime.datetime.now().date()
name = data.get('name')
eventType = data.get('type')
countup = data.get('reverse' , False)
defaultFriendlyName = ''
numberOfDays = 0

defaultIcon = "mdi:calendar-star"

# Convert the date we got
dateStr = data.get('date')
Expand All @@ -29,52 +30,70 @@
nextOccurYear = int(today.year)
nextOccur = datetime.date(nextOccurYear , dateMonth , dateDay)

if nextOccur < date:
# date must be the first occurrence
nextOccur = date
# If countup (reverse == true)
if countup:
defaultIcon = "mdi:calendar-arrow-right"
years = today.year - date.year

if nextOccur < today:
#if event has passed this year, get days between then and today
numberOfDays = (today - nextOccur).days

else:
# Count days from last year
lastYearDate = datetime.date(today.year - 1 , dateMonth, dateDay)
numberOfDays = (today - lastYearDate).days


# Regular countdown
else:
if nextOccur < date:
# date must be the first occurrence
nextOccur = date

if nextOccur < today:
# if event has passed this year, nextOccur is next year
nextOccurYear = nextOccurYear + 1
nextOccur = datetime.date(nextOccurYear, dateMonth, dateDay)
if nextOccur < today:
# if event has passed this year, nextOccur is next year
nextOccurYear = nextOccurYear + 1
nextOccur = datetime.date(nextOccurYear, dateMonth, dateDay)

years = nextOccurYear - dateYear
years = nextOccurYear - dateYear

if years < 0:
# if years is negative, then date is more than 365 days away
# nextOccur will be the first occurrence
years = 0
if years < 0:
# if years is negative, then date is more than 365 days away
# nextOccur will be the first occurrence
years = 0

numberOfDays = (nextOccur - today).days
numberOfDays = (nextOccur - today).days


# Set the default friendly name
if eventType.lower() == 'birthday':
# add an apostophe for birthdays
defaultFriendlyName = "{}'s {}".format(name , eventType)
# add an apostophe for birthdays
defaultFriendlyName = "{}'s {}".format(name , eventType)
else:
defaultFriendlyName = "{} {}".format(name , eventType)
defaultFriendlyName = "{} {}".format(name , eventType)


# Sanitise the entity_id to meet the criteria by
# replacing Scandanavian characters and spaces
name1 = name.replace("Æ" , "AE")
name2 = name1.replace("Ø" , "O")
name3 = name2.replace("Å" , "AA")
name4 = name3.replace("æ" , "ae")
name5 = name4.replace("ø" , "o")
name6 = name5.replace("å" , "aa")
safeName = name6.replace(" " , "_")
sensorName = "sensor.{}_{}".format(eventType , safeName)
rawName = "{}_{}".format(eventType , name)
rawName1 = rawName.replace("Æ" , "AE")
rawName2 = rawName1.replace("Ø" , "O")
rawName3 = rawName2.replace("Å" , "AA")
rawName4 = rawName3.replace("æ" , "ae")
rawName5 = rawName4.replace("ø" , "o")
rawName6 = rawName5.replace("å" , "aa")
safeName = rawName6.replace(" " , "_")
sensorName = "sensor.{}".format(safeName)


# Send the sensor to homeassistant
hass.states.set(sensorName , numberOfDays ,
{
"icon" : data.get("icon", "mdi:calendar-star"),
"unit_of_measurement" : "days" ,
"friendly_name" : data.get('friendly_name', defaultFriendlyName),
"nextoccur" : "{}/{}/{}".format(nextOccur.day , nextOccur.month , nextOccur.year) ,
"years" : years
}
)
{
"icon" : data.get("icon", defaultIcon),
"unit_of_measurement" : "days" ,
"friendly_name" : data.get('friendly_name', defaultFriendlyName),
"nextoccur" : "{}/{}/{}".format(nextOccur.day , nextOccur.month , nextOccur.year) ,
"years" : years
}
)

0 comments on commit 8fc440e

Please sign in to comment.