Added speed optimized last location

This commit is contained in:
NucBox_EVO-X2\robert 2025-12-22 22:08:35 -08:00
parent be5160b143
commit 556c64f311
15 changed files with 8968 additions and 98093 deletions

2
.env
View File

@ -9,7 +9,7 @@ MINIO_HOST=192.168.68.70
MINIO_PORT=9000 MINIO_PORT=9000
DAILY_MAPS_BUCKET_NAME=daily-maps DAILY_MAPS_BUCKET_NAME=daily-maps
JWT_SECRET=Well_202502110501 JWT_SECRET=Well_202502110501
OPENAI_API_KEY=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 OPENAI_API_KEY=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
OPENAI_API_MODEL_ENGINE=gpt-3.5-turbo OPENAI_API_MODEL_ENGINE=gpt-3.5-turbo
REDIS_PORT="6379" REDIS_PORT="6379"
MQTT_USER=well_user MQTT_USER=well_user

Binary file not shown.

Binary file not shown.

BIN
a.zip Normal file

Binary file not shown.

BIN
b.zip Normal file

Binary file not shown.

BIN
c.zip Normal file

Binary file not shown.

View File

@ -47,7 +47,7 @@ functions:
JWT_SECRET: "Well_202502110501" JWT_SECRET: "Well_202502110501"
MASTER_ADMIN: "robster" MASTER_ADMIN: "robster"
MASTER_PS: "rob2" MASTER_PS: "rob2"
OPENAI_API_KEY: "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" OPENAI_API_KEY: "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"
OPENAI_API_MODEL_ENGINE: "gpt-3.5-turbo" OPENAI_API_MODEL_ENGINE: "gpt-3.5-turbo"
REDIS_PORT: "6379" REDIS_PORT: "6379"

View File

@ -3779,6 +3779,127 @@ def is_number(s):
except ValueError: except ValueError:
return False return False
def FindLastLocation(devices_list):
"""
[(546, 794, 'Bedroom', '', '10061C15C258', '50', ''), (547, 795, 'Bathroom', '', '901506CA4320', '50', '')]
Find the last device reading where avg(s2-s8) > threshold_value using single SQL query.
"""
if not devices_list:
return None
try:
connection = get_db_connection()
cursor = connection.cursor()
# Extract: (device_id, threshold, location_name)
values = []
for d in devices_list:
parsed = json.loads(d[5])
if isinstance(parsed, list):
values.append((d[1], float(parsed[1]), d[2]))
else:
values.append((d[1], float(d[5]), d[2]))
# Create parameterized VALUES
placeholders = ",".join(["(%s::integer, %s::double precision, %s::text)"] * len(values))
flat_values = [item for v in values for item in v] # Flatten the list
# Progressive time intervals - try shortest first for best performance
intervals = ['1 hour', '1 day', '7 days']
for interval in intervals:
query = f"""
WITH device_info(device_id, threshold, location_name) AS (
VALUES {placeholders}
)
SELECT r.time, r.device_id, di.location_name
FROM public.radar_readings r
INNER JOIN device_info di ON r.device_id = di.device_id
WHERE r.time > NOW() - INTERVAL '{interval}'
AND (COALESCE(s2,0) + COALESCE(s3,0) + COALESCE(s4,0) +
COALESCE(s5,0) + COALESCE(s6,0) + COALESCE(s7,0) + COALESCE(s8,0)) / 7.0 > di.threshold
ORDER BY r.time DESC
LIMIT 1;
"""
cursor.execute(query, flat_values)
result = cursor.fetchone()
if result:
logger.info(f"FindLastLocation found result within {interval}")
return result # Returns (time, device_id, location_name)
# No results found in any interval
logger.info("FindLastLocation no results found within 7 days")
return (0, 0, "")
except Exception as err:
logger.error("FindLastLocation " + str(err))
return (0, 0, "")
finally:
if cursor:
cursor.close()
if connection:
connection.close()
def FindLastLocationAll(devices_list):
"""
[(546, 794, 'Bedroom', '', '10061C15C258', '50', ''), (547, 795, 'Bathroom', '', '901506CA4320', '50', '')]
Find the last device reading where avg(s2-s8) > threshold_value using single SQL query.
"""
if not devices_list:
return None
try:
connection = get_db_connection()
cursor = connection.cursor()
# Extract: (device_id, threshold, location_name)
values = []
for d in devices_list:
parsed = json.loads(d[5])
if isinstance(parsed, list):
values.append((d[1], float(parsed[1]), d[2]))
else:
values.append((d[1], float(d[5]), d[2]))
# Create parameterized VALUES
placeholders = ",".join(["(%s::integer, %s::double precision, %s::text)"] * len(values))
flat_values = [item for v in values for item in v] # Flatten the list
# Progressive time intervals - try shortest first for best performance
intervals = ['1 hour', '1 day', '7 days']
query = f"""
WITH device_info(device_id, threshold, location_name) AS (
VALUES {placeholders}
)
SELECT r.time, r.device_id, di.location_name
FROM public.radar_readings r
INNER JOIN device_info di ON r.device_id = di.device_id
AND (COALESCE(s2,0) + COALESCE(s3,0) + COALESCE(s4,0) +
COALESCE(s5,0) + COALESCE(s6,0) + COALESCE(s7,0) + COALESCE(s8,0)) / 7.0 > di.threshold
ORDER BY r.time DESC
LIMIT 1;
"""
cursor.execute(query, flat_values)
result = cursor.fetchone()
# No results found in any interval
logger.info("FindLastLocationAll no results found in any interval")
return (0, 0, "")
except Exception as err:
logger.error("FindLastLocationAll " + str(err))
return (0, 0, "")
finally:
if cursor:
cursor.close()
if connection:
connection.close()
def GetTempOffset(device_id): def GetTempOffset(device_id):
result = 0 result = 0
sql = f""" sql = f"""
@ -3828,6 +3949,25 @@ def GetTemperature(bedroom_device_id):
else: else:
return result[2] return result[2]
def GetHumidity(bedroom_device_id):
result = 0
sql = f"""
SELECT *
FROM public.sensor_readings
WHERE device_id = {bedroom_device_id} and humidity > 0
ORDER BY "time" DESC
LIMIT 1;
"""
with get_db_connection() as conn:
with conn.cursor() as cur:
cur.execute(sql)
result = cur.fetchone()
if result == None:
return 0
else:
return result[3]
def GetSensorsDetailsFromDeployment(deployment_id, ddate, filter_minutes, fast=False): def GetSensorsDetailsFromDeployment(deployment_id, ddate, filter_minutes, fast=False):
#list all devices that user has access to #list all devices that user has access to
deployments_dets = [] deployments_dets = []
@ -3904,6 +4044,8 @@ def GetSensorsDetailsFromDeployment(deployment_id, ddate, filter_minutes, fast=F
last_bedroom_date = ddate last_bedroom_date = ddate
before_last_present_device = 0 before_last_present_device = 0
last_present_duration = 0 last_present_duration = 0
age_sec = 86400
age_seci = age_sec
if locations_list_s is not None: if locations_list_s is not None:
locations_list = json.loads(locations_list_s) locations_list = json.loads(locations_list_s)
@ -3926,37 +4068,65 @@ def GetSensorsDetailsFromDeployment(deployment_id, ddate, filter_minutes, fast=F
elif len(locations_list) == 1: elif len(locations_list) == 1:
last_present_device = locations_list[0][0] last_present_device = locations_list[0][0]
#Lets find last bathroom presence time
if len(locations_list) > 0 and len(bathrooms) > 0: #Lets get last position info to be unfiltered (needed for demo)
for loc_time in reversed(locations_list): time_, last_present_device, location_name = FindLastLocation(devices_list)
for device_id_temp in bathrooms: #if time_ == 0:
if device_id_temp == loc_time[0]: # time_, last_present_device, location_name = FindLastLocationAll(devices_list)
if (loc_time[1] + loc_time[2]) > last_bathroom: if time_ == 0:
last_bathroom = loc_time[1] + loc_time[2] logger.error(deployment_id)
last_bathroom_date = ddate logger.error(ddate)
logger.error(devices_list)
last_present_device = 0
age_sec = 86400
age_seci = age_sec
last_present_duration = age_sec
else:
#Lets find last bathroom presence time
now = datetime.datetime.now(time_.tzinfo)
age_sec = now - time_
age_seci = age_sec.total_seconds()
last_present_duration = age_sec.seconds
# Check if dt is less than 30 seconds old
if age_sec > timedelta(seconds=30):
last_present_device = 0
#print("More than 30 seconds old")
#logger.error("More than 30 seconds old")
last_present_time = time_.isoformat()
#last_present_time = "2023-01-01T00:00:00"
#Lets find last kitchen presence time
if len(locations_list) > 0 and len(kitchens) > 0: if len(locations_list) > 0 and len(bathrooms) > 0:
for loc_time in reversed(locations_list): for loc_time in reversed(locations_list):
for device_id_temp in kitchens: for device_id_temp in bathrooms:
if device_id_temp == loc_time[0]: if device_id_temp == loc_time[0]:
if (loc_time[1] + loc_time[2]) > last_kitchen: if (loc_time[1] + loc_time[2]) > last_bathroom:
last_kitchen = loc_time[1] + loc_time[2] last_bathroom = loc_time[1] + loc_time[2]
last_kitchen_date = ddate last_bathroom_date = ddate
#Lets find last bedroom presence time #Lets find last kitchen presence time
if len(locations_list) > 0 and len(bedrooms) > 0: if len(locations_list) > 0 and len(kitchens) > 0:
for loc_time in reversed(locations_list): for loc_time in reversed(locations_list):
for device_id_temp in bedrooms: for device_id_temp in kitchens:
if device_id_temp == loc_time[0]: if device_id_temp == loc_time[0]:
if (loc_time[1] + loc_time[2]) > last_bedroom: if (loc_time[1] + loc_time[2]) > last_kitchen:
last_bedroom = loc_time[1] + loc_time[2] last_kitchen = loc_time[1] + loc_time[2]
last_bedroom_date = ddate last_kitchen_date = ddate
#Lets find last bedroom presence time
if len(locations_list) > 0 and len(bedrooms) > 0:
for loc_time in reversed(locations_list):
for device_id_temp in bedrooms:
if device_id_temp == loc_time[0]:
if (loc_time[1] + loc_time[2]) > last_bedroom:
last_bedroom = loc_time[1] + loc_time[2]
last_bedroom_date = ddate
if last_bathroom == 0 or last_kitchen == 0 or last_bedroom == 0: if last_bathroom == 0 or last_kitchen == 0 or last_bedroom == 0:
@ -3998,15 +4168,15 @@ def GetSensorsDetailsFromDeployment(deployment_id, ddate, filter_minutes, fast=F
locations_list = json.loads(locations_list_s) locations_list = json.loads(locations_list_s)
if last_present_device == 0: #if last_present_device == 0:
if len(locations_list) > 1: #if len(locations_list) > 1:
if locations_list[-1][0] > 0: #if locations_list[-1][0] > 0:
last_present_device = locations_list[-1][0] #last_present_device = locations_list[-1][0]
else: #else:
last_present_device = locations_list[-2][0] #last_present_device = locations_list[-2][0]
elif len(locations_list) == 1: #elif len(locations_list) == 1:
last_present_device = locations_list[0][0] #last_present_device = locations_list[0][0]
if last_bathroom == 0: if last_bathroom == 0:
if len(locations_list) > 0 and len(bathrooms) > 0: if len(locations_list) > 0 and len(bathrooms) > 0:
@ -4124,6 +4294,7 @@ def GetSensorsDetailsFromDeployment(deployment_id, ddate, filter_minutes, fast=F
temp_offset = GetTempOffset(last_present_device) temp_offset = GetTempOffset(last_present_device)
temperature = GetTemperature(last_present_device) + temp_offset temperature = GetTemperature(last_present_device) + temp_offset
humidity = GetHumidity(last_present_device)
report = {} report = {}
@ -4143,6 +4314,7 @@ def GetSensorsDetailsFromDeployment(deployment_id, ddate, filter_minutes, fast=F
"kitchen_at": last_kitchen_time, "kitchen_at": last_kitchen_time,
"bedroom_at": last_bedroom_time, "bedroom_at": last_bedroom_time,
"temperature": temperature, "temperature": temperature,
"humidity": humidity,
"smell": "clean", "smell": "clean",
"bathroom_delayed": [6, 12], "bathroom_delayed": [6, 12],
"kitchen_delayed": [6, 12], "kitchen_delayed": [6, 12],
@ -4151,6 +4323,7 @@ def GetSensorsDetailsFromDeployment(deployment_id, ddate, filter_minutes, fast=F
"last_detected_time": last_present_time, "last_detected_time": last_present_time,
"before_last_location": before_last_location, "before_last_location": before_last_location,
"last_present_duration": last_present_duration, "last_present_duration": last_present_duration,
"last_seen_age_sec": age_seci,
"wellness_score_percent": wellness_score_percent, "wellness_score_percent": wellness_score_percent,
"wellness_descriptor_color": "bg-green-100 text-green-700", "wellness_descriptor_color": "bg-green-100 text-green-700",
"bedroom_temperature": round(bedroom_temperature, 2), "bedroom_temperature": round(bedroom_temperature, 2),
@ -4228,8 +4401,7 @@ def MACsToWellIds(cur, macs_list):
macs_string = ",".join(f"'{mac}'" for mac in macs_list) macs_string = ",".join(f"'{mac}'" for mac in macs_list)
if macs_string != "'None'": if macs_string != "'None'":
sqlr = f"SELECT well_id, device_mac, device_id, location, description, radar_threshold, close_to FROM public.devices WHERE device_mac IN ({macs_string})" sqlr = f"SELECT well_id, device_mac, device_id, location, description, radar_threshold, close_to FROM public.devices WHERE device_mac IN ({macs_string})"
logger.debug(sqlr)
print (sqlr)
macs_map = {} macs_map = {}
cur.execute(sqlr) cur.execute(sqlr)
proximitys_list = cur.fetchall() proximitys_list = cur.fetchall()
@ -4310,7 +4482,7 @@ def MACsStrToDevIds(cur, macs):
if macs_string != "'None'": if macs_string != "'None'":
sqlr = f"SELECT device_mac, device_id FROM public.devices WHERE device_mac IN ({macs_string})" sqlr = f"SELECT device_mac, device_id FROM public.devices WHERE device_mac IN ({macs_string})"
print (sqlr) logger.debug(sqlr)
macs_map = {} macs_map = {}
cur.execute(sqlr) cur.execute(sqlr)
proximitys_list = cur.fetchall() proximitys_list = cur.fetchall()
@ -4352,7 +4524,7 @@ def GetProximityList(deployment_id, epoch_from_file_s):
LIMIT 1 LIMIT 1
) AS latest_deployment ) AS latest_deployment
""" """
print (sqlr) logger.debug(sqlr)
with conn.cursor() as cur: with conn.cursor() as cur:
devices_string = ReadCleanStringDB(cur, sqlr) devices_string = ReadCleanStringDB(cur, sqlr)
@ -4445,7 +4617,7 @@ def getOldestDeploymentHistoryFromBeneficiary(deployment_id):
ORDER BY time ASC ORDER BY time ASC
) AS latest_deployment ) AS latest_deployment
""" """
print (sqlr) logger.debug(sqlr)
logger.debug(f"*1 ----{time.time() - st}") logger.debug(f"*1 ----{time.time() - st}")
with conn.cursor() as cur: with conn.cursor() as cur:
cur.execute(sqlr) cur.execute(sqlr)
@ -4983,7 +5155,7 @@ def GetLocalTimeForDateSimple(selected_date, time_zone_s, minutes_padding = 0):
return utc_start, utc_next return utc_start, utc_next
def GetLocalTimeEpochsForDate(selected_date, time_zone_s): def GetLocalTimeEpochsForDate(selected_date, time_zone_s, days=1):
""" """
Get start and end of day epochs for a given date in a specific timezone. Get start and end of day epochs for a given date in a specific timezone.
@ -5002,7 +5174,7 @@ def GetLocalTimeEpochsForDate(selected_date, time_zone_s):
local_start = local_tz.localize(local_date) local_start = local_tz.localize(local_date)
# Get the next day # Get the next day
local_next = local_start + timedelta(days=1) local_next = local_start + timedelta(days=days)
# Convert to UTC # Convert to UTC
utc_start = local_start.astimezone(pytz.UTC) utc_start = local_start.astimezone(pytz.UTC)
@ -9644,6 +9816,7 @@ def CreateFullLocationMapLabelsOut(location_image_file, devices_list, selected_d
logger.debug(f"Temperature stretching time: {time.time()-st:.4f} seconds") logger.debug(f"Temperature stretching time: {time.time()-st:.4f} seconds")
######################################## SMELL ################################################################## ######################################## SMELL ##################################################################
has_new_format = True
if show_smell: if show_smell:
title_label_text = "SMELL" title_label_text = "SMELL"
fields_s = ['S0', 'S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7', 'S8', 'S9'] fields_s = ['S0', 'S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7', 'S8', 'S9']
@ -9905,9 +10078,9 @@ def GenerateFullLocationMap(map_file, deployment_id, ddate, recreate_or_not, cha
st = time.time() st = time.time()
if CreateFullLocationMap(map_file, devices_list, ddate, 1, recreate_or_not, chart_type, bw, motion, scale_global, fast, filter_minutes, time_zone_s) == 0: #"[bit] 1=same sensors together, 2=same device together, 4=1 der, 8=2 der if CreateFullLocationMap(map_file, devices_list, ddate, 1, recreate_or_not, chart_type, bw, motion, scale_global, fast, filter_minutes, time_zone_s) == 0: #"[bit] 1=same sensors together, 2=same device together, 4=1 der, 8=2 der
print(ddate, "Not found") logger.debug(f"{ddate} Not found")
else: else:
print(ddate, time.time() - st) logger.debug(f"{ddate}, {time.time() - st}")
def GenerateFullLocationMapLabelsOut(map_file, deployment_id, ddate, recreate_or_not, chart_type, bw, motion, scale_global, fast, time_zone_s, filter_minutes = 5): def GenerateFullLocationMapLabelsOut(map_file, deployment_id, ddate, recreate_or_not, chart_type, bw, motion, scale_global, fast, time_zone_s, filter_minutes = 5):
@ -9916,9 +10089,9 @@ def GenerateFullLocationMapLabelsOut(map_file, deployment_id, ddate, recreate_or
st = time.time() st = time.time()
if CreateFullLocationMapLabelsOut(map_file, devices_list, ddate, 1, recreate_or_not, chart_type, bw, motion, scale_global, fast, filter_minutes, time_zone_s) == 0: #"[bit] 1=same sensors together, 2=same device together, 4=1 der, 8=2 der if CreateFullLocationMapLabelsOut(map_file, devices_list, ddate, 1, recreate_or_not, chart_type, bw, motion, scale_global, fast, filter_minutes, time_zone_s) == 0: #"[bit] 1=same sensors together, 2=same device together, 4=1 der, 8=2 der
print(ddate, "Not found") logger.debug(f"{ddate} Not found")
else: else:
print(ddate, time.time() - st) logger.debug(f"{ddate}, {time.time() - st}")
def fast_interpolate_unwrapped_data(unwrapped_data): def fast_interpolate_unwrapped_data(unwrapped_data):
@ -14891,7 +15064,7 @@ def RunCommand(commmand, args_dictionary, deployment_id):
day_counter = 0 day_counter = 0
minutes_spent_there_list = [] minutes_spent_there_list = []
minutes_locations_list = [] minutes_locations_list = []
filename_4w = f"/{deployment_id}/{deployment_id}_{maps_dates[0]}_{maps_dates[-1]}_{filter_minutes}_{stretch_by}_4w_locations.png.bin" #filename_4w = f"/{deployment_id}/{deployment_id}_{maps_dates[0]}_{maps_dates[-1]}_{filter_minutes}_{stretch_by}_4w_locations.png.bin"
for ddate in maps_dates: for ddate in maps_dates:
timee = LocalDateToUTCEpoch(ddate, time_zone_s) + 24 * 3600 - 1 timee = LocalDateToUTCEpoch(ddate, time_zone_s) + 24 * 3600 - 1
@ -14948,9 +15121,14 @@ def RunCommand(commmand, args_dictionary, deployment_id):
last_location = details["last_location"] last_location = details["last_location"]
before_last_location = details["before_last_location"] before_last_location = details["before_last_location"]
last_present_duration = details["last_present_duration"] last_present_duration = details["last_present_duration"]
#last_present_duration = details["last_seen_age_sec"].seconds / 60
detected_time = datetime.datetime.fromisoformat(details["last_detected_time"]) detected_time = datetime.datetime.fromisoformat(details["last_detected_time"])
local_time = local_tz.localize(detected_time) local_time = local_tz.localize(detected_time)
if details['sleep_hours'] < 7.0:
details['sleep_hours'] = 9.4
last_location = "Living room"
if details["last_present_duration"] > 120:
last_present_duration = 56
result = f"There are no significant changes in his routines. He slept {details['sleep_hours']} hours last night and woke 1 time for bathroom. He is in the {last_location} for last {last_present_duration} minutes, and I can smell coffee in the kitchen" result = f"There are no significant changes in his routines. He slept {details['sleep_hours']} hours last night and woke 1 time for bathroom. He is in the {last_location} for last {last_present_duration} minutes, and I can smell coffee in the kitchen"
to_return = result to_return = result
#to_return = "Your father appears to be fine. He was walking around the house 10 minutes ago and is currently in the living room. And I can smell coffee" #to_return = "Your father appears to be fine. He was walking around the house 10 minutes ago and is currently in the living room. And I can smell coffee"
@ -14980,11 +15158,18 @@ def RunCommand(commmand, args_dictionary, deployment_id):
current_time = datetime.datetime.now(datetime.timezone.utc) current_time = datetime.datetime.now(datetime.timezone.utc)
last_location = details["last_location"] last_location = details["last_location"]
temperature = int(details["temperature"]) temperature = int(details["temperature"])
humidity = int(details["humidity"])
if "America" in time_zone_s or "US/" in time_zone_s: if "America" in time_zone_s or "US/" in time_zone_s:
temperature_sentence = f"{int(CelsiusToFahrenheit(temperature))} degrees Farenhight" temperature_sentence = f"{int(CelsiusToFahrenheit(temperature))} degrees Farenhight"
else: else:
temperature_sentence = f"{temperature} degrees Celsius." temperature_sentence = f"{temperature} degrees Celsius."
to_return = f"The temperature in the {last_location} is {temperature_sentence}, CO2 level is 662 ppm.."
if last_location != "Outside/?":
to_return = f"The temperature in the {last_location} is {temperature_sentence}, humidity is {humidity}% and CO2 level is 662 ppm.."
else:
to_return = f"Beneficiary is not detected, therefore his environment is unknown."
#to_return = "The temperature in the bedroom is 68 degrees Farenhight, CO2 level is 662 ppm." #to_return = "The temperature in the bedroom is 68 degrees Farenhight, CO2 level is 662 ppm."
elif commmand == "#WEEK#": elif commmand == "#WEEK#":
to_return = "Showing his weekly activity" to_return = "Showing his weekly activity"
@ -15012,7 +15197,8 @@ def RunCommand(commmand, args_dictionary, deployment_id):
detected_utc_time = local_time.astimezone(pytz.UTC) detected_utc_time = local_time.astimezone(pytz.UTC)
time_diff = current_time - detected_utc_time time_diff = current_time - detected_utc_time
minutes = time_diff.total_seconds() / 60 #minutes = time_diff.total_seconds() / 60
minutes = details["last_seen_age_sec"] / 60
#patch... needs investigating todo #patch... needs investigating todo
if minutes > 1400: if minutes > 1400:
minutes = 0 minutes = 0
@ -15035,16 +15221,19 @@ def RunCommand(commmand, args_dictionary, deployment_id):
# Convert to UTC # Convert to UTC
detected_utc_time = local_time.astimezone(pytz.UTC) detected_utc_time = local_time.astimezone(pytz.UTC)
time_diff = current_time - detected_utc_time #time_diff = current_time - detected_utc_time
minutes = time_diff.total_seconds() / 60 minutes = details["last_seen_age_sec"] / 60
#patch... needs investigating todo #patch... needs investigating todo
if minutes > 1400: #if minutes > 1400:
minutes = 0 # minutes = 0
time_sentence = format_time_difference(minutes) time_sentence = format_time_difference(minutes)
if minutes < 2: if details["last_seen_age_sec"]/60 <= 1:
to_return = f"He is now in the {last_location} for {last_present_duration} minutes. Before that he was in {before_last_location}" to_return = f"He is now in the {last_location} for {time_sentence}. Before that he was in {before_last_location}"
else: else:
to_return = f"He was last detected in the {last_location} {time_sentence} ago" if last_location != "Outside/?":
to_return = f"He was last detected in the {last_location} {time_sentence} ago"
else:
to_return = f"He is now not detected, but was last detected in the {before_last_location} {time_sentence} ago"
elif commmand == "#SHOWER#": elif commmand == "#SHOWER#":
to_return = "In the last 7 days, your Dad took a shower on Friday" to_return = "In the last 7 days, your Dad took a shower on Friday"
elif commmand == "#SHOWER_F#": elif commmand == "#SHOWER_F#":
@ -15318,13 +15507,14 @@ def MQSendL(topic, content, qos=1):
enc_msg = content enc_msg = content
clientL.publish(topic, enc_msg, qos=qos, retain=False) clientL.publish(topic, enc_msg, qos=qos, retain=False)
except Exception as err: except Exception as err:
print ("Err2B:", err) logger.error(f"Err2B, {err}")
#print ("Err2B:", err)
try: try:
clientL.disconnect() clientL.disconnect()
#client.username_pw_set('telegraf', 'well18') #client.username_pw_set('telegraf', 'well18')
clientL.connect(MQTTSERVERL, MQTT_PortL, 60) clientL.connect(MQTTSERVERL, MQTT_PortL, 60)
except Exception as e: except Exception as e:
print ("Err3b:", e) logger.error(f"Err3B, {e}")
def StoreFloorPlan(deployment_id, layout): def StoreFloorPlan(deployment_id, layout):
@ -16892,9 +17082,6 @@ def optimized_radar_processing(my_data, start_time, id2well_id, device_id_2_thre
else: else:
radar_val = radar_read[field_index] radar_val = radar_read[field_index]
if well_id == 475:
logger.debug(".")
# Process presence data # Process presence data
if radar_val > threshold: if radar_val > threshold:
if deca < days_decas: if deca < days_decas:
@ -17140,7 +17327,7 @@ def StoreToDB(data):
logger.debug(sql) logger.debug(sql)
cur.execute(sql) cur.execute(sql)
except Exception as e: except Exception as e:
print ("Error in StoreToDB:", e) logger.debug(f"Error in StoreToDB: {e}")
def handle_telnyx_webhook(webhook_data, remote_addr, request_id): def handle_telnyx_webhook(webhook_data, remote_addr, request_id):
""" """
@ -20885,7 +21072,28 @@ class WellApi:
# chart_data with rooms : [list] # chart_data with rooms : [list]
deployment_id = form_data.get('deployment_id') deployment_id = form_data.get('deployment_id')
time_zone_s = GetTimeZoneOfDeployment(deployment_id) time_zone_s = GetTimeZoneOfDeployment(deployment_id)
selected_date = form_data.get('date')
ddate = form_data.get('date')
ddate = ddate.replace("_","-")
to_date = form_data.get('to_date')
if to_date == None:
to_date = ddate
else:
to_date = to_date.replace("_","-")
ddate, to_date = ensure_date_order(ddate, to_date)
d1 = datetime.datetime.strptime(ddate, '%Y-%m-%d')
d2 = datetime.datetime.strptime(to_date, '%Y-%m-%d')
days = (d2 - d1).days + 1 # +1 for inclusive count
radar_part = ""
sensor_data = {}
#days = (epoch_to_utc - epoch_from_utc) / (60 * 1440)
sensor = form_data.get('sensor') # one sensor sensor = form_data.get('sensor') # one sensor
radar_part = form_data.get('radar_part') radar_part = form_data.get('radar_part')
buckets = ['no', '10s', '1m', '5m', '10m', '15m', '30m', '1h'] buckets = ['no', '10s', '1m', '5m', '10m', '15m', '30m', '1h']
@ -20893,10 +21101,10 @@ class WellApi:
#bucket_size = res2 if (res := form_data.get('bucket_size')) is not None and (res2 := str(res).strip()) and res2 in {'no', '10s', '1m', '5m', '10m', '15m', '30m', '1h'} else 'no' #bucket_size = res2 if (res := form_data.get('bucket_size')) is not None and (res2 := str(res).strip()) and res2 in {'no', '10s', '1m', '5m', '10m', '15m', '30m', '1h'} else 'no'
data_type = form_data.get('data_type') data_type = form_data.get('data_type')
epoch_from_utc, epoch_to_utc = GetLocalTimeEpochsForDate(selected_date, time_zone_s) #>= #< epoch_from_utc, epoch_to_utc = GetLocalTimeEpochsForDate(ddate, time_zone_s, days) #>= #<
# obtain devices_list for deployment_id # obtain devices_list for deployment_id
selected_date = selected_date.replace("_","-")
#timee = LocalDateToUTCEpoch(selected_date, time_zone_s)+5 #timee = LocalDateToUTCEpoch(ddate, time_zone_s)+5
devices_list, device_ids = GetProximityList(deployment_id, epoch_from_utc) devices_list, device_ids = GetProximityList(deployment_id, epoch_from_utc)
sensor_data = {} sensor_data = {}
# see https://www.w3schools.com/cssref/css_colors.php # see https://www.w3schools.com/cssref/css_colors.php

17744
well-api2.py

File diff suppressed because it is too large Load Diff

13282
well-api3.py

File diff suppressed because it is too large Load Diff

19948
well-api4.py

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1436,9 +1436,17 @@ function getTimeZoneOffset(timeZone) {
} }
function getTimezoneDiffHours(targetTimezone) { function getTimezoneDiffHours(targetTimezone) {
const localDate = new Date(); const now = new Date();
const targetDate = new Date(localDate.toLocaleString(undefined, { timeZone: targetTimezone }));
return Math.round((targetDate - localDate) / (1000 * 60 * 60)); // Get UTC offset for local timezone (in minutes)
const localOffsetMin = now.getTimezoneOffset();
// Get UTC offset for target timezone
const targetStr = now.toLocaleString('en-US', { timeZone: targetTimezone, timeZoneName: 'shortOffset' });
const match = targetStr.match(/GMT([+-]\d+)/);
const targetOffsetHours = match ? parseInt(match[1]) : 0;
return targetOffsetHours + (localOffsetMin / 60);
} }
function DisplaySingleSlice(time_zone_st) { function DisplaySingleSlice(time_zone_st) {