Beispiel #1
0
 def __init__(self, sh, *args, **kwargs):
     from bin.smarthome import VERSION
     if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5':
         self.logger = logging.getLogger(__name__)
     self._apiKey = self.get_parameter_value('apiKey')
     self._userKey = self.get_parameter_value('userKey')
     self._device = self.get_parameter_value('device')
     self._po = Http()
Beispiel #2
0
    def __init__(self, smarthome):
        super().__init__()
        if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5':
            self.logger = logging.getLogger(__name__)
        try:
            self.shtime = Shtime.get_instance()
            self.handle_login = self.get_parameter_value('handle_login')
            try:
                self.dl = Http(timeout=self.get_parameter_value('timeout'),
                               hide_login=self.handle_login)
            except:
                self.dl = Http(hide_login=self.handle_login)
            self._items = []
            self._icals = {}
            self._ical_aliases = {}
            self._cycle = self.get_parameter_value('cycle')
            calendars = self.get_parameter_value('calendars')
            config_dir = self.get_parameter_value('directory')
        except Exception as err:
            self.logger.error('Problems initializing: {}'.format(err))
            self._init_complete = False
            return
        try:
            self._directory = '{}/{}'.format(self.get_vardir(), config_dir)
        except Exception:
            self._directory = '{}/var/{}'.format(smarthome.get_basedir(),
                                                 config_dir)
        self._directory = os.path.normpath(self._directory)
        try:
            os.makedirs(self._directory)
            self.logger.debug('Created {} subfolder in var'.format(config_dir))
        except OSError as e:
            if e.errno != errno.EEXIST:
                self.logger.error(
                    'Problem creating {} folder in {}/var'.format(
                        config_dir, smarthome.get_basedir()))
                self._init_complete = False
                return

        for calendar in calendars:
            if isinstance(calendar, dict):
                calendar = list("{!s}:{!s}".format(k, v)
                                for (k, v) in calendar.items())[0]
            if ':' in calendar and 'http' != calendar[:4]:
                name, _, cal = calendar.partition(':')
                calendar = cal.strip()
                self.logger.info(
                    'Registering calendar {} with alias {}.'.format(
                        Network.clean_uri(calendar, self.handle_login), name))
                self._ical_aliases[name.strip()] = calendar
            else:
                self.logger.info(
                    'Registering calendar {} without alias.'.format(
                        Network.clean_uri(calendar, self.handle_login)))
            calendar = calendar.strip()
            self._icals[calendar] = self._read_events(calendar)

        self.shtime = Shtime.get_instance()
Beispiel #3
0
    def __init__(self, sh):
        """
        Initalizes the plugin.
        """
        self.logger.debug("Init method called")
        # Call init code of parent class (SmartPlugin)
        super().__init__()

        from bin.smarthome import VERSION
        if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5':
            self.logger = logging.getLogger(__name__)

        self._items = []
        # get the parameters for the plugin (as defined in metadata plugin.yaml):
        self._account = self.get_parameter_value('account')
        self._password = EcoVacsAPI.md5(self.get_parameter_value('password'))
        self._wanted_device = self.get_parameter_value('device')

        self.mybot = {
            'nick': None,
            'did': None,
            'country': self.get_parameter_value('country').lower(),
            'continent': self.get_parameter_value('continent').lower(),
            'model': None,
            'iconURL': None,
            'live_map': None,
            'last_clean_logs': [],
            'last_clean_map': None,
            'available': False,
            'battery_level': 0,
            'state': None,
            'state_text': None,
            'fan_speed': None,
            'water_level': None,
            'components': [],
            'rooms': []
        }

        # Check if country and continent defined, if not try to autolocate
        http = Http()
        if not self.mybot['country'] or not self.mybot['continent']:
            _locate = http.get_json(
                'http://ip-api.com/json?fields=continentCode,countryCode')
        if not self.mybot['country']:
            if _locate and _locate['countryCode']:
                self.logger.info('Autodetected country: {}'.format(
                    _locate['countryCode']))
                self._update_items('country', _locate['countryCode'].lower())
            else:
                self.logger.error(
                    'No country defined and autolocate not possible, please specify country in plugin configuration !'
                )
                self._init_complete = False
                return

        if not self.mybot['continent']:
            if _locate and _locate['continentCode']:
                self.logger.info('Autodetected continent: {}'.format(
                    _locate['continentCode']))
                self._update_items('continent',
                                   _locate['continentCode'].lower())
            else:
                self.logger.error(
                    'No continent defined and autolocate not possible, please specify continent in plugin configuration !'
                )
                self._init_complete = False
                return

        self.device = None
        self._device_id = "".join(
            random.choice(string.ascii_uppercase + string.digits)
            for _ in range(16))
        self._cycle = self.get_parameter_value('interval')
        self._items = {}

        if not self.init_webinterface():
            self._init_complete = False

        return
Beispiel #4
0
class Pushover(SmartPlugin):

    PLUGIN_VERSION = "1.6.1.0"

    _url = "https://api.pushover.net/1/messages.json"

    def __init__(self, sh, *args, **kwargs):
        from bin.smarthome import VERSION
        if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5':
            self.logger = logging.getLogger(__name__)
        self._apiKey = self.get_parameter_value('apiKey')
        self._userKey = self.get_parameter_value('userKey')
        self._device = self.get_parameter_value('device')
        self._po = Http()

    def run(self):
        self.alive = True

    def stop(self):
        self.alive = False

    def __call__(self,
                 title=None,
                 message='',
                 priority=None,
                 retry=None,
                 expire=None,
                 sound=None,
                 url=None,
                 url_title=None,
                 device=None,
                 userKey=None,
                 apiKey=None,
                 attachment=None):
        data = {}

        data['timestamp'] = int(time.time())

        if title:
            data['title'] = title[:250]

        data['message'] = message[:1000]

        if priority:
            if isinstance(priority, int) and priority >= -2 and priority <= 2:
                data['priority'] = priority

                if retry and priority == 2:
                    if isinstance(retry, int) and retry >= 30:
                        data['retry'] = retry
                    else:
                        data['retry'] = 30
                        self.logger.error(
                            "Pushover message retry need at least 30 secounds! I set it to 30!"
                        )
                elif not retry and priority == 2:
                    self.logger.error(
                        "Pushover message priority = 2 need retry to be set, degrade priority to 1!"
                    )
                    data['priority'] = 1

                if expire and priority == 2:
                    if isinstance(expire, int) and expire <= 10800:
                        data['expire'] = expire
                    else:
                        data['expire'] = 10800
                        self.logger.error(
                            "Pushover message expire need at most 10800 secounds! I set it to 10800."
                        )
                elif not expire and priority == 2:
                    self.logger.error(
                        "Pushover message priority = 2 need expire to be set, degrade priority to 1!"
                    )
                    data['priority'] = 1

                # delete not used vars
                if data['priority'] < 2:
                    if 'expire' in data:
                        del data['expire']
                    if 'retry' in data:
                        del data['retry']

            else:
                self.logger.error(
                    "Pushover message priority need to be a number between -2 and 2!"
                )

        if sound:
            data['sound'] = sound

        if url:
            data['url'] = url[:512]
            if url_title:
                data['url_title'] = url_title[:100]

        if userKey:
            data['user'] = userKey
        elif self._userKey:
            data['user'] = self._userKey
        else:
            self.logger.error("Pushover needs a userKey")
            return

        if apiKey:
            data['token'] = apiKey
        elif self._apiKey:
            data['token'] = self._apiKey
        else:
            self.logger.error("Pushover needs a apiKey")
            return

        if device:
            data['device'] = device
        elif self._device:
            data['device'] = self._device

        if attachment:
            files = {'attachment': open(attachment, 'rb')}
        else:
            files = {}

        try:
            json_data = self._po.post_json(self._url, json=data, files=files)
            (_status_code, _reason) = self._po.response_status()

            # process response
            if (_status_code == 200 and json_data['status'] == 1):
                self.logger.debug(
                    "Pushover returns: Notification successful submitted.")
            elif (_status_code == 429):
                self.logger.warning(
                    "Pushover returns: Message limits have been reached.")
            else:
                self.logger.warning("Pushover returns: {0} - {1}".format(
                    _status_code, _reason))

        except Exception as e:
            self.logger.warning(
                "Could not send Pushover notification. Error: {}".format(e))
Beispiel #5
0
class iCal(SmartPlugin):
    PLUGIN_VERSION = "1.5.4"
    ALLOW_MULTIINSTANCE = False
    DAYS = ("MO", "TU", "WE", "TH", "FR", "SA", "SU")
    FREQ = ("YEARLY", "MONTHLY", "WEEKLY", "DAILY", "HOURLY", "MINUTELY",
            "SECONDLY")
    PROPERTIES = ("SUMMARY", "DESCRIPTION", "LOCATION", "CATEGORIES", "CLASS")

    def __init__(self, smarthome):
        super().__init__()
        if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5':
            self.logger = logging.getLogger(__name__)
        try:
            self.shtime = Shtime.get_instance()
            try:
                self.dl = Http(timeout=self.get_parameter_value('timeout'))
            except:
                self.dl = Http('')
            self._items = []
            self._icals = {}
            self._ical_aliases = {}
            cycle = self.get_parameter_value('cycle')
            calendars = self.get_parameter_value('calendars')
            config_dir = self.get_parameter_value('directory')
            self.handle_login = self.get_parameter_value('handle_login')
        except Exception as err:
            self.logger.error('Problems initializing: {}'.format(err))
            self._init_complete = False
            return
        try:
            self._directory = '{}/{}'.format(self.get_vardir(), config_dir)
        except Exception:
            self._directory = '{}/var/{}'.format(smarthome.get_basedir(),
                                                 config_dir)
        self._directory = os.path.normpath(self._directory)
        try:
            os.makedirs(self._directory)
            self.logger.debug('Created {} subfolder in var'.format(config_dir))
        except OSError as e:
            if e.errno != errno.EEXIST:
                self.logger.error(
                    'Problem creating {} folder in {}/var'.format(
                        config_dir, smarthome.get_basedir()))
                self._init_complete = False
                return

        for calendar in calendars:
            if isinstance(calendar, dict):
                calendar = list("{!s}:{!s}".format(k, v)
                                for (k, v) in calendar.items())[0]
            if ':' in calendar and 'http' != calendar[:4]:
                name, _, cal = calendar.partition(':')
                calendar = cal.strip()
                self.logger.info(
                    'Registering calendar {} with alias {}.'.format(
                        self._clean_uri(calendar), name))
                self._ical_aliases[name.strip()] = calendar
            else:
                self.logger.info(
                    'Registering calendar {} without alias.'.format(
                        self._clean_uri(calendar)))
            calendar = calendar.strip()
            self._icals[calendar] = self._read_events(calendar)

        self.shtime = Shtime.get_instance()
        self.scheduler_add('iCalUpdate',
                           self._update_items,
                           cron='* * * *',
                           prio=5)
        self.scheduler_add('iCalRefresh',
                           self._update_calendars,
                           cycle=int(cycle),
                           prio=5)

    def run(self):
        self.alive = True

    def stop(self):
        self.scheduler_remove('iCalUpdate')
        self.scheduler_remove('iCalRefresh')
        self.alive = False

    def parse_item(self, item):
        if self.has_iattr(item.conf, 'ical_calendar'):
            uri = self.get_iattr_value(item.conf, 'ical_calendar').strip()

            if uri in self._ical_aliases:
                uri = self._ical_aliases[uri]

            if uri not in self._icals:
                self._icals[uri] = self._read_events(uri)

            self._items.append(item)

    def parse_logic(self, logic):
        pass

    def update_item(self, item, caller=None, source=None, dest=None):
        pass

    def __call__(self,
                 ics='',
                 delta=1,
                 offset=0,
                 username=None,
                 password=None,
                 prio=1,
                 verify=True):
        if ics in self._ical_aliases:
            self.logger.debug(
                'iCal retrieve events by alias {0} -> {1}'.format(
                    ics, self._ical_aliases[ics]))
            return self._filter_events(self._icals[self._ical_aliases[ics]],
                                       delta, offset)

        if ics in self._icals:
            self.logger.debug('iCal retrieve cached events {0}'.format(ics))
            return self._filter_events(self._icals[ics], delta, offset)

        self.logger.debug('iCal retrieve events {0}'.format(ics))
        return self._filter_events(
            self._read_events(ics,
                              username=username,
                              password=password,
                              prio=prio,
                              verify=verify), delta, offset)

    def _update_items(self):
        if len(self._items):
            now = self.shtime.now()

            events = {}
            for calendar in self._icals:
                events[calendar] = self._filter_events(self._icals[calendar],
                                                       0, 0)

            for item in self._items:
                calendar = item.conf['ical_calendar']

                if calendar in self._ical_aliases:
                    calendar = self._ical_aliases[calendar]

                val = False
                for date in events[calendar]:
                    for event in events[calendar][date]:
                        if event['Start'] <= now <= event['End'] or (
                                event['Start'] == event['End'] and
                                event['Start'] <= now <= event['End'].replace(
                                    second=59, microsecond=999)):
                            val = True
                            break

                item(val)

    def _update_calendars(self):
        for uri in self._icals:
            self._icals[uri] = self._read_events(uri)
            self.logger.debug('Updated calendar {0}'.format(
                self._clean_uri(uri)))

        if len(self._icals):
            self._update_items()

    def _filter_events(self, events, delta=1, offset=0, prio=1):
        now = self.shtime.now()
        offset = offset - 1  # start at 23:59:59 the day before
        delta += 1  # extend delta for negative offset
        start = now.replace(hour=23, minute=59, second=59,
                            microsecond=0) + datetime.timedelta(days=offset)
        end = start + datetime.timedelta(days=delta)
        revents = {}
        for event in events:
            event = events[event]
            e_start = event['DTSTART']
            e_end = event['DTEND']
            if 'RRULE' in event and (event['RRULE'] is not None):
                e_duration = e_end - e_start
                for e_rstart in event['RRULE'].between(start, end, inc=True):
                    if e_rstart not in event['EXDATES']:
                        date = e_rstart.date()
                        revent = {
                            'Start': e_rstart,
                            'End': e_rstart + e_duration
                        }
                        for prop in self.PROPERTIES:
                            if prop in event:
                                revent[prop.capitalize()] = event[prop]
                        if date not in revents:
                            revents[date] = [revent]
                        else:
                            revents[date].append(revent)
                    else:
                        self.logger.info(
                            "Removed {0} because it is in the excluded dates list"
                            .format(e_rstart))
            else:
                if (e_start > start and e_start < end) or (e_start < start
                                                           and e_end > start):
                    date = e_start.date()
                    revent = {'Start': e_start, 'End': e_end}
                    for prop in self.PROPERTIES:
                        if prop in event:
                            revent[prop.capitalize()] = event[prop]
                    if date not in revents:
                        revents[date] = [revent]
                    else:
                        revents[date].append(revent)
        return revents

    def _read_events(self,
                     ics,
                     username=None,
                     password=None,
                     prio=1,
                     verify=True):
        if ics.startswith('http'):
            _, _, cal = ics.partition('//')
            name = '{}.ics'.format(cal.split('/')[0].replace('.', '_'))
            for entry in self._ical_aliases:
                name = '{}.ics'.format(
                    entry) if ics == self._ical_aliases[entry] else name
            filename = '{}/{}'.format(self._directory, name)
            auth = 'HTTPBasicAuth' if username else None
            downloaded = self.dl.download(url=ics,
                                          local=filename,
                                          params={
                                              username: username,
                                              password: password
                                          },
                                          verify=verify,
                                          auth=auth)
            if downloaded is False:
                self.logger.error(
                    'Could not download online ics file {0}.'.format(ics))
                return {}
            self.logger.debug(
                'Online ics {} successfully downloaded to {}'.format(
                    ics, filename))
            ics = os.path.normpath(filename)
        try:
            ics = ics.replace('\\', os.sep).replace('/', os.sep)
            ics = '{}/{}'.format(self._directory,
                                 ics) if self._directory not in ics else ics
            with open(ics, 'r') as f:
                ical = f.read()
                self.logger.debug('Read offline ical file {}'.format(ics))
        except IOError as e:
            self.logger.error(
                'Could not open local ics file {0} (directory {1}): {2}'.
                format(ics, self._directory, e))
            return {}

        return self._parse_ical(ical, ics, prio)

    #parse different date formats used in google calendar. Timezone is either coded in time field cointaining ('T') or in separate TZID field.
    def _parse_date(self, val, dtzinfo, par=''):

        if 'T' in val:  # ISO datetime
            val, sep, off = val.partition('Z')
            dt = datetime.datetime.strptime(val, "%Y%m%dT%H%M%S")
            # 'Z' indicates 'Zulu', thus UTC time, therefore specify time zone utc:
            dt = dt.replace(tzinfo=datetime.timezone.utc)

        # the following condition occurs for complete day schedules. They do not have the 'T' lettre in start/end times.
        else:  # date
            y = int(val[0:4])
            m = int(val[4:6])
            d = int(val[6:8])
            dt = datetime.datetime(y, m, d)
            # Using timestamp configured in smarthome as reference for all complete day timestamps:
            dt = dt.replace(tzinfo=dtzinfo)

        # handling of series calendar entries:
        if par.startswith('TZID='):
            tmp, par, timezoneFromCalendar = par.partition('=')
            #self.logger.debug('Decoding series entry with time zone: {0}'.format(timezoneFromCalendar))
            #self.logger.debug('Datetime before conversion: {0}'.format(dt))

            calendar_tz = dateutil.tz.gettz(timezoneFromCalendar)

            dt = dt.replace(tzinfo=calendar_tz)

            #self.logger.debug('Datetime after conversion for series entries: {}'.format(dt))

        # convert all time stamps to local timezone, configured in smarthome
        dt = dt.astimezone(self.shtime.tzinfo())
        #self.logger.debug('Datetime after final conversion in plugin ical: {}'.format(dt))

        #convert time based on time zone info which has been extracted on a higher level:
        #dt = dt.astimezone(dtzinfo)

        return dt

    def _parse_ical(self, ical, ics, prio):
        events = {}
        tzinfo = self.shtime.tzinfo()
        ical = ical.replace("\r\n\\n", ", ")
        ical = ical.replace("\n\\n", ", ").replace("\\n", ", ")
        ical = ical.replace("\\n", ", ")
        ical = ical.replace("\r ", "").replace(
            "\n ", "")  # in case long lines continue in the next line
        for line in ical.splitlines():
            if line == 'BEGIN:VEVENT':
                prio_count = {
                    'UID': 1,
                    'SUMMARY': 1,
                    'SEQUENCE': 1,
                    'RRULE': 1,
                    'CLASS': 1,
                    'DESCRIPTION': 1
                }
                event = {'EXDATES': []}
            elif line == 'END:VEVENT':
                if 'UID' not in event:
                    self.logger.warning(
                        "problem parsing {0} no UID for event: {1}".format(
                            ics, event))
                    continue
                if 'SUMMARY' not in event:
                    self.logger.warning(
                        "problem parsing {0} no SUMMARY for UID: {1}".format(
                            ics, event['UID']))
                    continue
                if 'DTSTART' not in event:
                    self.logger.warning(
                        "problem parsing {0} no DTSTART for UID: {1}".format(
                            ics, event['UID']))
                    continue
                if 'DTEND' not in event:
                    self.logger.warning(
                        "Warning in parsing {0} no DTEND for UID: {1}. Setting DTEND from DTSTART"
                        .format(ics, event['UID']))
                    # Set end to start time:
                    event['DTEND'] = event['DTSTART']
                    continue
                if 'RRULE' in event:
                    event['RRULE'] = self._parse_rrule(event, tzinfo)
                if event['UID'] in events:
                    if 'RECURRENCE-ID' in event:
                        events[event['UID']]['EXDATES'].append(
                            event['RECURRENCE-ID'])
                        events[event['UID'] +
                               event['DTSTART'].isoformat()] = event
                    else:
                        self.logger.warning(
                            "problem parsing {0} duplicate UID: {1} ({2})".
                            format(ics, event['UID'], event['SUMMARY']))
                        continue
                else:
                    events[event['UID']] = event
                del (event)
            elif 'event' in locals():
                key, sep, val = line.partition(':')
                key, sep, par = key.partition(';')
                key = key.upper()
                # why does the folowing code overwrite the time zone info configured in smarthomeNG?
                if key == 'TZID':
                    tzinfo = dateutil.tz.gettz(val)
                    self.logger.warning('Debug time zone: {0}'.format(val))
                elif key in [
                        'UID', 'SUMMARY', 'SEQUENCE', 'RRULE', 'CLASS',
                        'DESCRIPTION'
                ]:
                    if event.get(key) is None or prio_count[key] == prio:
                        prio_count[key] = prio_count.get(key) + 1
                        event[key] = val
                    else:
                        self.logger.debug(
                            'Value {} for entry {} ignored because of prio setting'
                            .format(val, key))
                elif key in ['DTSTART', 'DTEND', 'EXDATE', 'RECURRENCE-ID']:
                    try:
                        date = self._parse_date(val, tzinfo, par)
                    except Exception as e:
                        if key == 'EXDATE':
                            date = []
                            values = val.split(",")
                            for value in values:
                                date.append(
                                    self._parse_date(value, tzinfo, par))
                        else:
                            self.logger.warning(
                                "Problem parsing: {0}: {1}".format(ics, e))
                            continue
                    if key == 'EXDATE':
                        event['EXDATES'].append(date)  # noqa
                    else:
                        event[key] = date  # noqa
                else:
                    event[key] = val  # noqa
            try:
                event['EXDATES'] = [y for x in event['EXDATES'] for y in x]
            except Exception:
                pass
        return events

    def _parse_rrule(self, event, tzinfo):
        rrule = dict(a.split('=') for a in event['RRULE'].upper().split(';'))
        self.logger.debug("Rrule {0}".format(rrule))
        args = {}
        if 'FREQ' not in rrule:
            self.logger.debug("Rrule has no frequency")
            return
        freq = self.FREQ.index(rrule['FREQ'])
        self.logger.debug("Frequency: {0}".format(freq))
        del (rrule['FREQ'])
        if 'DTSTART' not in rrule:
            rrule['DTSTART'] = event['DTSTART']
        if 'WKST' in rrule:
            if rrule['WKST'] in self.DAYS:
                rrule['WKST'] = self.DAYS.index(rrule['WKST'])
            else:
                rrule['WKST'] = int(rrule['WKST'])
        if 'BYDAY' in rrule:
            days = rrule['BYDAY'].split(',')
            new_days = []
            for day in days:
                day = day.strip()
                if day.isalpha():
                    if day in self.DAYS:
                        day = self.DAYS.index(day)
                else:
                    n = int(day[0:-2])
                    day = self.DAYS.index(day[-2:])
                    day = dateutil.rrule.weekday(day, n)
                new_days.append(day)
            rrule['BYWEEKDAY'] = new_days
            del (rrule['BYDAY'])
        if 'COUNT' in rrule:
            rrule['COUNT'] = int(rrule['COUNT'])
        if 'INTERVAL' in rrule:
            rrule['INTERVAL'] = int(rrule['INTERVAL'])
        if 'BYMONTHDAY' in rrule:
            rrule['BYMONTHDAY'] = int(rrule['BYMONTHDAY'])
        if 'BYMONTH' in rrule:
            rrule['BYMONTH'] = int(rrule['BYMONTH'])
        if 'UNTIL' in rrule:
            try:
                rrule['UNTIL'] = self._parse_date(rrule['UNTIL'], tzinfo)
            except Exception as e:
                self.logger.warning(
                    "Problem parsing UNTIL: {1} --- {0} ".format(event, e))
                return
        for par in rrule:
            args[par.lower()] = rrule[par]

        return dateutil.rrule.rrule(freq, **args)

    def _clean_uri(self, uri):
        # check for http[s]?://user:[email protected]/... style uris and strip name/pass
        pattern = re.compile('http([s]?)://([^:]+:[^@]+@)')
        if self.handle_login == 'show' or not pattern.match(uri):
            return uri

        replacement = {'strip': 'http\g<1>://', 'mask': 'http\g<1>://***:***@'}
        return pattern.sub(replacement[self.handle_login], uri)
Beispiel #6
0
    def __init__(self, smarthome):
        if '.'.join(VERSION.split('.', 2)[:2]) <= '1.5':
            self.logger = logging.getLogger(__name__)
        try:
            self.shtime = Shtime.get_instance()
            try:
                self.dl = Http(timeout=self.get_parameter_value('timeout'))
            except:
                self.dl = Http('')
            self._items = []
            self._icals = {}
            self._ical_aliases = {}
            self.sh = smarthome
            cycle = self.get_parameter_value('cycle')
            calendars = self.get_parameter_value('calendars')
            config_dir = self.get_parameter_value('directory')
        except Exception as err:
            self.logger.error('Problems initializing: {}'.format(err))
            self._init_complete = False
            return
        try:
            self._directory = '{}/{}'.format(self.get_vardir(), config_dir)
        except Exception:
            self._directory = '{}/var/{}'.format(self.sh.get_basedir(),
                                                 config_dir)
        try:
            os.makedirs(self._directory)
            self.logger.debug('Created {} subfolder in var'.format(config_dir))
        except OSError as e:
            if e.errno != errno.EEXIST:
                self.logger.error(
                    'Problem creating {} folder in {}/var'.format(
                        config_dir, self.sh.get_basedir()))
                self._init_complete = False
                return

        for calendar in calendars:
            if isinstance(calendar, dict):
                calendar = list("{!s}:{!s}".format(k, v)
                                for (k, v) in calendar.items())[0]
            if ':' in calendar and 'http' != calendar[:4]:
                name, _, cal = calendar.partition(':')
                calendar = cal.strip()
                self.logger.info(
                    'Registering calendar {} with alias {}.'.format(
                        calendar, name))
                self._ical_aliases[name.strip()] = calendar
            else:
                self.logger.info(
                    'Registering calendar {} without alias.'.format(calendar))
            calendar = calendar.strip()
            self._icals[calendar] = self._read_events(calendar)

        smarthome.scheduler.add('iCalUpdate',
                                self._update_items,
                                cron='* * * *',
                                prio=5)
        smarthome.scheduler.add('iCalRefresh',
                                self._update_calendars,
                                cycle=int(cycle),
                                prio=5)