SignalK / specification

Signal K is a JSON-based format for storing and sharing marine data from different sources (e.g. nmea 0183, 2000, seatalk, etc)
Other
91 stars 69 forks source link

RFC 0009: Digital Switching #441

Open Krillle opened 6 years ago

Krillle commented 6 years ago

Summary

Digital Switching is not yet part of the schema. Some Digital Switching bus systems like e.g. Raymarine EmpirBus [1] are sending their data via NMEA 2000 and therefore can be monitored and controlled via Signal K. This RFC is intended to propose and discuss a schema for Digital Switching devices.

Type of devices

Digital Switching includes mainly switches with the state on or off, and dimmers with a value 0% - 100%.

Connected to these controls can be almost anything electrical like lights, fans, navigation lights, horn, windlass, engine ignition. The type of device connected to the control is not necessarily transparent to the NMEA bus.

Proposed Schema

The dimmer values and switch states are stored in the following schema:

electrical/controls/<identifier>
electrical/controls/<identifier>/state (on|off)
electrical/controls/<identifier>/brightness (0..1 where 1 = 100%)
electrical/controls/<identifier>/type (switch | dimmer | etc.) electrical/controls/<identifier>/name (System name of control, e.g. 'Switch 0.8')

electrical/controls<identifier>/meta/displayName (Display name of control)

electrical/controls/<identifier>/associatedDevice/instance (Technical device address according to Digital Switching System)

electrical/controls/<identifier>/associatedDevice/device (Technical device address according to Digital Switching System)

electrical/controls/<identifier>/source (Information which plugin needs to take care of device)

electrical/controls/<identifier>/dataModel (Data Model used in Digital Switching, in EmpirBus programming different data models can be used)

electrical/controls/<identifier>/manufacturer/name
electrical/controls/<identifier>/manufacturer/model

<identifier> is the device identifier specific to Digital Switching System. Concattenated from the name of digital switching system and a system plugin proprietary device address (systemname-deviceaddress), e.g. for EmpirBus NXT devices this is empirBusNxt-instance<instance>-dimmer|switch<#>

<instance> is the ID of the respective EmpirBus NXT API component for 3rd party communication 0..49

<#> is the ID of the dimmer (1..2) or switch (1..8)

state is state of switch or dimmer 'on' or 'off'

brightness the dimming ratio of dimmer from 0 to 1, where 1 = 100%

associatedDevice is the address of device proprietary to the plugin and digital switching system, e.g. for EmpirBus NXT {"instance":0,"switch":0} or {"instance":0,"dimmer":0}

First question probably asked

Isn't state and brightness actually same, therefore brightness of a dimmer should be stored in state as a ratio? A dimmer can be switched off, but it can have a stored brightness level that is to be set when the dimmer is switched on again. This is why the schema needs to have two values for it: State is on or off, while brightness is the brightness to set it to.

Same as the HomeKit characteristics of dimmers are designed: Characteristic.On Characteristic.Brightness

First usage

The first plugin using this schema is the signal-empirbus-plugin [2], which can be used to monitor and control Raymarine Digital Switching [1].

[1] http://www.raymarine.com/view/?id=6863 [2] https://github.com/sbender9/signalk-empirbus-plugin

bkp7 commented 6 years ago

Just some initial thoughts upon first reading:

In the case of lighting there should be a concept of macros or patterns. eg. in some vessels the lower helm is in the same space as the saloon. There is a need for differing levels of brightness and/or colour in different areas of the same room. Think individually addressable 'bulbs'.

There should be a way to link power sources with consumers ie. identifying electrical buses. Also as part of this the switching of buses and electrical sources needs to be considered including cross over (linking buses). An individual device could be designed to be connected to 2 buses to allow for redundancy. There is already a concept of associatedBus (ac and dc) in the electrical schema.

The electrical schema in its current form has a number of bugs and issues, which should be rectified before adding more stuff, eg #310

There have been previous discussions regarding switching and the insights gained there should be incorporated here eg. #310, #187

Looking at the proposed schema could you clarify what is meant by a 'control'. Is this the actual control mechanism (eg. physical switch, switch on a screen), or is it the circuit control module. Similarly for 'device', is this an individually addressable device capable of turning itself on and off, or is this the circuit control module, or a channel on the circuit control module? How are chained control modules dealt with? Also could you clarify how you anticipate the SignalK servers interacting? eg. the slave server within a circuit control module would know the state of that module, and the slave server running physical switches will receive inputs from those switches, how do the 2 interact?

Some targets for controls are already in the schema eg. trim/tilt.

I don't think there is currently any concept of 'consumers' in the electrical schema. Only an inverter can report its power consumption via its dcQualities. This seems a bit odd, for example why cant a charger report its ac consumption? Also the electrical schema currently has a separate branch for ac buses but not one for dc buses. I think these apparent anomalies should be looked at/discussed in this context.

Krillle commented 6 years ago

Thanks for your comments, wich are interesting thoughts on a complex general approach.

Yet the reality of connecting to digital switching bus systems is disillusioning here:

The way how a digital switching system is controlling what device onboard is subject to the programming "on the other side" of the API of the digital switching system and therefore not transparent to Signal K. The information visible to Signal K is depending on the API of the digital switching system and the way how it's API is used in the individual programming of the digital switching system.

I can speak for EmpirBus, of which I have in deep knowledge:

In EmpirBus NXT a third party application can receive and send NMEA messages containing word and bit numbers to a virtual device processing these values in the digital switching system. In what way these values are processed for controlling connected devices is subject to the individual programming of the respective system.

No other data that these bits and words are transparent to the third party application. All the rest is up to the the matching programming of the individual implementation of digital switching system and the application using the Signal K API.

In normal environments a bit value will represent a status on or off, while a word value represents a ratio 0% - 100%.

Combination of words and bits for sure could be used for complex controls like e.g. in extreme light show patterns, but this was stretched too far trying to cover such a "digital switching " hacks" with a general schema.

This is why am proposing switches with state on/off and dimmers with state 0%-100%. All the rest has to be seen as a kind of meta data, setting theses values in their context. But this meta data is (in case of EmpirBus NXT) not coming from the digital switching itself, but must be added by the respective plugin providing the data.

Therefore I recommend to keep it simple and use a as low complex schema as possible.

I have deep knowledge of Raymarine EmpirBus NXT. This is so far the only Digital Switching system communicating on NMEA I know. My assumptions are generalized from this system. Therefore input from someone familiar with another digital switching system would be welcome, e.g. the system used by Jetten yachts.

bkp7 commented 6 years ago

The Mastervolt czone system runs on NMEA2000 and can be fully operated from Garmin MFDs.

I think there is a crucial question here. Is SignalK just another way to represent data from other systems, or is it able to stand alone. If we do it right there is no reason not to have Signal K switch modules and Signal K enabled pumps, bulbs, etc. I don't think it needs to be complex, but it should be able to cover more than just one manufacturers system.

To quote: "Signal K is a modern and open data format for marine use...... Signal K is the first truly open data format for the marine industry and is set to revolutionize how we consume and interact with data on boats."

mxtommy commented 6 years ago

Just some random thoughts.

I think there's quite a bit in there that is specific to the NXT. I think a lot of those paths would be more appropriate in a meta type field? associatedDevice, dataModel, and even name/type are all just describing the data as far as I can tell.

For what it's worth I'm developing an ESP8266 "switch" using signalk. I'm using a single path, though I've only coded on/off so far. The switch reports it's current state to that path, and accepts Put requests to that path to change the value.

Also regarding "state", I'm using boolean values (true/false, aka 0/1) instead of on/off. My paths aren't hard coded, but I'm thinking things like "electrical.control.cabinLightsOn" or something where true/false make sense. my issue with "on"/"off" is that they're just strings. You'll get people using "On", "ON", etc. Or On/Off in another language etc. Then you need to have more complicated logic to test if something is "on" or not. true/false are much more suited IMO.

Krillle commented 6 years ago

Yes, I do agree to that: Bus specific information in meta data and technical advantage of true/false over on/off. I used on/off to have it better human readable.

The type I think is not meta data, but describes the fundamental functionality of the switching element. Question is, if there is any more basic electrical functionally over on/off switches and 0%-100% ratio types.

“CabinLightsOn” would be a valid identifier in the proposed schema.

fabdrol commented 6 years ago

I’m actually working on a complex EmpirBus control implementation for a super yacht at the moment, which needed some of the more complex behaviours that are currently lacking. We solved that like this:

We found that this model provides much more flexibility whilst also more closely representing how circuits actually look (one physical switch may have 5 loads)

Krillle commented 6 years ago

How would your implementation communicate with Signal K:

A) Using the provided 3rd party application API: In what way would you map your setup to the available bits and words data models [1]? B) Or or reverse engineering the EmpirBus internal NMEA communication and maybe making the EmpirBus implementation transparent to Signal K?

How would the Signal K data model map your implementation then: A) Mapping the Data model of bits (0/1) and words (ratio) B) Or mapping the structure of your implementation

I think this is the core question, as there are no standard NMEA PGN messages fo digital switching: A) Should Signal K map the data model of available API interfaces B) Or should Signal K convert the information sent over the interfaces back to the structure of the digital switching implementation, (which is not transparent through NMEA but depends on the respective implementation)

[1] https://github.com/sbender9/signalk-empirbus-plugin/blob/empirbus-api-communication/docs/PGN%2065280%20EmpirBus%20Application%20Specific%20PGN.pdf

fabdrol commented 6 years ago

@Krillle

IMHO I don't believe the upstream implementation (i.e., how the actual switching is executed) is important for this RFC: the point of Signal K is to provide a sane, complete data model to represent things in a nautical environment, enable services to communicate about those things, etc. In the context of digital switching, that means representing (A) what things (electrical loads (i.e. outputs) and inputs) there are in an installation and (B) what the state of those things is (on/off, dimming level, other state related data). The third and final consideration (C) is how to control those things; which is - as you pointed out - specific to various kinds of hardware (i.e. EmpirBus NXT, E.T.A. PowerPlex, MasterVolt C-Zone, Naviop, etc etc)

In the data model we came up with after multiple rounds of software design, The ABC above is defined thus:

A: Loads, Fuses, Values, Inputs (& Switches) B: state, dimmingLevel, tripped, value properties on those entities C: Switches, with their associated policies.

Defined as Signal K data, that would look something like this ():

// Loads
/electrical/loads/<identifier>/state
/electrical/loads/<identifier>/dimmingLevel
/electrical/loads/<identifier>/meta/listeners 
/electrical/loads/<identifier>/meta/fuse // Optional related fuse
/electrical/loads/<identifier>/meta/name // Optional name
/electrical/loads/<identifier>/meta/description // Optional description
/electrical/loads/<identifier>/meta/location // Optional location (e.g. Crew Cabin or Switch Bank Port)

// Fuses
/electrical/fuses/<identifier>/tripped
/electrical/fuses/<identifier>/meta/load // Optional related load
/electrical/fuses/<identifier>/meta/name // Optional name
/electrical/fuses/<identifier>/meta/description // Optional description
/electrical/fuses/<identifier>/meta/location // Optional location (e.g. Crew Cabin or Switch Bank Port)

// (Physical) inputs
/electrical/inputs/<identifier>/state // Pressed or not pressed
/electrical/inputs/<identifier>/meta/kind // Kind of input (level or edge) 
/electrical/inputs/<identifier>/meta/policies // List of named policies that defined the behaviour of the input
/electrical/inputs/<identifier>/meta/name // Optional name
/electrical/inputs/<identifier>/meta/description // Optional description
/electrical/inputs/<identifier>/meta/location // Optional location (e.g. Crew Cabin or Switch Bank Port)

// Values
/electrical/values/<identifier>/value
/electrical/values/<identifier>/meta/dataType
/electrical/values/<identifier>/meta/name // Optional name
/electrical/values/<identifier>/meta/description // Optional description
/electrical/values/<identifier>/meta/location // Optional location (e.g. Crew Cabin or Switch Bank Port)

// Switches
/electrical/switches/<identifier>/state
/electrical/switches/<identifier>/dimmingLevel
/electrical/switches/<identifier>/meta/policies // List of named policies that define the behaviour of this switch
/electrical/switches/<identifier>/meta/name // Optional name
/electrical/switches/<identifier>/meta/description // Optional description
/electrical/switches/<identifier>/meta/location // Optional location (e.g. Crew Cabin or Switch Bank Port)

Policy design could be implemented as a plugin (using visual programming) or a plugin for a specific vessel; listeners are simpler, they are defined as: [{ behaviour: 'mirrorState', load: '<identifier>' }]

Examples of policies are: turning on all navigation lights (multiple loads) when it gets dark, turning on a bilge pump when the bilge sensor level input is high, etc etc

Krillle commented 6 years ago

@fabdrol

This schema sounds very reasonable. I like. Especially I like the idea of separating (physical) inputs and loads, so a physical input connected to the digital switching system could control an external device via Signal K and vice versa (as already thought of before) an external inout could control devices connected to the digital switching.

What is the difference between loads and switches (maybe I am missing the english technical term)?

fabdrol commented 6 years ago

@Krillle Load -> a "consumer" of electricity, e.g. a light, motor, etc Switch -> a synthetic/conceptual thing, that exists in the data model only, used for controlling one or more loads

The reason for this distinction is: consider a larger ship with multiple cabins and common areas (corridors, kitchen). A user wants to turn on the lights in the common area. In the common area will be many loads (corridor lights 1-5, kitchen light, floor moodlighting, etc), probably multiple digital inputs (physical buttons). In the digital interface, the user wants a UI control to turn on/off all those lights at once.

In addition, Switches are a useful place to centralise complex behaviour (as opposed to scattering it all over the model - in loads, fuses, inputs, etc). If you want to trigger a complex behaviour using a input, the convention would be to trigger a Switch from an Input.

Thinking about it, I'd like to change my proposed schema for inputs slightly. Instead of providing a "behaviour" property, inputs should look like this (forcing the use of a Switch for behaviour).

// (Physical) inputs
/electrical/inputs/<identifier>/state
/electrical/inputs/<identifier>/meta/kind
/* The related switch. If the input kind is "edge", a HIGH signal toggles the related switch. 
If the input kind is "level", every LOW signal turns the related switch off (if it's on), 
HIGH signals turn it on (so it's only on when the level input is HIGH, e.g. a bilge sensor) */
/electrical/inputs/<identifier>/meta/switch
/electrical/inputs/<identifier>/meta/name
/electrical/inputs/<identifier>/meta/description
/electrical/inputs/<identifier>/meta/location
Krillle commented 6 years ago

@fabdrol

Yes, I see and like the point in your approach.

To better understand the mapping to an API in practice: When we look at this EmpirBus example application in [1] last page: In what Signal K schema keys setup for the DCU (Dimmer Control Unit) controlled by 3rd party API instance 0+1 word 0 would result:

[1] https://github.com/sbender9/signalk-empirbus-plugin/blob/empirbus-api-communication/docs/PGN%2065280%20EmpirBus%20Application%20Specific%20PGN.pdf

fabdrol commented 6 years ago

I’d say that that is an implementation detail, up to the respective plugin (EmpitBus, ETA, Mastervolt, Navico, etc).

However, to give some pointers for plugin development, I’d say:

Krillle commented 6 years ago

I am wondering now whether to choose 0/1 or on/off to represent the status of a switch in the digital switching context. The other day it was said the Signal K API schema values should be human readable to avoid confusion. This would vote for on/off. On the other hand 0/1 is more easy to process, as mxtommy suggested above [1]. Any more opinions on that?

[1] https://github.com/SignalK/specification/issues/441#issuecomment-369381875

tkurki commented 6 years ago

Definitely not on/off.

JSON schema types are

Elsewhere in the schema we have used ratio, a number with zero to one range, for example in tank levels.

Krillle commented 6 years ago

Since this is a Boolean value (on or off), we should choose boolean true/false. Are you okay with this?

sumps commented 6 years ago

Why not use ratio and combine switches and dimmers? So 0 = OFF, 1 = ON and anything in between is a PWM/Dimmer type level.

Krillle commented 6 years ago

A dimmer can be switched off, but it can have a stored brightness level that is to be set when the dimmer is switched on again. This is why the schema needs to have two values for it: State is on or off, while dimmingLevel is the brightness to set it to.

Same as the HomeKit characteristics of dimmers are designed: Characteristic.On Characteristic.Brightness

sumps commented 6 years ago

I would not get hung up on that method, we have lots of other loads on a boat that will have variable "dimmed" values. You can have lastLevel or defaultLevel instead.

Krillle commented 6 years ago

Yes, that was also possible. Will be also two values for it. will always be lastLevel == state except when state == 0.

Somehow I like better the clear state = true|false and dimmingLevel is the ratio.

fabdrol commented 6 years ago

@sumps we started out with a ratio for state, based on the exact same thinking. We had some very smart code that could infer certain information from the broader data model, to solve the problem @Krillle described (i.e. loads turning on with the correct dimming value). In the end, we moved back to a simpler model, with a state (1/0) and a dimmingLevel.

@Krille: regarding true/false or 1/0: it doesn't really matter much, one could simply define it as a integer value in the range 0-1 (inclusive). Saves a type conversion step down the line. From a semantic point of view I would prefer 1 or 0, because: the state of this load is 1 bears more meaning to me than the state of this load is true. Having said that, however, I realise that that's a rather subjective argument!

Do you have a gist or repo with example JSON hanging around? Maybe we could move this on by defining the JSON together, based on both our use cases.

Krillle commented 6 years ago

Good Idea. This is the sample output from the EmpirBus NXT current version: https://gist.github.com/Krillle/7973762dfccf1163c18242bc184b54e4

Is this what you have in mind, or the Signal K specification in JSON itself: https://github.com/Krillle/specification

tkurki commented 5 years ago

https://github.com/SignalK/n2k-signalk/pull/87

preeve9534 commented 5 years ago

Chipping in on https://github.com/SignalK/specification/issues/441#issuecomment-369615894

Some systems report device failure and the level at which this happens may be hardware dependent. I have N2K switch and relay modules which report failure at the level of a switch/relay channel. In the case of both switches and relays the system continues to report a state: for example a failed relay may be stuck on or off or a physical switch connection may have a suspect electrical resistance.

In @fabdrol 's model I think this means that the load, fuse and input components need to acknowledge this.

I'm also having a bit of dissonance with the proposed model's naming convention around switches and inputs - this could easily be my problem because I tend to think of a physical switch as something that generates an input signal to a system (an equivalent input could come from a programmatic source).

The proposed model seems to view an "input as something that generates a signal to a switch": i.e. makes an abstract thing (input) concrete and a (in my prejudice anyway) a mostly concrete thing (switch) abstract. Are these labels the wrong way around?

Krillle commented 5 years ago

The proposed model seems to view an "input as something that generates a signal to a switch": i.e. makes an abstract thing (input) concrete and a (in my prejudice anyway) a mostly concrete thing (switch) abstract. Are these labels the wrong way around?

Inputs are physical inputs like push buttons, switches, sensors. So it's other way round than you prejudice: An input is some concrete physical thing, which generates a signal to the abstract bus system and Signal K data.

preeve9534 commented 5 years ago

I completely get that. However the post I linked to also proposed what I took to be an abstract component called "switch" which seemed to be an implementer of input policy. I interpreted this as:

Physical Device ---> Input ---> Switch ---> Signal K Bus

Linguistically this seems to me to raise a semantic issue. Or have I misunderstood the earlier post? Is there a diagram on where this thinking is at?

I get:

Switch } Dimmer } PIR } Sensor }--> Physical --------------> Input Module <---> Signal K Bus Another } Interface/MCU Implementing Physical } Policy Thing }

Sorry to labour the point, but I'm about to refactor some existing code and I'd like to do it in a meaningful way.

P

joabakk commented 4 years ago

Hi all, I started playing with the idea of switching devices. This seemed like the most relevant issue. One thing I think should be included is a state such as unavailable, or an available boolean. That way, when a wifi relay is not online, you won't get an ugly error when you try to control it. I just installed a tasmota relay on a heater for winter use.

plektra commented 3 years ago

Hello, Is there any news regarding this issue? It would be great to have switches and dimmers natively supported in Signal K specification since I believe there are many of us who would like to implement wide range of different kind of digital switching and PWM-type adjusting etc. Extending the spec with EmpirBus plugin enables this but somehow it feels wrong to use proprietary definitions, especially EmpirBus N2k PGN. So in order to effectively support this in Signal K standard spec, would it also require NMEA 2000 support? I mean not only binary switching with PGNs 127501 & 127502 but more complex controlling. It's a bit of a pity that N2k is heavily a sensor network and controlling things seems not to have attracted attention besides EmpirBus. Would it be time to fix this lack by Signal K? :)

sbender9 commented 3 years ago

There is currently support for the N2K switching pgns. Also support for switching via Hue and people use SensESP to do switching with custom hardware.

It would be great to have this stuff in the spec, but it doesn't limit us from building stuff.