Compare commits

...

3 Commits

Author SHA1 Message Date
86a5fa20a4
main: treat elevation offset as offset from horizon
Rather than having somewhat confusing flipped logic when the rotator is
operating in the 180-90 degree elevation regime, this internally
performs sign flipping. This means that a 3 degree elevation offset
means "point an additional 3 degrees up from the horizon" regardless
of whether the rotator is operating in the 0-90 or 180-90 elevation
ranges.
2024-08-22 11:55:12 -07:00
b6caab906a
main: respect elevation mask
This is done silently, in the sense that the UI doesn't show that it is
clamping the requested pointing target in this way.
2024-08-22 11:49:01 -07:00
511f2ca903
add config
This is very basic, but it beats having everything be hardcoded.
2024-08-22 11:46:54 -07:00
2 changed files with 86 additions and 8 deletions

47
src/Config.zig Normal file
View File

@ -0,0 +1,47 @@
const std = @import("std");
const Config = @This();
elevation_mask: f64 = 19,
rotctld: AddressPort = .{ .address = "127.0.0.1", .port = 4533 },
listen: AddressPort = .{ .address = "127.0.0.1", .port = 42069 },
const confdir = "rotint";
const conffile = "config.json";
pub fn default() Config {
return .{};
}
pub fn load(allocator: std.mem.Allocator, env: *const std.process.EnvMap) !Config {
if (env.get("XDG_CONFIG_HOME")) |cfg|
if (cfg.len > 0) {
return try loadPath(allocator, try std.fs.path.join(
allocator,
&.{ cfg, confdir, conffile },
));
};
if (env.get("HOME")) |home|
if (home.len > 0) {
return try loadPath(allocator, try std.fs.path.join(
allocator,
&.{ home, ".config", confdir, conffile },
));
};
return error.ConfigHomeMissing;
}
fn loadPath(allocator: std.mem.Allocator, path: []const u8) !Config {
defer allocator.free(path);
const data = try std.fs.cwd().readFileAlloc(allocator, path, 1024);
defer allocator.free(data);
return try std.json.parseFromSliceLeaky(Config, allocator, data, .{});
}
const AddressPort = struct {
address: []const u8,
port: u16,
};

View File

@ -6,6 +6,7 @@ const xev = @import("xev");
const networking = @import("./networking.zig");
const rotctl = @import("./rotctl.zig");
const Config = @import("./Config.zig");
const log = std.log.scoped(.rotint);
@ -84,6 +85,7 @@ pub const RotInt = struct {
command_freq: u8 = 4,
pollcount: u9 = 0,
state: State = .initial,
conf: Config,
termbuffer: std.io.BufferedWriter(4096, std.io.AnyWriter),
vx: *vaxis.Vaxis,
@ -110,8 +112,18 @@ pub const RotInt = struct {
self.rotator.rotint = self;
self.log = try Log.init();
const connect_addr = try std.net.Address.parseIp("127.0.0.1", 4533);
try self.rotator.connect(self.loop, connect_addr);
const rotctld_addr = std.net.Address.parseIp(
self.conf.rotctld.address,
self.conf.rotctld.port,
) catch |err| {
log.err("could not parse rotctld address {s}:{d}: {s}", .{
self.conf.rotctld.address,
self.conf.rotctld.port,
@errorName(err),
});
return err;
};
try self.rotator.connect(self.loop, rotctld_addr);
}
pub fn stateEvent(self: *RotInt, event: State) void {
@ -126,12 +138,15 @@ pub const RotInt = struct {
},
.rotator_ready => if (self.state == .rotator_connected) {
self.warn("rotator ready", .{});
const listen_addr = std.net.Address.parseIp("127.0.0.1", 42069) catch {
self.warn("bogus listen address", .{});
const listen_addr = std.net.Address.parseIp(
self.conf.listen.address,
self.conf.listen.port,
) catch |err| {
self.showError("bogus listen address: {s}", .{@errorName(err)});
return;
};
self.server.listen(self.loop, listen_addr) catch {
self.warn("listen problem", .{});
self.server.listen(self.loop, listen_addr) catch |err| {
self.showError("listen problem: {s}", .{@errorName(err)});
return;
};
// demangle here to avoid causing initial moves
@ -165,10 +180,15 @@ pub const RotInt = struct {
self.pollcount = (self.pollcount + 1) % self.command_freq;
if (self.pollcount == 0) {
const mangled: AzEl = .{
var mangled: AzEl = .{
.az = self.requested_posture.az + self.offsets.az,
.el = self.requested_posture.el + self.offsets.el,
.el = self.requested_posture.el + if (self.requested_posture.el > 90) -self.offsets.el else self.offsets.el,
};
mangled.el = if (mangled.el > 90)
@min(mangled.el, 180 - self.conf.elevation_mask)
else
@max(mangled.el, self.conf.elevation_mask);
self.sendRotatorCommand(.{ .set_position = mangled });
} else {
self.sendRotatorCommand(.get_position);
@ -209,6 +229,10 @@ pub const RotInt = struct {
log.warn(fmt, args);
}
pub fn showError(_: *RotInt, comptime fmt: []const u8, args: anytype) void {
log.err(fmt, args);
}
pub fn handleControlRequest(self: *RotInt, req: []const u8) void {
const command = self.parser.parseCommand(req) catch |err| switch (err) {
error.Incomplete => return,
@ -387,8 +411,15 @@ pub fn main() !void {
});
defer loop.deinit();
var env = try std.process.getEnvMap(alloc);
defer env.deinit();
var app: RotInt = .{
.allocator = alloc,
.conf = Config.load(alloc, &env) catch cfg: {
log.warn("Could not load config file. Using defaults.", .{});
break :cfg Config.default();
},
.termbuffer = tty.bufferedWriter(),
.vx = &vx,
.loop = &loop,