Skip to content

Commit

Permalink
Merge pull request #27 from ni/configure-data-rate-save-project
Browse files Browse the repository at this point in the history
Add get/set data rate and save project functions.
  • Loading branch information
ccaltagi authored Nov 2, 2022
2 parents d02b259 + d572f67 commit 4000bd5
Show file tree
Hide file tree
Showing 11 changed files with 347 additions and 14 deletions.
43 changes: 43 additions & 0 deletions examples/Basic/set_data_rate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os
import sys

from flexlogger.automation import Application
from flexlogger.automation import DataRateLevel


DATA_RATE_LEVEL_LOOKUP = {
"Slow": DataRateLevel.SLOW,
"Medium": DataRateLevel.MEDIUM,
"Fast": DataRateLevel.FAST
}


def main(project_path):
"""Launch FlexLogger, open a project, and sets the data rate values."""
with Application.launch() as app:
project = app.open_project(path=project_path)
channel_specification = project.open_channel_specification_document()
slow_date_rate = input("Specify the data rate value for the Slow level in Hertz: ")
channel_specification.set_data_rate(DataRateLevel.SLOW, float(slow_date_rate))
medium_date_rate = input("Specify the data rate value for the Medium level in Hertz: ")
channel_specification.set_data_rate(DataRateLevel.MEDIUM, float(medium_date_rate))
fast_date_rate = input("Specify the data rate value for the Fast level in Hertz: ")
channel_specification.set_data_rate(DataRateLevel.FAST, float(fast_date_rate))
channel_name = input("Enter the name of the channel you want to set the data rate level of: ")
data_rate_level = input("Enter the data rate level you want to set (Slow, Medium or Fast: ")
channel_specification.set_data_rate_level(channel_name, DATA_RATE_LEVEL_LOOKUP.get(data_rate_level))

print("Data rate set. Press Enter to save and close the project...")
input()
project.save()
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 @@ -2,8 +2,10 @@

package national_instruments.flex_logger.automation.protocols;

import "google/protobuf/timestamp.proto";
import "ConfigurationBasedSoftware/FlexLogger/Automation/FlexLogger.Automation.Protocols/DataRateLevel.proto";
import "DiagramSdk/Automation/DiagramSdk.Automation.Protocols/Identifiers.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

// Service interface for a server side channel specification document.
service ChannelSpecificationDocument {
Expand All @@ -17,6 +19,16 @@ service ChannelSpecificationDocument {
rpc IsChannelEnabled(IsChannelEnabledRequest) returns (IsChannelEnabledResponse) {}
// RPC call to enable/disable channels
rpc SetChannelEnabled(SetChannelEnabledRequest) returns (SetChannelEnabledResponse) {}
// 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
rpc SetDataRate(SetDataRateRequest) returns (google.protobuf.Empty) {}
// RPC call to get the data rate level of the subsystem that owns a channel
rpc GetDataRateLevel(GetDataRateLevelRequest) returns (GetDataRateLevelResponse) {}
// RPC call to set the data rate level of the subsystem that owns a channel
rpc SetDataRateLevel(SetDataRateLevelRequest) returns (google.protobuf.Empty) {}
// RPC call to get the actual data rate of the subsystem that owns a channel
rpc GetActualDataRate(GetActualDataRateRequest) returns (GetActualDataRateResponse) {}
}

// Request object for getting all channel names
Expand Down Expand Up @@ -87,3 +99,65 @@ message SetChannelEnabledRequest {
// Response object for setting a channel enable state
message SetChannelEnabledResponse {
}

// Request object for getting the data rate
message GetDataRateRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The data rate level (Slow, Medium, Fast, Counter, Digital, OnDemand)
DataRateLevel data_rate_level = 2;
}

// Response object for getting the data rate
message GetDataRateResponse {
// The value of the data rate
double data_rate = 1;
}

// Request object for setting the data rate
message SetDataRateRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The data rate level (Slow, Medium, Fast, Counter, Digital, OnDemand)
DataRateLevel data_rate_level = 2;
// The value of the data rate to set
double data_rate = 3;
}

// Request object for getting the data rate of a specific channel
message GetDataRateLevelRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The name of the channel in the subsystem to set the data rate to
string channel_name = 2;
}

// Response object for getting the data rate of a specific channel
message GetDataRateLevelResponse {
// The data rate level
DataRateLevel data_rate_level = 1;
}

// Request object for setting the data rate level of a specific channel
message SetDataRateLevelRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The name of the channel in the subsystem to set the data rate to
string channel_name = 2;
// The data rate level to set
DataRateLevel data_rate_level = 3;
}

// Request object for getting the actual data rate of a specific channel
message GetActualDataRateRequest {
// The id for the channel specification document
national_instruments.diagram_sdk.automation.protocols.ElementIdentifier document_identifier = 1;
// The name of the channel in the subsystem to set the data rate to
string channel_name = 2;
}

// Response object for getting the actual data rate of a specific channel
message GetActualDataRateResponse {
// The data rate
double data_rate = 1;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
syntax = "proto3";

package national_instruments.flex_logger.automation.protocols;

enum DataRateLevel {
DATA_RATE_LEVEL_NONE = 0;
// The slow analog input rate
DATA_RATE_LEVEL_SLOW = 1;
// The medium analog input rate
DATA_RATE_LEVEL_MEDIUM = 2;
// The fast analog input rate
DATA_RATE_LEVEL_FAST = 3;
// The counter input rate
DATA_RATE_LEVEL_COUNTER = 4;
// The digital input rate
DATA_RATE_LEVEL_DIGITAL = 6;
// On demand sample rate
DATA_RATE_LEVEL_ON_DEMAND = 7;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
package national_instruments.flex_logger.automation.protocols;

import "DiagramSdk/Automation/DiagramSdk.Automation.Protocols/Identifiers.proto";
import "google/protobuf/empty.proto";

// Service interface for a server side project.
service Project {
Expand All @@ -18,6 +19,8 @@ service Project {
rpc Close(CloseProjectRequest) returns (CloseProjectResponse) {}
// RPC call to query the file path of the current project.
rpc GetProjectFilePath(GetProjectFilePathRequest) returns (GetProjectFilePathResponse) {}
// RPC call to save the current project.
rpc Save(google.protobuf.Empty) returns (google.protobuf.Empty) {}
}

// Information necessary to open the channel specification document.
Expand Down Expand Up @@ -89,4 +92,4 @@ message GetProjectFilePathRequest {
message GetProjectFilePathResponse {
// The project file path
string project_file_path = 1;
}
}
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.3"
version = "0.1.4"
else:
with open(os.path.join(script_dir, "VERSION"), "r") as version_file:
version = version_file.read().rstrip()
Expand Down
1 change: 1 addition & 0 deletions src/flexlogger/automation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
from ._flexlogger_error import FlexLoggerError
from ._channel_data_point import ChannelDataPoint
from ._test_property import TestProperty
from ._data_rate_level import DataRateLevel
152 changes: 142 additions & 10 deletions src/flexlogger/automation/_channel_specification_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,32 @@
from grpc import Channel, RpcError

from ._channel_data_point import ChannelDataPoint
from ._data_rate_level import DataRateLevel
from ._flexlogger_error import FlexLoggerError
from .proto import (
ChannelSpecificationDocument_pb2,
ChannelSpecificationDocument_pb2_grpc,
)
from .proto.Identifiers_pb2 import ElementIdentifier
from .proto.DataRateLevel_pb2 import DataRateLevel as DataRateLevel_pb2

DATA_RATE_LEVEL_MAP = {
DataRateLevel.SLOW: DataRateLevel_pb2.DATA_RATE_LEVEL_SLOW,
DataRateLevel.MEDIUM: DataRateLevel_pb2.DATA_RATE_LEVEL_MEDIUM,
DataRateLevel.FAST: DataRateLevel_pb2.DATA_RATE_LEVEL_FAST,
DataRateLevel.COUNTER: DataRateLevel_pb2.DATA_RATE_LEVEL_COUNTER,
DataRateLevel.DIGITAL: DataRateLevel_pb2.DATA_RATE_LEVEL_DIGITAL,
DataRateLevel.ON_DEMAND: DataRateLevel_pb2.DATA_RATE_LEVEL_ON_DEMAND,
}

DATA_RATE_LEVEL_PB2_MAP = {
DataRateLevel_pb2.DATA_RATE_LEVEL_SLOW: DataRateLevel.SLOW,
DataRateLevel_pb2.DATA_RATE_LEVEL_MEDIUM: DataRateLevel.MEDIUM,
DataRateLevel_pb2.DATA_RATE_LEVEL_FAST: DataRateLevel.FAST,
DataRateLevel_pb2.DATA_RATE_LEVEL_COUNTER: DataRateLevel.COUNTER,
DataRateLevel_pb2.DATA_RATE_LEVEL_DIGITAL: DataRateLevel.DIGITAL,
DataRateLevel_pb2.DATA_RATE_LEVEL_ON_DEMAND: DataRateLevel.ON_DEMAND,
}


class ChannelSpecificationDocument:
Expand All @@ -29,27 +49,24 @@ def __init__(
self._raise_if_application_closed = raise_if_application_closed
self._identifier = identifier

def is_channel_enabled(self, channel_name: str) -> bool:
"""Get the current enabled state of the specified channel.
def get_actual_data_rate(self, channel_name: str) -> float:
"""Get the actual data rate for 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.IsChannelEnabled(
ChannelSpecificationDocument_pb2.IsChannelEnabledRequest(
document_identifier=self._identifier, channel_name=channel_name
response = stub.GetActualDataRate(
ChannelSpecificationDocument_pb2.GetActualDataRateRequest(
document_identifier=self._identifier, channel_name=channel_name
)
)

return response.channel_enabled
return response.data_rate
except (RpcError, ValueError) as error:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to get channel enable state") from error
raise FlexLoggerError("Failed to get the actual data rate.") from error

def get_channel_names(self) -> List[str]:
"""Get all the channel names in the document.
Expand Down Expand Up @@ -95,6 +112,73 @@ def get_channel_value(self, channel_name: str) -> ChannelDataPoint:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to get channel value") from error

def get_data_rate(self, data_rate_level: DataRateLevel) -> float:
"""Get the data rate for a specific date rate level in Hertz.
Args:
data_rate_level: The data rate level to get the data rate for.
Raises:
FlexLoggerError: if the data_rate_level is invalid.
"""
stub = ChannelSpecificationDocument_pb2_grpc.ChannelSpecificationDocumentStub(self._channel)
try:
data_rate_level_parameter = DATA_RATE_LEVEL_MAP.get(data_rate_level)
response = stub.GetDataRate(
ChannelSpecificationDocument_pb2.GetDataRateRequest(
document_identifier=self._identifier, data_rate_level=data_rate_level_parameter
)
)

return response.data_rate
except (RpcError, ValueError) as error:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to get the data rate: data rate level invalid.") from error

def get_data_rate_level(self, channel_name: str) -> DataRateLevel:
"""Get the data rate level of the specified channel
Args:
channel_name: The name of the channel.
Raises:
FlexLoggerError: if getting the data rate level fails.
"""
stub = ChannelSpecificationDocument_pb2_grpc.ChannelSpecificationDocumentStub(self._channel)
try:
response = stub.GetDataRateLevel(
ChannelSpecificationDocument_pb2.GetDataRateLevelRequest(
document_identifier=self._identifier, channel_name=channel_name
)
)

return DATA_RATE_LEVEL_PB2_MAP.get(response.data_rate_level)
except (RpcError, ValueError) as error:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to get the data rate level.") from error

def is_channel_enabled(self, channel_name: str) -> bool:
"""Get the current enabled 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.IsChannelEnabled(
ChannelSpecificationDocument_pb2.IsChannelEnabledRequest(
document_identifier=self._identifier, channel_name=channel_name
)
)

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

def set_channel_enabled(self, channel_name: str, channel_enabled: bool) -> None:
"""Enable or disable the specified channel.
Expand Down Expand Up @@ -140,3 +224,51 @@ def set_channel_value(self, channel_name: str, channel_value: float) -> None:
except (RpcError, ValueError) as error:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to set channel value") from error

def set_data_rate(self, data_rate_level: DataRateLevel, data_rate: float) -> None:
"""Set the data rate of a specific data rate level.
Args:
data_rate_level: The data rate level to get the data rate for.
data_rate: The value of the data rate to set in Hertz.
Raises:
FlexLoggerError: if setting the data rate fails.
"""
stub = ChannelSpecificationDocument_pb2_grpc.ChannelSpecificationDocumentStub(self._channel)
try:
data_rate_level_parameter = DATA_RATE_LEVEL_MAP.get(data_rate_level)
stub.SetDataRate(
ChannelSpecificationDocument_pb2.SetDataRateRequest(
document_identifier=self._identifier,
data_rate_level=data_rate_level_parameter,
data_rate=data_rate
)
)
except (RpcError, ValueError) as error:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to set the data rate") from error

def set_data_rate_level(self, channel_name: str, data_rate_level: DataRateLevel) -> None:
"""Set the data rate level of the specified channel
Note: This may affect other channels in the same module or chassis set to the same data rate level.
Args:
channel_name: The name of the channel.
data_rate_level: The data rate level to set.
Raises:
FlexLoggerError: if setting the data rate level fails.
"""
stub = ChannelSpecificationDocument_pb2_grpc.ChannelSpecificationDocumentStub(self._channel)
try:
data_rate_level_parameter = DATA_RATE_LEVEL_MAP.get(data_rate_level)
stub.SetDataRateLevel(
ChannelSpecificationDocument_pb2.SetDataRateLevelRequest(
document_identifier=self._identifier,
channel_name=channel_name,
data_rate_level=data_rate_level_parameter
)
)
except (RpcError, ValueError) as error:
self._raise_if_application_closed()
raise FlexLoggerError("Failed to set the data rate level.") from error
Loading

0 comments on commit 4000bd5

Please sign in to comment.