protected override async void MessageReceivedHandler(string deviceType, string deviceId, string subTopic, string payload)
        {
            if (deviceType == "scale")
            {
                var remoteScale = m_RemoteScales.FirstOrDefault(scale => scale.DeviceId == deviceId);
                switch (subTopic)
                {
                case "heartbeat":
                    if (remoteScale == null)
                    {
                        remoteScale = new RemoteScale {
                            DeviceId = deviceId
                        };
                        m_RemoteScales.Add(remoteScale);
                        await NetClient.PublishAsync($"scale/{remoteScale.DeviceId}/weight/get");

                        await NetClient.PublishAsync($"scale/{remoteScale.DeviceId}/global_position/get");
                    }
                    await ProcessHeartbeat(remoteScale);

                    break;

                case "weight":
                    remoteScale?.WeightFromJson(payload);
                    break;

                case "global_position":
                    remoteScale?.GlobalPositionFromJson(payload);
                    if (remoteScale != null)
                    {
                        remoteScale.IsGlobalPositionCoarse = false;
                    }
                    break;

                case "wifi":
                    await UpdateBeacons(payload);

                    break;
                }
            }
            else
            {
                switch (subTopic)
                {
                case "global_position":
                    UpdateBeaconPosition(deviceId, payload);
                    break;
                }
            }
        }
        private async Task ProcessHeartbeat(RemoteScale remoteScale)
        {
            remoteScale.AliveTimestamp = Stopwatch.GetTimestamp();

            if (remoteScale.AliveTimestamp - m_WiFiScanTimestamp > Stopwatch.Frequency * 5)
            {
                await NetClient.PublishAsync($"scale/{remoteScale.DeviceId}/wifi/scan");

                m_WiFiScanTimestamp = remoteScale.AliveTimestamp;
            }

            if (!remoteScale.HasGlobalPosition || remoteScale.IsGlobalPositionCoarse)
            {
                var coarsePosition = Beacon.ComputeGlobalPosition(m_Beacons);
                if (coarsePosition != null)
                {
                    remoteScale.GlobalPosition         = coarsePosition;
                    remoteScale.IsGlobalPositionCoarse = true;
                }
            }
        }