#include <ucw/string.h>
#include <ucw/unaligned.h>
+#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
static mtx_t light_mutex;
static cnd_t light_cond;
-static byte light_pwm[4];
+static double light_brightness[2];
+static double light_temperature[2];
static bool light_refresh;
/*** MQTT ***/
msg(L_DEBUG, "MQTT < %s %s", m->topic, val);
int index;
- if (!strcmp(m->topic, "burrow/lights/catarium/top"))
+ if (!strcmp(m->topic, "burrow/lights/catarium/bottom"))
index = 0;
- else if (!strcmp(m->topic, "burrow/lights/catarium/bottom"))
+ else if (!strcmp(m->topic, "burrow/lights/catarium/top"))
index = 1;
else
return;
- int warm, cold;
- if (sscanf(val, "%d%d", &warm, &cold) != 2 ||
- !(warm >= 0 && warm < 256 && cold >= 0 && cold < 256)) {
+ double bright, temp;
+ if (sscanf(val, "%lf%lf", &bright, &temp) != 2 ||
+ !(bright >= 0 && bright <= 1 && temp >= 0 && temp <= 1)) {
msg(L_ERROR, "Invalid value of %s: %s", m->topic, val);
return;
}
mtx_lock(&light_mutex);
- light_pwm[2*index] = warm;
- light_pwm[2*index + 1] = cold;
+ light_brightness[index] = bright;
+ light_temperature[index] = temp;
light_refresh = 1;
cnd_broadcast(&light_cond);
mtx_unlock(&light_mutex);
open_device();
}
-/*** Protocol ***/
+/*** DMX ***/
+
+static byte dmx_packet[5];
+
+static int dmx_build_packet(void)
+{
+ byte *pkt = dmx_packet;
+ pkt[0] = 0;
+
+ for (int i=0; i < 2; i++) {
+ double r = 2;
+ double x = (exp(r*light_brightness[i]) - 1) / (exp(r) - 1);
+ double t = light_temperature[i];
+ double w = 2*x*(1-t);
+ double c = 2*x*t;
+ pkt[2*i + 1] = CLAMP((int)(255*w), 0, 255);
+ pkt[2*i + 2] = CLAMP((int)(255*c), 0, 255);
+ }
+
+ return sizeof(dmx_packet);
+}
+
+
+/*** Main ***/
static int use_daemon;
static int use_debug;
while (!need_resend && !light_refresh)
cnd_wait(&light_cond, &light_mutex);
- byte packet[5];
- int len = sizeof(packet);
- packet[0] = 0;
- memcpy(packet + 1, light_pwm, 4);
-
+ int len = dmx_build_packet();
light_refresh = 0;
need_resend = 0;
mtx_unlock(&light_mutex);
msg(L_DEBUG, "Sending DMX packet");
int err, transferred;
- if (err = libusb_bulk_transfer(devh, 0x01, packet, len, &transferred, 1000))
+ if (err = libusb_bulk_transfer(devh, 0x01, dmx_packet, len, &transferred, 1000))
usb_error("USB transfer failed: error %d", err);
else if (transferred != len)
usb_error("USB short transfer: %d out of %d bytes", transferred, len);