[DEV] add capability to get the data with the python timestamps

This commit is contained in:
Edouard DUPIN 2023-02-17 19:04:04 +01:00
parent f30c8d30db
commit 10d6edad5a
10 changed files with 132 additions and 26 deletions

View File

@ -22,7 +22,7 @@
<dependency> <dependency>
<groupId>kangaroo-and-rabbit</groupId> <groupId>kangaroo-and-rabbit</groupId>
<artifactId>archidata</artifactId> <artifactId>archidata</artifactId>
<version>0.3.1</version> <version>0.3.3</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -80,6 +80,7 @@ public class WebLauncher {
rc.registerClasses(StateHistoryResource.class); rc.registerClasses(StateHistoryResource.class);
rc.registerClasses(LogResource.class); rc.registerClasses(LogResource.class);
rc.registerClasses(HealthCheck.class); rc.registerClasses(HealthCheck.class);
rc.registerClasses(Front.class); rc.registerClasses(Front.class);

View File

@ -13,7 +13,7 @@ import jakarta.ws.rs.core.Response.ResponseBuilder;
import org.kar.archidata.api.FrontGeneric; import org.kar.archidata.api.FrontGeneric;
import org.kar.karanage.util.ConfigVariable; import org.kar.karanage.util.ConfigVariable;
@Path("/karanage") @Path("/front")
public class Front extends FrontGeneric { public class Front extends FrontGeneric {
public Front() { public Front() {
this.baseFrontFolder = ConfigVariable.getFrontFolder(); this.baseFrontFolder = ConfigVariable.getFrontFolder();

View File

@ -52,7 +52,8 @@ public class LogResource {
@PathParam("system") String system, @PathParam("system") String system,
@QueryParam("since") String since, @QueryParam("since") String since,
@QueryParam("sinceId") Integer sinceId, @QueryParam("sinceId") Integer sinceId,
@QueryParam("limit") Integer limit) throws Exception { @QueryParam("limit") Integer limit,
@QueryParam("mode") String mode) throws Exception {
// Keep Group ID: // Keep Group ID:
if (groupName == null || groupName.length() == 0) { if (groupName == null || groupName.length() == 0) {
throw new InputException("group", "Missing URL parameter /state/{group}/..."); throw new InputException("group", "Missing URL parameter /state/{group}/...");
@ -136,7 +137,17 @@ public class LogResource {
} else { } else {
out.append(","); out.append(",");
} }
out.append("{ \"id\": " + data.id + ", \"time\": \"" + data.create_date.toInstant().toString() + "\", \"data\":" + data.data + "}"); out.append("{ \"id\": " + data.id + ", \"time\": ");
if ("raw".equals(mode)) {
double seconds = data.create_date.toInstant().toEpochMilli() * 0.001;
out.append(seconds);
} else {
out.append("\"");
out.append(data.create_date.toInstant().toString());
out.append("\"");
}
out.append(", \"data\":" + data.data + "}");
} }
out.append("]"); out.append("]");
return out.toString(); return out.toString();

View File

@ -33,7 +33,8 @@ public class StateHistoryResource {
@PathParam("topic") String topic, @PathParam("topic") String topic,
@QueryParam("since") String since, @QueryParam("since") String since,
@QueryParam("sinceId") Integer sinceId, @QueryParam("sinceId") Integer sinceId,
@QueryParam("limit") Integer limit) throws Exception { @QueryParam("limit") Integer limit,
@QueryParam("mode") String mode) throws Exception {
// Keep Group ID: // Keep Group ID:
if (groupName == null || groupName.length() == 0) { if (groupName == null || groupName.length() == 0) {
throw new InputException("group", "Missing URL parameter /state/{group}/..."); throw new InputException("group", "Missing URL parameter /state/{group}/...");
@ -117,7 +118,16 @@ public class StateHistoryResource {
} else { } else {
out.append(","); out.append(",");
} }
out.append("{ \"id\": " + data.id + ", \"time\": \"" + data.modify_date.toInstant().toString() + "\", \"data\":" + data.data + "}"); out.append("{ \"id\": " + data.id + ", \"time\": ");
if ("raw".equals(mode)) {
double seconds = data.modify_date.toInstant().toEpochMilli() * 0.001;
out.append(seconds);
} else {
out.append("\"");
out.append(data.modify_date.toInstant().toString());
out.append("\"");
}
out.append(", \"data\":" + data.data + "}");
} }
out.append("]"); out.append("]");
return out.toString(); return out.toString();

View File

@ -33,7 +33,8 @@ public class StateResource {
public static String getWithTopic( public static String getWithTopic(
@PathParam("group") String groupName, @PathParam("group") String groupName,
@PathParam("topic") String topic, @PathParam("topic") String topic,
@QueryParam("since") String since) throws Exception { @QueryParam("since") String since,
@QueryParam("mode") String mode) throws Exception {
if (groupName == null || groupName.length() == 0) { if (groupName == null || groupName.length() == 0) {
throw new InputException("group", "Missing URL parameter /state/{group}/..."); throw new InputException("group", "Missing URL parameter /state/{group}/...");
} }
@ -74,7 +75,28 @@ public class StateResource {
throw new FailException(Response.Status.NOT_FOUND, "Topic does not exist: '" + topic + "'"); throw new FailException(Response.Status.NOT_FOUND, "Topic does not exist: '" + topic + "'");
} }
} }
return "{ \"time\": \"" + data.modify_date.toInstant().toString() + "\", \"data\":" + data.data + "}"; StringBuilder out = new StringBuilder("{ \"time\": ");
if ("raw".equals(mode)) {
double seconds = data.modify_date.toInstant().toEpochMilli() * 0.001;
out.append(seconds);
return "{ \"time\": " + seconds + ", \"data\":" + data.data + "}";
} else {
out.append("\"");
out.append(data.modify_date.toInstant().toString());
out.append("\"");
}
out.append(", \"state\":");
if (data.state == null) {
out.append("null");
} else {
out.append("\"");
out.append(data.state);
out.append("\"");
}
out.append(", \"data\":");
out.append(data.data);
out.append("}");
return out.toString();
} }
@GET @GET
@ -83,7 +105,8 @@ public class StateResource {
@PermitAll @PermitAll
public String get( public String get(
@PathParam("group") String groupName, @PathParam("group") String groupName,
@QueryParam("since") String since) throws Exception { @QueryParam("since") String since,
@QueryParam("mode") String mode) throws Exception {
if (groupName == null || groupName.length() == 0) { if (groupName == null || groupName.length() == 0) {
throw new InputException("group", "Missing URL parameter /state/{group}/..."); throw new InputException("group", "Missing URL parameter /state/{group}/...");
} }
@ -125,7 +148,24 @@ public class StateResource {
} else { } else {
out.append(","); out.append(",");
} }
out.append("{ \"time\": \"" + data.modify_date.toInstant().toString() + "\", \"topic\": \"" + data.topic + "\", \"data\":" + data.data + "}"); out.append("{ \"time\": ");
if ("raw".equals(mode)) {
double seconds = data.modify_date.toInstant().toEpochMilli() * 0.001;
out.append(seconds);
} else {
out.append("\"");
out.append(data.modify_date.toInstant().toString());
out.append("\"");
}
out.append(", \"state\":");
if (data.state == null) {
out.append("null");
} else {
out.append("\"");
out.append(data.state);
out.append("\"");
}
out.append(", \"topic\": \"" + data.topic + "\", \"data\":" + data.data + "}");
} }
out.append("]"); out.append("]");
return out.toString(); return out.toString();

View File

@ -5,6 +5,7 @@ import json
from pathlib import Path from pathlib import Path
import subprocess import subprocess
import time import time
from datetime import timezone
from typing import Dict, List from typing import Dict, List
from karanage import ( from karanage import (
@ -21,6 +22,8 @@ if __name__ == '__main__':
parser.add_argument("-C", "--connection", type=str, help="json configuration file") parser.add_argument("-C", "--connection", type=str, help="json configuration file")
parser.add_argument("-t", "--topic", type=str, help="Topic of the message") parser.add_argument("-t", "--topic", type=str, help="Topic of the message")
parser.add_argument("-s", "--since", type=str, help="Iso date since the value time must be") parser.add_argument("-s", "--since", type=str, help="Iso date since the value time must be")
parser.add_argument("-w", "--watch", help="Display new states", action='store_true')
# This element are read from the connection file: # This element are read from the connection file:
parser.add_argument("-u", "--url", type=str, help="Base URL of the web service") parser.add_argument("-u", "--url", type=str, help="Base URL of the web service")
@ -39,6 +42,14 @@ if __name__ == '__main__':
# create the rest interface of karanage # create the rest interface of karanage
stateInterface = KaranageState(connection) stateInterface = KaranageState(connection)
data = stateInterface.gets(topic=args.topic, since=args.since) # transform since in a datetime:
print(f"Ret = {json.dumps(data, indent=4)}") while True:
data = stateInterface.gets(topic=args.topic, since=args.since)
for elem in data:
print(f"{elem.topic} @ {elem.time.astimezone()} => {elem.state}");
print(json.dumps(elem.data, indent=4))
args.since = elem.time
if not args.watch:
break
else:
time.sleep(1)

View File

@ -1 +1 @@
0.5.0-dev 0.6.0-dev

View File

@ -9,8 +9,9 @@
## ##
import enum import enum
import json import json
from typing import Dict, Optional from typing import Dict, Optional, Union, List, NamedTuple
from datetime import datetime, timezone
import requests import requests
from .connection import KaranageConnectionInterface from .connection import KaranageConnectionInterface
@ -22,6 +23,21 @@ class StateSystem(enum.Enum):
FAIL = "FAIL" FAIL = "FAIL"
DOWN = "DOWN" DOWN = "DOWN"
class StateData(NamedTuple):
topic: str
time: datetime
state: str
data: Dict
def convert_to_state_data(json_data: Dict, topic:Optional[str] = None) -> StateData:
time = datetime.fromtimestamp(json_data["time"], timezone.utc)
if topic is not None:
topic = topic
else:
topic = json_data["topic"]
return StateData(topic, time, json_data["state"], json_data["data"])
## Generic karanage sending system. ## Generic karanage sending system.
class KaranageState: class KaranageState:
@ -53,40 +69,57 @@ class KaranageState:
f"Fail send message: '{ret.url}'", ret.status, ret.data f"Fail send message: '{ret.url}'", ret.status, ret.data
) )
def gets(self, topic: Optional[str] = None, since: Optional[str] = None) -> Dict: def gets(self, topic: Optional[str] = None, since: Union[None, str, datetime] = None) -> List[StateData]:
"""Get all the topic fom the server. """Get all the topic fom the server.
:param since: ISO1866 time value. :param since: ISO1866 time value.
:return: A dictionary with the requested data. :return: A dictionary with the requested data.
""" """
param = {} param = {
"mode":"raw" # request raw mode to have the timestant in a float in second
}
if since is not None: if since is not None:
param["since"] = since if since is str:
param["since"] = since
else:
param["since"] = since.replace(tzinfo=timezone.utc).isoformat()
ret = self.connection.get("state", topic, params=param) ret = self.connection.get("state", topic, params=param)
if 200 <= ret.status <= 299: if 200 <= ret.status <= 299:
return json.loads(ret.data) out: List[StateData] = []
for elem in json.loads(ret.data):
out.append(convert_to_state_data(elem, topic))
return out
raise KaranageException(f"Fail get data: '{ret.url}'", ret.status, ret.data) raise KaranageException(f"Fail get data: '{ret.url}'", ret.status, ret.data)
def get_history( def get_history(
self, self,
topic: Optional[str] = None, topic: Optional[str] = None,
since: Optional[str] = None, since: Union[None, str, datetime] = None,
since_id: Optional[int] = None, since_id: Optional[int] = None,
limit: Optional[int] = None, limit: Optional[int] = None,
) -> Dict: ) -> List[StateData]:
"""Get all the topic fom the server. """Get all the topic fom the server.
:param since: ISO1866 time value. :param since: ISO1866 time value.
:param since_id: remote BDD index of the field. :param since_id: remote BDD index of the field.
:param limit: the number of value we want to get :param limit: the number of value we want to get
:return: A dictionary with the requested data. :return: A dictionary with the requested data.
""" """
param = {} param = {
"mode":"raw" # request raw mode to have the timestant in a float in second
}
if since is not None: if since is not None:
param["since"] = since if since is str:
param["since"] = since
else:
param["since"] = since.replace(tzinfo=timezone.utc).isoformat()
if since_id is not None: if since_id is not None:
param["sinceId"] = since_id param["sinceId"] = since_id
if limit is not None: if limit is not None:
param["limit"] = limit param["limit"] = limit
ret = self.connection.get("state_history", topic, params=param) ret = self.connection.get("state_history", topic, params=param)
if 200 <= ret.status <= 299: if 200 <= ret.status <= 299:
return json.loads(ret.data) out: List[StateData] = []
for elem in json.loads(ret.data):
out.append(convert_to_state_data(elem, topic))
return out
raise KaranageException(f"Fail get data: '{ret.url}'", ret.status, ret.data) raise KaranageException(f"Fail get data: '{ret.url}'", ret.status, ret.data)

View File

@ -1 +1 @@
0.5.0-dev 0.6.0-dev