Git Product home page Git Product logo

device-sdk-go's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

device-sdk-go's Issues

Example simple-device fails to run with confdir flag confict

I built the example service and when trying to run it I get the following:

mhall@mhall-laptop:~/go/src/github.com/edgexfoundry/device-sdk-go/examples/simple/cmd$ ./simple-device 
./simple-device flag redefined: confdir
panic: ./simple-device flag redefined: confdir

goroutine 1 [running]:
flag.(*FlagSet).Var(0xc42007c060, 0x812e00, 0xc420080d70, 0x7ca8b7, 0x7, 0x7d9b25, 0x2d)
	/usr/lib/go-1.10/src/flag/flag.go:810 +0x540
flag.StringVar(0xc420080d70, 0x7ca8b7, 0x7, 0x0, 0x0, 0x7d9b25, 0x2d)
	/usr/lib/go-1.10/src/flag/flag.go:719 +0x8a
main.main()
	/home/mhall/go/src/github.com/edgexfoundry/device-sdk-go/examples/simple/cmd/main.go:40 +0x1ac

Changing the flag from "confdir" to "confDir" (or removing that flag altogether) fixes this issue.

Implement private device struct

Implement a new private device struct which encapsulates the public Device object imported from edgex-go. This new struct can then include a mutex which can be used to prevent a Device from being removed while operations involving it are in-progress.

Estimated effort: 3d

Create a customizable configuration field and API for users

The SDK currently manages all configuration (local and via the registry). If an author of a device profile wants to add protocol-specific configuration values, this is not possible today. Instead, they would be required handle protocol configuration entirely separate from the existing mechanisms. Fixing this issue would allow a DS develop to leverage the existing configuration mechanisms to support protocol-specific configuration values, perhaps via the use of another level of path in the configuration key naming.

Proposed change to ProtocolDriver.HandleOperation

I suggest that we alter this method in two ways.

Firstly that where a command encompasses multiple ResourceOperations these should be handled in a single call. This allows the device implementation to perform optimized multiple reads or writes on hardware which is capable.

Secondly that the method is split into two variants for PUT and GET operations. The parameters required for these two are different, and I feel there is not enough code commonality to warrant implementing both in a single method.

This would result in something like

HandleGetOperation (device *models.Device,
   objects []models.DeviceObject,
   results []CommandResult)

(ValueDescriptor and ResourceObject are held in the CommandResult)

and

HandlePutOperation (device *models.Device,
    objects []models.DeviceObject,
   requests []CommandRequest)

Where CommandRequest is defined similarly to CommandResult but containing a value to set rather than a Result to be filled in.

Implement binary encoding of Events & Readings

Implement binary encoding (using CBOR) of events & readings.

This first assumes that a new bytes field (vs. the result field which is a string) has been added to the Reading struct, so the CBOR can encode the byes properly.

Estimated effort: 5-7d

Add public Service methods to remove or update Devices

Top-level Service methods should be added to allow device service implementations to dynamically update or remove devices. The operations result in changes to Core Metadata in addition to the device service's local Device objects.

A top-level AddDevice Service method already exists.

Estimated effort: 3-4d

Implement Reading assertions

Assertions are another attribute in a device resource's value PropertyValue which specify a string value which the result is compared against. If the comparison fails, then the result is set to a string of the form “Assertion failed for device resource: , with value: ”, this also has a side-effect of setting the device operatingstate to DISABLED. In the case of the single device /command endpoint, a 500 status code is also returned. If the all form of the /command endpoint is used an assertion failure will return a 200 status, and it's the responsibilty of the client to check each reading for assertion failures.

As assertions are operations on results after they've been transformed into the string to be passed in the Reading, assertions cannot as currently defined, be applied to binary readings which result in an array of bytes vs. a string result in the Reading.

For more details see the Device Services functional requirements document.

Estimated effort: 2d

Simplify device profile caching

The current implementation of the local device profile caching as implemented in profiles.go is based on the original EdgeX Java Device Services SDK. The original code is overly-complicated and has one enormous function called addDevice() which should be broken up. Instead of having a simple map or array of DeviceProfile structs, maps of DeviceObjects and commands are created.

Recently a map of DeviceProfile objects was added to handle automatic importing of device profiles via on-disk YAML files.

This task is to explore simplification of the code, possibly using recently added DeviceProfile map directly instead using the derived command and objects maps. Thread safety should also be reviewed, and unit tests added as part of this task.

Estimated effort: 5-8d

Implement the ping endpoint

Implement the ping endpoint, and ensure that if the consul/registry is enabled, the ping endpoint is specified when registering as a service.

Estimated effort: 1d

Add param member to CommandRequest and remove from ProtocolDriver.HandleCommands

The ProtocolDriver HandleCommands function has a parameter called 'params' which is used to pass command actuation parameters to the protocol specific code. Currently if the 'set/put' form of the command endpoint is called, this parameter is the corresponding JSON passed to the endpoint. It was suggested instead that we should parse this JSON and add a new parms field to the CommandRequest struct to simply the work the ProtocolDriver has to perform.

Implement Reading mappings

Implement reading mappings.

Mappings are an attribute in resource operation (see Appendix C - Device Profiles for details) and consist of a static list of string result values that contain a fixed mapping. Ex.

[ “8675309”: “911”, “2112”: “1”, “777”: “666”]

Mapping are applied after assertions are checked, and are the final transformation before readings are created.

For more details see the Device Services functional requirements document.

Note - support for mappings is a nice-to-have for Dehli.

Estimated effort: 2d

Add service dependency startup logic

Per the California Service Name design, an EdgeX service should ensure that its dependent services are available before responding to REST endpoints, including ping.

If the registry/consul is specified on startup, then the SDK should query Consul to determine availability of Core Data and Metadata. If the registry is not specified, then the SDK must query the service directly via REST to ensure availability.

Once dependent services have been been verified as available:

  • if the registry is being used, then the SDK should register the device service with consul

  • the SDK should start responding to REST requests

Priority: High
Estimated effort: 2d

Add versions to glide.yaml

Currently most of the device-sdk-go dependencies pull from head/tip vs. specifying a specific release for each in glide.yaml. The same has been planned for edgex-go.

Note - both the mgo and yaml packages specify versions via gopkg.in.

Implement Reading transforms

Implement transformations of device readings.

The values that can be read from a device are defined in the PropertyValues of device resources as defined by a DeviceProfile. A PropertyValue may specify optional attributes which are used to transform the readings from devices/sensors. These attributes are defined below and are applied to the native data types (float* or int/uint*) in the following order:

base – a base value which is raised to the power of the reading value
scale – a multiplicative factor applied to the reading
offset – an additive factor applied to the reading

For more details see the Device Services functional requirements document.

Estimated effort: 2d

make the waiting arguments configurable in clients initialization

The current implementation of clients/init.go:

	for i := 0; i < 50; i++ {
		if common.UseRegistry {
			if checkServiceAvailableByConsul(common.CurrentConfig.Clients[serviceId].Name) == true {
				return nil
			}
		} else {
			if checkServiceAvailableByPing(serviceId) == nil {
				return nil
			}
		}
		time.Sleep(2 * time.Second)
		common.LogCli.Debug(fmt.Sprintf("Checked %d times for %s availibility", i+1, serviceId))
	}

The 50 and 2 should be configurable.

Validate DeviceProfiles on import

When DeviceProfiles are auto-imported on device service startup, there should be some constraints checking implemented. These constraints should be represented by configuration settings and should include:

  • max number of device resources
  • max number of resource commands
  • max number of resource operations (applies to get & put)

Review thread safety in devices.go

The code in devices.go should be reviewed for thread safety. The current implementation was based on the original EdgeX Java Device Services SDK. This change is dependent on a new internal device struct to be created, so that devices can be locked when operations involving the device are in-progress.

Estimated effort: 2d

Review devices/profiles struct and pointer usage

Review composition of internal complex data types as used in the device and profile cache. Should arrays/maps use structs or pointers to structs? Currently the device cache use pointers to Device structs in it's map, whereas the profile cache code doesn't use pointers in its commands and objects maps. In theory, none of the code that accesses devices in the local cache should need to modify the devices, so there's no reason for the pointer usage other than the potential optimization.

Estimated effort: 2-3d

Add public Service methods to add/update/remove DeviceProfiles

Add public Service methods to allow a device service to dynamically add/update or remove DeviceProfile objects. The operations result in changes to Core Metadata in addition to the device service's local DeviceProfile objects.

Estimated effort: 2-3d

Implement cache unit tests

Implement unit tests that cover the device cache logic, which is also responsible to updating Core Metadata with any changes to the local devices.

Estimated effort: 3d

Add devices init/remove command support

Add support for generic init and disconnect functions when devices are added or removed from the device service. The commands must be valid commands in the corresponding device profile. The functions are defined by the configuration settings InitCmd and RemoveCmd settings, and arguments for both are specified in the InitCmdArgs and RemoveCmdArgs settings.

Note - it might be a good idea to update the setting names to include "Dev" or "Device". Also maybe InitCmd should be AddDeviceCmd to make things more sensical?

Estimated effort: 3-4d

Implement size constraints for devices & profiles

Implement size constraints (w/unit tests) for devices and profiles based on configuration settings. Constraints should include:

  • max devices (total & per profile)

  • max labels per device

  • max device profiles

  • max commands per device profile

  • max resource operations per device profile command

  • max number of device resources

  • max number of resource commands

  • max number of resource operations (applies to get & put)

Estimated effort: 2-3d

Implement All form of GET command endpoint

Currently the command endpoint only supports specifying a deviceId. Another form of the endpoint replaces a specific device id with the word "all", which instructs the device service to send the given command to all of it's devices.

Note - this form of the command was intended for ease of scheduling periodic readings of all of a device service's devices. If the device service supports multiple device profiles, then the same command needs to be available in all of them.

For more details see the Device Services functional requirements document.

Estimated effort: 3-4d

Add registry settings support

If the registry/consul is enabled on service startup, try to read initial configuration settings from consul.

In order for this feature to work, the settings for the device service need to be injected into consul via core-config-seed, or some other out-of-band mechanism.

Priority: High
Estimated effort: 5d

Consul doesn't work when clients initial.

Because client api use internal Consul variable. But when startup we have another Consul variable in sdk.

Error log:

Calling service.Start.
Init: useRegistry: true profile:  confDir: ./examples/simple/cmd/res/
Register in Consul...INFO: 2018/09/11 19:37:59 Check edgex-core-metadata service's status by Consul...
INFO: 2018/09/11 19:37:59 Check edgex-core-data service's status by Consul...
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x12979c3]

goroutine 85 [running]:
github.com/edgexfoundry/device-sdk-go/vendor/github.com/hashicorp/consul/api.(*Client).newRequest(0x0, 0x13e6c99, 0x3, 0x13ead4b, 0x12, 0x0)
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/hashicorp/consul/api/api.go:644 +0x63
github.com/edgexfoundry/device-sdk-go/vendor/github.com/hashicorp/consul/api.(*Agent).Services(0xc000189d90, 0x0, 0x0, 0x0)
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/hashicorp/consul/api/agent.go:245 +0x6d
github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/internal/pkg/consul.GetServiceEndpoint(0xc0000cc540, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/internal/pkg/consul/consul.go:85 +0x7b
github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/pkg/clients/types.Endpoint.Monitor(0xc0000cc540, 0x13, 0x13eb304, 0x13, 0x1, 0xc0001e80f0, 0x29, 0xc0001c82a0)
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/pkg/clients/types/endpoint.go:15 +0x1c3
created by github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/pkg/clients/metadata.(*AddressableRestClient).init
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/pkg/clients/metadata/addressable.go:54 +0xe6
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x12979c3]

goroutine 91 [running]:
github.com/edgexfoundry/device-sdk-go/vendor/github.com/hashicorp/consul/api.(*Client).newRequest(0x0, 0x13e6c99, 0x3, 0x13ead4b, 0x12, 0x0)
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/hashicorp/consul/api/api.go:644 +0x63
github.com/edgexfoundry/device-sdk-go/vendor/github.com/hashicorp/consul/api.(*Agent).Services(0xc000185d90, 0x0, 0x0, 0x0)
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/hashicorp/consul/api/agent.go:245 +0x6d
github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/internal/pkg/consul.GetServiceEndpoint(0xc0000cc540, 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/internal/pkg/consul/consul.go:85 +0x7b
github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/pkg/clients/types.Endpoint.Monitor(0xc0000cc540, 0x13, 0x13ec1a6, 0x15, 0x1, 0xc0001e8180, 0x2b, 0xc0001c83c0)
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/pkg/clients/types/endpoint.go:15 +0x1c3
created by github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/pkg/clients/metadata.(*DeviceProfileRestClient).init
	/Users/bruce/go/src/github.com/edgexfoundry/device-sdk-go/vendor/github.com/edgexfoundry/edgex-go/pkg/clients/metadata/device_profile.go:53 +0xe6

Process finished with exit code 2

Implement command unit tests

Implement unit tests for the command endpoint (GET & PUT).

This relies on a few other tasks being completed first, namely ensuring that there are interfaces for needed clients and the caching code so that things can be mocked.

Estimated effort: 5-7d

Implement callback to handle device adminState

It was decided at the last F2F, that the one Core Metadata callback function to be supported for Dehli is handling changes to a device's adminState (LOCKED or UNLOCKED).

Estimated effort: 3d

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.