Skip to content

Commit

Permalink
Optimize internal event, add restart service, and update statistic da…
Browse files Browse the repository at this point in the history
…tas (#36)

Optimize internal event, add restart service, and update statistic datas
  • Loading branch information
PoppyPop authored Aug 7, 2021
1 parent e8c2407 commit 5ad1aa0
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 7 deletions.
4 changes: 4 additions & 0 deletions createtty.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
#

socat -d -d -v pty,raw,echo=0,link=./reader pty,raw,echo=0,link=./writer
10 changes: 10 additions & 0 deletions custom_components/teleinformation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

async def async_setup(hass: HomeAssistant, config: Config):
"""Set up this integration using YAML is not supported."""

return True


Expand Down Expand Up @@ -52,6 +53,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):

entry.add_update_listener(_async_reload_entry)

def handle_restart(call):
"""Handle the service call."""
restart_usb_dongle = hass.data[DOMAIN][entry.entry_id][DATA_DONGLE]

restart_usb_dongle.stop_serial_read()
restart_usb_dongle.initialize_reading()

hass.services.async_register(DOMAIN, "restart", handle_restart)

return True


Expand Down
38 changes: 35 additions & 3 deletions custom_components/teleinformation/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from homeassistant.const import ENERGY_WATT_HOUR
from homeassistant.const import POWER_VOLT_AMPERE
from homeassistant.const import POWER_WATT
from homeassistant.util import dt

NAME = "TeleInformation"
DOMAIN = "teleinformation"
Expand Down Expand Up @@ -43,186 +44,217 @@
None,
None,
None,
None,
], # N° d’identification du compteur : ADCO(12 caractères)
"OPTARIF": [
"Option tarifaire",
None,
None,
None,
None,
], # Option tarifaire(type d’abonnement) : OPTARIF(4 car.)
"ISOUSC": [
"Intensité souscrite",
ELECTRIC_CURRENT_AMPERE,
DEVICE_CLASS_CURRENT,
None,
None,
], # Intensité souscrite : ISOUSC( 2 car.unité = ampères)
"HCHC": [
"Heures creuses",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
STATE_CLASS_MEASUREMENT,
dt.utc_from_timestamp(0),
], # Index heures creuses si option = heures creuses : HCHC( 9 car.unité = Wh)
"HCHP": [
"Heures pleines",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
STATE_CLASS_MEASUREMENT,
dt.utc_from_timestamp(0),
], # Index heures pleines si option = heures creuses : HCHP( 9 car.unité = Wh)
"PTEC": [
"Période Tarifaire",
None,
None,
None,
None,
], # Période tarifaire en cours : PTEC( 4 car.)
"IINST": [
"Intensite instantanee",
ELECTRIC_CURRENT_AMPERE,
DEVICE_CLASS_CURRENT,
STATE_CLASS_MEASUREMENT,
None,
], # Intensité instantanée : IINST( 3 car.unité = ampères)
"IINST1": [
"Intensite instantanee phase 1",
ELECTRIC_CURRENT_AMPERE,
DEVICE_CLASS_CURRENT,
STATE_CLASS_MEASUREMENT,
None,
], # Intensité instantanée : IINST( 3 car.unité = ampères)
"IINST2": [
"Intensite instantanee phase 2",
ELECTRIC_CURRENT_AMPERE,
DEVICE_CLASS_CURRENT,
STATE_CLASS_MEASUREMENT,
None,
], # Intensité instantanée : IINST( 3 car.unité = ampères)
"IINST3": [
"Intensite instantanee phase 3",
ELECTRIC_CURRENT_AMPERE,
DEVICE_CLASS_CURRENT,
STATE_CLASS_MEASUREMENT,
None,
], # Intensité instantanée : IINST( 3 car.unité = ampères)
"IMAX": [
"Intensite max",
ELECTRIC_CURRENT_AMPERE,
DEVICE_CLASS_CURRENT,
None,
None,
], # Intensité maximale : IMAX( 3 car.unité = ampères)
"IMAX1": [
"Intensite max phase 1",
ELECTRIC_CURRENT_AMPERE,
DEVICE_CLASS_CURRENT,
None,
None,
], # Intensité maximale : IMAX( 3 car.unité = ampères)
"IMAX2": [
"Intensite max phase 2",
ELECTRIC_CURRENT_AMPERE,
DEVICE_CLASS_CURRENT,
None,
None,
], # Intensité maximale : IMAX( 3 car.unité = ampères)
"IMAX3": [
"Intensite max phase 3",
ELECTRIC_CURRENT_AMPERE,
DEVICE_CLASS_CURRENT,
None,
None,
], # Intensité maximale : IMAX( 3 car.unité = ampères)
"PMAX": [
"Puissance maximale triphasée atteinte",
POWER_WATT,
DEVICE_CLASS_POWER,
None,
None,
], # Puissance apparente : PAPP( 5 car.unité = Volt.ampères)
"PAPP": [
"Puissance apparente",
POWER_VOLT_AMPERE,
DEVICE_CLASS_POWER,
STATE_CLASS_MEASUREMENT,
None,
], # Puissance apparente : PAPP( 5 car.unité = Volt.ampères)
"HHPHC": [
"Groupe horaire",
None,
None,
None,
None,
], # Groupe horaire si option = heures creuses ou tempo : HHPHC(1 car.)
"MOTDETAT": [
"Mot d etat",
None,
None,
None,
None,
], # Mot d’état(autocontrôle) : MOTDETAT(6 car.)
"BASE": [
"Base",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
STATE_CLASS_MEASUREMENT,
dt.utc_from_timestamp(0),
], # Index si option = base : BASE( 9 car.unité = Wh)
"EJPHN": [
"EJP Heures normales",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
None,
], # Index heures normales si option = EJP : EJP HN( 9 car.unité = Wh)</para>
"EJPHPM": [
"EJP Heures de pointe",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
None,
], # Index heures de pointe mobile si option = EJP : EJP HPM( 9 car.unité = Wh)</para>
"PEJP": [
"EJP Préavis",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
None,
], # Préavis EJP si option = EJP : PEJP( 2 car.) 30mn avant période EJP</para>
"BBRHCJB": [
"Tempo heures bleues creuses",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
None,
], # Index heures creuses jours bleus si option = tempo : BBR HC JB( 9 car.unité = Wh)</para>
"BBRHPJB": [
"Tempo heures bleues pleines",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
None,
], # Index heures pleines jours bleus si option = tempo : BBR HP JB( 9 car.unité = Wh)</para>
"BBRHCJW": [
"Tempo heures blanches creuses",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
None,
], # Index heures creuses jours blancs si option = tempo : BBR HC JW( 9 car.unité = Wh)</para>
"BBRHPJW": [
"Tempo heures blanches pleines",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
None,
], # Index heures pleines jours blancs si option = tempo : BBR HP JW( 9 car.unité = Wh)</para>
"BBRHCJR": [
"Tempo heures rouges creuses",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
None,
], # Index heures creuses jours rouges si option = tempo : BBR HC JR( 9 car.unité = Wh)</para>
"BBRHPJR": [
"Tempo heures rouges pleines",
ENERGY_WATT_HOUR,
DEVICE_CLASS_ENERGY,
None,
None,
], # Index heures pleines jours rouges si option = tempo : BBR HP JR( 9 car.unité = Wh)</para>
"DEMAIN": [
"Tempo couleur demain",
None,
None,
None,
None,
], # Couleur du lendemain si option = tempo : DEMAIN</para>
"ADPS": [
"Dépassement Puissance",
None,
None,
None,
None,
], # Avertissement de dépassement de puissance souscrite : ADPS( 3 car.unité = ampères) (message émis uniquement en cas de dépassement effectif, dans ce cas il est immédiat)</para>
"PPOT": [
"Présence des potentiels ",
None,
None,
None,
None,
], # Présence des potentiels : PPOT ( 2 car.) </para>
}

Expand Down
13 changes: 10 additions & 3 deletions custom_components/teleinformation/dongle.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ async def serial_read(self):
else:

is_over = True
currentframe = {}

while True:
try:
Expand Down Expand Up @@ -125,14 +126,19 @@ async def serial_read(self):
name = name.decode()
value = value.decode()
_LOGGER.debug("Got : [%s] = (%s)", name, value)
self.hass.helpers.dispatcher.dispatcher_send(
SIGNAL_RECEIVE_MESSAGE, {name: value}
)

currentframe[name] = value

if name == "ADCO" and self.device_id is None:
self.device_id = value

if (not is_over) and (b"\x03" in line):
is_over = True

self.hass.helpers.dispatcher.dispatcher_send(
SIGNAL_RECEIVE_MESSAGE, currentframe
)

_LOGGER.debug(" End Frame")
continue

Expand All @@ -155,6 +161,7 @@ def stop_serial_read(self):
"""Close resources."""
if self._serial_loop_task:
self._serial_loop_task.cancel()
self._serial_loop_task = None


async def detect():
Expand Down
7 changes: 6 additions & 1 deletion custom_components/teleinformation/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,14 @@ def state(self):

@property
def state_class(self):
"""Return the state of the device."""
"""Return the state_class of the device."""
return SENSOR_TYPES[self.dev_name][3]

@property
def last_reset(self):
"""Return the last_reset of the device."""
return SENSOR_TYPES[self.dev_name][4]

@property
def available(self) -> bool:
"""Return True if entity is available."""
Expand Down
8 changes: 8 additions & 0 deletions custom_components/teleinformation/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Example services.yaml entry

# Service ID
restart:
# Service name as shown in UI
name: Restart serial reading
# Description of the service
description: Restart the serial reader
43 changes: 43 additions & 0 deletions serialWrite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import logging
import time

import serial

ser = serial.Serial(
port="/workspaces/integration_teleinformation/writer",
baudrate=1200,
# bytesize=7,
# parity=serial.PARITY_EVEN,
# stopbits=serial.STOPBITS_ONE
)
count = 0
_LOGGER = logging.getLogger(__name__)


def getFrameWithCheckSum(frame):
"""Check if a frame is valid."""
datas = frame.encode("ascii")
computed_checksum = (sum(datas) & 0x3F) + 0x20

return (frame + " " + chr(computed_checksum) + "\n").encode("ascii")


while 1:
ser.write(b"\x02\n")
ser.write(b"ADCO 700801422425 :\n")
ser.write(b"OPTARIF BASE 0\n")
ser.write(b"ISOUSC 30 9\n")
# ser.write(b'BASE 008528238 /\n')

ser.write(getFrameWithCheckSum("BASE " + str(count)))

ser.write(b"PTEC TH.. $\n")
ser.write(b"IINST 002 Y\n")
ser.write(b"IMAX 090 H\n")
ser.write(b"PAPP 00360 *\n")
ser.write(b"\x03\n")

_LOGGER.log(0, "Frame")

time.sleep(5)
count += 1

0 comments on commit 5ad1aa0

Please sign in to comment.