rushabhcodes/desk-fidget-counter
A desk knob assembly combining a circuit board with PETG-printed mechanical parts and vendor CAD-modeled hardware.
- Version
- 5.6.1
- License
- MIT
- Stars
- 0
firmware/dashboard.c
// SPDX-License-Identifier: MIT
#include "dashboard.h"
#include <string.h>
static unsigned days(unsigned y, unsigned m) {
static const unsigned n[] = {31,28,31,30,31,30,31,31,30,31,30,31};
return n[m-1] + (m == 2 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0));
}
static bool number(const char **p, unsigned *out, unsigned digits, char sep) {
unsigned v=0,n=0;
while (**p>='0' && **p<='9' && n<digits) { v=v*10+(unsigned)(*(*p)++-'0'); n++; }
if (!n || **p!=sep) return false;
*out=v; if(sep) (*p)++; return true;
}
bool dashboard_receive(Dashboard *d, const char *line, uint32_t now) {
if (strlen(line)>60 || strncmp(line,"DASH ",5)) return false;
const char *p=line+5; unsigned h,m,s,y,mo,day,cpu,ram,battery,ac;
if (!number(&p,&h,2,':') || !number(&p,&m,2,':') || !number(&p,&s,2,' ') ||
!number(&p,&y,4,'-') || !number(&p,&mo,2,'-') || !number(&p,&day,2,' ') ||
!number(&p,&cpu,4,' ') || !number(&p,&ram,4,' ')) return false;
bool missing=!strncmp(p,"-1 ",3);
if (missing) { battery=0; p+=3; }
else if (!number(&p,&battery,3,' ')) return false;
if (!number(&p,&ac,1,0) || h>23 || m>59 || s>59 || y<2020 || y>9999 ||
mo<1 || mo>12 || day<1 || day>days(y,mo) || cpu>1000 || ram>1000 ||
battery>100 || ac>1) return false;
*d=(Dashboard){.seconds=h*3600+m*60+s,.year=y,.month=mo,.day=day,
.cpu_tenths=cpu,.ram_tenths=ram,.battery_percent=missing?-1:(int)battery,.ac=ac,
.received=true,.received_at=now};
return true;
}
bool dashboard_fresh(const Dashboard *d, uint32_t now) {
return d->received && (uint32_t)(now-d->received_at)<5000;
}
unsigned dashboard_seconds(const Dashboard *d, uint32_t now) {
return (d->seconds+(uint32_t)(now-d->received_at)/1000)%86400;
}
void dashboard_date(const Dashboard *d, uint32_t now, unsigned *year, unsigned *month, unsigned *day) {
*year=d->year; *month=d->month; *day=d->day;
// Called only on fresh samples; at most one midnight has elapsed.
if (dashboard_fresh(d,now) && dashboard_seconds(d,now)<d->seconds) {
if (++*day>days(*year,*month)) {
*day=1;
if (++*month>12) { *month=1; ++*year; }
}
}
}
