private void scanBusAddresses()
        {
            Debug.Print(MethodNames.SCAN_BUS_ADDRESSES);
            if (loadAddressWhitelist())
            {
                Debug.Print(LogMessages.LOADED_WHITELIST);
                return;
            }
            ushort speed   = 100;
            ushort timeout = 200;

            for (byte i = SLAVE_SCAN_LOW; i < SLAVE_SCAN_HIGH; i++)
            {
                I2CBus i2C = new I2CBus(i, speed, timeout);
                try
                {
                    i2C.WriteByte(0);
                    var slaveAddressOnly = new Slave {
                        address = i, clock_stretch = 40000, name = "not_assigned", role = Role.UNDEFINED
                    };
                    _assimSlaves.Add(slaveAddressOnly);
                }
                catch { }
            }
            if (_assimSlaves.Count == 0)
            {
                //Debug.Print("No I2C devices found.");
            }
            else
            {
                //Debug.Print(_numberOfDevices.ToString() + " I2C devices found.");
            }
        }
        private void setMetaOfInterest(Slave slave, Hashtable rootPairs, String i2cName, String value)
        {
            switch (i2cName)
            {
            case I2cMessages.ASSIM_NAME:
                slave.name = value;
                return;

            case I2cMessages.ASSIM_VERSION:
                return;

            case I2cMessages.POWER_DOWN:
                return;

            case I2cMessages.PREPARE_MS:
                return;

            case I2cMessages.RESPONSE_MS:
                return;

            case I2cMessages.VCC_MV:
                return;

            case I2cMessages.ASSIM_ROLE:
                slave.role = value == I2cMessages.SENSOR ? Role.SENSOR : Role.ACTOR;
                return;

            case I2cMessages.CLOCK_STRETCH:
                slave.clock_stretch = Convert.ToInt32(value);
                return;

            default:
                break;    // end of base properties
            }
            var valueParts    = value.Split(':');
            var subValueParts = valueParts[1].Split('|');
            var idxStr        = valueParts[0];
            var idx           = Convert.ToInt32(idxStr);
            var propKey       = "";

            if (!rootPairs.Contains(idxStr))
            {
                rootPairs.Add(idxStr, new Hashtable());
            }
            Hashtable propertyIdxHashtable = ((Hashtable)rootPairs[idxStr]);

            // property based metadata
            switch (i2cName)
            {
            case I2cMessages.VIZ_CARD_TYPE:
                value = valueParts[1];
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.CARD_TYPE, value);
                setDefaultsForCardTtype(value, propertyIdxHashtable);
                return;

            case I2cMessages.VIZ_ICONS:
                propKey = subValueParts[0];
                value   = subValueParts[1];
                if (!propertyIdxHashtable.Contains(VizJsonKeys.ICONS))
                {
                    propertyIdxHashtable.Add(VizJsonKeys.ICONS, new ArrayList());
                }
                var leafHashtable = new Hashtable();
                leafHashtable.Add(HashtableKeys.NAME, propKey);
                leafHashtable.Add(HashtableKeys.VALUE, value);
                ((ArrayList)propertyIdxHashtable[VizJsonKeys.ICONS]).Add(leafHashtable);
                return;

            case I2cMessages.VIZ_LABELS:
                propKey = subValueParts[0];
                value   = subValueParts[1];
                if (!propertyIdxHashtable.Contains(VizJsonKeys.LABELS))
                {
                    propertyIdxHashtable.Add(VizJsonKeys.LABELS, new ArrayList());
                }
                var leafHashtable2 = new Hashtable();
                leafHashtable2.Add(HashtableKeys.NAME, propKey);
                leafHashtable2.Add(HashtableKeys.VALUE, value);
                ((ArrayList)propertyIdxHashtable[VizJsonKeys.LABELS]).Add(leafHashtable2);
                return;

            case I2cMessages.VIZ_MIN:
                value = valueParts[1];
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.MIN, Convert.ToInt32(value));
                return;

            case I2cMessages.VIZ_MAX:
                value = valueParts[1];
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.MAX, Convert.ToInt32(value));
                return;

            case I2cMessages.VIZ_UNITS:
                value = valueParts[1];
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.UNITS, value);
                return;

            case I2cMessages.VIZ_TOTAL:
                value = valueParts[1];
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.TOTAL, Convert.ToInt32(value));
                return;

            case I2cMessages.VIZ_VALUES:
                propKey = subValueParts[0];
                value   = subValueParts[1];
                if (!propertyIdxHashtable.Contains(VizJsonKeys.VALUES))
                {
                    propertyIdxHashtable.AddOrUpdate(VizJsonKeys.VALUES, new ArrayList());
                }
                if (((ArrayList)propertyIdxHashtable[VizJsonKeys.VALUES]).Count == 2)
                {    // remove the defaults - ToDo: more robust strategy
                    ((ArrayList)propertyIdxHashtable[VizJsonKeys.VALUES]).RemoveAt(0);
                    ((ArrayList)propertyIdxHashtable[VizJsonKeys.VALUES]).RemoveAt(0);
                }
                var leafHashtable3 = new Hashtable();
                leafHashtable3.Add(HashtableKeys.NAME, propKey);
                leafHashtable3.Add(HashtableKeys.VALUE, value);
                ((ArrayList)propertyIdxHashtable[VizJsonKeys.VALUES]).Add(leafHashtable3);
                return;

            case I2cMessages.VIZ_IS_SERIES:
                value = valueParts[1];
                bool valueBool = value == JsonValues.IS_SEREIES_VALUE;
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.IS_SERIES, valueBool);
                if (valueBool)
                {
                    setDefaultsForCardTtype(I2cMessages.CARDTYPE_CHART_LINE, propertyIdxHashtable);
                }
                return;

            case I2cMessages.VIZ_M_SERIES:
                return;

            case I2cMessages.VIZ_HIGH:
                value = valueParts[1];
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.HIGH, Convert.ToInt32(value));
                return;

            case I2cMessages.VIZ_LOW:
                value = valueParts[1];
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.LOW, Convert.ToInt32(value));
                return;

            case I2cMessages.VIZ_TOTL_UNIT:
                value = subValueParts[0];
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.TOTAL, Convert.ToInt32(value));
                value = subValueParts[1];
                propertyIdxHashtable.AddOrUpdate(VizJsonKeys.UNITS, value);
                return;
            }
        }