public void Save(Device device)
        {
            if (device == null)
                throw new ArgumentNullException("device");
            if (string.IsNullOrEmpty(device.GUID))
                throw new ArgumentException("Device.GUID must have a valid value!", "device.GUID");

            if (device.Network != null)
            {
                device.NetworkID = device.Network.ID;
            }
            else if (device.NetworkID != null)
            {
                device.Network = _mongo.Networks.FindOneById(device.NetworkID.Value);
                if (device.Network == null)
                    throw new ArgumentException("Specified NetworkID does not exist!", "device.NetworkID");
            }

            if (device.DeviceClass != null)
            {
                device.DeviceClassID = device.DeviceClass.ID;
            }
            else
            {
                device.DeviceClass = _mongo.DeviceClasses.FindOneById(device.DeviceClassID);
                if (device.DeviceClass == null)
                    throw new ArgumentException("Specified DeviceClassID does not exist!", "device.DeviceClassID");
            }

            _mongo.EnsureIdentity(device);
            _mongo.Devices.Save(device);
        }
        private void ResolveNetwork(Device device, bool verifyNetworkKey, Func<Network, bool> networkAccessCheck)
        {
            if (device.Network == null)
                return; // device could have no network assigned

            var network = (Network)null;
            if (device.Network.Name != null)
            {
                // network name is passed
                network = DataContext.Network.Get(device.Network.Name);
                if (network == null)
                {
                    // auto-create network - only for test environments
                    if (!_configuration.Network.AllowAutoCreate)
                        throw new UnauthroizedNetworkException("Automatic network creation is not allowed, please specify an existing network!");

                    network = device.Network;
                    Validate(network);
                    DataContext.Network.Save(network);
                }
                else
                {
                    if (verifyNetworkKey && network.Key != null && network.Key != device.Network.Key)
                        throw new UnauthroizedNetworkException("Could not register a device because target network is protected with a key!");
                    if (networkAccessCheck != null && !networkAccessCheck(network))
                        throw new UnauthroizedNetworkException("Could not register a device because target network is not accessible!");
                }
            }
            else
            {
                throw new InvalidDataException("Specified 'network' object must include 'name' property!");
            }

            device.Network = network;
        }
        /// <summary>
        /// Initializes all required properties
        /// </summary>
        /// <param name="notification">Notification text</param>
        /// <param name="device">Associated device object</param>
        public DeviceNotification(string notification, Device device)
        {
            if (string.IsNullOrEmpty(notification))
                throw new ArgumentException("Notification is null or empty!", "notification");
            if (device == null)
                throw new ArgumentNullException("device");

            this.Notification = notification;
            this.Device = device;
        }
        /// <summary>
        /// Initializes all required properties
        /// </summary>
        /// <param name="command">Command text</param>
        /// <param name="device">Associated device object</param>
        public DeviceCommand(string command, Device device)
        {
            if (string.IsNullOrEmpty(command))
                throw new ArgumentException("Command is null or empty!", "command");
            if (device == null)
                throw new ArgumentNullException("device");

            this.Command = command;
            this.Device = device;
        }
예제 #5
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="code">Equipment code</param>
        /// <param name="timestamp">Equipment state timestamp</param>
        /// <param name="device">Associated device object</param>
        public DeviceEquipment(string code, DateTime timestamp, Device device)
        {
            if (string.IsNullOrEmpty(code))
                throw new ArgumentException("Code is null or empty!", "code");
            if (device == null)
                throw new ArgumentNullException("device");

            this.Code = code;
            this.Timestamp = timestamp;
            this.Device = device;
        }
예제 #6
0
        /// <summary>
        /// Register new or update existing device
        /// </summary>
        public JObject SaveDevice(Device device, JObject deviceJson,
            bool verifyNetworkKey = true)
        {
            // load original device for comparison
            var sourceDevice = device.ID > 0 ? DataContext.Device.Get(device.ID) : null;

            // map and validate the device object
            var deviceMapper = GetMapper<Device>();

            ResolveNetwork(deviceJson, verifyNetworkKey);
            ResolveDeviceClass(deviceJson, device.ID == 0);
            deviceMapper.Apply(device, deviceJson);
            Validate(device);

            // save device object
            DataContext.Device.Save(device);

            // replace equipments for the corresponding device class
            if (!device.DeviceClass.IsPermanent && deviceJson["equipment"] is JArray)
            {
                foreach (var equipment in DataContext.Equipment.GetByDeviceClass(device.DeviceClass.ID))
                {
                    DataContext.Equipment.Delete(equipment.ID);
                }
                foreach (JObject jEquipment in (JArray)deviceJson["equipment"])
                {
                    var equipment = GetMapper<Equipment>().Map(jEquipment);
                    equipment.DeviceClass = device.DeviceClass;
                    Validate(equipment);
                    DataContext.Equipment.Save(equipment);
                }
            }

            // save the device diff notification
            var diff = deviceMapper.Diff(sourceDevice, device);
            var notificationName = sourceDevice == null ? SpecialNotifications.DEVICE_ADD : SpecialNotifications.DEVICE_UPDATE;
            var notification = new DeviceNotification(notificationName, device);
            notification.Parameters = diff.ToString();
            DataContext.DeviceNotification.Save(notification);
            _messageBus.Notify(new DeviceNotificationAddedMessage(device.ID, notification.ID));

            return deviceMapper.Map(device);
        }
        /// <summary>
        /// Register new or update existing device.
        /// </summary>
        /// <param name="device">Source device to update.</param>
        /// <param name="deviceJson">A JSON object with device properties.</param>
        /// <param name="verifyNetworkKey">Whether to verify if a correct network key is passed.</param>
        /// <param name="networkAccessCheck">An optional delegate to verify network access control.</param>
        public JObject SaveDevice(Device device, JObject deviceJson,
            bool verifyNetworkKey = true, Func<Network, bool> networkAccessCheck = null)
        {
            // load original device for comparison
            var sourceDevice = device.ID > 0 ? DataContext.Device.Get(device.ID) : null;

            // map and validate the device object
            var deviceMapper = GetMapper<Device>();
            deviceMapper.Apply(device, deviceJson);
            Validate(device);

            // resolve and verify associated objects
            ResolveNetwork(device, verifyNetworkKey, networkAccessCheck);
            ResolveDeviceClass(device);

            // save device object
            DataContext.Device.Save(device);

            // backward compatibility with 1.2 - equipment was passed on device level
            if (!device.DeviceClass.IsPermanent && deviceJson["equipment"] is JArray)
            {
                device.DeviceClass.Equipment = new List<Equipment>();
                foreach (JObject jEquipment in (JArray)deviceJson["equipment"])
                {
                    var equipment = GetMapper<Equipment>().Map(jEquipment);
                    Validate(equipment);
                    device.DeviceClass.Equipment.Add(equipment);
                }
                DataContext.DeviceClass.Save(device.DeviceClass);
            }

            // save the device diff notification
            var diff = deviceMapper.Diff(sourceDevice, device);
            var notificationName = sourceDevice == null ? SpecialNotifications.DEVICE_ADD : SpecialNotifications.DEVICE_UPDATE;
            var notification = new DeviceNotification(notificationName, device);
            notification.Parameters = diff.ToString();
            DataContext.DeviceNotification.Save(notification);
            _messageBus.Notify(new DeviceNotificationAddedMessage(device.ID, notification.ID, notification.Notification));

            return deviceMapper.Map(device);
        }
예제 #8
0
        public void Save(Device device)
        {
            if (device == null)
                throw new ArgumentNullException("device");
            if (device.GUID == Guid.Empty)
                throw new ArgumentException("Device.ID must have a valid value!", "device.ID");

            using (var context = new DeviceHiveContext())
            {
                if (device.Network != null)
                {
                    context.Networks.Attach(device.Network);
                }
                context.DeviceClasses.Attach(device.DeviceClass);
                context.Devices.Add(device);
                if (device.ID > 0)
                {
                    context.Entry(device).State = EntityState.Modified;
                }
                context.SaveChanges();
            }
        }
        private void EnsureDeviceExists(DataContext dataContext, string deviceGuid)
        {
            var device = dataContext.Device.Get(deviceGuid);
            if (device != null)
            {
                if (device.Name == "test device")
                    return;
                
                device.Name = "test device";
                dataContext.Device.Save(device);
                return;
            }

            device = new Device(deviceGuid)
            {
                Name = "test device",
                Network = GetNetwork(dataContext),
                DeviceClass = GetDeviceClass(dataContext),
                Key = DeviceKey
            };

            dataContext.Device.Save(device);
        }
        private bool IsDeviceAccessible(WebSocketConnectionBase connection, Device device, string accessKeyAction)
        {
            var user = (User)connection.Session["User"];
            if (user == null)
                return false;

            if (user.Role != (int)UserRole.Administrator)
            {
                if (device.NetworkID == null)
                    return false;

                var userNetworks = (List<UserNetwork>)connection.Session["UserNetworks"];
                if (userNetworks == null)
                {
                    userNetworks = DataContext.UserNetwork.GetByUser(user.ID);
                    connection.Session["UserNetworks"] = userNetworks;
                }

                if (!userNetworks.Any(un => un.NetworkID == device.NetworkID))
                    return false;
            }

            // check if access key permissions are sufficient
            var accessKey = (AccessKey)connection.Session["AccessKey"];
            return accessKey == null || accessKey.Permissions.Any(p =>
                p.IsActionAllowed(accessKeyAction) && p.IsAddressAllowed(connection.Host) &&
                p.IsNetworkAllowed(device.NetworkID) && p.IsDeviceAllowed(device.GUID.ToString()));
        }
예제 #11
0
        public void DeviceCommandTest()
        {
            var network = new Network("N1");
            NetworkRepository.Save(network);

            var deviceClass = new DeviceClass("D1", "V1");
            DeviceClassRepository.Save(deviceClass);

            var device = new Device(Guid.NewGuid(), "key", "Test", network, deviceClass);
            DeviceRepository.Save(device);

            var command = new DeviceCommand("Test", device);
            DeviceCommandRepository.Save(command);

            // test GetByDevice
            var commands = DeviceCommandRepository.GetByDevice(device.ID, null, null);
            Assert.Greater(commands.Count, 0);

            // test Get(id)
            var command1 = DeviceCommandRepository.Get(command.ID);
            Assert.IsNotNull(command1);
            Assert.AreEqual("Test", command1.Command);
            Assert.AreEqual(device.ID, command1.DeviceID);

            // test Save
            command.Command = "Test2";
            command.Parameters = "{}";
            command.Status = "OK";
            command.Result = "Success";
            DeviceCommandRepository.Save(command);
            var command2 = DeviceCommandRepository.Get(command.ID);
            Assert.AreEqual("Test2", command2.Command);
            Assert.AreEqual("{}", command2.Parameters);
            Assert.AreEqual("OK", command2.Status);
            Assert.AreEqual("Success", command2.Result);

            // test Delete
            DeviceCommandRepository.Delete(command.ID);
            var command3 = DeviceCommandRepository.Get(command.ID);
            Assert.IsNull(command3);
        }
예제 #12
0
 private void Notify(WebSocketConnectionBase connection, Device device, DeviceCommand command)
 {
     connection.SendResponse("command/insert",
         new JProperty("deviceGuid", device.GUID),
         new JProperty("command", CommandMapper.Map(command)));
 }
예제 #13
0
        public void DeviceCommand()
        {
            var network = new Network("N1");
            DataContext.Network.Save(network);
            RegisterTearDown(() => DataContext.Network.Delete(network.ID));

            var deviceClass = new DeviceClass("D1", "V1");
            DataContext.DeviceClass.Save(deviceClass);
            RegisterTearDown(() => DataContext.DeviceClass.Delete(deviceClass.ID));

            var device = new Device(Guid.NewGuid().ToString(), "Test", network, deviceClass);
            DataContext.Device.Save(device);
            RegisterTearDown(() => DataContext.Device.Delete(device.ID));

            var command = new DeviceCommand("Test", device);
            DataContext.DeviceCommand.Save(command);
            RegisterTearDown(() => DataContext.DeviceCommand.Delete(command.ID));

            // test GetByDevice
            var commands = DataContext.DeviceCommand.GetByDevice(device.ID);
            Assert.Greater(commands.Count, 0);

            // test Get(id)
            var command1 = DataContext.DeviceCommand.Get(command.ID);
            Assert.IsNotNull(command1);
            Assert.AreEqual("Test", command1.Command);
            Assert.AreEqual(device.ID, command1.DeviceID);

            // test Save
            command.Command = "Test2";
            command.Parameters = "{ }";
            command.Status = "OK";
            command.Result = "\"Success\"";
            command.UserID = 1;
            DataContext.DeviceCommand.Save(command);
            var command2 = DataContext.DeviceCommand.Get(command.ID);
            Assert.AreEqual("Test2", command2.Command);
            Assert.AreEqual("{ }", command2.Parameters);
            Assert.AreEqual("OK", command2.Status);
            Assert.AreEqual("\"Success\"", command2.Result);
            Assert.AreEqual(1, command2.UserID);

            // test Delete
            DataContext.DeviceCommand.Delete(command.ID);
            var command3 = DataContext.DeviceCommand.Get(command.ID);
            Assert.IsNull(command3);
        }
예제 #14
0
        public void DeviceEquipment()
        {
            var network = new Network("N1");
            DataContext.Network.Save(network);
            RegisterTearDown(() => DataContext.Network.Delete(network.ID));

            var deviceClass = new DeviceClass("D1", "V1");
            DataContext.DeviceClass.Save(deviceClass);
            RegisterTearDown(() => DataContext.DeviceClass.Delete(deviceClass.ID));

            var device = new Device(Guid.NewGuid().ToString(), "Test", network, deviceClass);
            DataContext.Device.Save(device);
            RegisterTearDown(() => DataContext.Device.Delete(device.ID));

            var equipment = new DeviceEquipment("Test", DateTime.UtcNow, device);
            DataContext.DeviceEquipment.Save(equipment);
            RegisterTearDown(() => DataContext.DeviceEquipment.Delete(equipment.ID));

            // test GetByDevice
            var equipments = DataContext.DeviceEquipment.GetByDevice(device.ID);
            Assert.Greater(equipments.Count, 0);

            // test GetByDeviceAndCode
            var equipment0 = DataContext.DeviceEquipment.GetByDeviceAndCode(device.ID, "Test");
            Assert.IsNotNull(equipment0);

            // test Get(id)
            var equipment1 = DataContext.DeviceEquipment.Get(equipment.ID);
            Assert.IsNotNull(equipment1);
            Assert.AreEqual("Test", equipment1.Code);
            Assert.AreEqual(device.ID, equipment1.DeviceID);

            // test Save
            equipment.Code = "Test2";
            equipment.Parameters = "{ }";
            DataContext.DeviceEquipment.Save(equipment);
            var equipment2 = DataContext.DeviceEquipment.Get(equipment.ID);
            Assert.AreEqual("Test2", equipment2.Code);
            Assert.AreEqual("{ }", equipment2.Parameters);

            // test Delete
            DataContext.DeviceEquipment.Delete(equipment.ID);
            var equipment3 = DataContext.DeviceEquipment.Get(equipment.ID);
            Assert.IsNull(equipment3);
        }
예제 #15
0
        public void SaveDevice(Guid deviceId, JObject device)
        {
            try
            {
                // load device from repository
                var deviceEntity = DataContext.Device.Get(deviceId);
                if (deviceEntity != null)
                {
                    if (CurrentDevice == null)
                    {
                        if (!AuthenticateImpl())
                            throw new WebSocketRequestException("Not authorized");
                    }

                    if (CurrentDevice.GUID != deviceId)
                        throw new WebSocketRequestException("Not authorized");
                }
                else
                {
                    // otherwise, create new device
                    deviceEntity = new Device(deviceId);
                }

                device = _deviceService.SaveDevice(deviceEntity, device);
                SendResponse(new JProperty("device", device));
            }
            catch (ServiceException e)
            {
                SendErrorResponse(e.Message);
            }            
        }
예제 #16
0
        public void DeviceNotification()
        {
            var network = new Network("N1");
            DataContext.Network.Save(network);
            RegisterTearDown(() => DataContext.Network.Delete(network.ID));

            var deviceClass = new DeviceClass("D1", "V1");
            DataContext.DeviceClass.Save(deviceClass);
            RegisterTearDown(() => DataContext.DeviceClass.Delete(deviceClass.ID));

            var device = new Device(Guid.NewGuid().ToString(), "Test", network, deviceClass);
            DataContext.Device.Save(device);
            RegisterTearDown(() => DataContext.Device.Delete(device.ID));

            var notification = new DeviceNotification("Test", device);
            DataContext.DeviceNotification.Save(notification);
            RegisterTearDown(() => DataContext.DeviceNotification.Delete(notification.ID));

            // test GetByDevice
            var notifications = DataContext.DeviceNotification.GetByDevice(device.ID);
            Assert.Greater(notifications.Count, 0);

            // test Get(id)
            var notification1 = DataContext.DeviceNotification.Get(notification.ID);
            Assert.IsNotNull(notification1);
            Assert.AreEqual("Test", notification1.Notification);
            Assert.AreEqual(device.ID, notification1.DeviceID);

            // test Save
            notification.Notification = "Test2";
            notification.Parameters = "{ }";
            DataContext.DeviceNotification.Save(notification);
            var notification2 = DataContext.DeviceNotification.Get(notification.ID);
            Assert.AreEqual("Test2", notification2.Notification);
            Assert.AreEqual("{ }", notification2.Parameters);

            // test Delete
            DataContext.DeviceNotification.Delete(notification.ID);
            var notification3 = DataContext.DeviceNotification.Get(notification.ID);
            Assert.IsNull(notification3);
        }
        private void Notify(WebSocketConnectionBase connection, Guid subscriptionId, DeviceCommand command, Device device,
            bool isInitialCommand = false)
        {
            if (!isInitialCommand)
            {
                var initialCommandList = GetInitialCommandList(connection, subscriptionId);
                lock (initialCommandList) // wait until all initial commands are sent
                {
                    if (initialCommandList.Contains(command.ID))
                        return;
                }

                if (!IsDeviceAccessible(connection, device, "GetDeviceCommand"))
                    return;
            }

            connection.SendResponse("command/insert",
                new JProperty("subscriptionId", subscriptionId),
                new JProperty("deviceGuid", device.GUID),
                new JProperty("command", GetMapper<DeviceCommand>().Map(command)));
        }
        public void Authenticate()
        {
            var device = (Device)ActionContext.GetParameter("AuthDevice");
            if (device == null)
                throw new WebSocketRequestException("Please specify valid authentication data");

            SessionDevice = device;
            SendSuccessResponse();
        }
예제 #19
0
        public void DeviceEquipmentTest()
        {
            var network = new Network("N1");
            NetworkRepository.Save(network);

            var deviceClass = new DeviceClass("D1", "V1");
            DeviceClassRepository.Save(deviceClass);

            var device = new Device(Guid.NewGuid(), "key", "Test", network, deviceClass);
            DeviceRepository.Save(device);

            var equipment = new DeviceEquipment("Test", DateTime.UtcNow, device);
            DeviceEquipmentRepository.Save(equipment);

            // test GetByDevice
            var equipments = DeviceEquipmentRepository.GetByDevice(device.ID);
            Assert.Greater(equipments.Count, 0);

            // test GetByDeviceAndCode
            var equipment0 = DeviceEquipmentRepository.GetByDeviceAndCode(device.ID, "Test");
            Assert.IsNotNull(equipment0);

            // test Get(id)
            var equipment1 = DeviceEquipmentRepository.Get(equipment.ID);
            Assert.IsNotNull(equipment1);
            Assert.AreEqual("Test", equipment1.Code);
            Assert.AreEqual(device.ID, equipment1.DeviceID);

            // test Save
            equipment.Code = "Test2";
            equipment.Parameters = "{}";
            DeviceEquipmentRepository.Save(equipment);
            var equipment2 = DeviceEquipmentRepository.Get(equipment.ID);
            Assert.AreEqual("Test2", equipment2.Code);
            Assert.AreEqual("{}", equipment2.Parameters);

            // test Delete
            DeviceEquipmentRepository.Delete(equipment.ID);
            var equipment3 = DeviceEquipmentRepository.Get(equipment.ID);
            Assert.IsNull(equipment3);
        }
예제 #20
0
        public void DeviceTest()
        {
            var network = new Network("N1");
            NetworkRepository.Save(network);

            var deviceClass = new DeviceClass("D1", "V1");
            DeviceClassRepository.Save(deviceClass);

            var device = new Device(Guid.NewGuid(), "key", "Test", network, deviceClass);
            DeviceRepository.Save(device);

            // test GetByNetwork
            var devices = DeviceRepository.GetByNetwork(network.ID);
            Assert.Greater(devices.Count, 0);

            // test Get(id)
            var device1 = DeviceRepository.Get(device.ID);
            Assert.IsNotNull(device1);
            Assert.AreEqual(device.GUID, device1.GUID);
            Assert.AreEqual("Test", device1.Name);
            Assert.AreEqual(network.ID, device1.NetworkID);
            Assert.AreEqual(deviceClass.ID, device1.DeviceClassID);
            Assert.IsNotNull(device1.Network);
            Assert.IsNotNull(device1.DeviceClass);

            // test Get(guid)
            var device2 = DeviceRepository.Get(device.GUID);
            Assert.IsNotNull(device2);
            Assert.AreEqual(device.GUID, device2.GUID);
            Assert.AreEqual("Test", device2.Name);
            Assert.AreEqual(network.ID, device2.NetworkID);
            Assert.AreEqual(deviceClass.ID, device2.DeviceClassID);
            Assert.IsNotNull(device2.Network);
            Assert.IsNotNull(device2.DeviceClass);

            // test Save
            device.Name = "Test2";
            device.Status = "Status";
            DeviceRepository.Save(device);
            var device3 = DeviceRepository.Get(device.ID);
            Assert.AreEqual("Test2", device3.Name);
            Assert.AreEqual("Status", device3.Status);

            // test update relationship
            var deviceClass2 = new DeviceClass("D2", "V2");
            DeviceClassRepository.Save(deviceClass2);
            device.DeviceClass = deviceClass2;
            DeviceRepository.Save(device);
            var device4 = DeviceRepository.Get(device.ID);
            Assert.AreEqual(deviceClass2.ID, device4.DeviceClassID);
            Assert.IsNotNull(device4.DeviceClass);

            // test Delete
            DeviceRepository.Delete(device.ID);
            var device5 = DeviceRepository.Get(device.ID);
            Assert.IsNull(device5);
        }
예제 #21
0
        public void DeviceNotificationTest()
        {
            var network = new Network("N1");
            NetworkRepository.Save(network);

            var deviceClass = new DeviceClass("D1", "V1");
            DeviceClassRepository.Save(deviceClass);

            var device = new Device(Guid.NewGuid(), "key", "Test", network, deviceClass);
            DeviceRepository.Save(device);

            var notification = new DeviceNotification("Test", device);
            DeviceNotificationRepository.Save(notification);

            // test GetByDevice
            var notifications = DeviceNotificationRepository.GetByDevice(device.ID, null, null);
            Assert.Greater(notifications.Count, 0);

            // test Get(id)
            var notification1 = DeviceNotificationRepository.Get(notification.ID);
            Assert.IsNotNull(notification1);
            Assert.AreEqual("Test", notification1.Notification);
            Assert.AreEqual(device.ID, notification1.DeviceID);

            // test Save
            notification.Notification = "Test2";
            notification.Parameters = "{}";
            DeviceNotificationRepository.Save(notification);
            var notification2 = DeviceNotificationRepository.Get(notification.ID);
            Assert.AreEqual("Test2", notification2.Notification);
            Assert.AreEqual("{}", notification2.Parameters);

            // test Delete
            DeviceNotificationRepository.Delete(notification.ID);
            var notification3 = DeviceNotificationRepository.Get(notification.ID);
            Assert.IsNull(notification3);
        }
        private void Notify(WebSocketConnectionBase connection, Guid subscriptionId, DeviceNotification notification, Device device,
            bool isInitialNotification = false)
        {
            if (!isInitialNotification)
            {
                var initialNotificationList = GetInitialNotificationList(connection, subscriptionId);
                lock (initialNotificationList) // wait until all initial notifications are sent
                {
                    if (initialNotificationList.Contains(notification.ID))
                        return;
                }

                if (!IsDeviceAccessible(connection, device, "GetDeviceNotification"))
                    return;
            }

            connection.SendResponse("notification/insert",
                new JProperty("subscriptionId", subscriptionId),
                new JProperty("deviceGuid", device.GUID),
                new JProperty("notification", GetMapper<DeviceNotification>().Map(notification)));
        }
예제 #23
0
        /// <name>register</name>
        /// <summary>
        ///     <para>Registers a device.</para>
        ///     <para>If device with specified identifier has already been registered, it gets updated in case when valid key is provided in the authorization header.</para>
        /// </summary>
        /// <param name="id">Device unique identifier.</param>
        /// <param name="json" cref="Device">In the request body, supply a <see cref="Device"/> resource.</param>
        /// <returns cref="Device">If successful, this method returns a <see cref="Device"/> resource in the response body.</returns>
        /// <request>
        ///     <parameter name="network" mode="remove" />
        ///     <parameter name="deviceClass" mode="remove" />
        ///     <parameter name="network" type="integer or object" required="false">
        ///         <para>Network identifier or <see cref="Network"/> object.</para>
        ///         <para>If object is passed, the target network will be searched by name and automatically created if not found.</para>
        ///         <para>In case when existing network is protected with the key, the key value must be included.</para>
        ///     </parameter>
        ///     <parameter name="deviceClass" type="integer or object" required="true">
        ///         <para>Device class identifier or <see cref="DeviceClass"/> object.</para>
        ///         <para>If object is passed, the target device class will be searched by name and version, and automatically created if not found.</para>
        ///         <para>The device class object will be also updated accordingly unless the <see cref="DeviceClass.IsPermanent"/> flag is set.</para>
        ///     </parameter>
        ///     <parameter name="equipment" type="array" required="false" cref="Equipment">
        ///         <para>Array of <see cref="Equipment"/> objects to be associated with the device class. If specified, all existing values will be replaced.</para>
        ///         <para>In case when device class is permanent, this value is ignored.</para>
        ///     </parameter>
        /// </request>
        public JObject Put(Guid id, JObject json)
        {
            // load device from repository
            var device = DataContext.Device.Get(id);
            if (device != null)
            {
                // if device exists, administrator or device authorization is required
                if ((RequestContext.CurrentUser == null || RequestContext.CurrentUser.Role != (int)UserRole.Administrator) &&
                    (RequestContext.CurrentDevice == null || RequestContext.CurrentDevice.GUID != id))
                {
                    ThrowHttpResponse(HttpStatusCode.Unauthorized,  "Not authorized");
                }
            }
            else
            {
                // otherwise, create new device
                device = new Device(id);
            }

            JObject result = null;

            try
            {
                result = _deviceService.SaveDevice(device, json,
                    RequestContext.CurrentUser == null);
            }
            catch (InvalidDataException e)
            {
                ThrowHttpResponse(HttpStatusCode.BadRequest, e.Message);
            }
            catch (UnauthroizedNetworkException e)
            {
                ThrowHttpResponse(HttpStatusCode.Forbidden, e.Message);
            }

            return result;
        }
 private bool IsDeviceAccessible(Device device, string accessKeyAction)
 {
     return IsDeviceAccessible(Connection, device, accessKeyAction);
 }
예제 #25
0
        private void Notify(WebSocketConnectionBase connection, DeviceNotification notification, Device device)
        {
            var user = (User) connection.Session["user"];
            if (user == null || !IsNetworkAccessible(device.NetworkID, user))
                return;

            connection.SendResponse("notification/insert",
                new JProperty("deviceGuid", device.GUID),
                new JProperty("notification", NotificationMapper.Map(notification)));
        }
예제 #26
0
        private void ResolveDeviceClass(Device device)
        {
            if (device.DeviceClass == null)
                throw new InvalidDataException("Required 'deviceClass' property can not be null!");

            var deviceClass = (DeviceClass)null;
            if (device.DeviceClass.Name != null && device.DeviceClass.Version != null)
            {
                // device class name and version are passed
                deviceClass = DataContext.DeviceClass.Get(device.DeviceClass.Name, device.DeviceClass.Version);
                if (deviceClass == null)
                {
                    // auto-create device class
                    deviceClass = device.DeviceClass;

                    Validate(deviceClass);
                    if (deviceClass.Equipment != null)
                        deviceClass.Equipment.ForEach(e => Validate(e));
                    DataContext.DeviceClass.Save(deviceClass);
                }
                else if (!deviceClass.IsPermanent)
                {
                    // auto-update device class if it's not set as permanent
                    deviceClass.Data = device.DeviceClass.Data;
                    deviceClass.IsPermanent = device.DeviceClass.IsPermanent;
                    deviceClass.OfflineTimeout = device.DeviceClass.OfflineTimeout;
                    if (device.DeviceClass.Equipment != null)
                    {
                        deviceClass.Equipment.Clear();
                        deviceClass.Equipment.AddRange(device.DeviceClass.Equipment);
                    }
                    
                    Validate(deviceClass);
                    deviceClass.Equipment.ForEach(e => Validate(e));
                    DataContext.DeviceClass.Save(deviceClass);
                }
            }
            else
            {
                throw new InvalidDataException("Specified 'deviceClass' object must include 'name' and 'version' properties!");
            }

            device.DeviceClass = deviceClass;
        }
예제 #27
0
        /// <name>register</name>
        /// <summary>
        ///     <para>Registers a device.</para>
        ///     <para>If device with specified identifier has already been registered, it gets updated in case when valid key is provided in the authorization header.</para>
        /// </summary>
        /// <param name="id">Device unique identifier.</param>
        /// <param name="json" cref="Device">In the request body, supply a <see cref="Device"/> resource.</param>
        /// <returns cref="Device">If successful, this method returns a <see cref="Device"/> resource in the response body.</returns>
        /// <request>
        ///     <parameter name="network" mode="remove" />
        ///     <parameter name="deviceClass" mode="remove" />
        ///     <parameter name="network" type="integer, string, or object" required="true">
        ///         <para>Network identifier, network key or <see cref="Network"/> object.</para>
        ///         <para>If object is passed, the target network will be searched by name and automatically created if not found.</para>
        ///         <para>In case when existing network is protected with the key, the key value must be included.</para>
        ///     </parameter>
        ///     <parameter name="deviceClass" type="integer or object" required="true">
        ///         <para>Device class identifier or <see cref="DeviceClass"/> object.</para>
        ///         <para>If object is passed, the target device class will be searched by name and version, and automatically created if not found.</para>
        ///     </parameter>
        ///     <parameter name="equipment" type="array" required="false" cref="Equipment">
        ///         <para>Array of <see cref="Equipment"/> objects to be associated with the device class. If specified, all existing values will be replaced.</para>
        ///         <para>In case when device class is permanent, this value is ignored.</para>
        ///     </parameter>
        /// </request>
        public JObject Put(Guid id, JObject json)
        {
            // load device from repository
            var device = DataContext.Device.Get(id);
            if (device != null)
            {
                // if device exists, administrator or device authorization is required
                if ((RequestContext.CurrentUser == null || RequestContext.CurrentUser.Role != (int)UserRole.Administrator) &&
                    (RequestContext.CurrentDevice == null || RequestContext.CurrentDevice.GUID != id))
                {
                    ThrowHttpResponse(HttpStatusCode.Unauthorized, "Not authorized");
                }
            }
            else
            {
                // otherwise, create new device
                device = new Device(id);
            }

            // map and save the device object
            ResolveNetwork(json, device.ID == 0);
            ResolveDeviceClass(json, device.ID == 0);

            Mapper.Apply(device, json);
            Validate(device);

            DataContext.Device.Save(device);

            // replace equipments for the corresponding device class
            if (!device.DeviceClass.IsPermanent && json["equipment"] is JArray)
            {
                foreach (var equipment in DataContext.Equipment.GetByDeviceClass(device.DeviceClass.ID))
                {
                    DataContext.Equipment.Delete(equipment.ID);
                }
                foreach (JObject jEquipment in (JArray)json["equipment"])
                {
                    var equipment = GetMapper<Equipment>().Map(jEquipment);
                    equipment.DeviceClass = device.DeviceClass;
                    Validate(equipment);
                    DataContext.Equipment.Save(equipment);
                }
            }

            return Mapper.Map(device);
        }
예제 #28
0
        public void Device()
        {
            var network = new Network("N1");
            DataContext.Network.Save(network);
            RegisterTearDown(() => DataContext.Network.Delete(network.ID));

            var deviceClass = new DeviceClass("D1", "V1");
            DataContext.DeviceClass.Save(deviceClass);
            RegisterTearDown(() => DataContext.DeviceClass.Delete(deviceClass.ID));

            var device = new Device(Guid.NewGuid().ToString(), "Test", network, deviceClass);
            DataContext.Device.Save(device);
            RegisterTearDown(() => DataContext.Device.Delete(device.ID));

            // test GetByNetwork
            var devices = DataContext.Device.GetByNetwork(network.ID);
            Assert.Greater(devices.Count, 0);

            // test Get(id)
            var device1 = DataContext.Device.Get(device.ID);
            Assert.IsNotNull(device1);
            Assert.AreEqual(device.GUID, device1.GUID);
            Assert.IsNull(device1.Key);
            Assert.AreEqual("Test", device1.Name);
            Assert.AreEqual(network.ID, device1.NetworkID);
            Assert.AreEqual(deviceClass.ID, device1.DeviceClassID);
            Assert.IsNotNull(device1.Network);
            Assert.IsNotNull(device1.DeviceClass);

            // test Get(guid)
            var device2 = DataContext.Device.Get(device.GUID);
            Assert.IsNotNull(device2);
            Assert.AreEqual(device.GUID, device2.GUID);
            Assert.AreEqual("Test", device2.Name);
            Assert.AreEqual(network.ID, device2.NetworkID);
            Assert.AreEqual(deviceClass.ID, device2.DeviceClassID);
            Assert.IsNotNull(device2.Network);
            Assert.IsNotNull(device2.DeviceClass);

            // test Save
            device.Key = "key";
            device.Name = "Test2";
            device.Status = "Status";
            device.Data = "{ }";
            device.Network = null;
            device.NetworkID = null;
            DataContext.Device.Save(device);
            var device3 = DataContext.Device.Get(device.ID);
            Assert.AreEqual("key", device3.Key);
            Assert.AreEqual("Test2", device3.Name);
            Assert.AreEqual("Status", device3.Status);
            Assert.AreEqual("{ }", device3.Data);
            Assert.IsNull(device3.Network);
            Assert.IsNull(device3.NetworkID);

            // test update relationship
            var deviceClass2 = new DeviceClass("D2", "V2");
            DataContext.DeviceClass.Save(deviceClass2);
            RegisterTearDown(() => DataContext.DeviceClass.Delete(deviceClass2.ID));
            device.DeviceClass = deviceClass2;
            DataContext.Device.Save(device);
            var device4 = DataContext.Device.Get(device.ID);
            Assert.AreEqual(deviceClass2.ID, device4.DeviceClassID);
            Assert.IsNotNull(device4.DeviceClass);

            // test Delete
            DataContext.Device.Delete(device.ID);
            var device5 = DataContext.Device.Get(device.ID);
            Assert.IsNull(device5);
        }
        /// <summary>
        /// Notifies the device about new command.
        /// </summary>
        /// <action>command/insert</action>
        /// <response>
        ///     <parameter name="deviceGuid" type="string">Device unique identifier.</parameter>
        ///     <parameter name="command" cref="DeviceCommand">A <see cref="DeviceCommand"/> resource representing the command.</parameter>
        /// </response>
        private void Notify(WebSocketConnectionBase connection, Device device, DeviceCommand command,
            bool isInitialCommand = false)
        {
            if (!isInitialCommand)
            {
                var initialCommandList = GetInitialCommandList(connection);
                lock (initialCommandList) // wait until all initial commands are sent
                {
                    if (initialCommandList.Contains(command.ID))
                        return;
                }
            }

            connection.SendResponse("command/insert",
                new JProperty("deviceGuid", device.GUID),
                new JProperty("command", MapDeviceCommand(command)));
        }