syntax = "proto3"; package hc900; import "google/protobuf/timestamp.proto"; option csharp_namespace = "Hc900.Gateway"; // ─── Data types ─── message TagValue { string tag_name = 1; oneof value { float float32_val = 2; uint32 uint16_val = 3; } uint32 quality = 4; // 192=good, 0=bad google.protobuf.Timestamp timestamp = 5; } message TagMetadata { string tag_name = 1; uint32 address = 2; uint32 count = 3; // register count (1 for uint16, 2 for float32) string type = 4; // "float32" or "uint16" string access = 5; // "R" or "RW" string description = 6; string eu = 7; // engineering unit } // ─── Read ─── message ReadTagsRequest { repeated string tag_names = 1; // empty means "all cached" } message ReadTagsResponse { repeated TagValue values = 1; bool from_cache = 2; } // ─── Write ─── message WriteTagRequest { string tag_name = 1; double value = 2; // always sent as double; gateway casts to float32 or uint16 } message WriteTagResponse { bool success = 1; string error = 2; } // ─── Stream (real-time) ─── message StreamTagsRequest { int32 interval_ms = 1; // 0 = push on every poll repeated string tag_names = 2; // empty = all } // ─── Metadata ─── message ListTagsRequest { string filter = 1; // tag name prefix match, empty = all int32 limit = 2; // 0 = unlimited } message ListTagsResponse { repeated TagMetadata tags = 1; } // ─── Health ─── message HealthCheckRequest {} message HealthCheckResponse { enum ServingStatus { UNKNOWN = 0; SERVING = 1; NOT_SERVING = 2; } ServingStatus status = 1; double uptime_sec = 2; uint64 poll_count = 3; double last_poll_ms = 4; // duration of last full poll in ms string controller_ip = 5; uint32 active_tags = 6; } // ─── Service ─── service ModbusGateway { rpc ReadTags(ReadTagsRequest) returns (ReadTagsResponse); rpc WriteTag(WriteTagRequest) returns (WriteTagResponse); rpc StreamTags(StreamTagsRequest) returns (stream TagValue); rpc ListTags(ListTagsRequest) returns (ListTagsResponse); rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse); }