Skip to content

Commit

Permalink
Bug Fixes & Germination (#13)
Browse files Browse the repository at this point in the history
* fix for graph w/ language select

* fix for timezone issue w/ graphs

* fix for timezone issue w/ graphs
  • Loading branch information
dwot authored Jan 6, 2025
1 parent 2aaa9cf commit 8bf8755
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 14 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.13
0.1.14
81 changes: 73 additions & 8 deletions handlers/plant.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ func GetStatuses() []types.Status {
return nil
}

rows, err := db.Query("SELECT id, status FROM plant_status")
rows, err := db.Query("SELECT id, status FROM plant_status ORDER BY status_order")
if err != nil {
fieldLogger.WithError(err).Error("Failed to query statuses")
return nil
Expand Down Expand Up @@ -378,7 +378,7 @@ func GetPlant(id string) types.Plant {
fieldLogger.WithError(err).Error("Failed to open database")
return plant
}
rows, err := db.Query("SELECT p.id, p.name, p.description, p.clone, p.start_dt, s.name as strain_name, b.name as breeder_name, z.name as zone_name, (select ps.status from plant_status_log psl left outer join plant_status ps on psl.status_id = ps.id where psl.plant_id = p.id order by strftime('%s', psl.date) desc limit 1) as current_status, (select ps.id from plant_status_log psl left outer join plant_status ps on psl.status_id = ps.id where psl.plant_id = p.id order by strftime('%s', psl.date) desc limit 1) as status_id, p.sensors, s.id, p.harvest_weight, coalesce(s.cycle_time, 0), coalesce(s.url, ''), s.autoflower, coalesce(p.parent_plant_id, 0), coalesce(p2.name, '') as parent_name FROM plant p LEFT OUTER JOIN plant p2 on coalesce(p.parent_plant_id, 0) = p2.id LEFT OUTER JOIN strain s on p.strain_id = s.id left outer join breeder b on b.id = s.breeder_id LEFT OUTER JOIN zones z on p.zone_id = z.id WHERE p.id = $1", id)
rows, err := db.Query("SELECT p.id, p.name, p.description, p.clone, p.start_dt, s.name as strain_name, b.name as breeder_name, z.name as zone_name, z.id as zone_id, (select ps.status from plant_status_log psl left outer join plant_status ps on psl.status_id = ps.id where psl.plant_id = p.id order by strftime('%s', psl.date) desc limit 1) as current_status, (select ps.id from plant_status_log psl left outer join plant_status ps on psl.status_id = ps.id where psl.plant_id = p.id order by strftime('%s', psl.date) desc limit 1) as status_id, p.sensors, s.id, p.harvest_weight, coalesce(s.cycle_time, 0), coalesce(s.url, ''), s.autoflower, coalesce(p.parent_plant_id, 0), coalesce(p2.name, '') as parent_name FROM plant p LEFT OUTER JOIN plant p2 on coalesce(p.parent_plant_id, 0) = p2.id LEFT OUTER JOIN strain s on p.strain_id = s.id left outer join breeder b on b.id = s.breeder_id LEFT OUTER JOIN zones z on p.zone_id = z.id WHERE p.id = $1", id)
if err != nil {
fieldLogger.WithError(err).Error("Failed to query plant")
return plant
Expand All @@ -394,6 +394,7 @@ func GetPlant(id string) types.Plant {
var strain_name string
var breeder_name string
var zone_name string
var zoneID int
var status string
var statusID int
var sensors string
Expand All @@ -404,7 +405,7 @@ func GetPlant(id string) types.Plant {
var autoflower bool
var parent_id uint
var parent_name string
err = rows.Scan(&id, &name, &description, &isClone, &start_dt, &strain_name, &breeder_name, &zone_name, &status, &statusID, &sensors, &strain_id, &harvest_weight, &cycle_time, &strain_url, &autoflower, &parent_id, &parent_name)
err = rows.Scan(&id, &name, &description, &isClone, &start_dt, &strain_name, &breeder_name, &zone_name, &zoneID, &status, &statusID, &sensors, &strain_id, &harvest_weight, &cycle_time, &strain_url, &autoflower, &parent_id, &parent_name)
if err != nil {
fieldLogger.WithError(err).Error("Failed to scan plant")
return plant
Expand Down Expand Up @@ -613,7 +614,7 @@ func GetPlant(id string) types.Plant {
//Convert int and dates to strings
strCurrentHeight := strconv.Itoa(iCurrentHeight)

plant = types.Plant{id, name, description, status, statusID, strain_name, strain_id, breeder_name, zone_name, iCurrentDay, iCurrentWeek, strCurrentHeight, heightDate, lastWaterDate, lastFeedDate, measurements, activities, statusHistory, sensorList, latestImage, images, isClone, start_dt, harvest_weight, harvestDate, cycle_time, strain_url, estHarvestDate, autoflower, parent_id, parent_name}
plant = types.Plant{id, name, description, status, statusID, strain_name, strain_id, breeder_name, zone_name, zoneID, iCurrentDay, iCurrentWeek, strCurrentHeight, heightDate, lastWaterDate, lastFeedDate, measurements, activities, statusHistory, sensorList, latestImage, images, isClone, start_dt, harvest_weight, harvestDate, cycle_time, strain_url, estHarvestDate, autoflower, parent_id, parent_name}
}

return plant
Expand Down Expand Up @@ -1066,7 +1067,7 @@ FROM plant p
WHERE ps.id IN ` + inClause + ` AND psl.date = (
SELECT MAX(date) FROM plant_status_log WHERE plant_id = p.id
)
ORDER BY p.name;`
ORDER BY p.start_dt, p.name;`

// Open the database connection
db, err := model.GetDB()
Expand Down Expand Up @@ -1120,7 +1121,29 @@ ORDER BY p.name;`
}

func GetLivingPlants() []types.PlantListResponse {
statuses := []int{1, 2, 3} // Seedling, Veg, Flower
//Load status ids from database where active = 1
db, err := model.GetDB()
if err != nil {
logger.Log.WithError(err).Error("Failed to open database")
return nil
}
rows, err := db.Query("SELECT id FROM plant_status WHERE active = 1")
if err != nil {
logger.Log.WithError(err).Error("Failed to query plant statuses")
return nil
}
defer rows.Close()

var statuses []int
for rows.Next() {
var status int
if err := rows.Scan(&status); err != nil {
logger.Log.WithError(err).Error("Failed to scan status")
return nil
}
statuses = append(statuses, status)
}

result, _ := getPlantsByStatus(statuses)
return result
}
Expand All @@ -1133,7 +1156,28 @@ func LivingPlantsHandler(c *gin.Context) {

// HarvestedPlantsHandler handles the /plants/harvested endpoint.
func HarvestedPlantsHandler(c *gin.Context) {
statuses := []int{4, 5, 6} // Success
db, err := model.GetDB()
if err != nil {
logger.Log.WithError(err).Error("Failed to open database")
return
}
rows, err := db.Query("SELECT id FROM plant_status WHERE active = 0 and status <> 'Dead'")
if err != nil {
logger.Log.WithError(err).Error("Failed to query plant statuses")
return
}
defer rows.Close()

var statuses []int
for rows.Next() {
var status int
if err := rows.Scan(&status); err != nil {
logger.Log.WithError(err).Error("Failed to scan status")
return
}
statuses = append(statuses, status)
}

plants, err := getPlantsByStatus(statuses)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve plants"})
Expand All @@ -1145,7 +1189,28 @@ func HarvestedPlantsHandler(c *gin.Context) {

// DeadPlantsHandler handles the /plants/dead endpoint.
func DeadPlantsHandler(c *gin.Context) {
statuses := []int{7} // Dead
db, err := model.GetDB()
if err != nil {
logger.Log.WithError(err).Error("Failed to open database")
return
}

rows, err := db.Query("SELECT id FROM plant_status WHERE status = 'Dead'")
if err != nil {
logger.Log.WithError(err).Error("Failed to query plant statuses")
return
}
defer rows.Close()

var statuses []int
for rows.Next() {
var status int
if err := rows.Scan(&status); err != nil {
logger.Log.WithError(err).Error("Failed to scan status")
return
}
statuses = append(statuses, status)
}
plants, err := getPlantsByStatus(statuses)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve plants"})
Expand Down
6 changes: 4 additions & 2 deletions handlers/sensor_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func querySensorHistoryByTime(sensor string, timeMinutes string) ([]types.Sensor
}

timeThreshold := time.Now().In(time.Local).Add(-time.Duration(timeMinutesInt) * time.Minute).Format("2006-01-02 15:04:05")
query := "SELECT sd.id, sd.sensor_id, sd.value, sd.create_dt, s.name FROM sensor_data sd left outer join sensors s on s.id = sd.sensor_id WHERE sd.sensor_id = $1 AND sd.create_dt > $2 ORDER BY sd.create_dt"
query := "SELECT sd.id, sd.sensor_id, sd.value, sd.create_dt, s.name FROM sensor_data sd left outer join sensors s on s.id = sd.sensor_id WHERE sd.sensor_id = $1 AND datetime(sd.create_dt, 'localtime') > $2 ORDER BY sd.create_dt"
rows, err := db.Query(query, sensorInt, timeThreshold)
if err != nil {
sensorLogger.WithError(err).Error("Failed to execute query")
Expand All @@ -127,6 +127,7 @@ func querySensorHistoryByTime(sensor string, timeMinutes string) ([]types.Sensor
sensorLogger.WithError(err).Error("Failed to scan row")
return sensorData, err
}
record.CreateDT = record.CreateDT.Local()
sensorData = append(sensorData, record)
}

Expand Down Expand Up @@ -160,7 +161,7 @@ func querySensorHistoryByDateRange(sensor string, startDate string, endDate stri
}

// Query sensor_data table for the given date range
query := "SELECT sd.id, sd.sensor_id, sd.value, sd.create_dt, s.name FROM sensor_data sd left outer join sensors s on s.id = sd.sensor_id WHERE sd.sensor_id = $1 AND sd.create_dt BETWEEN $2 AND $3 ORDER BY sd.create_dt"
query := "SELECT sd.id, sd.sensor_id, sd.value, sd.create_dt, s.name FROM sensor_data sd left outer join sensors s on s.id = sd.sensor_id WHERE sd.sensor_id = $1 AND datetime(sd.create_dt, 'localtime') BETWEEN $2 AND $3 ORDER BY sd.create_dt"
rows, err := db.Query(query, sensorInt, startDate, endDate)
if err != nil {
sensorLogger.WithError(err).Error(err)
Expand All @@ -175,6 +176,7 @@ func querySensorHistoryByDateRange(sensor string, startDate string, endDate stri
sensorLogger.WithError(err).Error(err)
return sensorData, err
}
record.CreateDT = record.CreateDT.Local()
sensorData = append(sensorData, record)
}

Expand Down
2 changes: 2 additions & 0 deletions model/migrations/004_germination.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
DELETE FROM plant_status WHERE status, = 'Germinating';
DELETE FROM plant_status WHERE status, = 'Planted';
13 changes: 13 additions & 0 deletions model/migrations/004_germination.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
alter table plant_status add column status_order INTEGER NOT NULL DEFAULT 0;
INSERT INTO plant_status (status, active, status_order) VALUES ('Germinating', 1, 1);
INSERT INTO plant_status (status, active, status_order) VALUES ('Planted', 1, 2);
UPDATE plant_status SET status_order = 3 WHERE status = 'Seedling';
UPDATE plant_status SET status_order = 4 WHERE status = 'Veg';
UPDATE plant_status SET status_order = 5 WHERE status = 'Flower';
UPDATE plant_status SET status_order = 6 WHERE status = 'Drying';
UPDATE plant_status SET status_order = 7 WHERE status = 'Curing';
UPDATE plant_status SET status_order = 8 WHERE status = 'Success';
UPDATE plant_status SET status_order = 9 WHERE status = 'Dead';

UPDATE plant_status SET active = 0 WHERE status = 'Drying';
UPDATE plant_status SET active = 0 WHERE status = 'Curing';
1 change: 1 addition & 0 deletions model/types/base_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ type Plant struct {
StrainID int `json:"strain_id"`
BreederName string `json:"breeder_name"`
ZoneName string `json:"zone_name"`
ZoneID int `json:"zone_id"`
CurrentDay int `json:"current_day"`
CurrentWeek int `json:"current_week"`
CurrentHeight string `json:"current_height"`
Expand Down
12 changes: 9 additions & 3 deletions web/templates/pages/plant.html
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,9 @@ <h5 class="modal-title" id="changeStatusModalLabel">{{ .lcl.update_plant }}</h5>
<label for="zoneSelect" class="form-label">{{ .lcl.title_zone }}</label>
<select class="form-select" id="zoneSelect" required>
{{ range .zones }}
<option value="{{ .ID }}">{{ .Name }}</option>
<option
{{ if eq .ID $.plant.ZoneID }}selected{{ end }}
value="{{ .ID }}">{{ .Name }}</option>
{{ end }}
<option value="new">{{ .lcl.add_new_zone }}</option>
</select>
Expand Down Expand Up @@ -721,7 +723,7 @@ <h5 class="modal-title" id="editStatusModalLabel">{{ .lcl.edit_status }}</h5>
<input type="hidden" id="statusId">
<div class="mb-3">
<label for="editStatusDate" class="form-label">{{ .lcl.title_date }}</label>
<input type="datetime-local" class="form-control" id="editStatusDate" required value="{{ now | formatDateTimeLocal }}">
<input type="datetime-local" class="form-control" id="editStatusDate" required>
</div>
{{ if .loggedIn }}
<button type="submit" class="btn btn-primary"><i class="fa-solid fa-floppy-disk"></i> {{ .lcl.save_changes }}</button>
Expand Down Expand Up @@ -1144,9 +1146,13 @@ <h5 class="modal-title" id="editActivityModalLabel">{{ .lcl.edit_activity }}</h5
const statusData = JSON.parse(row.getAttribute("data-status"));

document.getElementById("statusId").value = statusData.id;
const formattedDate = statusData.date.split("T")[0];
console.log(statusData.date);

const date = new Date(statusData.date);
const formattedDate = date.toISOString().slice(0, 16); // Removes seconds and 'Z'
document.getElementById("editStatusDate").value = formattedDate;


editStatusModal.show();
});
});
Expand Down

0 comments on commit 8bf8755

Please sign in to comment.