public async Task AddCountDownRule(CountDownRule cdr)
        {
            if (CountDownRules.Any(c => c.Id == cdr.Id))
            {
                throw new Exception("countdown rule with specified id already exists");
            }

            cdr = await this.AddCountDownRule(COUNTDOWN_NAMESPACE, cdr);

            CountDownRules.Add(cdr);
        }
        public async Task EditCountDownRule(string id, bool?enabled = null, int?delay = null, bool?poweredOn = null, string name = null)
        {
            CountDownRule cdr = CountDownRules.Find(c => c.Id == id);

            if (cdr == null)
            {
                throw new Exception("plug has no countdown rule with specified id");
            }

            cdr.Enabled   = enabled ?? cdr.Enabled;
            cdr.Delay     = delay ?? cdr.Delay;
            cdr.PoweredOn = poweredOn ?? cdr.PoweredOn;
            cdr.Name      = name ?? cdr.Name;

            await this.EditCountDownRule(COUNTDOWN_NAMESPACE, cdr);
        }
        public async Task EditCountDownRule(CountDownRule newCdr)
        {
            if (newCdr.Id == null)
            {
                throw new Exception("countdown rule id is required");
            }
            if (CountDownRules.Any(c => c.Id == newCdr.Id))
            {
                throw new Exception("countdown rule with specified id already exists");
            }

            CountDownRule cdr = CountDownRules.Find(c => c.Id == newCdr.Id);

            cdr.Enabled   = newCdr.Enabled;
            cdr.Delay     = newCdr.Delay;
            cdr.PoweredOn = newCdr.PoweredOn;
            cdr.Name      = newCdr.Name ?? cdr.Name;

            await this.EditCountDownRule(COUNTDOWN_NAMESPACE, cdr);
        }
        public async Task DeleteAllCountDownRules()
        {
            dynamic result = await Execute(COUNTDOWN_NAMESPACE, "delete_all_rules").ConfigureAwait(false);

            CountDownRules.Clear();
        }
        public async Task DeleteCountDownRule(string id)
        {
            dynamic result = await Execute(COUNTDOWN_NAMESPACE, "delete_rule", "id", id).ConfigureAwait(false);

            CountDownRules.RemoveAll(c => c.Id == id);
        }