Skip to content

Commit

Permalink
Merge pull request #14 from XtremeOwnage/dev-name
Browse files Browse the repository at this point in the history
Improved Logging, Added Kubernetes Manifests
  • Loading branch information
XtremeOwnageDotCom authored Aug 29, 2024
2 parents 9a62d82 + 2956424 commit 7851c67
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 7 deletions.
145 changes: 145 additions & 0 deletions Examples/Kubernetes/configuration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: configuration
namespace: rpdu2mqtt
data:
appsettings.json: |
{
"Logging": {
"LogLevel": {
"Default": "Information",
"System.Net.Http.HttpClient": "Warning",
"rPDU2MQTT.*": "Debug"
}
},
"Mqtt": {
// Add your MQTT Username and Password here.
"Username": "user",
"Password": "password",
// This will be the parent topic in MQTT, where keys are published to.
"ParentTopic": "Rack_PDU",
// This is the client-ID used.
"ClientID": "rpdu2mqtt",
// Set this to the host / ip of your MQTT server.
"Host": "localhost",
"Port": 1883,
"KeepAlive": 60
},
"Pdu": {
// Add your PDU's device ID here.
"DeviceId": "A0AE260C851900C3",
// Set to the URL, or IP for your PDU.
"Url": "http://your-pdu-ip-or-dns/",
// This is how often sensors will be published to MQTT (in seconds)
"PollInterval": 5,
// Timeout for requests to/from the PDU, in seconds.
"Timeout": 5
},
// This section allows overriding the generated entity_id, and names for various objects.
// Note- ID / entity_id, will only be set when the entity is created.
// Do not touch or change it throug here after it has been created! Otherwise, you can end up with duplicates, or other issues.
// "Name" can be freely updated, and home assistant will reflect updated names instantly (after the discovery runs)
"Overrides": {
// Allows overriding the generated identifier for the PDU. Leave blank to disable.
// Warning- Do not change after creation! This is the root, unique identifier used, and should not change!
// IF, you change this, you will have a lot of duplicated devices, and entities!!!!!!
"PduID": null,
// Allows overriding the generated entity name for the PDU. Leave blank to disable.
// This- can be changed at any time, and will update the name of the Device which represents the PDU.
// If null, this will default to the PDU's configured label.
"PduName": "Rack-PDU-1"
},
"Outlets": {
// The "entity_id" can be overridden, and customized for each outlet.
// By default, if not specified, an entity ID will be automatically generated from the labels configured via the PDU.
// Note- don't change this after initial discovery. Will cause problems.
"ID": {
//"1": "kube02",
//"2": "dell_md1220",
//"3": "outlet_3"
//..
},
// The "name" can be overridden, and customized for each outlet.
// This, represents the "display name", which is the human-readable, pretty version.
// By default, if not specified, this will be automatically generated from the labels configured via the PDU.
"Name": {
//"1": "Proxmox: Kube02",
//"2": "Dell: MD1220",
//"3": "Outlet 3 Friendly Name"
//..
},
///Allows enabling, or disabling specific devices.
// Disabled devices will not be discovered or published to MQTT.
"Enabled": {
"1": true,
"2": true,
"3": true
}
},
"Measurements": {
// This allows customizing the entity IDs generated for metrics.
// All measurement entity_ids will start with the generated ID for the device they belong to.
// ie, {device_name}_power, device_energy
// Output Format will be {EntityID}_{MeasurementID}
// Both measurement ID, and Name, is based on the data type presented from the PDU.
// This will affect ALL devices and entities, using measurements.
// Note- changing the ID only customizes the suffix.
"ID": {
"apparentpower": null,
"realpower": "power",
"energy": null,
"powerFactor": null,
"current": null,
"voltage": null
},
//Customize the names for measurements.
//Output Format will be {Entity Name} {Measurement Name}
"Name": {
"apparentpower": "Apparent Power",
"realpower": "Power",
"energy": "Energy",
"powerFactor": "Power Factor",
"current": "Current",
"voltage": "Voltage"
},
//Allow enabling, or disabling publishing specific measurement types.
//This applies to all entity types.
"Enabled": {
"apparentpower": true,
"realpower": true,
"energy": true,
"powerFactor": true,
"current": true,
"voltage": true,
// These are not enabled- because they don't quite map to anything useful.
"balance": false,
"currentCrestFactor": false
}
},
// Ignore this section for now...
"Actions": {
"Enabled": false,
"Username": "actionsUser",
"Password": "actionsPass"
},
"HomeAssistant": {
"DiscoveryEnabled": true,
"DiscoveryTopic": "homeassistant/discovery",
"DiscoveryInterval": 300,
// Default expireAfter interval applied to all sensors. After this time- the sensor will be marked as unavailable.
"SensorExpireAfterSeconds": 300
}
}
49 changes: 49 additions & 0 deletions Examples/Kubernetes/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
role: app
name: rpdu2mqtt
namespace: rpdu2mqtt
spec:
replicas: 1
revisionHistoryLimit: 1
selector:
matchLabels:
app: rpdu2mqtt
role: app
template:
metadata:
labels:
app: rpdu2mqtt
role: app
spec:
dnsPolicy: ClusterFirst
containers:
- image: ghcr.io/xtremeownage/rpdu2mqtt:dev-name
name: app
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
runAsUser: 1654
seccompProfile:
type: RuntimeDefault
capabilities:
drop:
- ALL
volumeMounts:
- name: config-files
mountPath: /config
resources:
limits:
memory: 800Mi
cpu: 300m
requests:
memory: 100Mi
cpu: 100m
volumes:
- name: config-files
configMap:
name: configuration
defaultMode: 0777

3 changes: 3 additions & 0 deletions Examples/Kubernetes/exec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ns="rpdu2mqtt"
kubectl exec -it -n $ns $(kubectl get pod -n $ns -l role=app -o jsonpath='{.items[0].metadata.name}') -- $1

7 changes: 7 additions & 0 deletions Examples/Kubernetes/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: Namespace
apiVersion: v1
metadata:
name: rpdu2mqtt
labels:
name: rPDU2MQTT
backup-policy: daily-backup
2 changes: 2 additions & 0 deletions rPDU2MQTT/Classes/PDU.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public PDU(Config config, HttpClient http, ILogger<PDU> log)
/// <returns></returns>
public async Task<RootData> GetRootData_Public(CancellationToken cancellationToken)
{
log.LogDebug("Querying /api");
var model = await http.GetFromJsonAsync<GetResponse<RootData>>("/api", options: Models.PDU.Converter.Settings, cancellationToken);
log.LogDebug($"Query response {model.RetCode}");

//Process device data.
processData(model.Data);
Expand Down
4 changes: 4 additions & 0 deletions rPDU2MQTT/Models/Config/PduConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ public class PduConfig
[Range(1, int.MaxValue, ErrorMessage = "PollInterval must be greater than 0.")]
[Display(Description = "The polling interval for the PDU in seconds.")]
public int PollInterval { get; set; } = 5;

[Range(1, 60 * 10, ErrorMessage = "Expected timeout between 1 second, and 10 minutes.")]
[Display(Description = "Http timeout for requests to PDU")]
public int Timeout { get; set; } = 5;
}
34 changes: 28 additions & 6 deletions rPDU2MQTT/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,28 @@
var host = Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((context, config) =>
{
config.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true)
if (Directory.Exists("/config"))
{
Console.WriteLine($"Found /config directory");
Console.WriteLine($"/config.appsettings.json exists: {File.Exists("/config/appsettings.json")}");

// Check /Config directory.
.SetBasePath("/config")
.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
config
.SetBasePath("/config")
.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true);
}
else
{
Console.WriteLine($"Did not find /config directory. Using {Directory.GetCurrentDirectory()}");
Console.WriteLine($"appsettings.json exists: {File.Exists("appsettings.json")}");
//Check for configuration files in the current directory.
config.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.Development.json", optional: true, reloadOnChange: true);
}


config.AddEnvironmentVariables();

})
.ConfigureServices((context, services) =>
{
Expand Down Expand Up @@ -48,6 +64,7 @@
services.AddHttpClient("pdu", client =>
{
client.BaseAddress = new Uri(pduConfiguration.Url);
client.Timeout = TimeSpan.FromSeconds(pduConfiguration.Timeout);
});

//Configure Services
Expand All @@ -73,9 +90,14 @@
})
.Build();


//Ensure we can actually connect to MQTT.
var client = host.Services.GetRequiredService<IHiveMQClient>();
var logger = host.Services.GetRequiredService<ILogger<IHiveMQClient>>();

logger.LogInformation($"Connecting to MQTT Broker at {client.Options.Host}:{client.Options.Port}");

await client.ConnectAsync();

logger.LogInformation("Successfully connected to broker!");

host.Run();
15 changes: 14 additions & 1 deletion rPDU2MQTT/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,33 @@
}
},
"Mqtt": {
// Add your MQTT Username and Password here.
"Username": "user",
"Password": "password",

// This will be the parent topic in MQTT, where keys are published to.
"ParentTopic": "Rack_PDU",

// This is the client-ID used.
"ClientID": "rpdu2mqtt",

// Set this to the host / ip of your MQTT server.
"Host": "localhost",
"Port": 1883,
"KeepAlive": 60
},
"Pdu": {
// Add your PDU's device ID here.
"DeviceId": "A0AE260C851900C3",

// Set to the URL, or IP for your PDU.
"Url": "http://your-pdu-ip-or-dns/",
"PollInterval": 5

// This is how often sensors will be published to MQTT (in seconds)
"PollInterval": 5,

// Timeout for requests to/from the PDU, in seconds.
"Timeout": 5
},
// This section allows overriding the generated entity_id, and names for various objects.
// Note- ID / entity_id, will only be set when the entity is created.
Expand Down Expand Up @@ -110,6 +121,8 @@
"currentCrestFactor": false
}
},

// Ignore this section for now...
"Actions": {
"Enabled": false,
"Username": "actionsUser",
Expand Down

0 comments on commit 7851c67

Please sign in to comment.