Exemple #1
0
        public void StatusPacketReceived(StatusPacket statusPacket)
        {
            Console.WriteLine("ROUTER: #" + statusPacket.deviceId + " (" + statusPacket.shortAddress + " = #" + Device.RouterAltId(statusPacket.shortAddress) + "), parent " + statusPacket.parentAddress + " (" + statusPacket.parentAltAddress + " = #" + Device.RouterAltId(statusPacket.parentAltAddress) + ").");
            Console.Write("NEIGHBOURS of #" + Device.RouterAltId(statusPacket.shortAddress) + ": ");
            for (int i = 0; i < statusPacket.neighbours.Length; i++)
            {
                Console.Write("#" + statusPacket.neighbours[i] + "; ");
            }
            Console.WriteLine("");

            Device device = null;

            if (devices.ContainsKey(statusPacket.deviceId))
            {
                device = devices[statusPacket.deviceId];
            }
            else
            {
                Console.WriteLine("NOTICE: New router: " + statusPacket.deviceId + "");
                device = new Device(statusPacket.deviceId, false);
                devices.Add(statusPacket.deviceId, device);
            }
            device.AddStatus(statusPacket);

//throw new NotImplementedException();
        }
        protected void UpdateModel()
        {
            if (manager != null)
            {
                // Ensure we can access the collection without interruption
                lock (manager)
                {
                    // Build a map of router short addresses
                    IDictionary <ushort, ushort> shortAddressMap = new Dictionary <ushort, ushort>();
                    foreach (Device device in manager.Devices.Values)
                    {
                        if (device.ShortAddress != 0xffff)
                        {
                            ushort altId = (ushort)Device.RouterAltId(device.ShortAddress);
                            ushort id    = (ushort)device.Id;
                            if (!shortAddressMap.ContainsKey(altId))
                            {
                                shortAddressMap.Add(altId, id);
                            }
                        }
                    }

                    // Update sensors
                    foreach (Sensor sensor in sensors.Values)
                    {
                        if (manager.Devices.ContainsKey(sensor.Id))
                        {
                            Device device = manager.Devices[sensor.Id];
                            sensor.Age           = device.DataAge;
                            sensor.ParentAddress = device.ParentAddress;
                            RenewConnection((ushort)sensor.Id, sensor.ParentAddress, true, sensor.Age);
                        }
                    }

                    // Update routers
                    foreach (Router router in routers.Values)
                    {
                        if (manager.Devices.ContainsKey(router.Id))
                        {
                            Device device = manager.Devices[router.Id];
                            router.Age           = device.DataAge;
                            router.ParentAddress = device.ParentAddress;

                            // Map short addresses to actual addresses
                            List <ushort> neighbourList = new List <ushort>();
                            foreach (ushort neighbourShortAddress in device.NeighbourShortAddresses)
                            {
                                if (shortAddressMap.ContainsKey(neighbourShortAddress))
                                {
                                    neighbourList.Add(shortAddressMap[neighbourShortAddress]);
//Console.WriteLine("NOTE: Alt. address for neighbour of device " + device.Id + ": #" + neighbourShortAddress + "");
                                }
                                else
                                {
//                                    Console.WriteLine("NOTE: Unknown alt. address for neighbour of device " + device.Id + ": #" + neighbourShortAddress + "");
                                }
                            }
                            ushort[] neighbours = neighbourList.ToArray();
                            router.Neighbours = neighbours;

                            // Update connections
                            RenewConnection((ushort)router.Id, router.ParentAddress, true, router.Age);
                            foreach (ushort neighbour in neighbours)
                            {
                                RenewConnection((ushort)router.Id, neighbour, false, router.Age);
                            }
                        }
                    }

                    // Remove dead connections
                    foreach (KeyValuePair <int, List <Connection> > pair in connections)
                    {
                        List <Connection> toDelete = new List <Connection>();
                        foreach (Connection connection in pair.Value)
                        {
                            if (connection.DataAge > MAX_CONNECTION_AGE)
                            {
                                toDelete.Add(connection);
                            }
                        }
                        foreach (Connection connection in toDelete)
                        {
                            Console.WriteLine("CONNECTION: Removed " + connection.A + " -> " + connection.B + " (" + connection.Parent + ") (t=" + connection.DataAge + ").");
                            pair.Value.Remove(connection);
                        }
                    }
                }
            }
        }
Exemple #3
0
        // Method to return a Packet, or null if invalid byte array
        public static Packet PacketFromBinary(byte[] buffer, DateTime timestamp)
        {
            Packet packet = null;

            if (buffer != null && buffer.Length > 0)
            {
                if (buffer.Length >= 5 && buffer[0] == 0x12 && buffer[1] == 0x54)           // USER_REPORT_TYPE && TEDDI (ASCII 'T')
                {
                    /*
                     * unsigned char  reportType;			// @0  [1] = 0x12 (USER_REPORT_TYPE)
                     * unsigned char  reportId;		    // @1  [1] = 0x54 (ASCII 'T')
                     * unsigned short deviceId;			// @2  [2] = Short device identifier (16-bit) [doesn't have to be part of the payload, but this format is the same as the WAX]
                     * unsigned char version;				// @4  [1] = (0x02 = format [seq/temp/ldr/audio/pir : short])
                     */
                    ushort deviceId = (ushort)(buffer[2] | (((ushort)buffer[3]) << 8));
                    byte   version  = buffer[4];

                    if (((version & 0x0f) == 0x03 || (version & 0x0f) >= 0x04) && buffer.Length >= 18)
                    {
                        /*
                         * unsigned char  reportType;          // @ 0  [1] USER_REPORT_TYPE (0x12)
                         * unsigned char  reportId;            // @ 1  [1] Report identifier (0x54, ASCII 'T')
                         * unsigned short deviceId;            // @ 2  [2] Device identifier (16-bit)
                         * unsigned char  version;             // @ 4  [1] Low nibble = packet version (0x3), high nibble = config (0x0)
                         * unsigned char  sampleCount;         // @ 5  [1] Sample count (default config is at 250 msec interval with an equal number of PIR and audio samples; 20 = 5 seconds)
                         * unsigned short sequence;            // @ 6  [2] Sequence number (16-bit)
                         * unsigned short unsent;              // @ 8  [2] Number of unsent samples (default config is in 250 msec units)
                         * unsigned short temp;                // @10  [2] Temperature (0.2 Hz)
                         * unsigned short light;               // @12  [2] Light (0.2 Hz)
                         * unsigned short battery;             // @14  [2] Battery (0.2 Hz)
                         * unsigned short humidity;            // @16  [2] Humidity [V4] (0.2 Hz) -- or [V3] 16-bit checksum to make packet zero-sum
                         * unsigned char  data[BITPACK10_SIZEOF(DATA_MAX_INTERVAL * 2)];   // @18 [50] PIR and audio energy (4 Hz, 20x 2x 10-bit samples)
                         * unsigned short parentAddress;		// @ADDITIONAL_OFFSET+0  [2] (optional) Parent address
                         * unsigned short parentAltAddress;	// @ADDITIONAL_OFFSET+2  [2] (optional) Parent alt. address
                         */
                        byte     config           = (byte)(buffer[4] >> 4);
                        byte     sampleCount      = (byte)(buffer[5]);
                        ushort   sequence         = (ushort)(buffer[6] | (((ushort)buffer[7]) << 8));
                        ushort   unsent           = (ushort)(buffer[8] | (((ushort)buffer[9]) << 8));
                        ushort   temp             = (ushort)(buffer[10] | (((ushort)buffer[11]) << 8));
                        ushort   light            = (ushort)(buffer[12] | (((ushort)buffer[13]) << 8));
                        ushort   battery          = (ushort)(buffer[14] | (((ushort)buffer[15]) << 8));
                        ushort   humidity         = (ushort)(buffer[16] | (((ushort)buffer[17]) << 8));
                        ushort[] pir              = new ushort[sampleCount];
                        ushort[] audio            = new ushort[sampleCount];
                        ushort   parentAddress    = 0xffff;
                        ushort   parentAltAddress = 0xffff;

                        if ((version & 0x0f) == 0x03)
                        {
                            humidity = 0;
                        }

                        int[]  teddiFrequency = new int[] { 4, 8, 16, 32, 64, 128, 256, 512, 1, 1, 1, 1, 1, 1, 1, 2 };
                        ushort sampleInterval = (ushort)(1000 / teddiFrequency[config]);

                        try
                        {
                            // Unpack PIR
                            for (int i = 0; i < sampleCount; i++)
                            {
                                pir[i] = BitUnpack_uint10(buffer, i, 18);
                            }

                            // Unpack Audio
                            for (int i = 0; i < sampleCount; i++)
                            {
                                audio[i] = BitUnpack_uint10(buffer, sampleCount + i, 18);
                            }

                            // For V3 data, divide temp/light/battery measurement down
                            if ((version & 0x0f) <= 0x03 && sampleCount > 0)
                            {
                                temp     /= sampleCount;
                                light    /= sampleCount;
                                battery  /= sampleCount;
                                humidity /= sampleCount;
                            }

                            // Check for additional data
                            int additionalIndex = 18 + BITPACK10_SIZEOF(sampleCount * 2);
                            if (additionalIndex + 4 <= buffer.Length)
                            {
                                parentAddress    = (ushort)(buffer[additionalIndex + 0] | (((ushort)buffer[additionalIndex + 1]) << 8));
                                parentAltAddress = (ushort)(buffer[additionalIndex + 2] | (((ushort)buffer[additionalIndex + 3]) << 8));
                                Console.WriteLine("SENSOR: #" + deviceId + ", parent " + parentAddress + " (" + parentAltAddress + " = #" + Device.RouterAltId(parentAltAddress) + ").");
                            }

                            // Create samples from the measurement data: deviceId, temp, light, humidity, pir[], audio[]
                            Sample[] sampleData = new Sample[sampleCount];
                            for (uint i = 0; i < sampleCount; i++)
                            {
                                sampleData[i] = new Sample(timestamp - TimeSpan.FromMilliseconds((unsent + sampleCount - 1 - i) * sampleInterval), (ushort)(sequence * sampleCount) + i, (short)pir[i], (short)temp, (short)light, (short)humidity, audio[i], battery);
                            }
                            packet = new Packet(timestamp - TimeSpan.FromMilliseconds((unsent + sampleCount - 1) * sampleInterval), deviceId, 1, 0, 0, (ushort)(sequence * sampleCount), 0, sampleCount, timestamp, unsent, temp, light, humidity, pir, audio, sampleData, parentAddress, parentAltAddress);
                        }
                        catch (IndexOutOfRangeException ex)
                        {
                            Console.Error.Write("EXCEPTION: " + ex + " while parsing packet.");
                        }
                    }
                    else
                    {
                        Console.Error.Write("[T?]");    // Unknown TEDDI packet type
                    }
                }
                else
                {
                    //Console.Error.Write("[?]");		// Unknown packet type
                }
            }
            return(packet);
        }