TapHome
Comunitate Beta Senzori

Glofox room bookings — room preparation

Rezervările spațiilor Glofox în TapHome prin API-ul REST cloud Glofox (HTTPS), un modul pentru fiecare sală: Booked now, Minutes to next booking și un indicator Prepare room care se activează cu un timp stabilit înaintea fiecărei rezervări. Smart rules folosesc indicatorul pentru a încălzi sau răci sala și a aprinde luminile și sistemul audio înainte de sosirea antrenorului, apoi le opresc la final. Doar citire; este necesar accesul Live la API, solicitat de superadminul studioului.

GlofoxPacket Parser → HTTP3 dispozitiveRevizia 1.0 Ultima actualizare: 10 noiembrie 2026

Trimis de Matej Hudec

Glofox room bookings — room preparation

Import în aplicația TapHomeHardware › Packet Parser › Adăugați din șablon

Descărcați șablon
Pe această pagină

Ghid de integrare

Glofox este platforma cloud de rezervări a ABC Fitness, așa că nu este nimic de cablat: TapHome Core citește rezervările sălilor din API-ul REST Glofox prin HTTPS. Configurarea pe partea studioului are trei părți — accesul la API-ul Glofox pentru studio, fiecare sală închiriată configurată ca spațiu rezervabil (facility) și Branch ID-ul și fusul orar ale studioului. Apoi șablonul se importă o dată pentru fiecare sală.

Capturile de ecran provin dintr-o locație de test Glofox Sandbox (ABC Fitness Developer Portal și dashboard-ul Glofox, octombrie 2026) și din aplicația TapHome conectată la o unitate de control de test cu rezervări simulate.

Configurare

1. Solicitați accesul la API-ul Glofox

Superadminul studioului se înregistrează în ABC Fitness Developer Portal (Account Type Customer) și face clic pe Request Integrator:

  • Environment: Live (Sandbox este doar o locație de test cu date demonstrative).
  • Namespace: namespace-ul Glofox al studioului.
  • Intended Use Case: de exemplu „TapHome building automation reads facility bookings to prepare rooms (heating, lights, audio) before each booking. Read-only.”

ABC Fitness verifică solicitările Live și răspunde prin e-mail. Cheia API (API key) și tokenul API (API token) se solicită apoi cu Request credentials și sosesc la adresa de e-mail a contului din portal. Întrebări despre acces: [email protected].

Ghidul de solicitare a accesului în ABC Fitness Developer Portal

Cheia API și tokenul API dau acces la datele Glofox ale studioului. Glofox cere ca acestea să fie folosite doar în integrări backend, niciodată în aplicații client; în TapHome își au locul doar în parametrii de import ai șablonului.

2. Configurați fiecare sală ca spațiu rezervabil

Activați mai întâi Settings → Booking → Facility Rental; comutatoarele pentru spații de mai jos apar abia după aceea. Apoi Manage → Facilities afișează lista sălilor. Fiecare sală pe care o închiriază antrenorii trebuie să fie un spațiu (facility) cu Bookable activat, cu un program de intervale (fila Schedule) și, la Price / Eligibility, cu Drop In Clients sau Clients permiși (un preț de 0 este în regulă). Fără acestea, rezervarea unui antrenor se termină cu „Membership not allowed”.

Spațiile (Facilities) în dashboard-ul Glofox
Detaliul spațiului cu Public și Bookable activate

3. Găsiți Branch ID-ul și fusul orar al studioului

Cu cheia API și tokenul, o singură cerere returnează locația studioului, ID-ul ei și fusul ei orar:

1
2
3
curl -s -X POST https://gf-api.aws.glofox.com/prod/v3.0/locations/retrieve \
  -H "x-api-key: <API key>" -H "x-glofox-api-token: <API token>" \
  -H "Content-Type: application/json" -d '{}'

data[]._id este BranchId, iar data[].address.timezone_id fusul orar al studioului (de exemplu Europe/Bratislava). Fără filtru, cererea returnează toate locațiile din namespace-urile pe care integrarea le poate citi, așa că, dacă aveți mai multe studiouri, alegeți intrarea studioului ale cărui săli le urmăresc modulele.

Ceasul scripturilor din TapHome Core trebuie să fie în fusul orar al studioului: pe Core 2025.2 acesta este fusul orar de sistem al unității de control, pe Core mai nou fusul orar al locației TapHome.

4. Importați șablonul o dată pentru fiecare sală

În aplicația TapHome deschideți interfața Packet parser (adăugați-o mai întâi dacă unitatea de control nu o are), apoi Adăugați din șablon → Adăugați din fișier și alegeți șablonul descărcat. Completați ApiKey, ApiToken, BranchId, LeadMinutes și FacilityId al sălii.

Introduceți numele sălii în Prefixul numelui dispozitivului și terminați-l cu un separator, de exemplu Sala de yoga - . Prefixul se alipește la numele dispozitivelor exact așa cum a fost scris, deci fără separator un dispozitiv se numește „Sala de yogaBooked now”. Zona plasează cele trei dispozitive ale sălii în zona sălii.

Parametrii de import în aplicația TapHome

Dacă Facility ID-ul nu este încă cunoscut, introduceți orice text. După prima interogare, modulul raportează o eroare care listează toate spațiile filialei (branch) cu ID-urile lor (Dispozitive → Erori și avertismente → modulul):

Eroarea modulului cu lista spațiilor filialei

Copiați ID-ul corect în variabila FacilityId a modulului (sau importați din nou) și repetați pentru fiecare sală.

5. Verificați în calendarul Glofox

Rezervările unei săli apar în Calendar din Glofox (filtrul Facilities). Cu o rezervare de la 10:00 la 11:00 și LeadMinutes 60, valorile sălii sunt:

OraBooked nowMinutes to next bookingPrepare room
8:30Free90Idle
9:00Free60Prepare
10:30Bookedurmătoarea rezervare sau 1440Prepare
11:00Freeurmătoarea rezervare sau 1440Idle

Minutele sunt minute întregi numărate de la interogare, așa că o valoare poate diferi de tabel cu unu.

Rezervarea unui spațiu în calendarul Glofox

În aplicația TapHome fiecare sală afișează cele trei valori sub modulul său:

Valorile sălii în aplicația TapHome

Smart rules

Prepare room (pregătirea sălii) este condiția pentru smart rules ale sălii: valoarea setată de încălzire sau răcire, scena de iluminat și cea audio cât timp este Prepare, totul oprit când revine la Idle. Booked now (sală rezervată acum) se potrivește pentru afișajele de ocupare; Minutes to next booking (minute până la următoarea rezervare) permite unei smart rule să pornească un sistem de încălzire lent mai devreme decât LeadMinutes.

Dispozitive disponibile 3

Aceste dispozitive apar în TapHome după import.

Glofox Room Modul

Glofox Room

Citire (modul)
# Bookings of this room (FacilityId) that run now or start within 24 h. Glofox times are the studio's local time
# ("yyyy-MM-dd HH:mm:ss"), so the Core's time zone must be the studio's. Texts in that format sort like the times,
# which lets JSONPath filters compare them directly.
VAR now := NOW();
VAR nowText := TOSTRING(now, "yyyy-MM-dd HH:mm:ss");
VAR leadText := TOSTRING(DATETIMEADD(now, 0, 0, 0, 0, LeadMinutes), "yyyy-MM-dd HH:mm:ss");
VAR nowLocal := ROUND(now.UNIXTIME + LOCALTIMEZONE() / 1000);
VAR hKey := "x-api-key: " + ApiKey;
VAR hToken := "x-glofox-api-token: " + ApiToken;
VAR hBranch := "x-glofox-branch-id: " + BranchId;
VAR msg := "";
VAR i := 0;
VAR fid := "";

# Every failed poll ends in RETURN before the values are written. After five failed polls in a row (Glofox or the
# internet down) the room is released, so an old "Prepare" does not keep heating and lights on.
failCount := failCount + 1;
IF failCount > 5
    bookedNow := 0;
    prepareRoom := 0;
    minsToNext := 1440;
END

# After start and then once an hour: the configured room must exist; if not, the error lists the rooms of the branch
# with their ids. facilityCheck counts the polls until the next check.
IF facilityCheck <= 0
    VAR fresp := SENDHTTPREQUEST("/prod/3.0/locations/" + BranchId + "/facilities?limit=100", "GET", "", hKey, hToken, hBranch);
    IF !fresp.IsSuccess
        # no connection: StatusCode 0 and no ReasonPhrase
        IF !ISNULL(fresp.ReasonPhrase)
            msg := " " + fresp.ReasonPhrase;
        END
        ADDERROR(1, "Glofox API: HTTP " + TOSTRING(fresp.StatusCode, "F0") + msg);
        RETURN(0);
    END
    IF ISNULL(PARSEJSON(fresp.Content, "$.data", TRUE))
        msg := PARSEJSON(fresp.Content, "$.message", TRUE);
        ADDERROR(2, "Glofox API: " + IF(ISNULL(msg), "unexpected answer", msg));
        RETURN(0);
    END
    IF ISNULL(PARSEJSON(fresp.Content, "$.data[?(@._id == '" + FacilityId + "')].name", TRUE))
        msg := "";
        fid := PARSEJSON(fresp.Content, "$.data[0]._id", TRUE);
        WHILE !ISNULL(fid)
            msg := msg + IF(i = 0, ": ", "; ") + PARSEJSON(fresp.Content, "$.data[" + TOSTRING(i, "F0") + "].name", TRUE) + " = " + fid;
            i := i + 1;
            fid := PARSEJSON(fresp.Content, "$.data[" + TOSTRING(i, "F0") + "]._id", TRUE);
        LOOP
        ADDERROR(3, "Facility '" + FacilityId + "' is not in this branch. Facilities" + msg);
        RETURN(0);
    END
    facilityCheck := 60;
END
facilityCheck := facilityCheck - 1;

VAR path := "/prod/2.2/branches/" + BranchId + "/bookings?status=BOOKED&limit=50&time_finish_start_date=" + TOSTRING(nowLocal, "F0") + "&time_start_end_date=" + TOSTRING(nowLocal + 86400, "F0") + "&page=";
VAR room := "$.data[?(@.model_id == '" + FacilityId + "' && @.status == 'BOOKED' && ";
VAR newBooked := 0;
VAR newPrepare := 0;
VAR nextText := "";
VAR candidate := "";
VAR total := 0;
VAR page := 1;
VAR pages := 1;
VAR nextStart := now;

# limit=50: a booking is about 1 kB (0.9 kB measured) and SENDHTTPREQUEST accepts at most 128 kB; at most 10 pages =
# 500 bookings of the whole branch (class bookings included)
VAR resp := SENDHTTPREQUEST(path + "1", "GET", "", hKey, hToken, hBranch);
WHILE page <= pages
    IF page > 1
        resp := SENDHTTPREQUEST(path + TOSTRING(page, "F0"), "GET", "", hKey, hToken, hBranch);
    END
    IF !resp.IsSuccess
        IF !ISNULL(resp.ReasonPhrase)
            msg := " " + resp.ReasonPhrase;
        END
        ADDERROR(1, "Glofox API: HTTP " + TOSTRING(resp.StatusCode, "F0") + msg);
        RETURN(0);
    END
    # a wrong API token or BranchId answers HTTP 200 with success:false and a message, and no meta
    total := PARSEJSON(resp.Content, "$.meta.totalCount", TRUE);
    IF ISNULL(total)
        msg := PARSEJSON(resp.Content, "$.message", TRUE);
        ADDERROR(2, "Glofox API: " + IF(ISNULL(msg), "unexpected answer", msg));
        RETURN(0);
    END
    pages := MIN(10, CEIL(total / 50));
    IF !ISNULL(PARSEJSON(resp.Content, room + "@.time_start <= '" + nowText + "' && @.time_finish > '" + nowText + "')]._id", TRUE))
        newBooked := 1;
    END
    IF !ISNULL(PARSEJSON(resp.Content, room + "@.time_start <= '" + leadText + "' && @.time_finish > '" + nowText + "')]._id", TRUE))
        newPrepare := 1;
    END
    # earliest booking that has not started: take any later than now, then ask for an earlier one until none is left
    candidate := PARSEJSON(resp.Content, room + "@.time_start > '" + nowText + "'" + IF(nextText = "", "", " && @.time_start < '" + nextText + "'") + ")].time_start", TRUE);
    WHILE !ISNULL(candidate)
        nextText := candidate;
        candidate := PARSEJSON(resp.Content, room + "@.time_start > '" + nowText + "' && @.time_start < '" + nextText + "')].time_start", TRUE);
    LOOP
    page := page + 1;
LOOP
IF total > 500
    ADDWARNING(4, "More than 500 bookings of the branch in the next 24 hours; only the first 500 were read, a booking of this room beyond them is not seen");
END

failCount := 0;
bookedNow := newBooked;
prepareRoom := newPrepare;
IF nextText = ""
    minsToNext := 1440;
ELSE
    nextStart := DATETIME(nextText, "yyyy-MM-dd HH:mm:ss");
    minsToNext := MIN(1440, FLOOR((nextStart.TICKS - now.TICKS) / 60000));
END
Booked now Contact reed

Booked now

Citire
RETURN(bookedNow);
Minutes to next booking Variabilă

Minutes to next booking

Citire
RETURN(minsToNext);
Prepare room Contact reed

Prepare room

Citire
RETURN(prepareRoom);
Conexiune: Packet Parser → HTTP

Parametri de import

Introduceți aceste valori când importați XML-ul.

Solicitat în aplicațieImplicit
Glofox API key (x-api-key header)Se introduce la import
Glofox API token (x-glofox-api-token header)Se introduce la import
Glofox Branch ID (x-glofox-branch-id header)Se introduce la import
Glofox Facility ID for this room (model_id in booking response)Se introduce la import
Lead time in minutes — Prepare Room activates this many minutes before a booking60

Ați găsit o problemă la acest șablon de dispozitiv?

Spuneți-ne ce nu funcționează, ce lipsește sau cum ar trebui să se comporte șablonul. Feedbackul dvs. ne ajută să păstrăm catalogul corect.

Șablon · portalul TapHome Glofox room bookings — room preparation Deschideți acest șablon în Customer Portal pentru a-l aplica într-una dintre locuințele dvs. sau pentru a propune o îmbunătățire și a o trimite înapoi în catalog. Packet Parser → HTTP Vezi în portalul TapHome