Skip to content

Commit

Permalink
Merge pull request #43 from ni/enable_disable_logging
Browse files Browse the repository at this point in the history
Add methods to get the logging state and enable/disable channel logging.
  • Loading branch information
ccaltagi authored Oct 16, 2024
2 parents 41486b3 + 8d053f4 commit e4caa00
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 3 deletions.
26 changes: 26 additions & 0 deletions examples/Basic/disable_channel_logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import os
import sys

from flexlogger.automation import Application


def main(project_path):
"""Launch FlexLogger, open a project, and disables a channel."""
with Application.launch() as app:
project = app.open_project(path=project_path)
channel_name = input("Enter the name of the channel to disable logging: ")
channel_specification = project.open_channel_specification_document()
channel_specification.set_channel_logging_enabled(channel_name, False)
print("Channel logging disabled. Press Enter to close the project...")
input()
project.close()
return 0


if __name__ == "__main__":
argv = sys.argv
if len(argv) < 2:
print("Usage: %s <path of project to open>" % os.path.basename(__file__))
sys.exit()
project_path_arg = argv[1]
sys.exit(main(project_path_arg))
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,24 @@ import "google/protobuf/timestamp.proto";
service ChannelSpecificationDocument {
// RPC call to get all channel names
rpc GetChannelNames(GetChannelNamesRequest) returns (GetChannelNamesResponse) {}
// RPC call to get channel names filtered by channel type
rpc GetFilteredChannelNames(GetFilteredChannelNamesRequest) returns (GetChannelNamesResponse) {}
// RPC call to get the latest value of a double channel
rpc GetDoubleChannelValue(GetDoubleChannelValueRequest) returns (GetDoubleChannelValueResponse) {}
// RPC call to set the value of a double channel
rpc SetDoubleChannelValue(SetDoubleChannelValueRequest) returns (SetDoubleChannelValueResponse) {}
// RPC call to get the latest values of double channels
rpc GetDoubleChannelValues(GetDoubleChannelValuesRequest) returns (GetDoubleChannelValuesResponse) {}
// RPC call to set the values of double channels
rpc SetDoubleChannelValues(SetDoubleChannelValuesRequest) returns (google.protobuf.Empty) {}
// RPC call to get a channel's enable state
rpc IsChannelEnabled(IsChannelEnabledRequest) returns (IsChannelEnabledResponse) {}
// RPC call to enable/disable channels
rpc SetChannelEnabled(SetChannelEnabledRequest) returns (SetChannelEnabledResponse) {}
// RPC call to get a channel logging's state
rpc IsChannelLoggingEnabled(IsChannelLoggingEnabledRequest) returns (IsChannelLoggingEnabledResponse) {}
// RPC call to enable/disable channel logging
rpc SetChannelLoggingEnabled(SetChannelLoggingEnabledRequest) returns (SetChannelLoggingEnabledResponse) {}
// RPC call to get the data rate for a specific data rate level
rpc GetDataRate(GetDataRateRequest) returns (GetDataRateResponse) {}
// RPC call to set the data rate of a specific data rate level
Expand All @@ -43,6 +53,22 @@ message GetChannelNamesResponse {
repeated string channel_names = 1;
}

// Request object for getting channel names filtered by channel type
message GetFilteredChannelNamesRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// Return configured channels.
bool configuredChannels = 2;
// Return input channels.
bool inputChannels = 3;
// Return output channels.
bool outputChannels = 4;
// Return analog channels.
bool analogChannels = 5;
// Return digital channels.
bool digitalChannels = 6;
}

// Request object for getting a channel value
message GetDoubleChannelValueRequest {
// The id for the channel specification document
Expand All @@ -63,16 +89,48 @@ message GetDoubleChannelValueResponse {
message SetDoubleChannelValueRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The name of the channel to get a double value for
// The name of the channel to set
string channel_name = 2;
// The value of the channel at the timestamp
// The value of the channel to set
double channel_value = 3;
}

// Response object for setting a channel value
message SetDoubleChannelValueResponse {
}

// Message that defines an individual channel value
message ChannelValue {
// The name of the channel
string channel_name = 1;
// The value of the channel
double channel_value = 2;
// The timestamp of the value
google.protobuf.Timestamp value_timestamp = 3;
}

// Request object for getting channel values
message GetDoubleChannelValuesRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The names of the channels to get double values for
repeated string channel_names = 2;
}

// Response object for getting channel values
message GetDoubleChannelValuesResponse {
// The channel values and their timestamps
repeated ChannelValue channel_values = 1;
}

// Request object for setting channel values
message SetDoubleChannelValuesRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The channel values to set
repeated ChannelValue channel_values = 2;
}

// Request object for getting a channel enable state
message IsChannelEnabledRequest {
// The id for the channel specification document
Expand Down Expand Up @@ -100,6 +158,33 @@ message SetChannelEnabledRequest {
message SetChannelEnabledResponse {
}

// Request object for getting a channel logging state
message IsChannelLoggingEnabledRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The name of the channel to get the logging state for
string channel_name = 2;
}

// Response object for getting a channel logging state
message IsChannelLoggingEnabledResponse {
bool channel_logging_enabled = 1;
}

// Request object for setting a channel logging state
message SetChannelLoggingEnabledRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The name of the channel to enable or disable
string channel_name = 2;
// The enable state to set
bool channel_logging_enabled = 3;
}

// Response object for setting a channel enable state
message SetChannelLoggingEnabledResponse {
}

// Request object for getting the data rate
message GetDataRateRequest {
// The id for the channel specification document
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def _get_version(name: str) -> str:
script_dir = os.path.dirname(os.path.realpath(__file__))
script_dir = os.path.join(script_dir, name)
if not os.path.exists(os.path.join(script_dir, "VERSION")):
version = "0.1.10"
version = "0.2.0"
else:
with open(os.path.join(script_dir, "VERSION"), "r") as version_file:
version = version_file.read().rstrip()
Expand Down
45 changes: 45 additions & 0 deletions src/flexlogger/automation/_channel_specification_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,51 @@ def set_channel_enabled(self, channel_name: str, channel_enabled: bool) -> None:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to set the channel enable state") from error

def is_channel_logging_enabled(self, channel_name: str) -> bool:
"""Get the current logging state of the specified channel.
Args:
channel_name: The name of the channel.
Raises:
FlexLoggerError: if getting the channel value fails.
"""
stub = ChannelSpecificationDocument_pb2_grpc.ChannelSpecificationDocumentStub(self._channel)
try:
response = stub.IsChannelLoggingEnabled(
ChannelSpecificationDocument_pb2.IsChannelLoggingEnabledRequest(
document_identifier=self._identifier, channel_name=channel_name
)
)

return response.channel_logging_enabled
except (RpcError, ValueError) as error:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to get channel logging enable state") from error

def set_channel_logging_enabled(self, channel_name: str, channel_logging_enabled: bool) -> None:
"""Enable or disable logging for the specified channel.
Args:
channel_name: The name of the channel.
channel_logging_enabled: The channel logging enabled state: true to enable logging, false to disable it.
Raises:
FlexLoggerError: if enabling or disabling the channel logging fails.
"""
stub = ChannelSpecificationDocument_pb2_grpc.ChannelSpecificationDocumentStub(self._channel)
try:
stub.SetChannelLoggingEnabled(
ChannelSpecificationDocument_pb2.SetChannelLoggingEnabledRequest(
document_identifier=self._identifier,
channel_name=channel_name,
channel_logging_enabled=channel_logging_enabled,
)
)
except (RpcError, ValueError) as error:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to set the channel logging state") from error

def set_channel_value(self, channel_name: str, channel_value: float) -> None:
"""Set the current value of the specified channel.
Expand Down
40 changes: 40 additions & 0 deletions tests/test_channel_specification_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,46 @@ def test__set_channel_enabled_for_readonly_channel__exception_raised(
with pytest.raises(FlexLoggerError):
channel_specification.set_channel_enabled("Channel 1", False)

@pytest.mark.integration # type: ignore
def test__project_with_writable_channels__disable_channel_logging__channel_logging_disabled(
self, app: Application
) -> None:
with open_project(app, "ProjectWithSwitchboard") as project:
channel_specification = project.open_channel_specification_document()

channel_specification.set_channel_logging_enabled("Switch 42", False)

channel_logging_enabled = channel_specification.is_channel_logging_enabled("Switch 42")

assert not channel_logging_enabled

@pytest.mark.integration # type: ignore
def test__project_with_writable_channels__channel_logging_enabled(
self, app: Application
) -> None:
with open_project(app, "ProjectWithSwitchboard") as project:
channel_specification = project.open_channel_specification_document()

channel_logging_enabled = channel_specification.is_channel_logging_enabled("Switch 42")

assert channel_logging_enabled

@pytest.mark.integration # type: ignore
def test__set_channel_logging_enabled_for_channel_that_does_not_exist__exception_raised(
self, app: Application, channels_with_produced_data: ChannelSpecificationDocument
) -> None:
channel_specification = channels_with_produced_data
with pytest.raises(FlexLoggerError):
channel_specification.set_channel_logging_enabled("Not a channel", True)

@pytest.mark.integration # type: ignore
def test__set_channel_logging_enabled_for_readonly_channel__exception_raised(
self, app: Application, channels_with_produced_data: ChannelSpecificationDocument
) -> None:
channel_specification = channels_with_produced_data
with pytest.raises(FlexLoggerError):
channel_specification.set_channel_logging_enabled("Channel 1", False)

@pytest.mark.integration # type: ignore
def test__project_with_channels__set_data_rate__data_rate_updated(
self, app: Application, channels_with_produced_data: ChannelSpecificationDocument
Expand Down

0 comments on commit e4caa00

Please sign in to comment.