Simple birthday reminder

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
janpep
Posts: 270
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2025.1
Location: Netherlands
Contact:

Simple birthday reminder

Post by janpep »

I want to share a simple birthday reminder script.
-- Fill table with your birthday calendar information. Two friends are added as an example.
-- Enter the mailto.
-- Create an alert device.
-- Schedule this script once per day.
-- The script looks at who's birthday is tomorrow.
-- It updates the alert device with date, name and age and sends email notification when found.

When no one is found:
BirthdayReminder-1.png
BirthdayReminder-1.png (8.85 KiB) Viewed 1600 times
When one or more are found:
BirthdayReminder-2.png
BirthdayReminder-2.png (9.99 KiB) Viewed 1600 times

Code: Select all

-- 21-03-2024- Jan Peppink, https://ict.peppink.nl
-- Fill table with your birthday calendar information.
-- Enter the mailto.
-- Create an alert device.
-- Schedule this script once per day.
-- The script looks at who's birthday is tomorrow.
-- It updates the alert device with date, name and age and sends email notification when found.
--
return {
	on = {
		timer = {
			'at 12:05',     -- Run once per day
			                -- Before - birthday(s) of today are shown.
			                -- After - birthday(s) of tomorrow are shown.
		}
	},
--	logging = {
--		level = domoticz.LOG_INFO,
--		marker = 'BirthdayReminder-',
--	},
	execute = function(domoticz, timer)
		-- Set Local environment=================
		-- loging level 0 = NO logging, 1 = INFO, 2 = DEBUG, 3 = ERROR or 4 = FORCE
		local debug_level = 2
		local _u = domoticz.utils
--		local _h = domoticz.helpers

		local dmTomorrow = domoticz.time.dateToDate(domoticz.time.rawDate, 'yyyy-mm-dd', 'dd-mm', 86400 )  -- Day and month tomorrow
		local mailContent = ''

		local alertIdx = n                        -- Set to the idx of the Virtual Alert sensor you have to create for this script
		local alertLevel = domoticz.ALERTLEVEL_GREY -- Holds the alertLevel (color) to set
		local alertText = ''
		local mailto = '[email protected]'     -- Set E-mail adres to sent to.

		-- Local Functions go here =============
		function split(str, character)
			result = {}
			index = 1
			for s in string.gmatch(str, "[^"..character.."]+") do
				result[index] = s
				index = index + 1
			end
			return result
		end

		-- Translate local day and month names
		--local lDday = {"zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"}
		local lmonthnames = {'januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'october', 'november', 'december'}
		local nextDay = domoticz.time.makeTime(domoticz.time.dateToDate(domoticz.time.rawDate, 'yyyy-mm-dd', 'yyyy-mm-dd hh:mm:ss', 86400))
		--local TestDate = lmonthnames[nextDay.wday] .. ' '..string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ' ' .. tostring(nextDay.year)

		--Create table birthdayarray
		birthdayarray = {}
		--january
		--february
		--march
		table.insert(birthdayarray, "1993-03-22;Your Friend1")
		table.insert(birthdayarray, "2001-03-22;Your Friend2")
		--april
		--may
		--june
		--july
		--august
		--september
		--october
		--november
		--december

		-- Now start to do something ============
		local loopcounter = 0
		for key,value in ipairs(birthdayarray) do
			local currentdayarray = split(value, ";")
			local dateFound = currentdayarray[1]
			local nameFound = currentdayarray[2]
			local dmBirthdayFound = domoticz.time.dateToDate(dateFound,'yyyy-mm-dd', 'dd-mm', 0 )  -- Day and month
			
			if dmTomorrow == dmBirthdayFound then
			    --Found someone for tomorrow. Calculate age
				local age = nextDay.year - domoticz.time.dateToDate(dateFound,'yyyy-mm-dd', 'yyyy', 0 )
				-- strip the .0 from the end of the age.
				age = _u.round(age,0)

				if loopcounter > 0 then
					-- Add a newline first when more than one birtday is found.
					alertText = alertText .. string.char(10)
					mailContent = mailContent .. '<br>'
				end 
				-- Add current content to the string
				alertText = alertText .. string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ': ' .. nameFound .. ' <span style="color: red;">' .. age .. '</span>' .. ' jaar!'
				mailContent = mailContent .. string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ': ' .. nameFound .. ' ' .. age .. ' jaar!'

				loopcounter = loopcounter + 1
			end
		end

		if mailContent ~= '' then
			domoticz.email( 'Morgen jarig!', mailContent, mailto )
			--
			alertLevel = domoticz.ALERTLEVEL_GREEN
			domoticz.devices(alertIdx).updateAlertSensor(alertLevel, alertText)
		else
		    alertLevel = domoticz.ALERTLEVEL_GREY
			alertText = string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ': Geen jarigen.'
			domoticz.devices(alertIdx).updateAlertSensor(alertLevel, alertText)
		end
	end
}
Dz on Ubuntu VM on DS718+ behind FRITZ!Box.
EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; Sonoff USB-Dongle Plus-E; Zigbee2Mqtt; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
Huntback
Posts: 28
Joined: Monday 02 January 2017 14:35
Target OS: NAS (Synology & others)
Domoticz version: 2024.2
Location: Apeldoorn
Contact:

Re: Simple birthday reminder

Post by Huntback »

Hello janpep,
Nice script, thank you.
Synology - DS411+II
Synology - DS918+
RFXCOM - RFXtrx433XL (LAN)
Oregon - Weatherstation
Some KAKU, Impuls, TFA, etc.
janpep
Posts: 270
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: Simple birthday reminder

Post by janpep »

Update of t-BirthdayReminder
I made a few changes to adapt to my current 'standard'.
- Some renaming and reordering, but same functionality.
- Placed 'Your settings', including the birthday table in the front.
- Made use of the stringSplit in dz.utils and removed the local split function.

Code: Select all

-- 21-03-2024- Jan Peppink, https://ict.peppink.nl
-- Fill table with your birthday calendar.
-- Enter the mailto.
-- Create an alert device.
-- Schedule this script once per day.
-- The script looks at who's birthday is tomorrow.
-- It updates the alert device with date, name and age and sends email notification when found.
-- 22-06-2024 Modified to my current standard. Placed 'Your settings', including the birthday table in the front.
--    Some renaming and changing order, but same functionality.
--    Replaced local split function for dz.utils.stringSplit function.

--- Your settings ----------------------------------------------------------------
-- First set the used device index numbers and variables you might want to change.
local bd_alertIdx = 99999                -- Set to the idx of the Virtual Alert sensor you have to create for this script
local bd_mailTo = '[email protected]'     -- Set E-mail adres to sent to.

--Create table with the birthdays.
local bd_table = {}
--january
--february
--march
--april
--may
--june
table.insert(bd_table , "1993-06-23;Your Friend 1")
table.insert(bd_table , "2001-06-23;Your Friend 2")
--july
--august
--september
--october
--november
--december

--------------------------------------------------------------------------------        
return {
	on = {
		timer = {
			'at 12:05',     -- Run once per day
			                -- Before time - birthday(s) of today are shown.
			                -- After time - birthday(s) of tomorrow are shown.
		}
	},
	logging = {
	    -- Level can be domoticz.LOG_INFO, domoicz.LOG_MODULE_EXEC_INFO, domoticz.LOG_DEBUG, domoticz.LOG_ERROR or domoticz.LOG_FORCE
        level = domoticz.LOG_INFO,
        --level = domoticz.LOG_DEBUG,
        marker = "Birthdayreminder-"
	},
	execute = function( dz, triggeredItem )
		-- Set Local environment=================
        local _u = dz.utils       -- Holds subset of handy utilities.
        --local _h = dz.helpers     -- Holds the global functions.
        --local _d = dz.globalData  -- Holds the global data.

		local dmTomorrow = dz.time.dateToDate(dz.time.rawDate, 'yyyy-mm-dd', 'dd-mm', 86400 )  -- Day and month tomorrow
		local mailContent = ''

		local alertLevel = dz.ALERTLEVEL_GREY -- Holds the alertLevel (color) to set
		local alertText = ''

		-- Local Functions go here =============


		-- Translate local day and month names
		--local lDday = {"zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"}
		local lmonthnames = {'januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'october', 'november', 'december'}
		local nextDay = dz.time.makeTime(dz.time.dateToDate(dz.time.rawDate, 'yyyy-mm-dd', 'yyyy-mm-dd hh:mm:ss', 86400))
		--local TestDate = lmonthnames[nextDay.wday] .. ' '..string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ' ' .. tostring(nextDay.year)

		-- Now start to do something ============
		local loopcounter = 0
		for key, value in ipairs(bd_table) do
			local currentdayarray = _u.stringSplit( value, ";")
			local dateFound = currentdayarray[1]
			local nameFound = currentdayarray[2]
			local dmBirthdayFound = dz.time.dateToDate(dateFound,'yyyy-mm-dd', 'dd-mm', 0 )  -- Day and month
			
			if dmTomorrow == dmBirthdayFound then
			    --Found someone for tomorrow. Calculate age
				local age = nextDay.year - dz.time.dateToDate(dateFound,'yyyy-mm-dd', 'yyyy', 0 )
				-- strip the .0 from the end of the age.
				age = _u.round( age, 0 )

				if loopcounter > 0 then
					-- Add a newline first when more than one birtday is found.
					alertText = alertText .. string.char(10)
					mailContent = mailContent .. '<br>'
				end 
				-- Add current content to the string
				dz.log( 'Found: ' ..     string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ': ' .. nameFound .. ' ' .. age .. ' jaar.', dz.LOG_DEBUG )
				alertText = alertText .. string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ': ' .. nameFound .. ' <span style="color: red;">' .. age .. '</span>' .. ' jaar!'
				mailContent = mailContent .. string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ': ' .. nameFound .. ' ' .. age .. ' jaar!'

				loopcounter = loopcounter + 1
			end
		end

		if mailContent ~= '' then
			dz.email( 'Morgen jarig!', mailContent, bd_mailTo, 0 )
			--
			alertLevel = dz.ALERTLEVEL_GREEN
			dz.devices(bd_alertIdx).updateAlertSensor( alertLevel, alertText )
		else
		    alertLevel = dz.ALERTLEVEL_GREY
			alertText = string.format( "%02d", nextDay.day ) .. ' ' .. lmonthnames[nextDay.month] .. ': Geen jarigen.'
			dz.devices(bd_alertIdx).updateAlertSensor( alertLevel, alertText )
		end
	end
}
-- That's All --------------------------------------------------
Last edited by janpep on Sunday 23 June 2024 15:49, edited 1 time in total.
Dz on Ubuntu VM on DS718+ behind FRITZ!Box.
EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; Sonoff USB-Dongle Plus-E; Zigbee2Mqtt; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
Fredom
Posts: 141
Joined: Saturday 19 September 2020 21:02
Target OS: Raspberry Pi / ODroid
Domoticz version: 2025.1
Location: Krimpen aan den IJssel
Contact:

Re: Simple birthday reminder

Post by Fredom »

Hi JanPep,
I don't know what's going wrong but I keep getting an error message.

Code: Select all

 2024-06-22 23:04:01.508 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:06.120 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:06.561 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:06.747 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:06.917 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:11.601 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:13.086 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:13.231 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:16.593 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:21.552 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:26.584 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:31.593 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:36.578 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:38.923 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:39.629 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:39.805 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:41.596 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)
2024-06-22 23:04:42.730 Error: dzVents: Error: (3.1.8) ...oticz/scripts/dzVents/generated_scripts/Verjaardagen.lua:25: bad argument #1 to 'insert' (table expected, got nil)

Code: Select all

-- 21-03-2024- Jan Peppink, https://ict.peppink.nl
-- Fill table with your birthday calendar.
-- Enter the mailto.
-- Create an alert device.
-- Schedule this script once per day.
-- The script looks at who's birthday is tomorrow.
-- It updates the alert device with date, name and age and sends email notification when found.
-- 22-06-2024 Modified to my current standard. Placed 'Your settings', including the birthday table in the front.
--    Some renaming and changing order, but same functionality.
--    Replaced local split function for dz.utils.stringSplit function.

--- Your settings ----------------------------------------------------------------
-- First set the used device index numbers and variables you might want to change.
local bd_alertIdx = 6                         -- Set to the idx of the Virtual Alert sensor you have to create for this script
local bd_mailTo = '[email protected]'     -- Set E-mail adres to sent to.

--Create table with the birthdays.
local bd_table = {}
--january
--february
--march
--april
--may
--june
table.insert(birthdayarray, "2020-06-24;Test1")
table.insert(birthdayarray, "2001-06-25;Test2")
table.insert(birthdayarray, "2010-06-26;Test3")
--july
--august
--september
--october
--november
--december
--------------------------------------------------------------------------------        
return {
	on = {
		timer = {
			'at 8:00',      -- Run once per day
			                -- Before time - birthday(s) of today are shown.
			                -- After time - birthday(s) of tomorrow are shown.
		}
	},
	logging = {
	    -- Level can be domoticz.LOG_INFO, domoicz.LOG_MODULE_EXEC_INFO, domoticz.LOG_DEBUG, domoticz.LOG_ERROR or domoticz.LOG_FORCE
        level = domoticz.LOG_INFO,
        --level = domoticz.LOG_DEBUG,
        marker = "-Birthdayreminder-"
	},
	execute = function( dz, triggeredItem )
		-- Set Local environment=================
        local _u = dz.utils       -- Holds subset of handy utilities.
        --local _h = dz.helpers     -- Holds the global functions.
        --local _d = dz.globalData  -- Holds the global data.

		local dmTomorrow = dz.time.dateToDate(dz.time.rawDate, 'yyyy-mm-dd', 'dd-mm', 86400 )  -- Day and month tomorrow
		local mailContent = ''

		local alertLevel = dz.ALERTLEVEL_GREY -- Holds the alertLevel (color) to set
		local alertText = ''

		-- Local Functions go here =============


		-- Translate local day and month names
		--local lDday = {"zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"}
		local lmonthnames = {'januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'october', 'november', 'december'}
		local nextDay = dz.time.makeTime(dz.time.dateToDate(dz.time.rawDate, 'yyyy-mm-dd', 'yyyy-mm-dd hh:mm:ss', 86400))
		--local TestDate = lmonthnames[nextDay.wday] .. ' '..string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ' ' .. tostring(nextDay.year)

		-- Now start to do something ============
		local loopcounter = 0
		for key, value in ipairs(bd_table) do
			local currentdayarray = _u.stringSplit( value, ";")
			local dateFound = currentdayarray[1]
			local nameFound = currentdayarray[2]
			local dmBirthdayFound = dz.time.dateToDate(dateFound,'yyyy-mm-dd', 'dd-mm', 0 )  -- Day and month
			
			if dmTomorrow == dmBirthdayFound then
			    --Found someone for tomorrow. Calculate age
				local age = nextDay.year - dz.time.dateToDate(dateFound,'yyyy-mm-dd', 'yyyy', 0 )
				-- strip the .0 from the end of the age.
				age = _u.round( age, 0 )

				if loopcounter > 0 then
					-- Add a newline first when more than one birtday is found.
					alertText = alertText .. string.char(10)
					mailContent = mailContent .. '<br>'
				end 
				-- Add current content to the string
				dz.log( 'Found: ' ..     string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ': ' .. nameFound .. ' ' .. age .. ' jaar.', dz.LOG_DEBUG )
				alertText = alertText .. string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ': ' .. nameFound .. ' <span style="color: red;">' .. age .. '</span>' .. ' jaar!'
				mailContent = mailContent .. string.format("%02d", nextDay.day) .. ' ' .. lmonthnames[nextDay.month] .. ': ' .. nameFound .. ' ' .. age .. ' jaar!'

				loopcounter = loopcounter + 1
			end
		end

		if mailContent ~= '' then
			dz.email( 'Morgen jarig!', mailContent, bd_mailTo, 0 )
			--
			alertLevel = dz.ALERTLEVEL_GREEN
			dz.devices(bd_alertIdx).updateAlertSensor( alertLevel, alertText )
		else
		    alertLevel = dz.ALERTLEVEL_GREY
			alertText = string.format( "%02d", nextDay.day ) .. ' ' .. lmonthnames[nextDay.month] .. ': Geen jarigen.'
			dz.devices(bd_alertIdx).updateAlertSensor( alertLevel, alertText )
		end
	end
}
-- That's All --------------------------------------------------
Yours sincerely,
Fred

Rasberry Pi 3B+ - Debian Bullseye - Domoticz 2025.1
RFLink - RFXCom - Zigbee (CC2531)
P1 Smart Meter - KaKu
janpep
Posts: 270
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2025.1
Location: Netherlands
Contact:

Re: Simple birthday reminder

Post by janpep »

Fredom wrote: Sunday 23 June 2024 15:25 I don't know what's going wrong but I keep getting an error message.
Sorry, I see now that, just before posting the script, I replaced my birthday table with the old example that still uses 'birthdayarray' from the previous version. In the new version of the script I shortened that to 'bd_table'. So you should be fine when you replace that for your test1, test2 and test3 persons.
I will edit it also in the script in previous post. Thanks for reporting.
Dz on Ubuntu VM on DS718+ behind FRITZ!Box.
EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; Sonoff USB-Dongle Plus-E; Zigbee2Mqtt; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
Fredom
Posts: 141
Joined: Saturday 19 September 2020 21:02
Target OS: Raspberry Pi / ODroid
Domoticz version: 2025.1
Location: Krimpen aan den IJssel
Contact:

Re: Simple birthday reminder

Post by Fredom »

janpep wrote: Sunday 23 June 2024 15:48
Fredom wrote: Sunday 23 June 2024 15:25 I don't know what's going wrong but I keep getting an error message.
Sorry, I see now that, just before posting the script, I replaced my birthday table with the old example that still uses 'birthdayarray' from the previous version. In the new version of the script I shortened that to 'bd_table'. So you should be fine when you replace that for your test1, test2 and test3 persons.
I will edit it also in the script in previous post. Thanks for reporting.
Thanks
it works perfectly now.
This script is very useful
Yours sincerely,
Fred

Rasberry Pi 3B+ - Debian Bullseye - Domoticz 2025.1
RFLink - RFXCom - Zigbee (CC2531)
P1 Smart Meter - KaKu
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest